Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
836 commits
Select commit Hold shift + click to select a range
b5fe827
fix(top-bar): hide cert tab strip on the edit page
May 28, 2026
9d9f2b1
feat(cert-forms): render picked contributors as avatar+name+handle cards
May 28, 2026
931d299
merge: feat/positioning-redesign into feat/design-consolidation
holkexyz May 28, 2026
6a249f0
Merge pull request #108 from hypercerts-org/feat/design-consolidation
holkexyz May 28, 2026
1a47daa
style(cert-forms): flat contributor card + vertically-center the row …
May 28, 2026
6d484eb
docs: lock in design consolidation rules for future AI agents
holkexyz May 28, 2026
b9a2381
feat(cert-edit): EditBanner replaces bottom Save/Cancel row + canSave…
May 28, 2026
6d3422e
fix(edit-banner): primary Save button no longer goes white-on-white o…
May 28, 2026
3599da7
fix(cert-forms): contributor card only renders after explicit commit
May 28, 2026
fafb659
feat(project): dedicated /project/<did>/<rkey>/edit page mirroring /p…
May 28, 2026
22e2f62
style(profile): shorten "Create new X" / "Create list" CTAs to "New X…
May 28, 2026
e3f922b
feat(project-forms): empty-state note under Certs when the user has n…
May 28, 2026
e2f1cf1
fix(explore): direct keep-set replaces complement, fixes inverted Peo…
May 28, 2026
9e16a75
chore(endorsements): remove dead temp.graph.endorsement legacy path
May 28, 2026
a0c896a
Merge pull request #109 from hypercerts-org/chore/remove-legacy-endor…
holkexyz May 28, 2026
c2d7a32
feat(cert): move Locations + map into the overview main pane
holkexyz May 28, 2026
d9414eb
fix(endorsements): sidebar endorse updates counter and Received tab
May 28, 2026
6ae4c40
feat(cert): show Updates above Locations on overview, cap at one card
holkexyz May 28, 2026
d321069
feat(cert): add Record tab with a schema field/value table
holkexyz May 28, 2026
74e71aa
docs(review): Phase 1 survey findings + CHANGES log
holkexyz May 28, 2026
ead9d67
docs(changes): restructure CHANGES log to append-only with sentinel
holkexyz May 28, 2026
07e945e
fix(context): reject non-http attachment uris in resolveAttachment [b…
holkexyz May 28, 2026
1fc73e3
fix(metadata): point OG image to existing certs-hero asset [bug-002]
holkexyz May 28, 2026
5383a38
fix(groups): preserve InvalidSwap discriminator on BFF writes [bug-003]
holkexyz May 28, 2026
d576305
fix(profile): await in-flight avatar/banner upload before save [bug-004]
holkexyz May 28, 2026
fc61e7d
fix(project): resolve location strongRef so it displays [bug-005]
holkexyz May 28, 2026
4088805
fix(groups): correct audit result pill class allowlist [bug-006]
holkexyz May 28, 2026
18dee15
fix(endorsements): show rejected awards in owner Received inbox [bug-…
holkexyz May 28, 2026
a980cc2
fix(upload): surface blob upload errors and clear preview [bug-008]
holkexyz May 28, 2026
b102c82
fix(profile): self-preview banner pick in BannerUpload [bug-009]
holkexyz May 28, 2026
d129b75
fix(home-feed): render location MapPin in feed card with period [bug-…
holkexyz May 28, 2026
020ef46
fix(use-user-activities): guard loadMore generation + dedup URIs [bug…
holkexyz May 28, 2026
af20bdc
fix(xrpc): redact secrets in echoed 4xx upstream messages [risk-001]
holkexyz May 28, 2026
722bcf5
fix(groups/register): use logSafe on org-limit check failure [risk-002]
holkexyz May 28, 2026
2d6e42f
fix(groups): sanitize handle and validate email at register boundary …
holkexyz May 28, 2026
416554d
fix(profile): reuse minted location rkey on save retry [risk-003]
holkexyz May 28, 2026
fc7b7fb
fix(seo): disallow app-only routes in robots.ts [risk-006]
holkexyz May 28, 2026
e423835
fix(project): route save-conflict re-read through authFetch [risk-008]
holkexyz May 28, 2026
3299ced
refactor(feed): delete dead UserFeed component [quality-001]
holkexyz May 28, 2026
6492574
docs(changes): log quality-002 BLOCKED [quality-002]
holkexyz May 28, 2026
75895ea
refactor(cert-context): paginate fetchAllCertContext via cursor [qual…
holkexyz May 29, 2026
05a13a2
refactor(profile): drop dead EndorseShortcut + inert overlay [quality…
holkexyz May 29, 2026
9dea289
refactor(workspace): drop dead fetchOrganizationDids exports [quality…
holkexyz May 29, 2026
15b8510
refactor(feed): delete dead CertHeadlineByline component [quality-049]
holkexyz May 29, 2026
fafa782
refactor(feed): delete dead LocationCard component [quality-050]
holkexyz May 29, 2026
743d110
docs(feed): correct FeedLayout JSDoc to real consumers [quality-051]
holkexyz May 29, 2026
5b98701
chore(ci): add ci.yml running lint/tsc/test on PRs [quality-009]
holkexyz May 29, 2026
ed186b0
chore(tsconfig): add tsconfig.test.json + typecheck:test [quality-010]
holkexyz May 29, 2026
73850c3
chore(config): pin Node version via engines and .nvmrc [quality-018]
holkexyz May 29, 2026
9fbb21c
chore(scripts): add typecheck npm script [quality-019]
holkexyz May 29, 2026
2ffe2a3
chore(lint): drop no-op --ext flag from lint script [quality-020]
holkexyz May 29, 2026
a8f9c57
chore(lint): expand lint to eslint . with build-output ignores [quali…
holkexyz May 29, 2026
0519f5b
fix(scripts): unify audit dev-server port default to 3000 [quality-022]
holkexyz May 29, 2026
8c6b483
chore(gitignore): anchor core pattern to /core [quality-023]
holkexyz May 29, 2026
d43ed60
refactor(atproto): constrain saveWithSwap TDrafts to Partial<TSnapsho…
holkexyz May 29, 2026
376983e
refactor(swap): share one array-guarded shallowEqual [quality-026]
holkexyz May 29, 2026
dcd6756
fix(badges): sort missing createdAt def to end of canonical pick [qua…
holkexyz May 29, 2026
e762ab9
refactor(atproto): location.ts uses shared strict parseAtUri [quality…
holkexyz May 29, 2026
0954187
refactor(notifications): validate load-bearing edge fields [quality-029]
holkexyz May 29, 2026
c219186
fix(atproto): validate resolveHandle alsoKnownAs is a handle [quality…
holkexyz May 29, 2026
fde4b18
refactor(hooks): add module-level cache to useOrgProfile [quality-006]
holkexyz May 29, 2026
4529435
docs(changes): log quality-037 SKIPPED [quality-037]
holkexyz May 29, 2026
0386675
fix(home-feed): track INVALID_CURSOR recovery controller [quality-031]
holkexyz May 29, 2026
e45219b
fix(hooks): abort focus-revalidate fetches via ref'd controller [qual…
holkexyz May 29, 2026
542fe29
docs(changes): log quality-033 BLOCKED [quality-033]
holkexyz May 29, 2026
1abb7da
refactor(hooks): read live lists in useEndorsementLists mutations [qu…
holkexyz May 29, 2026
f5a19a8
refactor(explore): tie loadMore fetch to generation signal [quality-035]
holkexyz May 29, 2026
d25a3d3
fix(profile): revoke promoted avatar/banner blob URL after save [qual…
holkexyz May 29, 2026
91f29bc
fix(hooks): usePendingAwardsCount returns null when logged out [quali…
holkexyz May 29, 2026
763d9d8
refactor(hooks): reset bottom-sheet viewport styles on cleanup [quali…
holkexyz May 29, 2026
f726a82
fix(hooks): clear bottom-sheet dismiss timeout on unmount [quality-040]
holkexyz May 29, 2026
1a3933c
fix(hooks): clear in-flight dedupe on useOrgMarker refresh [quality-041]
holkexyz May 29, 2026
fe30617
refactor(profile): extract shared PersonCard + name-cache hook [quali…
holkexyz May 29, 2026
87b36e5
fix(profile-lists): show fallback row when a project fails to load [q…
holkexyz May 29, 2026
9d8cdd5
refactor(profile): use useClickOutsideClose for endorsement dropdowns…
holkexyz May 29, 2026
515a1c2
docs(changes): log quality-045 BLOCKED [quality-045]
holkexyz May 29, 2026
6ead1da
fix(profile): stable createdAt sort in endorsement lists [quality-046]
holkexyz May 29, 2026
52c6ee0
refactor(profile-lists): use row index for checkbox aria-label [quali…
holkexyz May 29, 2026
8079ad2
refactor(profile): keep optimistic endorse on list-append failure [qu…
holkexyz May 29, 2026
4edb194
test(sanitize): add unit tests for stripInvisible/sanitizeEmail/sanit…
holkexyz May 29, 2026
f1ec9f8
refactor(search-actors): route catch log through logSafe [quality-014]
holkexyz May 29, 2026
aaa4ef1
refactor(notifications): drop response body from upstream error log […
holkexyz May 29, 2026
18c48fd
fix(xrpc): clamp upstream status to valid HTTP range [quality-016]
holkexyz May 29, 2026
d573291
fix(indexer): enforce 32KB body cap in bytes not UTF-16 units [qualit…
holkexyz May 29, 2026
9266ad8
refactor(popover): use --z-popover token instead of z-[40] [quality-008]
holkexyz May 29, 2026
f66c4f1
refactor(onboarding): revoke step-profile preview object URLs [qualit…
holkexyz May 29, 2026
f1d47db
fix(feed): reset imageFailed when ActivityCard imageUrl changes [qual…
holkexyz May 29, 2026
7e376fc
refactor(feed): memoize ActivityCard to avoid loadMore re-renders [qu…
holkexyz May 29, 2026
38245a2
refactor(right-rail): key news images by thumb URL not index [quality…
holkexyz May 29, 2026
6fbdab9
refactor(feed): make expanded locations map height viewport-relative …
holkexyz May 29, 2026
8a24feb
fix(auth): match safeRedirect http: gate to module's !==production [q…
holkexyz May 29, 2026
ea0a318
docs(auth): note swallowed deleteSession is not session fixation [qua…
holkexyz May 29, 2026
3479605
docs(csrf): document deliberate missing-Origin-AND-Referer reject [qu…
holkexyz May 29, 2026
ea16a22
docs(agents): correct ALLOWED_WRITE_COLLECTIONS count to eleven [qual…
holkexyz May 29, 2026
d4b05fb
refactor(utils): extract countGraphemes helper [quality-056-cert-5]
holkexyz May 29, 2026
657dd36
refactor(project): extract own-certs quick-pick into useOwnCerts [qua…
holkexyz May 29, 2026
1aa685a
docs(project): document activity-only meta reads in project-detail [q…
holkexyz May 29, 2026
c3cb71e
refactor(map): drop dead theme reactivity in base tiles [quality-056-…
holkexyz May 29, 2026
d684e3c
refactor(geocode): delete dead forwardGeocode export [quality-056-map-4]
holkexyz May 29, 2026
b4b151b
refactor(map): tokenize leaflet embed bg; justify JS hex [quality-056…
holkexyz May 29, 2026
d913f1f
refactor(ui): tokenize ProviderRedirectOverlay z-index [quality-056-u…
holkexyz May 29, 2026
bd27181
fix(ui): skeleton text variant aria-hidden + honor width [quality-056…
holkexyz May 29, 2026
576b2b9
fix(ui): hide icon child while loading + default button type [quality…
holkexyz May 29, 2026
ea35ea2
refactor(explore): delete dead ?attrs= filter never set by any UI [qu…
holkexyz May 29, 2026
f685bf8
fix(explore): add aria-haspopup to sort + quality popover triggers [q…
holkexyz May 29, 2026
54321da
refactor(groups): use ConfirmDialog for Leave Group modal [quality-05…
holkexyz May 29, 2026
5c86eda
refactor(groups): delete dead AddOrgModal + MembershipSyncModal [qual…
holkexyz May 29, 2026
672549c
docs(changes): log quality-056-groups-5 SKIPPED [quality-056-groups-5]
holkexyz May 29, 2026
34f6954
fix(test): use renderHook in safe-redirect test to clear lint error […
holkexyz May 29, 2026
bcb4f20
fix(groups): re-stage only failed members on partial add [quality-056…
holkexyz May 29, 2026
561caf9
docs(changes): log quality-056-profile-edit-2 SKIPPED [quality-056-pr…
holkexyz May 29, 2026
e234749
test(profile): link edit-form inputs to error text via aria-described…
holkexyz May 29, 2026
b2c5c45
refactor(profile): derive BannerUpload label from displayed image [qu…
holkexyz May 29, 2026
aaa0869
refactor(profile): tokenize avatar overlay colors [quality-056-profil…
holkexyz May 29, 2026
0d55605
refactor(landing): delete dead orbiting-logos component [quality-056-…
holkexyz May 29, 2026
abb79c6
refactor(legal): theme-aware link/text tokens for dark mode [quality-…
holkexyz May 29, 2026
6adb271
refactor(global-error): radius 6px to 2px + token comment [quality-05…
holkexyz May 29, 2026
0ba95a2
docs(agents): sync §2 tech-stack versions with package.json [quality-…
holkexyz May 29, 2026
9f75429
refactor(groups): derive role allowlists from one ORG_ROLES source [q…
holkexyz May 29, 2026
acd6447
perf(groups/register): early-exit member walk on self-added hit [qual…
holkexyz May 29, 2026
a2d25d9
refactor(notifications): use shared truncateDid + getInitials [qualit…
holkexyz May 29, 2026
b5d5dd3
refactor(labeller): drop dead exports pickKnownLabel/FilterValue/ALL_…
holkexyz May 29, 2026
74cd8ce
refactor(lib): drop dead exports getBlobRefLinkFromBlob/clearRecently…
holkexyz May 29, 2026
ff0a189
test(utils): cover did.ts isValidDid/isDid validators [quality-056-ut…
holkexyz May 29, 2026
317c2f6
test(utils): cover bounded-cache, format-date, ip, recently-viewed [q…
holkexyz May 29, 2026
abac1ee
docs(changes): finalize Phase 2 summary, held list, and follow-ups
holkexyz May 29, 2026
b75955f
Merge pull request #111 from hypercerts-org/overnight-review
holkexyz May 29, 2026
0bce563
Merge feat/positioning-redesign into fix/endorsement-received-overlay
holkexyz May 29, 2026
e70c9fb
Merge pull request #110 from hypercerts-org/fix/endorsement-received-…
holkexyz May 29, 2026
1efefb0
fix(auth): coerce OAuth prompt param to allowlist [judgment-001]
holkexyz May 29, 2026
adb12af
fix(resolve-did): add IP+DID rate limiter to GET /api/resolve-did [ju…
holkexyz May 29, 2026
722a001
fix(xrpc): cap foreign getBlob Content-Length (413) + fix Cache-Contr…
holkexyz May 29, 2026
e99b506
fix(auth): add Cache-Control private, no-store to /api/auth/session […
holkexyz May 29, 2026
2618930
fix(dashboard): gate custom-domain affordance off in group context [j…
holkexyz May 29, 2026
806bea1
fix(seo): canonicalize landing on /welcome; align sitemap/robots/mani…
holkexyz May 29, 2026
aed6b80
docs(postcss): note autoprefixer intentionally omitted [judgment-007]
holkexyz May 29, 2026
a96b1e3
refactor(explore): consolidate menu popovers + z-index token [judgmen…
holkexyz May 29, 2026
1542a34
Merge pull request #113 from hypercerts-org/judgment/clear-fixes
holkexyz May 29, 2026
65aa8ce
feat(resolve-did): optional indexer actorProfile fast-path [resolve-d…
holkexyz May 29, 2026
46e68e4
Merge pull request #114 from hypercerts-org/feat/resolve-did-indexer-…
holkexyz May 29, 2026
cb0d99d
fix(profile): inline-edit preserve avatar/banner; thread swapRecord […
holkexyz Jun 1, 2026
14f7dcd
fix(auth): never seed app.bsky on sign-in + guard app.certified seed …
holkexyz Jun 1, 2026
334eef5
fix(resolve-did): per-field appView fallback so a null indexer avatar…
holkexyz Jun 1, 2026
a07651a
fix(resolve-did): bsky profile is an all-or-nothing fallback [profile…
holkexyz Jun 1, 2026
363e348
Merge pull request #116 from hypercerts-org/fix/profile-avatar-dataloss
holkexyz Jun 1, 2026
9b18363
feat(indexer): send X-RateLimit-Bypass from /api/indexer + /api/notif…
Jun 1, 2026
95a8753
test: fix test-file type errors and wire typecheck:test into CI
Jun 1, 2026
525d0f7
fix(profile): guard follow/endorse while acting as a group
holkexyz Jun 2, 2026
8ff12ea
Merge pull request #117 from hypercerts-org/fix/acting-as-group-write…
holkexyz Jun 2, 2026
3573418
fix(nav): brandmark and /home route signed-out visitors to /welcome
holkexyz Jun 2, 2026
425eff9
Merge pull request #118 from hypercerts-org/fix/brandmark-welcome-rou…
holkexyz Jun 2, 2026
8e5dde4
docs(switcher): mockups + decision record for org identity model
holkexyz Jun 2, 2026
8f261ba
feat(org): act-as delegation — orgs can endorse and follow as first-c…
holkexyz Jun 2, 2026
42152df
feat(org): respond-as-group — orgs accept/reject endorsements they re…
holkexyz Jun 2, 2026
40d523e
Merge pull request #119 from hypercerts-org/feat/org-delegation
holkexyz Jun 2, 2026
ca93798
feat(profile): add Operate-as-group action to the groups tab
holkexyz Jun 2, 2026
b2936fd
fix(endorse): show the operator's real role, not a hard-coded "admin"
holkexyz Jun 2, 2026
e10e9a3
fix(org): no personal endorsement actions while acting as a group
holkexyz Jun 2, 2026
51fade1
feat(lists): accept a bare DID when adding accounts to a list
holkexyz Jun 2, 2026
0839f3c
Merge pull request #120 from hypercerts-org/fix/org-delegation-followups
holkexyz Jun 2, 2026
258df7d
Merge pull request #121 from hypercerts-org/fix/list-add-bare-did
holkexyz Jun 2, 2026
e065422
fix(dark-mode): unreadable white-on-white text on highlighted/active …
holkexyz Jun 2, 2026
de88414
Merge pull request #123 from hypercerts-org/fix/dark-mode-white-on-white
holkexyz Jun 2, 2026
a0b1ebe
chore(cert): remove the Record tab from the cert overview
holkexyz Jun 2, 2026
c6b0c7c
Merge pull request #124 from hypercerts-org/chore/remove-cert-record-tab
holkexyz Jun 2, 2026
1237e6d
fix(welcome): make the footer full-bleed (full screen wide)
holkexyz Jun 2, 2026
38a0e37
refactor(naming): rename cert -> activity in user-facing display text
holkexyz Jun 2, 2026
0a75774
Merge pull request #125 from hypercerts-org/fix/welcome-footer-full-w…
holkexyz Jun 2, 2026
7ac84eb
refactor(naming): rename cert -> activity in URL/query values
holkexyz Jun 2, 2026
c2a52cb
Merge pull request #126 from hypercerts-org/chore/rename-cert-to-acti…
holkexyz Jun 2, 2026
1db4965
fix(resolve-did): batch author/contributor resolution to stop 429s
holkexyz Jun 2, 2026
dee42c5
fix(resolve-did): address impl-review (weighted limit, cooldown, timers)
holkexyz Jun 2, 2026
91cfb03
Merge pull request #127 from hypercerts-org/fix/resolve-did-batch-429
holkexyz Jun 2, 2026
fc065a6
Merge staging into feat/positioning-redesign (ours): supersede stagin…
holkexyz Jun 2, 2026
ec8c6de
ci: bump Node to 20.19.0 — vitest 4 / rolldown needs util.styleText
holkexyz Jun 2, 2026
53fc822
Merge pull request #128 from hypercerts-org/feat/positioning-redesign
holkexyz Jun 2, 2026
44b90df
docs(component-library): add Phase 1 reuse analysis
holkexyz Jun 2, 2026
7dc45ed
feat(ui): add error-surface and surface-container-high tokens
holkexyz Jun 2, 2026
ed2bfd0
fix(ui): correctness + a11y/state completeness across primitives
holkexyz Jun 2, 2026
524cf4b
feat(ui): add Select, Checkbox, Radio, Switch, Toast, Banner primitives
holkexyz Jun 2, 2026
7fda7b7
feat(ui): complete AppDialog focus trap; add dialog family
holkexyz Jun 2, 2026
a9e8ca0
docs(component-library): add self-contained HTML styleguide
holkexyz Jun 2, 2026
ccb4fe1
refactor(profile): adopt Avatar size=2xl; fix undefined profile CSS t…
holkexyz Jun 2, 2026
8522a04
refactor(feed): adopt Skeleton/Banner/ErrorMessage; drop duplicate ke…
holkexyz Jun 2, 2026
0e79da8
refactor(layout): navbar->BottomSheet, nav drawers->Drawer, wire Toas…
holkexyz Jun 2, 2026
8895ba8
refactor(explore,landing): canonical Popover + lucide icons; fix expl…
holkexyz Jun 2, 2026
7093f01
refactor(create,project): dialogs->AppDialog/FormDialog, kebab->Popover
holkexyz Jun 2, 2026
7047903
refactor(groups,workspace,settings): Tabs/Popover/Select/Radio/Badge …
holkexyz Jun 2, 2026
2954cd3
refactor(ui): rewrite SignInModal onto AppDialog, FeedbackModal onto …
holkexyz Jun 2, 2026
911ffcc
feat(ui): add primitive enablers to unblock deferred migrations
holkexyz Jun 3, 2026
72b1fa1
chore(dev): add live component gallery for visual verification
holkexyz Jun 3, 2026
a20bdc9
refactor: migrate deferred items onto the new enablers (round 2)
holkexyz Jun 3, 2026
1c2c974
feat(ui): Badge square-tag shape + Popover checked (menuitemradio) items
holkexyz Jun 3, 2026
05dc2bd
refactor(profile,home): bio->Textarea, followers->Tabs, preview-tag->…
holkexyz Jun 3, 2026
41451f4
chore(styles): remove dead BEM left by primitive migration
holkexyz Jun 3, 2026
4071c2a
docs(component-library): document new primitive states in styleguide
holkexyz Jun 3, 2026
8286412
Merge pull request #129 from hypercerts-org/staging
holkexyz Jun 3, 2026
7d5da43
feat(ui): Combobox + SegmentedControl/ToggleGroup; Popover portal; In…
holkexyz Jun 3, 2026
c931d19
chore(dev): auth-mock preview harness for auth-gated surfaces
holkexyz Jun 3, 2026
9df3311
chore(dev): gallery demos for new primitives; fix profile preview + n…
holkexyz Jun 3, 2026
6a3eaef
refactor(search): migrate 5 typeahead surfaces onto the Combobox prim…
holkexyz Jun 3, 2026
5a58719
refactor: explore view-toggle/degrees + response toggles onto Segment…
holkexyz Jun 3, 2026
6ffa41b
refactor(layout): account-switcher menus onto portal Popover; in-page…
holkexyz Jun 3, 2026
f6370e1
refactor: bespoke inline/compact inputs onto Input bare/compact/flush…
holkexyz Jun 3, 2026
29cd1ad
chore(styles): remove dead BEM from the primitive migrations
holkexyz Jun 3, 2026
61139ba
docs(component-library): generate styleguide from live gallery; add d…
holkexyz Jun 3, 2026
c354b17
feat(ui): add barrel + cross-app canonical tokens
holkexyz Jun 3, 2026
78d7ac2
feat(ui): add IdentityRow primitive + formatCountBadge helper
holkexyz Jun 3, 2026
c5b73d3
chore(pwa): disable install prompt (manifest display browser)
holkexyz Jun 3, 2026
940bc60
Merge pull request #136 from hypercerts-org/chore/disable-pwa-install
holkexyz Jun 3, 2026
c88e1f3
feat(ui): Tailwind-ify AppDialog engine + AppDialogBody slot
holkexyz Jun 3, 2026
58c352e
refactor(ui): migrate dialog wrappers + consumers onto AppDialogBody
holkexyz Jun 3, 2026
13ebd15
refactor(ui): Tailwind-ify leaves + decouple form labels (parity)
holkexyz Jun 3, 2026
d687300
feat(ui): add numbered Pagination primitive + barrel export
holkexyz Jun 3, 2026
02f0301
refactor(ui): relative intra-ui imports (self-relocatable folder)
holkexyz Jun 3, 2026
7da0cd0
chore(styles): remove orphaned BEM CSS after Tailwind-ify
holkexyz Jun 3, 2026
930ab17
docs(design): update DESIGN.md to the canonical Tailwind library
holkexyz Jun 3, 2026
a9a6f92
docs(ui): complete /dev/gallery + regenerate the styleguide
holkexyz Jun 3, 2026
d92f675
fix(ui): SegmentedControl/ToggleGroup keep intrinsic height in flex t…
holkexyz Jun 3, 2026
7e880d4
feat(org): aggregating data layer for managed (group-owned) records
holkexyz Jun 3, 2026
74a14d4
feat(ui): PostingAs per-action write-identity picker (default You)
holkexyz Jun 3, 2026
581ddc1
chore(dev): managed harness fixtures + authors-aware mock indexer
holkexyz Jun 3, 2026
4097181
feat(managed): dedicated /managed hub aggregating group-owned records
holkexyz Jun 3, 2026
2064a12
feat(write): per-action PostingAs picker; act-as becomes read-scope only
holkexyz Jun 3, 2026
1608f2d
feat(aggregate): inline group-owned records on Home; bridge on own pr…
holkexyz Jun 3, 2026
cd1e1d3
test(preview): add managed + write-as-org preview surfaces
holkexyz Jun 3, 2026
4ba3e68
docs(org-identity): magic-indexer spec for notifications aggregation
holkexyz Jun 3, 2026
99c1f81
refactor(managed): extract shared useIdentityFocus hook
holkexyz Jun 3, 2026
0e6345f
feat(notifications): aggregate group notifications behind a flag
holkexyz Jun 3, 2026
4642a89
test(notifications): harness + tests for the aggregated path
holkexyz Jun 3, 2026
755f60c
docs(env): document NEXT_PUBLIC_NOTIFICATIONS_AGGREGATION flag
holkexyz Jun 3, 2026
887e14b
fix(review): correct Home provenance + decouple edit eligibility from…
holkexyz Jun 3, 2026
0f27182
fix(review): a11y + UX polish across the org-identity surfaces
holkexyz Jun 3, 2026
3d308a1
test(review): cover the flag-gate, owner tagging, and fan-out
holkexyz Jun 3, 2026
c528e02
docs(org-identity): feature plan + review round-1 decision log
holkexyz Jun 3, 2026
cf453c5
Merge pull request #138 from hypercerts-org/feat/org-identity-aggrega…
holkexyz Jun 4, 2026
ac9d3bf
Revert "feat: org-identity aggregation — surface group-owned work, pe…
holkexyz Jun 4, 2026
44be00e
Merge pull request #139 from hypercerts-org/revert-138-feat/org-ident…
holkexyz Jun 4, 2026
aa6e678
feat(aggregate): data layer for inline 'by {group}' record aggregation
holkexyz Jun 4, 2026
0826032
feat(home): aggregate group-owned records on the Home sidebar
holkexyz Jun 4, 2026
8dd40f4
feat(explore): aggregate 'My projects/activities' + fix 'My organizat…
holkexyz Jun 4, 2026
9e2d1a6
feat(profile): 'by {group}' on the Projects + Activities tabs
holkexyz Jun 4, 2026
6f9b4c6
test(dev): managed-scenario harness for verifying by-group aggregation
holkexyz Jun 4, 2026
089328f
feat: nav icons, explore/edit fixes, group-edit affordance
holkexyz Jun 4, 2026
6d51c81
fix: point navbar Explore icon at /explore not /search
holkexyz Jun 4, 2026
dc3f1f5
refactor: remove standalone /search page, fold into /explore
holkexyz Jun 4, 2026
9ed530f
feat: add Apps to the desktop hamburger drawer after Explore
holkexyz Jun 4, 2026
24c25bf
fix: align editing-project banner with the content box, not the colum…
holkexyz Jun 4, 2026
13a074f
fix: fixed-width date column in the home feed
holkexyz Jun 4, 2026
becc274
Add text labels below desktop nav icons
holkexyz Jun 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
181 changes: 181 additions & 0 deletions .agents/skills/impeccable/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
---
name: impeccable
description: "Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks."
argument-hint: "[{{command_hint}}] [target]"
user-invocable: true
allowed-tools:
- Bash(npx impeccable *)
license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution.
---

Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.

## Setup (non-optional)

Before any design work or file edits, pass these gates. Skipping them produces generic output that ignores the project.

| Gate | Required check | If fail |
|---|---|---|
| Context | The PRODUCT.md / DESIGN.md loader result is known from `node {{scripts_path}}/load-context.mjs`. | Run the loader before continuing. |
| Product | PRODUCT.md exists and is not empty or placeholder (`[TODO]` markers, <200 chars). | Run `{{command_prefix}}impeccable teach`, refresh context, then resume. Never synthesize PRODUCT.md from the user's original prompt alone. |
| Command | The matching command reference is loaded when a sub-command is used. | Load the reference before continuing. |
| Craft | `{{command_prefix}}impeccable craft` has a user-confirmed shape brief for this task. `teach` / PRODUCT.md never counts as shape. | Run `{{command_prefix}}impeccable shape` and wait for explicit brief confirmation. |
| Image | Required visual probes / mocks are generated or skipped with a reason. | Resolve the image-generation gate in `shape.md` or `craft.md` before code. |
| Mutation | All active gates above pass. | Do not edit project files yet. |

Codex-style agents must state this before editing files:

```text
IMPECCABLE_PREFLIGHT: context=pass product=pass command_reference=pass shape=pass|not_required image_gate=pass|skipped:<reason> mutation=open
```

For `{{command_prefix}}impeccable craft`, `shape=pass` is only valid after a separate user response approving the shape design brief, or when the user provided an already-confirmed brief in the request. Do not mark `shape=pass` after writing PRODUCT.md, summarizing assumptions, or drafting an unconfirmed brief yourself.

Other harnesses should follow the same checklist when they can expose this state.

### 1. Context gathering

Two files, case-insensitive. The loader looks at the project root by default and falls back to `.agents/context/` and `docs/` if the root is clean. Override with `IMPECCABLE_CONTEXT_DIR=path/to/dir` (absolute or relative to cwd).

- **PRODUCT.md**: required. Users, brand, tone, anti-references, strategic principles.
- **DESIGN.md**: optional, strongly recommended. Colors, typography, elevation, components.

Load both in one call:

```bash
node {{scripts_path}}/load-context.mjs
```

Consume the full JSON output. Never pipe through `head`, `tail`, `grep`, or `jq`. The output's `contextDir` field tells you where the files were resolved from.

If the output is already in this session's conversation history, don't re-run. Exceptions requiring a fresh load: you just ran `{{command_prefix}}impeccable teach` or `{{command_prefix}}impeccable document` (they rewrite the files), or the user manually edited one.

`{{command_prefix}}impeccable live` already warms context via `live.mjs`. If you've run `live.mjs`, don't also run `load-context.mjs` this session.

If PRODUCT.md is missing, empty, or placeholder (`[TODO]` markers, <200 chars): run `{{command_prefix}}impeccable teach`, then resume the user's original task with the fresh context. If the original task was `{{command_prefix}}impeccable craft`, resume into `{{command_prefix}}impeccable shape` before any implementation work.

If DESIGN.md is missing: nudge once per session (*"Run `{{command_prefix}}impeccable document` for more on-brand output"*), then proceed.

### 2. Register

Every design task is **brand** (marketing, landing, campaign, long-form content, portfolio: design IS the product) or **product** (app UI, admin, dashboard, tool: design SERVES the product).

Identify before designing. Priority: (1) cue in the task itself ("landing page" vs "dashboard"); (2) the surface in focus (the page, file, or route being worked on); (3) `register` field in PRODUCT.md. First match wins.

If PRODUCT.md lacks the `register` field (legacy), infer it once from its "Users" and "Product Purpose" sections, then cache the inferred value for the session. Suggest the user run `{{command_prefix}}impeccable teach` to add the field explicitly.

Load the matching reference: [reference/brand.md](reference/brand.md) or [reference/product.md](reference/product.md). The shared design laws below apply to both.

## Shared design laws

Apply to every design, both registers. Match implementation complexity to the aesthetic vision: maximalism needs elaborate code, minimalism needs precision. Interpret creatively. Vary across projects; never converge on the same choices. {{model}} is capable of extraordinary work. Don't hold back.

### Color

- Use OKLCH. Reduce chroma as lightness approaches 0 or 100; high chroma at extremes looks garish.
- Never use `#000` or `#fff`. Tint every neutral toward the brand hue (chroma 0.005–0.01 is enough).
- Pick a **color strategy** before picking colors. Four steps on the commitment axis:
- **Restrained**: tinted neutrals + one accent ≤10%. Product default; brand minimalism.
- **Committed**: one saturated color carries 30–60% of the surface. Brand default for identity-driven pages.
- **Full palette**: 3–4 named roles, each used deliberately. Brand campaigns; product data viz.
- **Drenched**: the surface IS the color. Brand heroes, campaign pages.
- The "one accent ≤10%" rule is Restrained only. Committed / Full palette / Drenched exceed it on purpose. Don't collapse every design to Restrained by reflex.

### Theme

Dark vs. light is never a default. Not dark "because tools look cool dark." Not light "to be safe."

Before choosing, write one sentence of physical scene: who uses this, where, under what ambient light, in what mood. If the sentence doesn't force the answer, it's not concrete enough. Add detail until it does.

"Observability dashboard" does not force an answer. "SRE glancing at incident severity on a 27-inch monitor at 2am in a dim room" does. Run the sentence, not the category.

### Typography

- Cap body line length at 65–75ch.
- Hierarchy through scale + weight contrast (≥1.25 ratio between steps). Avoid flat scales.

### Layout

- Vary spacing for rhythm. Same padding everywhere is monotony.
- Cards are the lazy answer. Use them only when they're truly the best affordance. Nested cards are always wrong.
- Don't wrap everything in a container. Most things don't need one.

### Motion

- Don't animate CSS layout properties.
- Ease out with exponential curves (ease-out-quart / quint / expo). No bounce, no elastic.

### Absolute bans

Match-and-refuse. If you're about to write any of these, rewrite the element with different structure.

- **Side-stripe borders.** `border-left` or `border-right` greater than 1px as a colored accent on cards, list items, callouts, or alerts. Never intentional. Rewrite with full borders, background tints, leading numbers/icons, or nothing.
- **Gradient text.** `background-clip: text` combined with a gradient background. Decorative, never meaningful. Use a single solid color. Emphasis via weight or size.
- **Glassmorphism as default.** Blurs and glass cards used decoratively. Rare and purposeful, or nothing.
- **The hero-metric template.** Big number, small label, supporting stats, gradient accent. SaaS cliché.
- **Identical card grids.** Same-sized cards with icon + heading + text, repeated endlessly.
- **Modal as first thought.** Modals are usually laziness. Exhaust inline / progressive alternatives first.

### Copy

- Every word earns its place. No restated headings, no intros that repeat the title.
- **No em dashes.** Use commas, colons, semicolons, periods, or parentheses. Also not `--`.

### The AI slop test

If someone could look at this interface and say "AI made that" without doubt, it's failed. Cross-register failures are the absolute bans above. Register-specific failures live in each reference.

**Category-reflex check.** Run at two altitudes; the second one catches what the first one misses.

- **First-order:** if someone could guess the theme + palette from the category alone ("observability → dark blue", "healthcare → white + teal", "finance → navy + gold", "crypto → neon on black"), it's the first training-data reflex. Rework the scene sentence and color strategy until the answer isn't obvious from the domain.
- **Second-order:** if someone could guess the aesthetic family from category-plus-anti-references ("AI workflow tool that's not SaaS-cream → editorial-typographic", "fintech that's not navy-and-gold → terminal-native dark mode"), it's the trap one tier deeper. The first reflex was avoided; the second wasn't. Rework until both answers are not obvious. The brand register's [reflex-reject aesthetic lanes](reference/brand.md) list catches the currently-saturated families.

## Commands

| Command | Category | Description | Reference |
|---|---|---|---|
| `craft [feature]` | Build | Shape, then build a feature end-to-end | [reference/craft.md](reference/craft.md) |
| `shape [feature]` | Build | Plan UX/UI before writing code | [reference/shape.md](reference/shape.md) |
| `teach` | Build | Set up PRODUCT.md and DESIGN.md context | [reference/teach.md](reference/teach.md) |
| `document` | Build | Generate DESIGN.md from existing project code | [reference/document.md](reference/document.md) |
| `extract [target]` | Build | Pull reusable tokens and components into design system | [reference/extract.md](reference/extract.md) |
| `critique [target]` | Evaluate | UX design review with heuristic scoring | [reference/critique.md](reference/critique.md) |
| `audit [target]` | Evaluate | Technical quality checks (a11y, perf, responsive) | [reference/audit.md](reference/audit.md) |
| `polish [target]` | Refine | Final quality pass before shipping | [reference/polish.md](reference/polish.md) |
| `bolder [target]` | Refine | Amplify safe or bland designs | [reference/bolder.md](reference/bolder.md) |
| `quieter [target]` | Refine | Tone down aggressive or overstimulating designs | [reference/quieter.md](reference/quieter.md) |
| `distill [target]` | Refine | Strip to essence, remove complexity | [reference/distill.md](reference/distill.md) |
| `harden [target]` | Refine | Production-ready: errors, i18n, edge cases | [reference/harden.md](reference/harden.md) |
| `onboard [target]` | Refine | Design first-run flows, empty states, activation | [reference/onboard.md](reference/onboard.md) |
| `animate [target]` | Enhance | Add purposeful animations and motion | [reference/animate.md](reference/animate.md) |
| `colorize [target]` | Enhance | Add strategic color to monochromatic UIs | [reference/colorize.md](reference/colorize.md) |
| `typeset [target]` | Enhance | Improve typography hierarchy and fonts | [reference/typeset.md](reference/typeset.md) |
| `layout [target]` | Enhance | Fix spacing, rhythm, and visual hierarchy | [reference/layout.md](reference/layout.md) |
| `delight [target]` | Enhance | Add personality and memorable touches | [reference/delight.md](reference/delight.md) |
| `overdrive [target]` | Enhance | Push past conventional limits | [reference/overdrive.md](reference/overdrive.md) |
| `clarify [target]` | Fix | Improve UX copy, labels, and error messages | [reference/clarify.md](reference/clarify.md) |
| `adapt [target]` | Fix | Adapt for different devices and screen sizes | [reference/adapt.md](reference/adapt.md) |
| `optimize [target]` | Fix | Diagnose and fix UI performance | [reference/optimize.md](reference/optimize.md) |
| `live` | Iterate | Visual variant mode: pick elements in the browser, generate alternatives | [reference/live.md](reference/live.md) |

Plus two management commands: `pin <command>` and `unpin <command>`, detailed below.

### Routing rules

1. **No argument**: render the table above as the user-facing command menu, grouped by category. Ask what they'd like to do.
2. **First word matches a command**: load its reference file and follow its instructions. Everything after the command name is the target.
3. **First word doesn't match**: general design invocation. Apply the setup steps, shared design laws, and the loaded register reference, using the full argument as context.

Setup (context gathering, register) is already loaded by then; sub-commands don't re-invoke `{{command_prefix}}impeccable`.

If the first word is `craft`, setup still runs first, but [reference/craft.md](reference/craft.md) owns the rest of the flow. If setup invokes `teach` as a blocker, finish teach, refresh context, then resume the original command and target.

## Pin / Unpin

**Pin** creates a standalone shortcut so `{{command_prefix}}<command>` invokes `{{command_prefix}}impeccable <command>` directly. **Unpin** removes it. The script writes to every harness directory present in the project.

```bash
node {{scripts_path}}/pin.mjs <pin|unpin> <command>
```

Valid `<command>` is any command from the table above. Report the script's result concisely. Confirm the new shortcut on success, relay stderr verbatim on error.
Loading