/quill-code
Edit the @posthog/quill design system locally and consume the change in products/desktop before it is published to npm. Use when changing quill components/primitives/tokens, when a quill change must be tested inside the Code app, or when the user mentions quill, the design
Claude Code
$ npx -y skills add posthog/posthog --skill quill-code --agent claude-code
Codex
$ npx skills add posthog/posthog --skill quill-code -a codex -y
Cursor
$ npx skills add posthog/posthog --skill quill-code -a cursor -y
Gemini CLI
$ npx skills add posthog/posthog --skill quill-code -a gemini-cli -y
GitHub Copilot
$ npx skills add posthog/posthog --skill quill-code -a github-copilot -y
OpenCode
$ npx skills add posthog/posthog --skill quill-code -a opencode -y
Windsurf
$ npx skills add posthog/posthog --skill quill-code -a windsurf -y
SKILL.md
quill-code.SKILL.mdname: quill-code
description: Edit the @posthog/quill design system locally and consume the change in products/desktop before it is published to npm. Use when changing quill components/primitives/tokens, when a quill change must be tested inside the Code app, or when the user mentions quill, the design system, the .local-quill tarball, or the @posthog/quill pnpm override.
quill-code
`@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 from `packages/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)
1. Edit/add the component in the right sub-package (above) and export it from that package's `src/index.ts`. 2. 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 install> Building only the aggregate (`packages/quill/packages/quill`) re-bundles the > sub-packages' **stale** `dist/`, so edits to primitives/components/blocks are > silently dropped. Always build at the workspace root. 3. Verify in the Code app (`pnpm dev`, or the `test-electron-app` skill). 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):
1. Bump the catalog version in `pnpm-workspace.yaml` (`'@posthog/quill': 0.3.0-beta.x`) to the published version. 2. Restore the override line to point back at the catalog, or remove the `file:` override. 3. `pnpm install`.
Do not commit a `file:./.local-quill/...` override or the `.local-quill/` tarballs.
Read more
name: quill-code description: Edit the @posthog/quill design system locally and consume the change in products/desktop before it is published to npm. Use when changing quill components/primitives/tokens, when a quill change must be tested inside the Code app, or when the user mentions quill, the design system, the .local-quill tarball, or the @posthog/quill pnpm override.
quill-code
`@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 from `packages/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)
1. Edit/add the component in the right sub-package (above) and export it from that package's `src/index.ts`. 2. 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 install> Building only the aggregate (`packages/quill/packages/quill`) re-bundles the > sub-packages' **stale** `dist/`, so edits to primitives/components/blocks are > silently dropped. Always build at the workspace root. 3. Verify in the Code app (`pnpm dev`, or the `test-electron-app` skill). 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):
1. Bump the catalog version in `pnpm-workspace.yaml` (`'@posthog/quill': 0.3.0-beta.x`) to the published version. 2. Restore the override line to point back at the catalog, or remove the `file:` override. 3. `pnpm install`.
Do not commit a `file:./.local-quill/...` override or the `.local-quill/` tarballs.
:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.
More skills from other plugins.
paddleocr-doc-parsing
Use this skill to extract structured Markdown/JSON from PDFs and document images—tables with cell-level precision, formulas as…
13c-metabolic-flux
Estimates intracellular metabolic fluxes from steady-state carbon-13 isotope-tracing measurements using validated atom maps,…
Questions about quill-code.
- Which coding agents can use quill-code?
- quill-code installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

