-
Notifications
You must be signed in to change notification settings - Fork 121
Add AGENTS.md and /implement skill #1114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,197 @@ | ||
| --- | ||
| name: implement | ||
| 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." | ||
| --- | ||
|
|
||
| # Implement Workflow | ||
|
|
||
| This skill handles the full lifecycle: plan -> implement -> verify -> commit -> draft PR. | ||
|
|
||
| ## Phase 1: Plan (requires approval) | ||
|
|
||
| 1. **Understand the request** — Read the issue description, linked context, or user instructions. | ||
| 2. **Explore the codebase** — Find relevant files, understand existing patterns, read tests. | ||
| 3. **Create an implementation plan**: | ||
| - What files will be modified/created | ||
| - What the changes will do | ||
| - What edge cases to consider | ||
| - What tests to add or update | ||
| 4. **Present the plan and STOP** — Wait for explicit user approval before proceeding. | ||
|
|
||
| Do NOT start coding until the plan is approved. If requirements are ambiguous, ask. | ||
|
|
||
| ## Phase 2: Implement | ||
|
|
||
| Execute the approved plan: | ||
| - Follow existing code patterns and conventions in the repo | ||
| - Keep changes minimal and focused — don't refactor unrelated code | ||
| - Kotlin warnings are treated as errors (`allWarningsAsErrors = true`) — write clean code | ||
| - Use `org.wordpress.aztec` package conventions | ||
| - **Unit tests**: Add or update tests covering new/changed logic. Follow existing test patterns in the repo. If writing meaningful tests would require disproportionate effort (e.g., complex setup, heavy mocking of framework internals), skip but notify the developer explaining why. | ||
|
|
||
| ## Phase 3: Verify | ||
|
|
||
| Run verification checks and fix any failures. Iterate until all checks pass. | ||
|
|
||
| ### 3a: Compile | ||
|
|
||
| ```bash | ||
| ./gradlew :aztec:assembleRelease :app:assembleDebug | ||
| ``` | ||
|
|
||
| If other modules were changed, compile those too: | ||
| ```bash | ||
| ./gradlew assembleRelease | ||
| ``` | ||
|
|
||
| ### 3b: Lint | ||
|
|
||
| ```bash | ||
| ./gradlew ktlint | ||
| ``` | ||
|
|
||
| - Fix violations — prefer real fixes over suppression | ||
| - Only suppress when it's a false positive and document why | ||
|
|
||
| ### 3c: Unit Tests | ||
|
|
||
| ```bash | ||
| ./gradlew aztec:testRelease | ||
| ``` | ||
|
|
||
| Or run specific tests related to the changes: | ||
| ```bash | ||
| ./gradlew :aztec:testReleaseUnitTest --tests "org.wordpress.aztec.SpecificTest" --info | ||
| ``` | ||
|
|
||
| **Test rules:** | ||
| - NEVER weaken or remove assertions to make tests pass | ||
| - NEVER modify production code just to pass a test without permission | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Twinsen81 |
||
| - Tests that pass only by not crashing are invalid — every test needs meaningful assertions | ||
| - If a test won't pass after reasonable attempts: stop and ask | ||
|
|
||
| ### 3d: Fix Errors | ||
|
|
||
| If any step fails: | ||
| 1. Analyze the error | ||
| 2. Fix the issue | ||
| 3. Re-run the failing check | ||
| 4. Repeat until green | ||
|
|
||
| ## Phase 4: Present Changes (requires approval) | ||
|
|
||
| Show a summary of all changes made: | ||
| - Files modified/created | ||
| - Key behavioral changes | ||
| - Test coverage | ||
|
|
||
| **STOP and wait for user approval** before committing. | ||
|
|
||
| ## Phase 5: Commit and Draft PR | ||
|
|
||
| Only proceed after explicit approval. | ||
|
|
||
| ### 5a: Run Final Lint | ||
|
|
||
| ```bash | ||
| ./gradlew ktlint | ||
| ``` | ||
|
|
||
| Fix any remaining issues. | ||
|
|
||
| ### 5b: Inspect Changes | ||
|
|
||
| ```bash | ||
| git status | ||
| git diff --stat | ||
| git diff | ||
| ``` | ||
|
|
||
| ### 5c: Plan Commits | ||
|
|
||
| Review the changes and determine if they should be split into multiple commits: | ||
| - Independent logical units = separate commits | ||
| - Bug fix + feature = separate commits | ||
| - Formatting + logic = separate commits | ||
|
|
||
| For **each commit**, prepare: | ||
| 1. **Commit message**: Imperative summary + brief body | ||
| 2. **Files**: Paths to stage | ||
| 3. **Summary**: What and why | ||
|
|
||
| **Commit message format** — use direct multi-line strings: | ||
| ```bash | ||
| git commit -m "Imperative summary | ||
|
|
||
| - Detail one | ||
| - Detail two | ||
| " | ||
| ``` | ||
|
|
||
| **Rules:** | ||
| - NO co-author lines — NEVER add "Co-Authored-By" or AI attribution | ||
| - Each commit should be cohesive and buildable | ||
| - Use `git add -p` to split mixed concerns if needed | ||
|
|
||
| ### 5d: Stage and Commit | ||
|
|
||
| ```bash | ||
| git add <specific files> | ||
| git commit -m "message" | ||
| ``` | ||
|
|
||
| ### 5e: Push and Create Draft PR | ||
|
|
||
| ```bash | ||
| # Get the correct remote owner/repo | ||
| git remote get-url origin | ||
|
|
||
| # Push | ||
| git push -u origin HEAD | ||
|
|
||
| # Create draft PR | ||
| PAGER=cat gh pr create --draft --title "PR title" --body "$(cat <<'EOF' | ||
| ### Fix | ||
| <description> | ||
|
|
||
| ### Test | ||
| 1. Step 1 | ||
| 2. Step 2 | ||
| EOF | ||
| )" | ||
| ``` | ||
|
|
||
| **PR rules:** | ||
| - Title: short, under 70 characters | ||
| - Body: follows the repo's PR template format (### Fix, ### Test, ### Review) | ||
| - Always create as **draft** | ||
| - Return the PR URL when done | ||
|
|
||
| ## Handling Edge Cases | ||
|
|
||
| ### Working on an issue with a branch name | ||
| If the user mentions an issue with a known branch name: | ||
| ```bash | ||
| git checkout trunk && git pull && git checkout -b <branch-name> | ||
| ``` | ||
|
|
||
| ### Determining diff base for existing PRs | ||
| PRs can be stacked — check the actual base: | ||
| ```bash | ||
| PAGER=cat gh pr view <NUMBER> --json baseRefName | ||
| ``` | ||
|
|
||
| ### Posting review comments | ||
| When reviewing or addressing PR feedback: | ||
| ```bash | ||
| # Create review JSON | ||
| printf '%s\n' '{ | ||
| "event": "COMMENT", | ||
| "body": "Review comment", | ||
| "comments": [ | ||
| {"path": "file.kt", "line": 42, "body": "Inline comment"} | ||
| ] | ||
| }' > /tmp/pr_review.json | ||
|
|
||
| PAGER=cat gh api repos/{owner}/{repo}/pulls/{number}/reviews --method POST --input /tmp/pr_review.json | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../.agents/skills |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,139 @@ | ||
| # Instructions | ||
|
|
||
| This file provides guidance to coding agents when working with code in this repository. | ||
|
|
||
| ## General Approach | ||
|
|
||
| - Analyze assumptions and provide counterpoints — prioritize truth over agreement. | ||
| - Treat me as an expert Android developer. Give overviews, not tutorials. | ||
| - Always give an overview of the solution before diving into implementation (unless explicitly asked to implement right away). | ||
| - Do not add comments for trivial logic or when the name is descriptive enough. | ||
|
|
||
| ## Architecture Overview | ||
|
|
||
| **AztecEditor-Android** is a rich-text HTML editor library for Android, built on the `EditText` / `Spannable` API. | ||
|
|
||
| **Stack**: Kotlin, Android Spannable API, Plugin architecture, Gradle with Kotlin DSL | ||
|
|
||
| ### Module Structure | ||
|
|
||
| ``` | ||
| :app — Demo application | ||
| :aztec — Core editor library (main deliverable) | ||
| :glide-loader — Image loading via Glide | ||
| :picasso-loader — Image loading via Picasso | ||
| :wordpress-comments — WordPress comments plugin | ||
| :wordpress-shortcodes — WordPress shortcodes plugin | ||
| :media-placeholders — Media placeholders with Compose support | ||
| ``` | ||
|
|
||
| All plugin/loader modules depend on `:aztec`. Published independently to Automattic S3 Maven (`org.wordpress:aztec`, `org.wordpress.aztec:*`). | ||
|
|
||
| ### Code Navigation (package: `org.wordpress.aztec`) | ||
|
|
||
| | To find... | Look in... | | ||
| |---------------------------------|------------------------------------------------------| | ||
| | Main editor component | `aztec/.../AztecText.kt` (extends EditText, ~3K LOC) | | ||
| | Editor facade / initialization | `aztec/.../Aztec.kt` | | ||
| | HTML parsing | `aztec/.../AztecParser.kt`, `AztecTagHandler.kt` | | ||
| | Custom spans (visual rendering) | `aztec/.../spans/` (62 files — one per HTML element) | | ||
| | Text formatting logic | `aztec/.../formatting/` (Block, Inline, Line, List) | | ||
| | Block element handlers | `aztec/.../handlers/` (Heading, List, Quote, etc.) | | ||
| | Plugin interfaces | `aztec/.../plugins/` (IAztecPlugin, IToolbarButton) | | ||
| | HTML source editor | `aztec/.../source/SourceViewEditText.kt` | | ||
| | Text change watchers | `aztec/.../watchers/` (30+ files, API-version buckets)| | ||
| | Toolbar | `aztec/.../toolbar/AztecToolbar.kt` | | ||
| | Undo/redo | `aztec/.../History.kt` | | ||
| | Compose placeholders | `media-placeholders/.../ComposePlaceholder*.kt` | | ||
|
|
||
| ### Key Architectural Patterns | ||
|
|
||
| 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. | ||
|
|
||
| 2. **Plugin architecture** — `IAztecPlugin` with sub-interfaces (`IToolbarButton`, `IClipboardPastePlugin`, `IOnDrawPlugin`). Plugins for `html2visual` and `visual2html` conversion pipelines. | ||
|
|
||
| 3. **Facade pattern** — `Aztec` class provides a builder-like fluent API to wire up editor, toolbar, source view, and plugins. | ||
|
|
||
| 4. **Handler/Formatter split** — Handlers deal with block element structure (headings, lists, quotes). Formatters apply styling (inline, block, line-block, list, link, indent). | ||
|
|
||
| 5. **Bidirectional HTML conversion** — HTML string <-> Spannable representation, with plugin hooks at each stage. | ||
|
|
||
| 6. **Watcher pattern** — Multiple `TextWatcher` implementations with API-version-specific buckets (API 25, 26+) for Samsung/OEM compatibility. | ||
|
|
||
| ### Common Crash Patterns (from recent PRs) | ||
|
|
||
| - `IndexOutOfBoundsException` from span start/end being out of bounds — always clamp to `[0, text.length]` | ||
| - `IllegalArgumentException` when span end < span start — validate before applying | ||
| - Samsung/custom emoji OEM issues causing unexpected span states | ||
| - Thread safety in `AztecAttributes` — operations should be synchronized | ||
|
|
||
| ## Git Operations (CRITICAL) | ||
| - **NEVER commit without explicit permission** | ||
| - **NEVER push without explicit permission** | ||
| - **NEVER create a PR without explicit permission** | ||
| - When asked to "fix" or "update" something, that does NOT imply permission to commit/push | ||
| - Always wait for explicit "commit", "push", or "create PR" commands | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Twinsen81 |
||
| ## Build Commands | ||
|
|
||
| ```bash | ||
| # Build and run the demo app | ||
| ./gradlew :app:installDebug && adb shell am start -n org.wordpress.aztec/org.wordpress.aztec.demo.MainActivity | ||
|
|
||
| # Build the demo app (without installing) | ||
| ./gradlew :app:assembleDebug | ||
|
|
||
| # Build the library | ||
| ./gradlew :aztec:assembleRelease | ||
|
|
||
| # Lint (ktlint + Android lint) | ||
| ./gradlew ktlint | ||
| ./gradlew lintRelease | ||
|
|
||
| # Unit tests (core library) | ||
| ./gradlew aztec:testRelease | ||
|
|
||
| # All unit tests | ||
| ./gradlew testRelease | ||
|
|
||
| # Specific test class | ||
| ./gradlew :aztec:testReleaseUnitTest --tests "org.wordpress.aztec.AztecParserTest" --info | ||
|
|
||
| # Specific test method | ||
| ./gradlew :aztec:testReleaseUnitTest --tests "org.wordpress.aztec.AztecParserTest.testMethodName" --info | ||
| ``` | ||
|
|
||
| ### Build Configuration | ||
|
|
||
| - All Kotlin warnings are errors (`allWarningsAsErrors = true`) | ||
| - Versions are defined in root `build.gradle` — check there for current Kotlin, AGP, SDK, and dependency versions | ||
|
|
||
| ## GitHub Commands | ||
|
|
||
| ```bash | ||
| PAGER=cat gh pr list | ||
| PAGER=cat gh pr view <NUMBER> | ||
| PAGER=cat gh pr view <NUMBER> --comments | ||
| PAGER=cat gh pr diff <NUMBER> | ||
| ``` | ||
|
|
||
| ## PR Template | ||
|
|
||
| PRs follow this format (from `.github/PULL_REQUEST_TEMPLATE.md`): | ||
| ``` | ||
| ### Fix | ||
| <description of what was fixed/added> | ||
|
|
||
| ### Test | ||
| 1. Step 1 | ||
| 2. Step 2 | ||
|
|
||
| ### Review | ||
| @reviewer | ||
| ``` | ||
|
|
||
| ## Skills | ||
|
|
||
| | Skill | Trigger phrases | | ||
| |-------------|------------------------------------------------------------------------------------------------------| | ||
| | `implement` | "implement", "fix this", "work on this", "build this", "add feature", any implementation request | | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Twinsen81: |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| AGENTS.md |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing a ":" in front of
aztec