Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .claude/skills/refactoring-entry/LESSONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,21 @@ brief.md or workflow.js and deleted here. Keep the calibration table current.
hand-defined `everywhere` that used to sit in an "across a whole tree" example's After and
buries the point (the optic is the reusable bit, not the walk). If the example needs shared
walk machinery, add `Plated`/`everywhere` to `shared/` (a `trait`/`class` with a `descend`
instance per type; `everywhere f s = descend (everywhere f) (f s)`) and declare the type's
instance per type; `everywhere f s = f (descend (everywhere f) s)`) and declare the type's
`Plated` instance in the example — the walk comes from the library, the example only says
which fields recurse. Same for any helper (a fold over the tree, a traversal builder): it
belongs in `shared/` or a library, not re-derived in the example.
→ folded into SKILL.md §3 and brief.md ("Never hand-write helpers").


## 2026-09-26 — 02 clean examples and diagram overlap review

- **Examples.** Keep domain optics named and compositional (`varP.andThen(nameL)`,
`.each`, `Plated.everywhere`); do not expose global `compose` calls or intermediate
values that the fluent API can express. Corrected `Plated.everywhere` to bottom-up:
transform children through `descend`, then apply the node rewrite.
- **Diagrams.** Numbered circles on panel borders, arrows crossing boxes and dashed
highlights through text produced visible overlap artifacts. Use a wide center gutter,
marker-ended arrows entirely inside that gutter, and low-alpha highlight fills with
no stroke. Render the actual SVG at desktop and mobile widths before assembly.
→ folded into workflow.js's diagram prompt.
4 changes: 2 additions & 2 deletions .claude/skills/refactoring-entry/workflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ Re-run every spec in both languages and sh ${EX}/run.sh; re-run the reviewer's m

You are the DIAGRAM agent. Produce small inline-SVG diagrams for the page /refactorings/${A.slug}/, saved under ${EX}/. Read ${REPO}/pages/refactorings/extract-method/diagrams/koan.svg and one of its NN-*/diagram.svg first and match their visual language exactly (same stroke widths, fonts, arrow style, dashed region convention).
- diagrams/koan.svg — the "to and from" pair for this refactoring: left = before-shape, right = after-shape, top arrow labelled with the move pointing right, bottom arrow labelled with the inverse pointing left. Use the terms from ${SCRATCH}/research.md's "To and from" section.
- NN-<ex>/diagram.svg for each example directory present (read Before/After in that dir first): left = Before with the affected region drawn as a dashed inner rectangle; right = After with the new structure and the relationship (call, instance, parameter) named on the arrow. Use the real names from the code.
Rules: viewBox-based, no fixed width/height; all strokes and text use currentColor so it works in light and dark themes; fills only rgba with low alpha or none; font-family: inherit; font-size 12–14 viewBox units; <title> for accessibility; role="img"; no external resources, no scripts, no site CSS classes; each file under 6 KB; NO {{ or {% sequences. Render-check each SVG with the chrome-devtools MCP tools (ToolSearch for mcp__chrome-devtools__new_page / take_screenshot; file:// URLs work) at 1000px and 360px wide and fix overlaps or clipped text. Return the list of files written and notes.`,
- NN-<ex>/diagram.svg for each example directory present (read Before/After in that dir first): left = Before, right = After, with the relationship (call, instance, parameter) named in a wide center gutter. Highlight affected regions with a low-alpha fill only; do not put dashed strokes through text, numbered circles on panel borders, or arrows across boxes. Use the real names from the code.
Rules: viewBox-based, no fixed width/height; all strokes and text use currentColor so it works in light and dark themes; fills only rgba with low alpha or none; font-family: inherit; font-size 12–14 viewBox units; <title> for accessibility; role="img"; no external resources, no scripts, no site CSS classes; each file under 6 KB; NO {{ or {% sequences. Render-check the real SVG at 1000px and 360px wide with whatever screenshot facility the current agent runtime provides (headless Chrome/Firefox, browser automation, or an image-rendering tool); inspect the images and fix every overlap or clipped label before returning. Return the list of files written and notes.`,
{ label: 'diagrams', phase: 'Diagrams', schema: DIAGRAM_SCHEMA })
}
return { examples, verdict, diagrams }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module After where

import Data.Char (toUpper)
import Optics (Lens(..), Prism(..), PartialLens(..), composeO, over)
import Optics (Lens(..), Prism(..), PartialLens(..), andThen, over)

data Var = Var { vName :: String, vRef :: Int }
deriving (Eq, Show)
Expand All @@ -20,7 +20,7 @@ nameL :: Lens Var String
nameL = Lens { view = vName, set = \(v, n) -> v { vName = n } }

varName :: PartialLens Expr String
varName = composeO varP nameL
varName = varP `andThen` nameL

upperVarName :: Expr -> Expr
upperVarName = over varName (map toUpper)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ object After:
)
val nameL: Lens[Var, String] =
Lens[Var, String](_.name, (v, n) => v.copy(name = n))
val varName: PartialLens[Expr, String] = compose(varP, nameL)
val varName: PartialLens[Expr, String] = varP.andThen(nameL)

def upperVarName(e: Expr): Expr = over(varName, _.toUpperCase)(e)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module After where
import Data.Char (toUpper)
import Optics
( Lens(..), Prism(..), PartialLens(..), Plated(..)
, composeO, over, everywhere
, andThen, over, everywhere
)

data Var = Var { vName :: String, vRef :: Int }
Expand All @@ -28,7 +28,7 @@ nameL :: Lens Var String
nameL = Lens { view = vName, set = \(v, n) -> v { vName = n } }

varName :: PartialLens Expr String
varName = composeO varP nameL
varName = varP `andThen` nameL

renameAll :: Expr -> Expr
renameAll = everywhere (over varName (map toUpper))
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object After:
)
val nameL: Lens[Var, String] =
Lens[Var, String](_.name, (v, n) => v.copy(name = n))
val varName: PartialLens[Expr, String] = compose(varP, nameL)
val varName: PartialLens[Expr, String] = varP.andThen(nameL)

def renameAll(e: Expr): Expr =
summon[Plated[Expr]].everywhere(over(varName, _.toUpperCase))(e)
Plated.everywhere(over(varName, _.toUpperCase))(e)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
-- reach every element, match the succeeded branch, edit its value.
module After where

import Optics (Lens(..), Prism(..), PartialLens(..), composeO, each, over)
import Optics
( Lens(..), Prism(..), PartialLens(..)
, andThen, each, over
)

data Ok = Ok { okValue :: Int }
deriving (Eq, Show)
Expand All @@ -18,11 +21,8 @@ succeededP = Prism
valueL :: Lens Ok Int
valueL = Lens { view = okValue, set = \(ok, v) -> ok { okValue = v } }

okVal :: PartialLens Result Int
okVal = composeO succeededP valueL

eachSucceeded :: PartialLens [Result] Int
eachSucceeded = each okVal
eachSucceeded = each (succeededP `andThen` valueL)

bumpSucceeded :: [Result] -> [Result]
bumpSucceeded = over eachSucceeded (+ 1)
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ object After:
)
val valueL: Lens[Ok, Int] =
Lens[Ok, Int](_.value, (ok, v) => ok.copy(value = v))
val okVal: PartialLens[Result, Int] = compose(succeededP, valueL)

val eachSucceeded: PartialLens[List[Result], Int] = each(okVal)
val eachSucceeded: PartialLens[List[Result], Int] =
succeededP.andThen(valueL).each

def bumpSucceeded(xs: List[Result]): List[Result] =
over(eachSucceeded, _ + 1)(xs)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading