Skip to content

Commit d122837

Browse files
adamleithpclaude
andcommitted
feat(skills): add quill-code skill
Local dev loop for the @posthog/quill design system: edit quill in the sibling mono, build the whole quill workspace, pack a content-hashed tarball into .local-quill, repoint the pnpm override, and reinstall — so quill changes can be tested in this app before publishing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 93fc08b commit d122837

2 files changed

Lines changed: 133 additions & 0 deletions

File tree

.claude/skills/quill-code/SKILL.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
name: quill-code
3+
description: Edit the @posthog/quill design system locally and consume the change in this repo (posthog-code) 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.
4+
---
5+
6+
# quill-code
7+
8+
`@posthog/quill` is **not** in this repo. It is a published catalog dependency whose
9+
source lives in the main PostHog monorepo at `../posthog/packages/quill`. To test an
10+
unpublished quill change inside this repo (posthog-code), you build quill, pack it to a
11+
tarball, and point a pnpm `overrides` entry at that tarball. This is a **temporary
12+
local-dev** state — revert before merging (see below).
13+
14+
## Quill layout (where to edit)
15+
16+
`../posthog/packages/quill` is the **workspace** (`@posthog/quill-workspace`). It
17+
contains sub-packages, each a layer of the design system:
18+
19+
- `packages/primitives/src` — base components (Card, Badge, Button, Progress, …)
20+
- `packages/components/src` — composed components (DataTable, DateTimePicker, Metric)
21+
- `packages/blocks/src`**product-level blocks** (e.g. `ExperimentCard`). Add the
22+
file here and export it from `packages/blocks/src/index.ts`.
23+
- `packages/quill/src` — the **aggregate** that re-exports all layers as `@posthog/quill`.
24+
25+
A new export in any sub-package flows to `@posthog/quill` automatically on build.
26+
27+
## The loop (every quill change)
28+
29+
1. Edit/add the component in the right sub-package (above) and export it from that
30+
package's `src/index.ts`.
31+
2. Re-sync into this repo:
32+
33+
```bash
34+
.claude/skills/quill-code/scripts/sync-quill.sh
35+
```
36+
37+
This builds the **whole quill workspace** (recursive `pnpm build` at the workspace
38+
root — it rebuilds the sub-packages BEFORE the aggregate bundles them), packs it
39+
into `.local-quill/` as a content-hashed `posthog-quill-local-<hash>.tgz`, rewrites
40+
the override line in `pnpm-workspace.yaml`, deletes stale tarballs, and runs
41+
`pnpm install`.
42+
43+
> Building only the aggregate (`packages/quill/packages/quill`) re-bundles the
44+
> sub-packages' **stale** `dist/`, so edits to primitives/components/blocks are
45+
> silently dropped. Always build at the workspace root — the script does this.
46+
3. Verify in the Code app (`pnpm dev`, or the `test-electron-app` skill). Repeat from 1.
47+
48+
After every quill edit you **must** re-run the sync — the app consumes the tarball, not
49+
the quill source, so unsynced edits are invisible here.
50+
51+
If quill lives elsewhere, set `QUILL_DIR=/abs/path/to/posthog/packages/quill/packages/quill`.
52+
53+
## Why a tarball, not `link:`
54+
55+
`link:` symlinks into the mono's `node_modules` and drags in its **React 18** types,
56+
colliding with this repo's **React 19** (dual-React → broken typecheck +
57+
invalid-hook-call at runtime). The tarball is copied into this repo's store and deduped
58+
against React 19. The filename is **content-hashed** because pnpm pins a tarball by
59+
integrity, so a stable filename gets cached stale across re-syncs.
60+
61+
## The override (what the script rewrites)
62+
63+
In `pnpm-workspace.yaml`, under `overrides:`:
64+
65+
```yaml
66+
'@posthog/quill': file:./.local-quill/posthog-quill-local-<hash>.tgz
67+
```
68+
69+
There is also a permanent pin you should leave alone:
70+
71+
```yaml
72+
'@posthog/quill>@base-ui/react': ^1.3.0 # quill ships a broken catalog: dep; do not remove
73+
```
74+
75+
## Reverting (before merge)
76+
77+
The override is local-dev only. Once the quill change is published to npm:
78+
79+
1. Bump the catalog version in `pnpm-workspace.yaml` (`'@posthog/quill': 0.3.0-beta.x`)
80+
to the published version.
81+
2. Restore the override line to point back at the catalog, or remove the `file:` override.
82+
3. `pnpm install`.
83+
84+
Do not commit a `file:./.local-quill/...` override or the `.local-quill/` tarballs.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env bash
2+
# Build local @posthog/quill, pack it to a content-hashed tarball, point the
3+
# pnpm override at it, and reinstall. See SKILL.md for the why.
4+
set -euo pipefail
5+
6+
# code repo root = dir containing pnpm-workspace.yaml, walking up from this script
7+
CODE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && while [ ! -f pnpm-workspace.yaml ] && [ "$PWD" != / ]; do cd ..; done && pwd)"
8+
[ -f "$CODE_ROOT/pnpm-workspace.yaml" ] || { echo "could not find pnpm-workspace.yaml above $0" >&2; exit 1; }
9+
10+
QUILL_DIR="${QUILL_DIR:-$CODE_ROOT/../posthog/packages/quill/packages/quill}"
11+
[ -d "$QUILL_DIR" ] || { echo "quill source not found: $QUILL_DIR (set QUILL_DIR=...)" >&2; exit 1; }
12+
13+
# The quill workspace root (@posthog/quill-workspace) is two levels up from the
14+
# aggregate package. We MUST build there: its `pnpm build` runs the recursive
15+
# `pnpm -r --filter '@posthog/quill-*' --filter '@posthog/quill' build`, which
16+
# rebuilds the sub-packages (primitives, components, blocks, ...) BEFORE the
17+
# aggregate bundles them. Building inside QUILL_DIR alone only re-bundles the
18+
# sub-packages' STALE dist, so edits to blocks/primitives/etc. are silently lost.
19+
QUILL_WS="${QUILL_WS:-$(cd "$QUILL_DIR/../.." && pwd)}"
20+
21+
DEST="$CODE_ROOT/.local-quill"
22+
WS="$CODE_ROOT/pnpm-workspace.yaml"
23+
24+
echo "==> building quill workspace in $QUILL_WS"
25+
( cd "$QUILL_WS" && pnpm build )
26+
27+
echo "==> packing tarball -> $DEST"
28+
mkdir -p "$DEST"
29+
( cd "$QUILL_DIR" && npm pack --pack-destination "$DEST" >/dev/null )
30+
31+
RAW="$(ls -t "$DEST"/posthog-quill-*.tgz | grep -v -- '-local-' | head -1)"
32+
[ -n "$RAW" ] || { echo "npm pack produced no posthog-quill-*.tgz" >&2; exit 1; }
33+
34+
HASH="$(md5 -q "$RAW" | cut -c1-8)"
35+
HASHED="posthog-quill-local-$HASH.tgz"
36+
cp "$RAW" "$DEST/$HASHED"
37+
rm -f "$RAW"
38+
# drop stale local tarballs so the pnpm store can't resolve an old integrity
39+
find "$DEST" -name 'posthog-quill-local-*.tgz' ! -name "$HASHED" -delete
40+
41+
echo "==> pointing override at .local-quill/$HASHED"
42+
# single override line: '@posthog/quill': file:./.local-quill/...
43+
sed -i '' -E "s#('@posthog/quill': file:\./\.local-quill/)[^']*#\1$HASHED#" "$WS"
44+
grep -q "$HASHED" "$WS" || { echo "failed to rewrite override line in $WS" >&2; exit 1; }
45+
46+
echo "==> pnpm install"
47+
( cd "$CODE_ROOT" && pnpm install )
48+
49+
echo "==> done. @posthog/quill now resolves to .local-quill/$HASHED"

0 commit comments

Comments
 (0)