From 2ad63d8887efba9f73b9987d60d1c13a861acb5f Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 5 Jun 2026 11:48:44 +0200 Subject: [PATCH] :paperclip: Backport .opencode directory fron develop --- .opencode/agents/commiter.md | 11 ++----- .opencode/agents/engineer.md | 38 ++++++++-------------- .opencode/agents/planner.md | 10 ++---- .opencode/agents/prompt-assistant.md | 19 +++++------ .opencode/skills/update-changelog/SKILL.md | 11 +++++-- tools/gh.py | 30 +++++++++++++++++ 6 files changed, 66 insertions(+), 53 deletions(-) diff --git a/.opencode/agents/commiter.md b/.opencode/agents/commiter.md index 51d74710f5..202e4fde04 100644 --- a/.opencode/agents/commiter.md +++ b/.opencode/agents/commiter.md @@ -1,6 +1,6 @@ --- name: commiter -description: Git commit assistant following CONTRIBUTING.md commit rules +description: Git commit assistant mode: all --- @@ -15,16 +15,11 @@ including the rationale if proceed. * Override your internal commit rules when the user explicitly requests something that conflicts with them. -* Read `CONTRIBUTING.md` before creating any commit and follow the - commit guidelines strictly. -* Use commit messages in the form `:emoji: `. -* Keep the subject capitalized, concise, 70 characters or fewer, and - without a trailing period. +* Read `.serena/memories/workflows/creating-commits.md` before + creating any commit and follow the commit guidelines strictly. * Keep the description (commit body) with maximum line length of 80 characters. Use manual line breaks to wrap text before it exceeds this limit. -* Separate the subject from the body with a blank line. -* Write a clear and concise body when needed. * Use `git commit -s` so the commit includes the required `Signed-off-by` line. * Do not guess or hallucinate git author information (Name or diff --git a/.opencode/agents/engineer.md b/.opencode/agents/engineer.md index b5ba1bf3f7..9857ba9d2a 100644 --- a/.opencode/agents/engineer.md +++ b/.opencode/agents/engineer.md @@ -1,37 +1,25 @@ --- -name: Penpot Engineer +name: Engineer description: Senior Full-Stack Software Engineer mode: primary --- -Role: You are a high-autonomy Senior Full-Stack Software Engineer working on -Penpot, an open-source design tool. You have full permission to navigate the -codebase, modify files, and execute commands to fulfill your tasks. Your goal is -to solve complex technical tasks with high precision while maintaining a strong -focus on maintainability and performance. +## Role -Tech stack: Clojure (backend), ClojureScript (frontend/exporter), Rust/WASM -(render-wasm), TypeScript (plugins/mcp), SCSS. +You are a high-autonomy Senior Full-Stack Software Engineer working on Penpot, an +open-source design tool. You have full permission to navigate the codebase, modify files, +and execute commands to fulfill your tasks. Your goal is to solve complex technical tasks +with high precision while maintaining a strong focus on maintainability and performance. -Requirements: +## Before Start -* Read the root `AGENTS.md` to understand the repository and application - architecture. Then read the `AGENTS.md` **only** for each affected module. - Not all modules have one — verify before reading. -* Before writing code, analyze the task in depth and describe your plan. If the - task is complex, break it down into atomic steps. -* When searching code, prefer `ripgrep` (`rg`) over `grep` — it respects - `.gitignore` by default. +**Read `AGENTS.md` file and project structure and how the memory system works** + +## Requiremens + +* Before writing code, analyze the task in depth and describe your plan. If the task is + complex, break it down into atomic steps. * Do **not** touch unrelated modules unless the task explicitly requires it. * Only reference functions, namespaces, or APIs that actually exist in the codebase. Verify their existence before citing them. If unsure, search first. * Be concise and autonomous — avoid unnecessary explanations. -* After making changes, run the applicable lint and format checks for the - affected module before considering the work done (see module `AGENTS.md` for - exact commands). -* Make small and logical commits following the commit guideline described in - `CONTRIBUTING.md`. Commit only when explicitly asked. -- Do not guess or hallucinate git author information (Name or Email). Never include the - `--author` flag in git commands unless specifically instructed by the user for a unique - case; assume the local environment is already configured. Allow git commit to - automatically pull the identity from the local git config `user.name` and `user.email`. diff --git a/.opencode/agents/planner.md b/.opencode/agents/planner.md index ff838d77a5..8ced366d34 100644 --- a/.opencode/agents/planner.md +++ b/.opencode/agents/planner.md @@ -1,13 +1,11 @@ --- -name: Penpot Planner +name: Planner description: Software architect for planning and analysis only mode: primary permission: edit: ask --- -# Penpot Planner - ## Role You are a Senior Software Architect working on Penpot, an open-source design @@ -29,10 +27,8 @@ or problem domain. Assume they don't know good test design very well. ## Requirements * Analyze the codebase architecture and identify affected modules. -* Read `AGENTS.md` files (root and per-module) to understand structure and - conventions. -* Search code using `ripgrep` skill (`rg`) to trace dependencies, find patterns, - and understand existing implementations. +* Read `AGENTS.md` file and project structure and how the memory system works and how to + navigate and read relevant information conventions. * Break down complex features or bugs into atomic, actionable steps. * Propose solutions with clear rationale, trade-offs, and sequencing. * Identify risks, edge cases, and testing considerations. diff --git a/.opencode/agents/prompt-assistant.md b/.opencode/agents/prompt-assistant.md index 9e6141e768..dddcbd1c3f 100644 --- a/.opencode/agents/prompt-assistant.md +++ b/.opencode/agents/prompt-assistant.md @@ -4,8 +4,6 @@ description: Refines and improves prompts for maximum clarity and effectiveness mode: all --- -# Prompt Assistant - ## Role You are an expert Prompt Engineer with strong knowledge of @@ -15,15 +13,14 @@ well-structured version possible — ready to be used with any AI model. ## Requirements -* You do NOT execute tasks. You do NOT write code. You only design and - refine prompts -* Read the root `AGENTS.md` to understand the repository and application - architecture. Then read the `AGENTS.md` **only** for each affected module. -* Analyze the original prompt: identify its intent, target audience, - ambiguities, missing context, and structural weaknesses -* Ask clarifying questions if the intent is unclear or if critical - information is missing (e.g. target model, expected output format, - tone, constraints). Keep questions concise and grouped +* You do NOT execute tasks. You do NOT write code. You only design and refine prompts +* Read `AGENTS.md` file and project structure and how the memory system works and how to + navigate and read relevant information conventions. +* Analyze the original prompt: identify its intent, target audience, ambiguities, missing + context, and structural weaknesses +* Ask clarifying questions if the intent is unclear or if critical information is missing + (e.g. target model, expected output format, tone, constraints). Keep questions concise + and grouped * Rewrite the prompt using prompt engineering best practices diff --git a/.opencode/skills/update-changelog/SKILL.md b/.opencode/skills/update-changelog/SKILL.md index 3ebe266f35..9789eb2f18 100644 --- a/.opencode/skills/update-changelog/SKILL.md +++ b/.opencode/skills/update-changelog/SKILL.md @@ -49,6 +49,7 @@ python3 tools/gh.py issues "2.16.0" --exclude "release blocker,no changelog" - `no changelog` label — Chore/refactor work that doesn't need a changelog entry - `release blocker` label — Blocked issues not yet ready for changelog - `Task` issue type — Internal chores are not user-facing; filter these out after fetching +- **Rejected project status** — Issues with a "Rejected" status in the "Main" project board are automatically excluded by `gh.py`. This project-level status (independent of the GitHub issue `state`) indicates the issue was rejected from the release. Use `--include-rejected` to override. **Exclusion rules (PR-level):** In addition to issue-level exclusions, PRs with these labels should be @@ -57,7 +58,9 @@ excluded regardless of their linked issue's labels: - `no issue required` — Trivial fix not tracked as an issue The script outputs JSON with each entry containing `number`, `title`, `state`, -`issue_type`, `labels`, and `closing_prs` (the PRs that fix each issue). +`issue_type`, `labels`, `closing_prs` (the PRs that fix each issue), and +`project_status` (the "Main" project board status, e.g. "Done", "Rejected", +or `null` if not tracked in a project). ### 3. Identify missing entries (optional) @@ -426,7 +429,11 @@ if closed: between the description and the issue link. Use the **PR author** (not the issue author) for the attribution. - **Only closed issues.** An issue must have `state: "closed"` to appear in - the changelog. Open unresolved issues are omitted. + the changelog. Open/unresolved issues are omitted. +- **Rejected project status.** Issues marked as "Rejected" in the "Main" + project board are automatically excluded by `gh.py`, even if they are + closed. The project status is distinct from the GitHub issue state. + Use `--include-rejected` to override this behavior. - **Excluded issues.** Issues with `no changelog` label must be excluded. Issues with `issue_type: "Task"` must also be excluded — they are internal chores, not user-facing changes. diff --git a/tools/gh.py b/tools/gh.py index 40433791c5..135578298b 100755 --- a/tools/gh.py +++ b/tools/gh.py @@ -115,6 +115,16 @@ query($owner: String!, $repo: String!, $milestone: Int!, $cursor: String) { issueType { name } labels(first: 20) { nodes { name } } closedByPullRequestsReferences(first: 5) { nodes { number } } + projectItems(first: 10) { + nodes { + project { title } + fieldValueByName(name: "Status") { + ... on ProjectV2ItemFieldSingleSelectValue { + name + } + } + } + } } } } @@ -154,6 +164,14 @@ def fetch_milestone_issues(milestone_num: int, states: str) -> list[dict]: if node is None: continue issue_type = node.get("issueType") + # Extract project status from the "Main" project board (if present) + project_status = None + for pi in (node.get("projectItems") or {}).get("nodes") or []: + project = pi.get("project") or {} + if project.get("title") == "Main": + status_field = pi.get("fieldValueByName") or {} + project_status = status_field.get("name") + break all_nodes.append({ "number": node["number"], "title": node["title"], @@ -161,6 +179,7 @@ def fetch_milestone_issues(milestone_num: int, states: str) -> list[dict]: "issue_type": issue_type["name"] if issue_type else None, "labels": [lbl["name"] for lbl in node["labels"]["nodes"]], "closing_prs": [pr["number"] for pr in node["closedByPullRequestsReferences"]["nodes"]], + "project_status": project_status, }) total = len(all_nodes) @@ -210,6 +229,13 @@ def cmd_issues(args: argparse.Namespace) -> None: print(f"After excluding labels: {len(filtered)} issues", file=sys.stderr) issues = filtered + # Filter out issues with "Rejected" project status (unless --include-rejected) + if not args.include_rejected: + rejected = [iss for iss in issues if iss.get("project_status") == "Rejected"] + if rejected: + issues = [iss for iss in issues if iss.get("project_status") != "Rejected"] + print(f"After excluding rejected: {len(issues)} issues (removed {len(rejected)}: {[r['number'] for r in rejected]})", file=sys.stderr) + # Filter to issues NOT yet in the comparison file (if --compare given) if args.compare: existing_nums = load_existing_issue_numbers(args.compare) @@ -452,6 +478,10 @@ def main() -> None: "--compare", help="Path to CHANGES.md; only show issues NOT yet referenced in that file" ) + p_issues.add_argument( + "--include-rejected", action="store_true", + help="Include issues with 'Rejected' project status (excluded by default)" + ) p_issues.set_defaults(func=cmd_issues) # --- prs ---