create-agent-skills 1.1.5 → 1.1.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/README.md +9 -5
- package/package.json +1 -1
- package/skills/lumi-tester/SKILL.md +288 -0
- package/skills/lumi-tester/examples/add-zoom-command.md +82 -0
- package/skills/lumi-tester/resources/common-pitfalls.md +58 -0
- package/skills/lumi-tester/resources/core-architecture.md +51 -0
- package/skills/project-documentation/SKILL.md +117 -0
- package/skills/project-documentation/examples/example_usage.md +74 -0
- package/skills/project-documentation/resources/standards.md +11 -0
- package/skills/project-documentation/resources/templates/architecture.md +22 -0
- package/skills/project-documentation/resources/templates/feature_guide.md +35 -0
- package/skills/project-documentation/resources/templates/flow.md +41 -0
- package/skills/project-documentation/resources/templates/setup.md +29 -0
- package/skills/project-documentation/resources/templates/technical_reference.md +24 -0
- package/skills/project-documentation/resources/templates/troubleshooting.md +17 -0
- package/skills/project-documentation/scripts/analyze_codebase.py +192 -0
- package/skills/remotion/SKILL.md +109 -0
- package/skills/remotion/resources/3d.md +86 -0
- package/skills/remotion/resources/animations.md +29 -0
- package/skills/remotion/resources/assets/charts-bar-chart.tsx +173 -0
- package/skills/remotion/resources/assets/text-animations-typewriter.tsx +100 -0
- package/skills/remotion/resources/assets/text-animations-word-highlight.tsx +108 -0
- package/skills/remotion/resources/assets.md +78 -0
- package/skills/remotion/resources/audio.md +172 -0
- package/skills/remotion/resources/calculate-metadata.md +104 -0
- package/skills/remotion/resources/can-decode.md +75 -0
- package/skills/remotion/resources/charts.md +58 -0
- package/skills/remotion/resources/compositions.md +146 -0
- package/skills/remotion/resources/display-captions.md +126 -0
- package/skills/remotion/resources/extract-frames.md +229 -0
- package/skills/remotion/resources/fonts.md +152 -0
- package/skills/remotion/resources/get-audio-duration.md +58 -0
- package/skills/remotion/resources/get-video-dimensions.md +68 -0
- package/skills/remotion/resources/get-video-duration.md +58 -0
- package/skills/remotion/resources/gifs.md +138 -0
- package/skills/remotion/resources/images.md +130 -0
- package/skills/remotion/resources/import-srt-captions.md +67 -0
- package/skills/remotion/resources/lottie.md +68 -0
- package/skills/remotion/resources/measuring-dom-nodes.md +35 -0
- package/skills/remotion/resources/measuring-text.md +143 -0
- package/skills/remotion/resources/sequencing.md +106 -0
- package/skills/remotion/resources/tailwind.md +11 -0
- package/skills/remotion/resources/text-animations.md +20 -0
- package/skills/remotion/resources/timing.md +179 -0
- package/skills/remotion/resources/transcribe-captions.md +19 -0
- package/skills/remotion/resources/transitions.md +122 -0
- package/skills/remotion/resources/trimming.md +53 -0
- package/skills/remotion/resources/videos.md +171 -0
- package/skills/tauri-v2/SKILL.md +2 -0
- package/skills/threejs/SKILL.md +273 -0
- package/skills/threejs/resources/animation.md +163 -0
- package/skills/threejs/resources/fundamentals.md +206 -0
- package/skills/threejs/resources/geometry.md +179 -0
- package/skills/threejs/resources/interaction.md +252 -0
- package/skills/threejs/resources/lighting.md +173 -0
- package/skills/threejs/resources/loaders.md +195 -0
- package/skills/threejs/resources/materials.md +230 -0
- package/skills/threejs/resources/postprocessing.md +200 -0
- package/skills/threejs/resources/shaders.md +195 -0
- package/skills/threejs/resources/textures.md +178 -0
- package/skills/documentation/SKILL.md +0 -222
- package/skills/maestro-testing/SKILL.md +0 -691
- package/skills/maestro-testing/examples/checkout-flow.md +0 -246
- package/skills/maestro-testing/examples/login-flow.md +0 -164
- package/skills/maestro-testing/examples/project-structure.md +0 -245
- package/skills/maestro-testing/resources/commands-reference.md +0 -142
package/README.md
CHANGED
|
@@ -5,13 +5,13 @@ CLI tool to install Agent Skills for AI coding assistants.
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx create-agent-skills
|
|
8
|
+
npx create-agent-skills@latest
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
Or install globally:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npm install -g create-agent-skills
|
|
14
|
+
npm install -g create-agent-skills@latest
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Usage
|
|
@@ -19,7 +19,7 @@ npm install -g create-agent-skills
|
|
|
19
19
|
Run the CLI and follow the interactive prompts:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
npx create-agent-skills
|
|
22
|
+
npx create-agent-skills@latest
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
### Options
|
|
@@ -40,15 +40,19 @@ npx create-agent-skills
|
|
|
40
40
|
|-------|-------------|
|
|
41
41
|
| `code-review` | Reviews code for bugs, style, and security issues |
|
|
42
42
|
| `create-agent-skill` | Helps create new skills following guidelines |
|
|
43
|
-
| `
|
|
43
|
+
| `flutter-clean-arch` | Flutter Clean Architecture using BLoC, Dio, and GetIt |
|
|
44
44
|
| `git-commit` | Writes conventional commit messages |
|
|
45
45
|
| `git-pr` | Creates well-structured pull requests |
|
|
46
46
|
| `git-review` | Reviews PRs for code quality and best practices |
|
|
47
|
-
| `
|
|
47
|
+
| `landing-page-slider` | Landing pages with integrated slider for presentations |
|
|
48
|
+
| `lumi-tester` | Guide for extending the Lumi Tester framework |
|
|
49
|
+
| `project-documentation` | Generates comprehensive documentation for existing projects |
|
|
50
|
+
| `remotion` | Create videos programmatically in React |
|
|
48
51
|
| `rust-backend` | Build backend services with Rust and Clean Architecture |
|
|
49
52
|
| `tailwindcss-v4` | Tailwind CSS v4 setup and migration guide |
|
|
50
53
|
| `tauri-v2` | Build desktop apps with Tauri v2 + React |
|
|
51
54
|
| `testing` | Helps write unit, integration, and E2E tests |
|
|
55
|
+
| `threejs` | Complete Three.js development guide |
|
|
52
56
|
|
|
53
57
|
## Creating New Skills
|
|
54
58
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lumi-tester
|
|
3
|
+
description: Comprehensive guide for extending the Lumi Tester framework. Use when adding new commands, selectors, or debugging the test runner.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Lumi Tester Development
|
|
7
|
+
|
|
8
|
+
This skill provides a step-by-step guide for extending the Lumi Tester automation framework. It covers adding new commands, selectors, and debugging workflows.
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
- Use when **adding a new automation command** (e.g., `scanBarcode`, `zoomIn`).
|
|
13
|
+
- Use when **adding a new selector strategy** (e.g., `barcode: "..."`, `ai_description: "..."`).
|
|
14
|
+
- Use when **debugging** command execution or driver issues.
|
|
15
|
+
- Use when **understanding the architecture** of `lumi-tester`.
|
|
16
|
+
|
|
17
|
+
## Architecture Overview
|
|
18
|
+
|
|
19
|
+
For a deep dive into the internal logic, see [Core Architecture & Internals](resources/core-architecture.md).
|
|
20
|
+
|
|
21
|
+
1. **Parser** (`src/parser/types.rs`): deserializes YAML to `TestCommand` enums.
|
|
22
|
+
2. **Executor** (`src/runner/executor.rs`): orchestrates execution, managing context (`TestContext`) and flow (`TestSessionState`). Handles logic *around* the driver (retries, logging, flow control).
|
|
23
|
+
3. **Driver Trait** (`src/driver/traits.rs`): defines the abstract `PlatformDriver` interface. Handles direct device interactions.
|
|
24
|
+
4. **Implementations** (`src/driver/<platform>/driver.rs`): concrete implementations for Android (ADB), iOS (IDB/WDA), and Web (Playwright).
|
|
25
|
+
|
|
26
|
+
## How to use
|
|
27
|
+
|
|
28
|
+
### Workflow 1: Add a New Command
|
|
29
|
+
|
|
30
|
+
Follow this strict order to ensure all layers are covered.
|
|
31
|
+
|
|
32
|
+
#### Step 1: Define Parser (`src/parser/types.rs`)
|
|
33
|
+
|
|
34
|
+
1. Add a `struct` for your command parameters (if it takes arguments).
|
|
35
|
+
```rust
|
|
36
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
37
|
+
#[serde(rename_all = "camelCase")] // Ensures camelCase in YAML maps to struct fields
|
|
38
|
+
pub struct MyNewCommandParams {
|
|
39
|
+
pub target: String,
|
|
40
|
+
#[serde(default)]
|
|
41
|
+
pub duration: Option<u64>,
|
|
42
|
+
/// Optional label for custom logging (e.g., "Press Login Button")
|
|
43
|
+
#[serde(default)]
|
|
44
|
+
pub label: Option<String>,
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
2. Add a variant to the `TestCommand` enum.
|
|
48
|
+
```rust
|
|
49
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
50
|
+
#[serde(rename_all = "camelCase")]
|
|
51
|
+
pub enum TestCommand {
|
|
52
|
+
// ...
|
|
53
|
+
#[serde(alias = "myCmd")] // Optional alias for YAML convenience
|
|
54
|
+
MyNewCommand(MyNewCommandParams), // or MyNewCommand, if no params
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
#### Step 2: Define Interface (`src/driver/traits.rs`)
|
|
59
|
+
|
|
60
|
+
1. Add the method signature to the `PlatformDriver` trait.
|
|
61
|
+
```rust
|
|
62
|
+
#[async_trait]
|
|
63
|
+
pub trait PlatformDriver: Send + Sync {
|
|
64
|
+
// ...
|
|
65
|
+
async fn my_new_command(&self, target: &str, duration: Option<u64>) -> Result<()>;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
2. (Optional) Provide a default implementation returning `Err("Not implemented")` if it's not supported on all platforms immediately.
|
|
69
|
+
|
|
70
|
+
#### Step 3: Integrate Executor (`src/runner/executor.rs`)
|
|
71
|
+
|
|
72
|
+
1. Locate `async fn execute_command`.
|
|
73
|
+
2. Add a match arm for your new command variant.
|
|
74
|
+
```rust
|
|
75
|
+
TestCommand::MyNewCommand(params) => {
|
|
76
|
+
println!(" {} Executing MyNewCommand...", "➤".blue());
|
|
77
|
+
// Verify selector if needed
|
|
78
|
+
// let selector = self.build_selector(..., params.ocr, ...)?;
|
|
79
|
+
self.driver.my_new_command(¶ms.target, params.duration).await?;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Step 4: Implement Driver Logic (`src/driver/<platform>/driver.rs`)
|
|
84
|
+
|
|
85
|
+
Implement the trait method for **EACH** supported platform (`android`, `ios`, `web`).
|
|
86
|
+
|
|
87
|
+
**Android (`src/driver/android/driver.rs`):**
|
|
88
|
+
```rust
|
|
89
|
+
async fn my_new_command(&self, target: &str, duration: Option<u64>) -> Result<()> {
|
|
90
|
+
// Use adb or uiautomator
|
|
91
|
+
adb::exec_command(&self.serial, &["shell", "input", ...]).await?;
|
|
92
|
+
Ok(())
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**iOS (`src/driver/ios/driver.rs`):**
|
|
97
|
+
```rust
|
|
98
|
+
async fn my_new_command(&self, target: &str, duration: Option<u64>) -> Result<()> {
|
|
99
|
+
// Use idb or WDA
|
|
100
|
+
self.wda_client.lock().await.perform_action(...).await?;
|
|
101
|
+
Ok(())
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Web (`src/driver/web/driver.rs`):**
|
|
106
|
+
```rust
|
|
107
|
+
async fn my_new_command(&self, target: &str, duration: Option<u64>) -> Result<()> {
|
|
108
|
+
let page = self.page.lock().await;
|
|
109
|
+
page.evaluate_js(...).await?;
|
|
110
|
+
Ok(())
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### Step 5: Update Documentation (`docs/commands.md`)
|
|
115
|
+
|
|
116
|
+
Add your new command to `lumi-tester/docs/commands.md`.
|
|
117
|
+
- Add to the Table of Contents if necessary.
|
|
118
|
+
- Add a new section with **Description**, **Example YAML**, and **Parameters Table**.
|
|
119
|
+
|
|
120
|
+
#### Step 6: Update VS Code Extension (`lumi-tester-vscode`)
|
|
121
|
+
|
|
122
|
+
Update `src/schema/commands.ts` in the `lumi-tester-vscode` repo to enable IntelliSense.
|
|
123
|
+
|
|
124
|
+
1. Add a new object to the `LUMI_COMMANDS` array:
|
|
125
|
+
```typescript
|
|
126
|
+
{
|
|
127
|
+
name: 'myNewCommand',
|
|
128
|
+
category: 'Interaction', // or 'App Management', 'Control Flow'...
|
|
129
|
+
description: 'Description of what it does',
|
|
130
|
+
hasParams: true,
|
|
131
|
+
snippet: 'myNewCommand:\n target: "$1"', // VS Code snippet
|
|
132
|
+
params: [
|
|
133
|
+
{ name: 'target', type: 'string', description: 'Target element' },
|
|
134
|
+
{ name: 'duration', type: 'number', description: 'Duration in ms' },
|
|
135
|
+
// For complex objects, use a rich snippet in the param definition:
|
|
136
|
+
{
|
|
137
|
+
name: 'ocr',
|
|
138
|
+
type: 'object',
|
|
139
|
+
description: 'Find by OCR',
|
|
140
|
+
snippet: 'ocr:\n text: "${1:text_to_find}"\n region: "${2|all,center|}"'
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
},
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
> [!TIP]
|
|
147
|
+
> **Rich Snippets**: For complex object parameters (like `ocr`, `permissions`), add a `snippet` field to the parameter definition. This allows users to tab through properties (e.g., `text`, `region`) instead of just getting a generic completion.
|
|
148
|
+
|
|
149
|
+
Selectors allow finding elements in different ways (Text, ID, OCR, etc.).
|
|
150
|
+
|
|
151
|
+
#### Step 1: Define Selector (`src/driver/traits.rs`)
|
|
152
|
+
|
|
153
|
+
Add a variant to the `Selector` enum.
|
|
154
|
+
|
|
155
|
+
```rust
|
|
156
|
+
#[derive(Debug, Clone, PartialEq)]
|
|
157
|
+
pub enum Selector {
|
|
158
|
+
// ...
|
|
159
|
+
MySelector(String, usize), // args: query, index
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### Step 2: Update Parameter Structs (`src/parser/types.rs`)
|
|
164
|
+
|
|
165
|
+
If your selector needs specific parameters in command definitions (like `ocr: true` or `ocr: { text: ... }`), update the relevant parameter structs (e.g., `TapParams`, `AssertParams`).
|
|
166
|
+
|
|
167
|
+
```rust
|
|
168
|
+
pub struct TapParams {
|
|
169
|
+
// ...
|
|
170
|
+
pub my_selector: Option<String>,
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### Step 3: Builder Logic (`src/runner/executor.rs`)
|
|
175
|
+
|
|
176
|
+
Update the `build_selector` function signature and logic.
|
|
177
|
+
|
|
178
|
+
1. Update function signature to accept your new parameter.
|
|
179
|
+
2. Add logic to build the `Selector`.
|
|
180
|
+
|
|
181
|
+
```rust
|
|
182
|
+
fn build_selector(
|
|
183
|
+
// ... existing params
|
|
184
|
+
my_param: &Option<String>, // Add your new param here
|
|
185
|
+
) -> Result<Selector> {
|
|
186
|
+
// ...
|
|
187
|
+
if let Some(query) = my_param {
|
|
188
|
+
return Ok(Selector::MySelector(query.clone(), 0));
|
|
189
|
+
}
|
|
190
|
+
// ...
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
> [!IMPORTANT]
|
|
195
|
+
> You MUST update **ALL** call sites of `build_selector` in `executor.rs` (e.g., inside `TapOn`, `AssertVisible`, etc.) to pass the new parameter. Usually pass `&None` or `¶ms.my_param`.
|
|
196
|
+
|
|
197
|
+
#### Step 4: Implement Finding Logic (`src/driver/<platform>/driver.rs`)
|
|
198
|
+
|
|
199
|
+
Update `find_element` (or equivalent internal finder) for each platform.
|
|
200
|
+
|
|
201
|
+
**Android:**
|
|
202
|
+
- Handle `Selector::MySelector` in `find_node_by_selector` (XML parsing) or `find_element` (UIA/OCR).
|
|
203
|
+
|
|
204
|
+
**iOS:**
|
|
205
|
+
- Handle `Selector::MySelector` in `find_element_internal`. Map to `idb` predicates or WDA class chains if possible.
|
|
206
|
+
|
|
207
|
+
**Web:**
|
|
208
|
+
- Update `selector_to_playwright` in `src/driver/web/driver.rs` to convert your selector to a Playwright-compatible string (CSS/XPath) OR handle it manually in `find_element`.
|
|
209
|
+
|
|
210
|
+
### Workflow 3: Modifying Existing Commands
|
|
211
|
+
|
|
212
|
+
If you add a field to an existing command struct (e.g., adding `label` to `TapParams`):
|
|
213
|
+
|
|
214
|
+
#### Step 1: Update Struct (`src/parser/types.rs`)
|
|
215
|
+
Add the field with `#[serde(default)]` if optional.
|
|
216
|
+
|
|
217
|
+
```rust
|
|
218
|
+
pub struct TapParams {
|
|
219
|
+
// ...
|
|
220
|
+
#[serde(default)]
|
|
221
|
+
pub label: Option<String>,
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
> [!WARNING]
|
|
226
|
+
> **CRITICAL: Check for Manual Parsing (`src/parser/yaml.rs`)**
|
|
227
|
+
> Some commands (like `LaunchApp`, `TapOn`) are **manually constructed** in `src/parser/yaml.rs` inside `parse_command_with_params`.
|
|
228
|
+
> If you add a field to the struct, you **MUST** update the initialization logic in `yaml.rs`.
|
|
229
|
+
>
|
|
230
|
+
> **Also Check**: `impl Default` blocks in `src/parser/types.rs`. If you add a field, update the default implementation.
|
|
231
|
+
|
|
232
|
+
#### Step 2: Update Usage
|
|
233
|
+
Update `executor.rs` or `driver` implementations to use the new field.
|
|
234
|
+
|
|
235
|
+
#### Step 3: Update Docs & VS Code
|
|
236
|
+
1. **Docs**: Update the parameter table in `docs/commands.md`.
|
|
237
|
+
2. **VS Code**: Add the new parameter to the `params` array in `lumi-tester-vscode/src/schema/commands.ts`.
|
|
238
|
+
|
|
239
|
+
> [!IMPORTANT]
|
|
240
|
+
> **Standardize Selectors**: If you add a new selector (e.g., `ocr`, `role`, `desc`) to `tap`, you **MUST** also add it to **ALL** other interaction and assertion commands that use selectors:
|
|
241
|
+
> - **Interactions**: `doubleTap`, `longPress`, `rightClick`, `type`, `tapAt`
|
|
242
|
+
> - **Scroll**: `scrollTo`, `scrollUntilVisible`
|
|
243
|
+
> - **Assertions**: `see`, `notSee`, `waitUntilVisible`, `waitNotSee`
|
|
244
|
+
>
|
|
245
|
+
> Failure to do this results in inconsistent autocomplete and frustrates users who expect the new selector to work everywhere.
|
|
246
|
+
|
|
247
|
+
## Logging & Debugging
|
|
248
|
+
|
|
249
|
+
### Logging Guidelines
|
|
250
|
+
- **User-Facing Logs**: Use `println!` with colored output for high-level steps (e.g., `➤ Executing...`).
|
|
251
|
+
- **Info**: `println!("{}", "➤ Message".blue())`
|
|
252
|
+
- **Success**: `println!("{}", "✓ Message".green())`
|
|
253
|
+
- **Error**: `println!("{}", "✗ Message".red())`
|
|
254
|
+
- **Debug Logs**: Use the `log` crate macros (`debug!`, `trace!`). These are hidden by default and only show when `RUST_LOG=debug` is set.
|
|
255
|
+
- **DO NOT** use `println!` for internal details.
|
|
256
|
+
- Example:
|
|
257
|
+
```rust
|
|
258
|
+
// In your driver or executor
|
|
259
|
+
log::debug!("Finding element with selector: {:?}", selector);
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Examples
|
|
263
|
+
|
|
264
|
+
- [Adding a Zoom Command](examples/add-zoom-command.md): End-to-end walkthrough of adding a new command across all layers.
|
|
265
|
+
|
|
266
|
+
## Troubleshooting
|
|
267
|
+
|
|
268
|
+
- **Common Issues**: See [Common Pitfalls & Troubleshooting](resources/common-pitfalls.md) for detailed solutions to parsing and execution errors.
|
|
269
|
+
- **Logs**: Use `println!` with colored output (`"msg".blue()`) for visibility.
|
|
270
|
+
- Blue: Info/Action (`"➤ Executing..."`)
|
|
271
|
+
- Cyan: Detail (`" Tap at..."`)
|
|
272
|
+
- Yellow: Warning
|
|
273
|
+
- Red: Error
|
|
274
|
+
- **Run with Trace**: `RUST_LOG=trace cargo run ...`
|
|
275
|
+
- **Output Dir**: Check the output directory (default `test_output/<timestamp>/`) for screenshots and logs.
|
|
276
|
+
- **Unit Tests**: Create a small unit test in the driver file to verify specific logic (e.g., regex parsing) without running a full simulator.
|
|
277
|
+
|
|
278
|
+
## Checklist for Success
|
|
279
|
+
|
|
280
|
+
- [ ] **Parser**: Did you add `struct` and `TestCommand` variant with correct `serde` attributes?
|
|
281
|
+
- [ ] **Executor**: Did you add the `match` arm? Did you update `build_selector` calls if needed?
|
|
282
|
+
- [ ] **Trait**: Did you add the method to `PlatformDriver`?
|
|
283
|
+
- [ ] **Impl**: Did you implement it for **Android**, **iOS**, and **Web**? (Or use `unimplemented!()`).
|
|
284
|
+
- [ ] **Legacy Init**: If modifying an existing command, did you check `src/parser/yaml.rs` for manual initialization?
|
|
285
|
+
- [ ] **Docs**: Did you update `docs/commands.md`?
|
|
286
|
+
- [ ] **VS Code**: Did you update `lumi-tester-vscode/src/schema/commands.ts`?
|
|
287
|
+
- [ ] **Build**: Run `cargo check` to catch missing implementations.
|
|
288
|
+
- [ ] **Test**: Verify with a minimal YAML file.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Example: Adding a `zoomIn` Command
|
|
2
|
+
|
|
3
|
+
This example demonstrates the complete workflow for adding a `zoomIn` command to `lumi-tester`.
|
|
4
|
+
|
|
5
|
+
## 1. Parser (`src/parser/types.rs`)
|
|
6
|
+
|
|
7
|
+
Add parameter struct and enum variant.
|
|
8
|
+
|
|
9
|
+
```rust
|
|
10
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
11
|
+
#[serde(rename_all = "camelCase")]
|
|
12
|
+
pub struct ZoomParams {
|
|
13
|
+
pub scale: f32, // e.g., 2.0 for 2x
|
|
14
|
+
#[serde(default)]
|
|
15
|
+
pub duration_ms: Option<u64>,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
pub enum TestCommand {
|
|
19
|
+
// ...
|
|
20
|
+
#[serde(alias = "zoom")]
|
|
21
|
+
ZoomIn(ZoomParams),
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 2. Driver Trait (`src/driver/traits.rs`)
|
|
26
|
+
|
|
27
|
+
Add abstract method.
|
|
28
|
+
|
|
29
|
+
```rust
|
|
30
|
+
#[async_trait]
|
|
31
|
+
pub trait PlatformDriver: Send + Sync {
|
|
32
|
+
// ...
|
|
33
|
+
async fn zoom_in(&self, scale: f32, duration_ms: Option<u64>) -> Result<()>;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 3. Executor (`src/runner/executor.rs`)
|
|
38
|
+
|
|
39
|
+
Connect parser to driver.
|
|
40
|
+
|
|
41
|
+
```rust
|
|
42
|
+
async fn execute_command(&mut self, command: &TestCommand) -> Result<()> {
|
|
43
|
+
match command {
|
|
44
|
+
// ...
|
|
45
|
+
TestCommand::ZoomIn(params) => {
|
|
46
|
+
println!(" {} Zooming in (scale: {})...", "🔍".blue(), params.scale);
|
|
47
|
+
self.driver.zoom_in(params.scale, params.duration_ms).await?;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 4. Driver Implementation (`src/driver/*/driver.rs`)
|
|
54
|
+
|
|
55
|
+
### Android (`android/driver.rs`) using pinch gesture
|
|
56
|
+
```rust
|
|
57
|
+
async fn zoom_in(&self, scale: f32, duration_ms: Option<u64>) -> Result<()> {
|
|
58
|
+
// Complex gesture: using adb shell input swipe with 2 pointers is hard.
|
|
59
|
+
// Better to use `adb exec-out uiautomator` or accessibility service if available.
|
|
60
|
+
// For simplicity, let's say we implement a basic center-out swipe.
|
|
61
|
+
println!(" {} Android zoom not fully implemented, simulating...", "⚠️".yellow());
|
|
62
|
+
Ok(())
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### iOS (`ios/driver.rs`) using WDA
|
|
67
|
+
```rust
|
|
68
|
+
async fn zoom_in(&self, scale: f32, duration_ms: Option<u64>) -> Result<()> {
|
|
69
|
+
// WDA has pinch method
|
|
70
|
+
self.wda_client.lock().await.perform_pinch(scale, ...).await?;
|
|
71
|
+
Ok(())
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Web (`web/driver.rs`) using CSS
|
|
76
|
+
```rust
|
|
77
|
+
async fn zoom_in(&self, scale: f32, duration_ms: Option<u64>) -> Result<()> {
|
|
78
|
+
let page = self.page.lock().await;
|
|
79
|
+
page.evaluate::<_, ()>("scale => document.body.style.zoom = scale", scale).await?;
|
|
80
|
+
Ok(())
|
|
81
|
+
}
|
|
82
|
+
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Common Pitfalls & Troubleshooting
|
|
2
|
+
|
|
3
|
+
This guide addresses frequent issues encountered when extending `lumi-tester`.
|
|
4
|
+
|
|
5
|
+
## 1. Parser Issues (YAML -> Rust)
|
|
6
|
+
|
|
7
|
+
### Issue: "unknown field" error parsing YAML
|
|
8
|
+
**Cause:** Mismatch between YAML field names and Rust struct fields.
|
|
9
|
+
**Solution:**
|
|
10
|
+
- Ensure `#[serde(rename_all = "camelCase")]` is on your struct.
|
|
11
|
+
- Verify you aren't using snake_case in YAML if Rust expects camelCase.
|
|
12
|
+
- Use `#[serde(alias = "oldName")]` for backward compatibility.
|
|
13
|
+
|
|
14
|
+
### Issue: Enum variant not matching
|
|
15
|
+
**Cause:** `TestCommand` enum parsing is sensitive to case or aliases.
|
|
16
|
+
**Solution:**
|
|
17
|
+
- Check `#[serde(alias = "...")]` on the enum variant.
|
|
18
|
+
- Remember `rename_all="camelCase"` applies to variants too (e.g., `MyCommand` becomes `myCommand` in YAML).
|
|
19
|
+
|
|
20
|
+
### Issue: "missing field" compilation error in `yaml.rs`
|
|
21
|
+
**Cause:** You added a field to a struct in `types.rs`, but `src/parser/yaml.rs` manually initializes this struct without the new field.
|
|
22
|
+
**Solution:**
|
|
23
|
+
- Open `src/parser/yaml.rs`.
|
|
24
|
+
- Search for the struct name (e.g., `LaunchAppParams`).
|
|
25
|
+
- Add the missing field to the initialization block (usually `field: None` or `Default::default()`).
|
|
26
|
+
|
|
27
|
+
### Issue: "missing field" in `Default` impl
|
|
28
|
+
**Cause:** The struct implements `Default` manually in `types.rs`, and you didn't update it.
|
|
29
|
+
**Solution:** Find `impl Default for MyStruct` in `types.rs` and add the new field.
|
|
30
|
+
|
|
31
|
+
## 2. Executor Issues
|
|
32
|
+
|
|
33
|
+
### Issue: "No selector specified" panic
|
|
34
|
+
**Cause:** `build_selector` called with `&None` for all selector fields.
|
|
35
|
+
**Solution:** ensure your new selector parameter is passed correctly and `build_selector` logic handles it (returns `Ok(Selector::...)`).
|
|
36
|
+
|
|
37
|
+
### Issue: Command executes but does nothing
|
|
38
|
+
**Cause:** Driver implementation might be empty or returning `Ok(())` without action.
|
|
39
|
+
**Solution:** Add println logs (`"➤ Executing..."`) inside the driver implementation to verify it's reached.
|
|
40
|
+
|
|
41
|
+
## 3. Playwright/Web Issues
|
|
42
|
+
|
|
43
|
+
### Issue: Selector works in Inspector but not in Test
|
|
44
|
+
**Cause:** Shadow DOM or dynamic ID visibility.
|
|
45
|
+
**Solution:**
|
|
46
|
+
- Use `page.locator()` methods which wait for visibility.
|
|
47
|
+
- Ensure `selector_to_playwright` produces valid CSS/XPath.
|
|
48
|
+
- For custom selectors (OCR/Image), ensure the helper returns coordinates properly.
|
|
49
|
+
|
|
50
|
+
## 4. Compilation Errors
|
|
51
|
+
|
|
52
|
+
### Issue: `method not found in ...`
|
|
53
|
+
**Cause:** Forgot to add method to `PlatformDriver` trait OR implement it in one of the drivers.
|
|
54
|
+
**Solution:** Check `src/driver/traits.rs` first. Then check implementations.
|
|
55
|
+
|
|
56
|
+
### Issue: `struct has missing field` in `build_selector` call
|
|
57
|
+
**Cause:** You updated `build_selector` signature but didn't update all call sites.
|
|
58
|
+
**Solution:** The compiler will point to every call site (TapOn, AssertVisible, etc.). You must update ALL of them.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Core Architecture & Internals
|
|
2
|
+
|
|
3
|
+
This document explains the internal working of `lumi-tester` to assist with maintenance and core refactoring.
|
|
4
|
+
|
|
5
|
+
## 1. Execution Flow (`Executor`)
|
|
6
|
+
|
|
7
|
+
The `TestExecutor` (`src/runner/executor.rs`) is the heart of the runner.
|
|
8
|
+
|
|
9
|
+
### Lifecycle of a Test Run
|
|
10
|
+
1. **Parsing**: `parse_test_file` (in `parser/yaml.rs`) converts YAML -> `TestFlow` struct.
|
|
11
|
+
2. **Initialization**: `TestExecutor::new` creates:
|
|
12
|
+
- `TestContext`: Holds variables, app ID, platform-specific configs.
|
|
13
|
+
- `TestSessionState`: Tracks overall progress.
|
|
14
|
+
- `EventEmitter`: Async channel for reporting events (logs, status updates).
|
|
15
|
+
3. **Flow Execution** (`run_file` -> `run_commands_set`):
|
|
16
|
+
- **Context Update**: Merges flow-specific header configs.
|
|
17
|
+
- **DDT Loop**: If `data` (CSV) is present, iterates over rows, injecting variables.
|
|
18
|
+
- **Command Loop**: Iterates through `TestCommand`s.
|
|
19
|
+
- **State Tracking**: Updates `CommandState` (Running -> Passed/Failed).
|
|
20
|
+
- **Event Emission**: Emits `CommandStarted`, `CommandPassed`, `CommandFailed`.
|
|
21
|
+
- **Error Handling**: Catches errors from `execute_command`.
|
|
22
|
+
- *Soft Errors*: Logged but don't stop flow (unless `continueOnFailure` is false).
|
|
23
|
+
- *Hard Errors*: Stop execution immediately.
|
|
24
|
+
|
|
25
|
+
## 2. State Management (`State`)
|
|
26
|
+
|
|
27
|
+
State is managed hierarchically in `src/runner/state.rs`:
|
|
28
|
+
|
|
29
|
+
- **TestSessionState**: Root level. Contains multiple `FlowState`s.
|
|
30
|
+
- **FlowState**: Represents one test file execution (or one DDT iteration). Contains `CommandState`s.
|
|
31
|
+
- **CommandState**: Individual command status (Pending, Running, Passed, Failed).
|
|
32
|
+
|
|
33
|
+
> **Maintenance Tip**: When adding new execution logic (e.g., `retry`), update `CommandStatus` enum and handle state transitions in `executor.rs`.
|
|
34
|
+
|
|
35
|
+
## 3. Driver Architecture
|
|
36
|
+
|
|
37
|
+
The `PlatformDriver` trait (`src/driver/traits.rs`) enforces consistency.
|
|
38
|
+
|
|
39
|
+
- **Lazy Initialization**: Drivers (especially iOS/Web) often use `OnceCell` for expensive resources (WDA client, Browser instance).
|
|
40
|
+
- **Thread Safety**: Drivers must be `Send + Sync` to work with async runtime.
|
|
41
|
+
- **Selector Handling**: `find_element` is usually the choke point.
|
|
42
|
+
- *Android*: Parsing XML hierarchy from `adb exec-out uiautomator`.
|
|
43
|
+
- *iOS*: `idb` UI tree or WDA predicate string.
|
|
44
|
+
- *Web*: Playwright selector engine.
|
|
45
|
+
|
|
46
|
+
## 4. Testing Strategy
|
|
47
|
+
|
|
48
|
+
To safely refactor core logic:
|
|
49
|
+
1. **Unit Tests**: located in `src/driver/*/mod.rs` or alongside source. Run with `cargo test`.
|
|
50
|
+
2. **E2E Verification**: Use the `my_testing/` folder YAMLs.
|
|
51
|
+
- Run `cargo run -- run my_testing/android/demo.yaml --platform android` for regression testing.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-documentation
|
|
3
|
+
description: Automatically generates comprehensive documentation (Overview, Architecture, Flows) for an existing project by analyzing code and identifying flows. Supports all languages (Python, JS/TS, Flutter, Swift, C++, Rust, etc.).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Project Documentation Generation Skill
|
|
7
|
+
|
|
8
|
+
This skill allows you to reverse-engineer an existing codebase to create high-quality, comprehensive documentation. It supports **Multi-Language Analysis** (C++, Java, Kotlin, Swift, Dart, Go, Rust, etc.) using a custom Python script.
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
- **Legacy Code**: Documenting undocumented projects.
|
|
13
|
+
- **Onboarding**: Creating specific "Feature Guides" or "Architecture Overviews".
|
|
14
|
+
- **Review**: Generating a "Current State" report before starting a refactor.
|
|
15
|
+
|
|
16
|
+
## Skill Structure
|
|
17
|
+
```text
|
|
18
|
+
.agent/skills/project-documentation/
|
|
19
|
+
├── SKILL.md # Main instructions
|
|
20
|
+
├── scripts/
|
|
21
|
+
│ └── analyze_codebase.py # Analysis script (Python)
|
|
22
|
+
├── resources/
|
|
23
|
+
│ ├── standards.md # Documentation Standards (REQUIRED)
|
|
24
|
+
│ └── templates/
|
|
25
|
+
│ ├── flow.md # Template for Business Flows (Logic)
|
|
26
|
+
│ ├── feature_guide.md # Template for UI/Screens
|
|
27
|
+
│ └── technical_reference.md # Template for Backend/API
|
|
28
|
+
└── examples/
|
|
29
|
+
└── example_usage.md # Complete walkthrough
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Prerequisites
|
|
33
|
+
|
|
34
|
+
- Python 3 installed.
|
|
35
|
+
- Read access to the project root directory.
|
|
36
|
+
- **REQUIRED**: Read the [Documentation Standards](./resources/standards.md) before writing any docs.
|
|
37
|
+
```bash
|
|
38
|
+
view_file ./resources/standards.md
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## How to Use
|
|
42
|
+
|
|
43
|
+
### Step 1: Run Analysis
|
|
44
|
+
|
|
45
|
+
Always run the script first to map the project.
|
|
46
|
+
```bash
|
|
47
|
+
# Run from the root of the project you want to document
|
|
48
|
+
# Note: The script is located in the skill's scripts directory
|
|
49
|
+
python3 ./scripts/analyze_codebase.py . > codebase_analysis.md
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Step 2: Create Checklist (Modular Plan)
|
|
53
|
+
|
|
54
|
+
You **MUST** create `documentation_checklist.md` assuming a modular structure:
|
|
55
|
+
- [ ] **`docs/README.md`**: Index and Overview.
|
|
56
|
+
- [ ] **`docs/setup.md`**: Installation instructions.
|
|
57
|
+
- [ ] **`docs/architecture.md`**: System diagrams.
|
|
58
|
+
- [ ] **`docs/flows/*.md`**: Business Logic Flows (CRITICAL).
|
|
59
|
+
- [ ] **`docs/api/*.md`**: API Reference (Low-level).
|
|
60
|
+
- [ ] **`docs/troubleshooting.md`**: Common issues.
|
|
61
|
+
|
|
62
|
+
### Step 3: Scaffold & Write
|
|
63
|
+
|
|
64
|
+
1. Create the directory structure:
|
|
65
|
+
```bash
|
|
66
|
+
mkdir -p docs/api docs/flows
|
|
67
|
+
```
|
|
68
|
+
2. Write each file using the appropriate template from the Resources section.
|
|
69
|
+
|
|
70
|
+
## Workflows
|
|
71
|
+
|
|
72
|
+
### Workflow 1: Backend / General
|
|
73
|
+
*Best for: Server code (Go, Rust, Node.js), CLI tools.*
|
|
74
|
+
- **Focus**: Endpoints, Database Schema, Data Models.
|
|
75
|
+
- **Structure**:
|
|
76
|
+
- `docs/api/[module].md` (Use [Technical Reference](./resources/templates/technical_reference.md))
|
|
77
|
+
- `docs/flows/[flow_name].md` (Use [Flow Template](./resources/templates/flow.md))
|
|
78
|
+
- `docs/architecture.md` (Use [Architecture Template](./resources/templates/architecture.md))
|
|
79
|
+
|
|
80
|
+
### Workflow 2: Mobile App
|
|
81
|
+
*Best for: Flutter, Swift, Kotlin, React Native.*
|
|
82
|
+
- **Focus**: User Flows, Navigation, State Logic.
|
|
83
|
+
- **Structure**:
|
|
84
|
+
- `docs/flows/[feature].md` (Use [Flow Template](./resources/templates/flow.md))
|
|
85
|
+
- `docs/setup.md` (Use [Setup Template](./resources/templates/setup.md))
|
|
86
|
+
|
|
87
|
+
### Workflow 3: Embedded / Legacy
|
|
88
|
+
*Best for: C/C++, Java, Embedded Systems.*
|
|
89
|
+
- **Focus**: Hardware Interactions, Memory Flows.
|
|
90
|
+
- **Structure**:
|
|
91
|
+
- `docs/architecture.md` (Use [Architecture Template](./resources/templates/architecture.md))
|
|
92
|
+
- `docs/flows/[process].md` (Use [Flow Template](./resources/templates/flow.md))
|
|
93
|
+
|
|
94
|
+
## Examples
|
|
95
|
+
|
|
96
|
+
- [Documenting a Flutter App](./examples/example_usage.md) - A complete walkthrough.
|
|
97
|
+
|
|
98
|
+
## Resources
|
|
99
|
+
|
|
100
|
+
- [Standards & Guidelines](./resources/standards.md)
|
|
101
|
+
- [Flow Template (Logic Traces)](./resources/templates/flow.md)
|
|
102
|
+
- [Technical Reference Template](./resources/templates/technical_reference.md)
|
|
103
|
+
- [Feature Guide Template](./resources/templates/feature_guide.md)
|
|
104
|
+
|
|
105
|
+
## Best Practices
|
|
106
|
+
|
|
107
|
+
- **Visuals First**: Always draw the Flow/Architecture before writing text.
|
|
108
|
+
- **Link to Code**: Use specific filenames from the analysis in your docs.
|
|
109
|
+
- **Keep it Portable**: Use relative paths in your generated documentation where possible.
|
|
110
|
+
|
|
111
|
+
## Troubleshooting
|
|
112
|
+
|
|
113
|
+
| Issue | Solution |
|
|
114
|
+
|-------|----------|
|
|
115
|
+
| Script not found | Ensure you are running the `python3` command relative to the skill directory or copy the script to your project root. |
|
|
116
|
+
| Output is empty | Check if the language extension is supported. The script supports .py, .js, .ts, .rs, .go, .java, .kt, .swift, .c, .cpp, .dart. |
|
|
117
|
+
| Diagram Errors | Start with a simple graph. Complex mermaid often breaks markdown viewers. |
|