mirror of
https://github.com/penpot/penpot.git
synced 2026-06-09 17:02:05 +00:00
Merge remote-tracking branch 'origin/main' into staging
This commit is contained in:
commit
82cfbedc26
5
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
5
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@ -1,7 +1,10 @@
|
||||
description: Create a report to help us improve
|
||||
labels: ["bug"]
|
||||
name: Bug report
|
||||
title: "bug: "
|
||||
type: Bug
|
||||
labels: ["triage"]
|
||||
projects: ["penpot/8"]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
blank_issues_enabled: true
|
||||
5
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
5
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@ -1,7 +1,10 @@
|
||||
description: Suggest an idea for this project.
|
||||
labels: ["needs triage", "enhancement"]
|
||||
labels: ["needs triage"]
|
||||
name: "Feature request"
|
||||
title: "feature: "
|
||||
type: Enhancement
|
||||
projects: ["penpot/8"]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
38
.github/ISSUE_TEMPLATE/new-render-bug-report.md
vendored
38
.github/ISSUE_TEMPLATE/new-render-bug-report.md
vendored
@ -1,38 +0,0 @@
|
||||
---
|
||||
name: New Render Bug Report
|
||||
about: Create a report about the bugs you have found in the new render
|
||||
title: ''
|
||||
labels: new render
|
||||
assignees: claragvinola
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Steps to Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots or screen recordings**
|
||||
If applicable, add screenshots or screen recording to help illustrate your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -15,6 +15,5 @@
|
||||
- [ ] Add or modify existing integration tests in case of bugs or new features, if applicable.
|
||||
- [ ] Refactor any modified SCSS files following the refactor guide.
|
||||
- [ ] Check CI passes successfully.
|
||||
- [ ] Update the `CHANGES.md` file, referencing the related GitHub issue, if applicable.
|
||||
|
||||
<!-- For more details, check the contribution guidelines: https://github.com/penpot/penpot/blob/develop/CONTRIBUTING.md -->
|
||||
|
||||
@ -70,12 +70,7 @@ module's `AGENTS.md` for the exact commands). If the formatter auto-fixes
|
||||
indentation, verify the logic is still semantically correct. All checks must
|
||||
pass before moving on.
|
||||
|
||||
### 6. Port the changelog entry (if any)
|
||||
|
||||
If the original commit added or modified a `CHANGES.md` entry, port that entry
|
||||
too — adapting wording and version references for the target branch.
|
||||
|
||||
### 7. Commit
|
||||
### 6. Commit
|
||||
|
||||
Ask the `commiter` sub-agent to create a commit. Stage all relevant files
|
||||
(exclude unrelated untracked files) and provide the original commit message as
|
||||
|
||||
123
.opencode/skills/issue-title/SKILL.md
Normal file
123
.opencode/skills/issue-title/SKILL.md
Normal file
@ -0,0 +1,123 @@
|
||||
---
|
||||
name: issue-title
|
||||
description: Derive a clear, well-formatted title for a GitHub issue from its description body, using descriptive present-tense for bugs and imperative mood for features, always including the "where" (location in the UI/module).
|
||||
---
|
||||
|
||||
# Skill: issue-title
|
||||
|
||||
Derive a concise, descriptive title for a GitHub issue based on its body
|
||||
content. Use **descriptive present tense for bugs** (e.g. "Plugin API
|
||||
crashes when setting text fills") and **imperative mood for features** (e.g.
|
||||
"Add customizable dash and gap controls"). No emoji or type prefixes
|
||||
(`feat:`, `bug:`, `feature:`, etc.).
|
||||
|
||||
Can be used both when **creating a new issue** and when **updating an
|
||||
existing one** that has a vague or outdated title.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Creating a new issue and need a well-formatted title from the draft body
|
||||
- An existing issue has a vague, outdated, or auto-generated title (e.g.
|
||||
`[PENPOT FEEDBACK]: ...`, `feature: ...`)
|
||||
- The current title doesn't reflect the actual content of the description
|
||||
- The title is missing the "where" (which part of the UI/module is affected)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- `gh` CLI authenticated (`gh auth status`)
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Get the issue body
|
||||
|
||||
For an **existing issue**, fetch it:
|
||||
|
||||
```bash
|
||||
gh issue view <NUMBER> --repo penpot/penpot --json title,body
|
||||
```
|
||||
|
||||
For a **new issue**, read the draft body from wherever it was provided
|
||||
(Taiga link, user report, discussion, etc.).
|
||||
|
||||
### 2. Read the body and derive a title
|
||||
|
||||
Extract the core problem or request from the description. Distinguish between
|
||||
bug reports and feature requests:
|
||||
|
||||
**Bug titles (descriptive, present tense):**
|
||||
Describe the symptom as it appears to the user. Format:
|
||||
`[Where] [present-tense verb] when [condition]`
|
||||
|
||||
- *"Plugin API crashes when setting text fills"*
|
||||
- *"Canvas renders glitches when zooming quickly"*
|
||||
- *"French Canada locale falls back to French (fr) translations"*
|
||||
- *"Text layer content is not deleted when WebGL render is enabled"*
|
||||
|
||||
Do **not** start bug titles with "Fix" or any imperative verb. The title
|
||||
should state what's broken, not command a fix.
|
||||
|
||||
**Feature / Enhancement titles (imperative mood):**
|
||||
Command what should be built. Format:
|
||||
`[Imperative verb] [what] in/on [where]`
|
||||
|
||||
- *"Add customizable dash and gap length controls to dashed strokes in the sidebar"*
|
||||
- *"Show user, timestamp, and hash in the workspace history panel like git commits"*
|
||||
- *"Validate shape on add-object to catch malformed inputs early"*
|
||||
|
||||
**Universal rules (both types):**
|
||||
- **Include the "where"** — specify the UI location or module (e.g.
|
||||
"in the sidebar", "in the workspace history panel", "on the stroke
|
||||
options")
|
||||
- **No prefixes** — strip `bug:`, `feature:`, `feat:`, `:bug:`, `:sparkles:`,
|
||||
`[PENPOT FEEDBACK]`, etc.
|
||||
- **No emoji** — plain text only
|
||||
- **Be specific** — prefer concrete detail over generality. If the
|
||||
description mentions two related problems, capture both.
|
||||
|
||||
**Examples:**
|
||||
|
||||
| Original / draft title | Type | New title |
|
||||
|---|---|---|
|
||||
| `[PENPOT FEEDBACK]: WebGL` | Bug | `Canvas renders glitches when zooming quickly — text appears distorted and nodes have background-colored rectangles` |
|
||||
| `bug: flatten-nested-tokens-json uses $type instead of $value as the DTCG token/group discriminator` | Bug | `Token import fails when group-level type inheritance is used — parser misidentifies groups as tokens` |
|
||||
| `feature: Dashed stroke customization` | Feature | `Add customizable dash and gap length controls to dashed strokes in the sidebar` |
|
||||
| `feature: Add more detail to history of actions` | Feature | `Show user, timestamp, and hash in the workspace history panel like git commits` |
|
||||
|
||||
### 3. Apply the title
|
||||
|
||||
**If updating an existing issue:**
|
||||
|
||||
```bash
|
||||
gh issue edit <NUMBER> --repo penpot/penpot --title "<NEW TITLE>"
|
||||
```
|
||||
|
||||
**If creating a new issue:**
|
||||
|
||||
```bash
|
||||
gh issue create --repo penpot/penpot --title "<NEW TITLE>" --body "<BODY>"
|
||||
```
|
||||
|
||||
### 4. Confirm
|
||||
|
||||
For updates, the command returns the issue URL. Verify by optionally fetching
|
||||
again:
|
||||
|
||||
```bash
|
||||
gh issue view <NUMBER> --repo penpot/penpot --json title
|
||||
```
|
||||
|
||||
## Key Principles
|
||||
|
||||
- **Bug titles describe the symptom** — present tense, 3rd person:
|
||||
"crashes", "fails", "shows", "is cut off", "does not load". Do not
|
||||
start with "Fix" or "Bug:".
|
||||
- **Feature titles use imperative mood** — command form: "Add", "Show",
|
||||
"Use", "Validate", "Support", "Toggle".
|
||||
- **Always include the "where"** — a title like "Crashes when zooming"
|
||||
is too vague; "Canvas crashes when zooming quickly" is clear.
|
||||
- **No prefixes, no emoji** — strip all type labels and decorative
|
||||
characters from the title.
|
||||
- **Derive from the body, not the current title** — the body contains
|
||||
the real detail; the current title may be auto-generated or stale.
|
||||
- **Two problems → cover both** — if the description has two distinct
|
||||
but related issues, capture both in the title joined by "and".
|
||||
@ -21,20 +21,3 @@ Co-authored-by: <You (the LLM)>
|
||||
## Commit Type Emojis
|
||||
|
||||
`:bug:` bug fix · `:sparkles:` enhancement · `:tada:` new feature · `:recycle:` refactor · `:lipstick:` cosmetic · `:ambulance:` critical fix · `:books:` docs · `:construction:` WIP · `:boom:` breaking · `:wrench:` config · `:zap:` perf · `:whale:` docker · `:paperclip:` other · `:arrow_up:` dep upgrade · `:arrow_down:` dep downgrade · `:fire:` removal · `:globe_with_meridians:` translations · `:rocket:` epic/highlight
|
||||
|
||||
|
||||
## Changelogs
|
||||
|
||||
**IMPORTANT:** do not modify the changelog unless it explicitly asked.
|
||||
|
||||
For user-facing or notable changes, update the relevant changelog under the unreleased section:
|
||||
- Main app/modules (`backend`, `frontend`, `common`, `render-wasm`, `exporter`, `mcp`): root `CHANGES.md`.
|
||||
- Plugin subproject changes: `plugins/CHANGELOG.md`.
|
||||
|
||||
Entry format uses the matching category (`:sparkles:`, `:bug:`, etc.) and references the GitHub issue:
|
||||
|
||||
```
|
||||
- Short description of change [#NNNN](https://github.com/penpot/penpot/issues/NNNN)
|
||||
```
|
||||
|
||||
Plugin API changelog prefixes: type/signature -> `**plugin-types:**`; runtime behavior -> `**plugin-runtime:**` in `plugins/CHANGELOG.md`.
|
||||
|
||||
11
AGENTS.md
11
AGENTS.md
@ -32,17 +32,6 @@ precision while maintaining a strong focus on maintainability and performance.
|
||||
5. When searching code, prefer `ripgrep` (`rg`) over `grep` — it respects
|
||||
`.gitignore` by default.
|
||||
|
||||
## Changelogs
|
||||
|
||||
The project has two changelogs:
|
||||
|
||||
- **Main project changelog**: `CHANGES.md` (root of the repository). Tracks changes for the core Penpot application (backend, frontend, common, render-wasm, exporter, mcp).
|
||||
- **Plugins changelog**: `plugins/CHANGELOG.md`. Tracks changes for the plugins subproject only.
|
||||
|
||||
When making changes, add a changelog entry to the appropriate file under the
|
||||
`## <version> (Unreleased)` section in the correct category
|
||||
(`:sparkles: New features & Enhancements` or `:bug: Bugs fixed`).
|
||||
|
||||
## GitHub Operations
|
||||
|
||||
To obtain the list of repository members/collaborators:
|
||||
|
||||
@ -237,9 +237,8 @@ setting this up.
|
||||
|
||||
## Changelog
|
||||
|
||||
When your change is user-facing or otherwise notable, add an entry to
|
||||
[CHANGES.md](CHANGES.md) following the same commit-type conventions. Reference
|
||||
the relevant GitHub issue or Taiga user story.
|
||||
The changelog is updated automatically as part of the release process. Contributors
|
||||
should **not** modify `CHANGES.md` manually in their pull requests.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
|
||||
@ -183,7 +183,7 @@
|
||||
:clj (Math/log10 x)))
|
||||
|
||||
(defn clamp [num from to]
|
||||
(if (< num from)
|
||||
(if (or (nan? num) (< num from))
|
||||
from
|
||||
(if (> num to) to num)))
|
||||
|
||||
|
||||
@ -738,7 +738,7 @@
|
||||
[h s v] (clr/hex->hsv value)]
|
||||
(merge data
|
||||
{:hex (or value "000000")
|
||||
:alpha (or opacity 1)
|
||||
:alpha (if (d/nan? opacity) 1 (or opacity 1))
|
||||
:r r :g g :b b
|
||||
:h h :s s :v v})))
|
||||
|
||||
@ -815,7 +815,6 @@
|
||||
(rx/filter (ptk/type? ::update-colorpicker-add-stop) stream)
|
||||
(rx/filter (ptk/type? ::update-colorpicker-add-auto) stream)
|
||||
(rx/filter (ptk/type? ::remove-gradient-stop) stream))
|
||||
(rx/debounce 40)
|
||||
(rx/map (constantly (colorpicker-onchange-runner on-change)))
|
||||
(rx/take-until stopper))))
|
||||
|
||||
|
||||
@ -42,9 +42,11 @@
|
||||
(when on-change
|
||||
(let [{:keys [left right top bottom]} (-> ev dom/get-target dom/get-bounding-rect)
|
||||
{:keys [x y]} (-> ev dom/get-client-position)
|
||||
h-size (- right left)
|
||||
v-size (- bottom top)
|
||||
unit-value (if is-vertical
|
||||
(mth/clamp (/ (- bottom y) (- bottom top)) 0 1)
|
||||
(mth/clamp (/ (- x left) (- right left)) 0 1))
|
||||
(if (pos? v-size) (mth/clamp (/ (- bottom y) v-size) 0 1) 0)
|
||||
(if (pos? h-size) (mth/clamp (/ (- x left) h-size) 0 1) 0))
|
||||
value (+ min-value (* unit-value (- max-value min-value)))]
|
||||
(on-change value))))]
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
(ns app.main.ui.workspace.viewport.pixel-overlay
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.math :as mth]
|
||||
[app.config :as cfg]
|
||||
@ -89,10 +90,10 @@
|
||||
(when (and (>= x 0) (< x img-width) (>= y 0) (< y img-height))
|
||||
(let [offset (* (+ (* y img-width) x) 4)
|
||||
rgba (unchecked-get image-data "data")
|
||||
r (obj/get rgba (+ 0 offset))
|
||||
g (obj/get rgba (+ 1 offset))
|
||||
b (obj/get rgba (+ 2 offset))
|
||||
a (obj/get rgba (+ 3 offset))
|
||||
r (d/check-num (obj/get rgba (+ 0 offset)) 255)
|
||||
g (d/check-num (obj/get rgba (+ 1 offset)) 255)
|
||||
b (d/check-num (obj/get rgba (+ 2 offset)) 255)
|
||||
a (d/check-num (obj/get rgba (+ 3 offset)) 255)
|
||||
color [r g b a]]
|
||||
;; Store latest color synchronously so the click handler always reads
|
||||
;; the correct pixel even before the rAF fires (fixes race condition)
|
||||
@ -293,13 +294,13 @@
|
||||
;; Only pick color when cursor is within canvas bounds to avoid garbage pixels
|
||||
(when (and (>= canvas-x 0) (< canvas-x img-width) (>= canvas-y 0) (< canvas-y img-height))
|
||||
(let [;; image-data pixels start from the bottom-left corner; invert y accordingly
|
||||
inverted-y (- img-height canvas-y)
|
||||
inverted-y (- img-height canvas-y 1)
|
||||
offset (* (+ (* inverted-y img-width) canvas-x) 4)
|
||||
rgba (.-data image-data)
|
||||
r (obj/get rgba (+ 0 offset))
|
||||
g (obj/get rgba (+ 1 offset))
|
||||
b (obj/get rgba (+ 2 offset))
|
||||
a (obj/get rgba (+ 3 offset))
|
||||
r (d/check-num (obj/get rgba (+ 0 offset)) 255)
|
||||
g (d/check-num (obj/get rgba (+ 1 offset)) 255)
|
||||
b (d/check-num (obj/get rgba (+ 2 offset)) 255)
|
||||
a (d/check-num (obj/get rgba (+ 3 offset)) 255)
|
||||
color [r g b a]]
|
||||
;; Store latest color synchronously so the click handler always reads
|
||||
;; the correct pixel even before the rAF fires (fixes race condition)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user