quill-code
SkillMediaquill-code is a skill for AI agents that work in the PostHog monorepo. It walks the agent through editing the @posthog/quill design system locally, primitives, components, blocks, or tokens, then building, packing, and wiring a pnpm override so the desktop Code app can consume the unpublished change before it reaches npm.
Use quill-code in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add quill-code and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the quill-code skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; ahel provides instructions and does not run this skill.
No other account needed.
Have the PostHog monorepo checked out, with the quill source at packages/quill and the desktop app at products/desktop.
What your AI can do with it
- Edit quill primitives, components, and blocks in packages/quill sub-packages
- Build the whole quill workspace so sub-packages rebuild before the aggregate
- Pack the built package into a uniquely named .local-quill tarball
- Point a temporary pnpm overrides entry at the local tarball
- Resync and verify each change in the running desktop app
- Revert the override once the change is published to npm
Getting started
- Have the PostHog monorepo checked out, with the quill source at packages/quill and the desktop app at products/desktop.
- Run pnpm install at the monorepo root once, since building quill uses the root workspace's install.
- Give your agent the skill so it knows the quill layout and the edit-build-pack-override loop.
- Ask the agent to make your quill change; it will build, pack, and point the override so you can verify in the desktop app.
- After the change is published to npm, have the agent revert the temporary override before merging.
What this skill tells your AI
The instructions your AI receives, as published by posthog/posthog in products/desktop/.claude/skills/quill-code/SKILL.md and read by ahel’s review.
@posthog/quill's source lives in this monorepo at packages/quill (repo root, two
levels up from products/desktop). Desktop still consumes the published npm package
via its nested workspace catalog — products/desktop is excluded from the root pnpm
workspace, so workspace: linking cannot reach it. To test an unpublished quill change
here, you build quill in-repo, pack it to a tarball, and point a pnpm overrides entry
at that tarball. This is a temporary local-dev state — revert before merging (see
below).
All commands below run from products/desktop/. Building quill uses the root
workspace's install, so run pnpm install at the monorepo root once first.
Quill layout (where to edit)
packages/quill (from the monorepo root) is the workspace
(@posthog/quill-workspace). It contains sub-packages, each a layer of the design
system:
packages/primitives/src— base components (Card, Badge, Button, Progress, …)packages/components/src— composed components (DataTable, DateTimePicker, Metric)packages/blocks/src— product-level blocks (e.g.ExperimentCard). Add the file here and export it frompackages/blocks/src/index.ts.packages/quill/src— the aggregate that re-exports all layers as@posthog/quill.
A new export in any sub-package flows to @posthog/quill automatically on build.
The loop (every quill change)
-
Edit/add the component in the right sub-package (above) and export it from that package's
src/index.ts. -
Re-sync into products/desktop manually — build → pack → point the override → reinstall:
# From products/desktop/ DESKTOP_ROOT="$PWD" QUILL_DIR="${QUILL_DIR:-../../packages/quill/packages/quill}" # a. Build the WHOLE quill workspace (two levels up from the aggregate), so the # sub-packages rebuild BEFORE the aggregate bundles them. ( cd "$QUILL_DIR/../.." && pnpm build ) # b. Pack into .local-quill/ under a UNIQUE filename. pnpm pins a tarball by # integrity, so a stable name caches stale across re-syncs — drop old local # tarballs first, then rename the packed file to a unique local name. # (Anchor on $DESKTOP_ROOT, not `git rev-parse --show-toplevel`: the git # toplevel is the monorepo root, not this workspace.) rm -f .local-quill/posthog-quill-local-*.tgz ( cd "$QUILL_DIR" && npm pack --pack-destination "$DESKTOP_ROOT/.local-quill" ) mv .local-quill/posthog-quill-[0-9]*.tgz ".local-quill/posthog-quill-local-$(git rev-parse --short HEAD)-$$.tgz" # c. Point the override at the new tarball, then reinstall. # Edit pnpm-workspace.yaml so overrides['@posthog/quill'] = file:./.local-quill/<new file> pnpm installBuilding only the aggregate (
packages/quill/packages/quill) re-bundles the sub-packages' staledist/, so edits to primitives/components/blocks are silently dropped. Always build at the workspace root. -
Verify in the Code app (
pnpm dev, or thetest-electron-appskill). Repeat from 1.
After every quill edit you must re-run the sync — the app consumes the tarball, not the quill source, so unsynced edits are invisible here.
For an out-of-tree quill checkout, set
QUILL_DIR=/abs/path/to/posthog/packages/quill/packages/quill.
Why a tarball, not link: or workspace:
workspace: cannot resolve across the nested-workspace boundary (products/desktop is
excluded from the root pnpm workspace). link: symlinks into the root workspace's
node_modules and drags in its React 18 types, colliding with this workspace's
React 19 (dual-React → broken typecheck + invalid-hook-call at runtime). The
tarball is copied into this workspace's store and deduped against React 19. The
filename is content-hashed because pnpm pins a tarball by integrity, so a stable
filename gets cached stale across re-syncs.
The override (what the script rewrites)
In pnpm-workspace.yaml, under overrides::
'@posthog/quill': file:./.local-quill/posthog-quill-local-<hash>.tgz
There is also a permanent pin you should leave alone:
'@posthog/quill>@base-ui/react': ^1.3.0 # quill ships a broken catalog: dep; do not remove
Reverting (before merge)
The override is local-dev only. Once the quill change is published to npm (quill
publishes from this monorepo via the manual publish-quill-npm workflow dispatch):
- Bump the catalog version in
pnpm-workspace.yaml('@posthog/quill': 0.3.0-beta.x) to the published version. - Restore the override line to point back at the catalog, or remove the
file:override. pnpm install.
Do not commit a file:./.local-quill/... override or the .local-quill/ tarballs.
Signals
- GitHub stars
- 40k
- Forks
- 3k
- Last commit
- Sep 2026
ahel review
K1binfo
installs-packages
Automated review, not a security audit. Ruleset v1+k2.
Others that do the same job
Questions
- Why can't desktop just link to the local quill workspace?
- products/desktop is excluded from the root pnpm workspace, so workspace: linking cannot reach it. The skill instead packs a tarball and points a pnpm overrides entry at it.
- Why does the packed tarball need a unique filename?
- pnpm pins a tarball by integrity, so a stable name caches stale across re-syncs. Old local tarballs are dropped and the new one gets a unique name.
Advanced
- Item type
- skill
- Key
quill-code- Source
- github.com/posthog/posthog
Related picks
Skill · mattpocock
The pick for TypeScripttypescript-pro
Skill · jeffallan
The pick for TypeScriptreact-component-performance
Skill · davila7
The pick for Reactreact-doctor
Skill · millionco
The pick for Reactprototype
Skill · mattpocock
More in Mediabrand-guidelines
Skill · anthropics
More in Media