Skip to content

Commit 7158e85

Browse files
committed
Add AGENTS.md and /implement skill
- AGENTS.md with repo architecture, build commands, code navigation - CLAUDE.md symlink to AGENTS.md - /implement skill: plan, implement, verify, commit, draft PR workflow - .claude/skills symlink to .agents/skills
1 parent 7c17677 commit 7158e85

4 files changed

Lines changed: 334 additions & 0 deletions

File tree

.agents/skills/implement/SKILL.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
name: implement
3+
description: "End-to-end implementation workflow: plan, implement, verify, commit, and open a draft PR. Use when asked to implement, fix, build, or work on something."
4+
---
5+
6+
# Implement Workflow
7+
8+
This skill handles the full lifecycle: plan -> implement -> verify -> commit -> draft PR.
9+
10+
## Phase 1: Plan (requires approval)
11+
12+
1. **Understand the request** — Read the issue description, linked context, or user instructions.
13+
2. **Explore the codebase** — Find relevant files, understand existing patterns, read tests.
14+
3. **Create an implementation plan**:
15+
- What files will be modified/created
16+
- What the changes will do
17+
- What edge cases to consider
18+
- What tests to add or update
19+
4. **Present the plan and STOP** — Wait for explicit user approval before proceeding.
20+
21+
Do NOT start coding until the plan is approved. If requirements are ambiguous, ask.
22+
23+
## Phase 2: Implement
24+
25+
Execute the approved plan:
26+
- Follow existing code patterns and conventions in the repo
27+
- Keep changes minimal and focused — don't refactor unrelated code
28+
- Kotlin warnings are treated as errors (`allWarningsAsErrors = true`) — write clean code
29+
- Use `org.wordpress.aztec` package conventions
30+
31+
## Phase 3: Verify
32+
33+
Run verification checks and fix any failures. Iterate until all checks pass.
34+
35+
### 3a: Compile
36+
37+
```bash
38+
./gradlew :aztec:assembleRelease :app:assembleDebug
39+
```
40+
41+
If other modules were changed, compile those too:
42+
```bash
43+
./gradlew assembleRelease
44+
```
45+
46+
### 3b: Lint
47+
48+
```bash
49+
./gradlew ktlint
50+
```
51+
52+
- Fix violations — prefer real fixes over suppression
53+
- Only suppress when it's a false positive and document why
54+
55+
### 3c: Unit Tests
56+
57+
```bash
58+
./gradlew aztec:testRelease
59+
```
60+
61+
Or run specific tests related to the changes:
62+
```bash
63+
./gradlew :aztec:testReleaseUnitTest --tests "org.wordpress.aztec.SpecificTest" --info
64+
```
65+
66+
**Test rules:**
67+
- NEVER weaken or remove assertions to make tests pass
68+
- NEVER modify production code just to pass a test without permission
69+
- Tests that pass only by not crashing are invalid — every test needs meaningful assertions
70+
- If a test won't pass after reasonable attempts: stop and ask
71+
72+
### 3d: Fix Errors
73+
74+
If any step fails:
75+
1. Analyze the error
76+
2. Fix the issue
77+
3. Re-run the failing check
78+
4. Repeat until green
79+
80+
## Phase 4: Present Changes (requires approval)
81+
82+
Show a summary of all changes made:
83+
- Files modified/created
84+
- Key behavioral changes
85+
- Test coverage
86+
87+
**STOP and wait for user approval** before committing.
88+
89+
## Phase 5: Commit and Draft PR
90+
91+
Only proceed after explicit approval.
92+
93+
### 5a: Run Final Lint
94+
95+
```bash
96+
./gradlew ktlint
97+
```
98+
99+
Fix any remaining issues.
100+
101+
### 5b: Inspect Changes
102+
103+
```bash
104+
git status
105+
git diff --stat
106+
git diff
107+
```
108+
109+
### 5c: Plan Commits
110+
111+
Review the changes and determine if they should be split into multiple commits:
112+
- Independent logical units = separate commits
113+
- Bug fix + feature = separate commits
114+
- Formatting + logic = separate commits
115+
116+
For **each commit**, prepare:
117+
1. **Commit message**: Imperative summary + brief body
118+
2. **Files**: Paths to stage
119+
3. **Summary**: What and why
120+
121+
**Commit message format** — use direct multi-line strings:
122+
```bash
123+
git commit -m "Imperative summary
124+
125+
- Detail one
126+
- Detail two
127+
"
128+
```
129+
130+
**Rules:**
131+
- NO co-author lines — NEVER add "Co-Authored-By" or AI attribution
132+
- Each commit should be cohesive and buildable
133+
- Use `git add -p` to split mixed concerns if needed
134+
135+
### 5d: Stage and Commit
136+
137+
```bash
138+
git add <specific files>
139+
git commit -m "message"
140+
```
141+
142+
### 5e: Push and Create Draft PR
143+
144+
```bash
145+
# Get the correct remote owner/repo
146+
git remote get-url origin
147+
148+
# Push
149+
git push -u origin HEAD
150+
151+
# Create draft PR
152+
PAGER=cat gh pr create --draft --title "PR title" --body "$(cat <<'EOF'
153+
### Fix
154+
<description>
155+
156+
### Test
157+
1. Step 1
158+
2. Step 2
159+
EOF
160+
)"
161+
```
162+
163+
**PR rules:**
164+
- Title: short, under 70 characters
165+
- Body: follows the repo's PR template format (### Fix, ### Test, ### Review)
166+
- Always create as **draft**
167+
- Return the PR URL when done
168+
169+
## Handling Edge Cases
170+
171+
### Working on an issue with a branch name
172+
If the user mentions an issue with a known branch name:
173+
```bash
174+
git checkout trunk && git pull && git checkout -b <branch-name>
175+
```
176+
177+
### Determining diff base for existing PRs
178+
PRs can be stacked — check the actual base:
179+
```bash
180+
PAGER=cat gh pr view <NUMBER> --json baseRefName
181+
```
182+
183+
### Posting review comments
184+
When reviewing or addressing PR feedback:
185+
```bash
186+
# Create review JSON
187+
printf '%s\n' '{
188+
"event": "COMMENT",
189+
"body": "Review comment",
190+
"comments": [
191+
{"path": "file.kt", "line": 42, "body": "Inline comment"}
192+
]
193+
}' > /tmp/pr_review.json
194+
195+
PAGER=cat gh api repos/{owner}/{repo}/pulls/{number}/reviews --method POST --input /tmp/pr_review.json
196+
```

.claude/skills

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../.agents/skills

AGENTS.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Instructions
2+
3+
This file provides guidance to coding agents when working with code in this repository.
4+
5+
## General Approach
6+
7+
- Analyze assumptions and provide counterpoints — prioritize truth over agreement.
8+
- Treat me as an expert Android developer. Give overviews, not tutorials.
9+
- Always give an overview of the solution before diving into implementation (unless explicitly asked to implement right away).
10+
- Do not add comments for trivial logic or when the name is descriptive enough.
11+
12+
## Architecture Overview
13+
14+
**AztecEditor-Android** is a rich-text HTML editor library for Android, built on the `EditText` / `Spannable` API.
15+
16+
**Stack**: Kotlin, Android Spannable API, Plugin architecture, Gradle with Kotlin DSL
17+
18+
### Module Structure
19+
20+
```
21+
:app — Demo application
22+
:aztec — Core editor library (main deliverable)
23+
:glide-loader — Image loading via Glide
24+
:picasso-loader — Image loading via Picasso
25+
:wordpress-comments — WordPress comments plugin
26+
:wordpress-shortcodes — WordPress shortcodes plugin
27+
:media-placeholders — Media placeholders with Compose support
28+
```
29+
30+
All plugin/loader modules depend on `:aztec`. Published independently to Automattic S3 Maven (`org.wordpress:aztec`, `org.wordpress.aztec:*`).
31+
32+
### Code Navigation (package: `org.wordpress.aztec`)
33+
34+
| To find... | Look in... |
35+
|---------------------------------|------------------------------------------------------|
36+
| Main editor component | `aztec/.../AztecText.kt` (extends EditText, ~3K LOC) |
37+
| Editor facade / initialization | `aztec/.../Aztec.kt` |
38+
| HTML parsing | `aztec/.../AztecParser.kt`, `AztecTagHandler.kt` |
39+
| Custom spans (visual rendering) | `aztec/.../spans/` (62 files — one per HTML element) |
40+
| Text formatting logic | `aztec/.../formatting/` (Block, Inline, Line, List) |
41+
| Block element handlers | `aztec/.../handlers/` (Heading, List, Quote, etc.) |
42+
| Plugin interfaces | `aztec/.../plugins/` (IAztecPlugin, IToolbarButton) |
43+
| HTML source editor | `aztec/.../source/SourceViewEditText.kt` |
44+
| Text change watchers | `aztec/.../watchers/` (30+ files, API-version buckets)|
45+
| Toolbar | `aztec/.../toolbar/AztecToolbar.kt` |
46+
| Undo/redo | `aztec/.../History.kt` |
47+
| Compose placeholders | `media-placeholders/.../ComposePlaceholder*.kt` |
48+
49+
### Key Architectural Patterns
50+
51+
1. **Span-based rendering** — Each HTML element has a custom `Span` class. Spans carry both visual rendering and semantic meaning. The `Spannable` API is central to everything.
52+
53+
2. **Plugin architecture**`IAztecPlugin` with sub-interfaces (`IToolbarButton`, `IClipboardPastePlugin`, `IOnDrawPlugin`). Plugins for `html2visual` and `visual2html` conversion pipelines.
54+
55+
3. **Facade pattern**`Aztec` class provides a builder-like fluent API to wire up editor, toolbar, source view, and plugins.
56+
57+
4. **Handler/Formatter split** — Handlers deal with block element structure (headings, lists, quotes). Formatters apply styling (inline, block, line-block, list, link, indent).
58+
59+
5. **Bidirectional HTML conversion** — HTML string <-> Spannable representation, with plugin hooks at each stage.
60+
61+
6. **Watcher pattern** — Multiple `TextWatcher` implementations with API-version-specific buckets (API 25, 26+) for Samsung/OEM compatibility.
62+
63+
### Common Crash Patterns (from recent PRs)
64+
65+
- `IndexOutOfBoundsException` from span start/end being out of bounds — always clamp to `[0, text.length]`
66+
- `IllegalArgumentException` when span end < span start — validate before applying
67+
- Samsung/custom emoji OEM issues causing unexpected span states
68+
- Thread safety in `AztecAttributes` — operations should be synchronized
69+
70+
## Git Operations (CRITICAL)
71+
- **NEVER commit without explicit permission**
72+
- **NEVER push without explicit permission**
73+
- **NEVER create a PR without explicit permission**
74+
- When asked to "fix" or "update" something, that does NOT imply permission to commit/push
75+
- Always wait for explicit "commit", "push", or "create PR" commands
76+
77+
## Build Commands
78+
79+
```bash
80+
# Build the demo app
81+
./gradlew :app:assembleDebug
82+
83+
# Build the library
84+
./gradlew :aztec:assembleRelease
85+
86+
# Lint (ktlint + Android lint)
87+
./gradlew ktlint
88+
./gradlew lintRelease
89+
90+
# Unit tests (core library)
91+
./gradlew aztec:testRelease
92+
93+
# All unit tests
94+
./gradlew testRelease
95+
96+
# Specific test class
97+
./gradlew :aztec:testReleaseUnitTest --tests "org.wordpress.aztec.AztecParserTest" --info
98+
99+
# Specific test method
100+
./gradlew :aztec:testReleaseUnitTest --tests "org.wordpress.aztec.AztecParserTest.testMethodName" --info
101+
```
102+
103+
### Build Configuration
104+
105+
- All Kotlin warnings are errors (`allWarningsAsErrors = true`)
106+
- Versions are defined in root `build.gradle` — check there for current Kotlin, AGP, SDK, and dependency versions
107+
108+
## GitHub Commands
109+
110+
```bash
111+
PAGER=cat gh pr list
112+
PAGER=cat gh pr view <NUMBER>
113+
PAGER=cat gh pr view <NUMBER> --comments
114+
PAGER=cat gh pr diff <NUMBER>
115+
```
116+
117+
## PR Template
118+
119+
PRs follow this format (from `.github/PULL_REQUEST_TEMPLATE.md`):
120+
```
121+
### Fix
122+
<description of what was fixed/added>
123+
124+
### Test
125+
1. Step 1
126+
2. Step 2
127+
128+
### Review
129+
@reviewer
130+
```
131+
132+
## Skills
133+
134+
| Skill | Trigger phrases |
135+
|-------------|------------------------------------------------------------------------------------------------------|
136+
| `implement` | "implement", "fix this", "work on this", "build this", "add feature", any implementation request |

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
AGENTS.md

0 commit comments

Comments
 (0)