quiver-cli 0.8.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -45
- package/bin/quiver-cli.mjs +3 -1
- package/dist/cli.js +546 -458
- package/package.json +2 -2
- package/template/.agents/AGENTS.md +4 -3
- package/template/.agents/config.json +7 -0
- package/template/.agents/plugins/opencode/rtk.ts +34 -0
- package/template/.agents/skills/agent-browser/SKILL.md +1 -0
- package/template/.agents/skills/apps/skybridge/SKILL.md +4 -0
- package/template/.agents/skills/design/impeccable/SKILL.md +36 -118
- package/template/.agents/skills/design/impeccable/reference/adapt.md +1 -0
- package/template/.agents/skills/design/impeccable/reference/adapt.native.md +58 -0
- package/template/.agents/skills/design/impeccable/reference/android.md +40 -0
- package/template/.agents/skills/design/impeccable/reference/animate.md +73 -188
- package/template/.agents/skills/design/impeccable/reference/audit.md +12 -9
- package/template/.agents/skills/design/impeccable/reference/audit.native.md +139 -0
- package/template/.agents/skills/design/impeccable/reference/bolder.md +19 -101
- package/template/.agents/skills/design/impeccable/reference/clarify.md +59 -253
- package/template/.agents/skills/design/impeccable/reference/colorize.md +51 -222
- package/template/.agents/skills/design/impeccable/reference/craft-floor.md +42 -0
- package/template/.agents/skills/design/impeccable/reference/craft.md +3 -121
- package/template/.agents/skills/design/impeccable/reference/critique.md +44 -23
- package/template/.agents/skills/design/impeccable/reference/degraded/asset-producer.md +90 -0
- package/template/.agents/skills/design/impeccable/reference/degraded/documenter.md +24 -0
- package/template/.agents/skills/design/impeccable/reference/degraded/finish-reviewer.md +37 -0
- package/template/.agents/skills/design/impeccable/reference/degraded/manual-edit-applier.md +92 -0
- package/template/.agents/skills/design/impeccable/reference/delight.md +47 -279
- package/template/.agents/skills/design/impeccable/reference/distill.md +2 -2
- package/template/.agents/skills/design/impeccable/reference/doctor.md +53 -0
- package/template/.agents/skills/design/impeccable/reference/document.md +60 -73
- package/template/.agents/skills/design/impeccable/reference/harden.md +1 -12
- package/template/.agents/skills/design/impeccable/reference/hooks.md +20 -5
- package/template/.agents/skills/design/impeccable/reference/init.md +72 -119
- package/template/.agents/skills/design/impeccable/reference/ios.md +45 -0
- package/template/.agents/skills/design/impeccable/reference/layout.md +54 -131
- package/template/.agents/skills/design/impeccable/reference/live-setup.md +102 -0
- package/template/.agents/skills/design/impeccable/reference/live.md +116 -511
- package/template/.agents/skills/design/impeccable/reference/new-work.md +105 -0
- package/template/.agents/skills/design/impeccable/reference/{product.md → operate.md} +6 -5
- package/template/.agents/skills/design/impeccable/reference/optimize.md +4 -4
- package/template/.agents/skills/design/impeccable/reference/overdrive.md +1 -4
- package/template/.agents/skills/design/impeccable/reference/polish.md +68 -212
- package/template/.agents/skills/design/impeccable/reference/quieter.md +3 -3
- package/template/.agents/skills/design/impeccable/reference/routing.md +18 -0
- package/template/.agents/skills/design/impeccable/reference/shape.md +38 -144
- package/template/.agents/skills/design/impeccable/reference/typeset.md +51 -250
- package/template/.agents/skills/design/impeccable/reference/visualize.md +47 -0
- package/template/.agents/skills/design/impeccable/scripts/command-metadata.json +1 -1
- package/template/.agents/skills/design/impeccable/scripts/concept-seed.mjs +558 -0
- package/template/.agents/skills/design/impeccable/scripts/context-signals.mjs +119 -10
- package/template/.agents/skills/design/impeccable/scripts/context.mjs +534 -45
- package/template/.agents/skills/design/impeccable/scripts/critique-storage.mjs +18 -47
- package/template/.agents/skills/design/impeccable/scripts/detector/browser/injected/index.mjs +96 -10
- package/template/.agents/skills/design/impeccable/scripts/detector/cli/main.mjs +174 -26
- package/template/.agents/skills/design/impeccable/scripts/detector/design-system.mjs +233 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns-browser.js +3348 -203
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/browser/detect-url.mjs +102 -7
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/regex/detect-text.mjs +297 -97
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +187 -16
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/detect-html.mjs +41 -11
- package/template/.agents/skills/design/impeccable/scripts/detector/findings.mjs +7 -1
- package/template/.agents/skills/design/impeccable/scripts/detector/node/file-system.mjs +16 -2
- package/template/.agents/skills/design/impeccable/scripts/detector/registry/antipatterns.mjs +207 -38
- package/template/.agents/skills/design/impeccable/scripts/detector/rules/checks.mjs +3082 -173
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/constants.mjs +11 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/fonts.mjs +30 -0
- package/template/.agents/skills/design/impeccable/scripts/doctor.mjs +336 -0
- package/template/.agents/skills/design/impeccable/scripts/embed-prompt.mjs +133 -0
- package/template/.agents/skills/design/impeccable/scripts/generate-image.mjs +240 -0
- package/template/.agents/skills/design/impeccable/scripts/hook-admin.mjs +98 -18
- package/template/.agents/skills/design/impeccable/scripts/hook-before-edit.mjs +46 -6
- package/template/.agents/skills/design/impeccable/scripts/hook-lib.mjs +518 -50
- package/template/.agents/skills/design/impeccable/scripts/hook.mjs +25 -8
- package/template/.agents/skills/design/impeccable/scripts/lib/artifact-schema.mjs +93 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/composition-catalog.mjs +200 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/concept-catalog.mjs +357 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-config.mjs +27 -7
- package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-paths.mjs +17 -8
- package/template/.agents/skills/design/impeccable/scripts/lib/provider.mjs +5 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/roll-selection.mjs +362 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness-deep.mjs +457 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness-notice.mjs +169 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness.mjs +457 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/surface-briefs.mjs +151 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/target-slug.mjs +33 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/template-extensions.mjs +146 -0
- package/template/.agents/skills/design/impeccable/scripts/live/accept-css.mjs +617 -0
- package/template/.agents/skills/design/impeccable/scripts/live/accept-verify.mjs +60 -0
- package/template/.agents/skills/design/impeccable/scripts/live/browser-script-parts.mjs +7 -1
- package/template/.agents/skills/design/impeccable/scripts/live/completion.mjs +10 -1
- package/template/.agents/skills/design/impeccable/scripts/live/event-validation.mjs +67 -5
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/astro.mjs +47 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/detect-utils.mjs +73 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/index.mjs +143 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/journal.mjs +197 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nextjs.mjs +49 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/nuxt.mjs +161 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/script-src.mjs +17 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/static-html.mjs +26 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/sveltekit.mjs +71 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tag-strategy.mjs +247 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/tanstack-start.mjs +70 -0
- package/template/.agents/skills/design/impeccable/scripts/live/frameworks/vite-generic.mjs +42 -0
- package/template/.agents/skills/design/impeccable/scripts/live/generation-preflight.mjs +149 -0
- package/template/.agents/skills/design/impeccable/scripts/live/instructions.mjs +142 -0
- package/template/.agents/skills/design/impeccable/scripts/live/poll-lanes.mjs +14 -0
- package/template/.agents/skills/design/impeccable/scripts/live/roots.mjs +508 -0
- package/template/.agents/skills/design/impeccable/scripts/live/session-store.mjs +324 -50
- package/template/.agents/skills/design/impeccable/scripts/live/source-lock.mjs +105 -0
- package/template/.agents/skills/design/impeccable/scripts/live/source-search.mjs +105 -0
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-ast.mjs +961 -0
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-component.mjs +588 -72
- package/template/.agents/skills/design/impeccable/scripts/live/sveltekit-adapter.mjs +59 -17
- package/template/.agents/skills/design/impeccable/scripts/live/tanstack-adapter.mjs +280 -0
- package/template/.agents/skills/design/impeccable/scripts/live/vocabulary.mjs +135 -0
- package/template/.agents/skills/design/impeccable/scripts/live-accept.mjs +210 -68
- package/template/.agents/skills/design/impeccable/scripts/live-browser.js +1562 -223
- package/template/.agents/skills/design/impeccable/scripts/live-commit-manual-edits.mjs +3 -0
- package/template/.agents/skills/design/impeccable/scripts/live-complete.mjs +33 -1
- package/template/.agents/skills/design/impeccable/scripts/live-inject.mjs +175 -255
- package/template/.agents/skills/design/impeccable/scripts/live-insert.mjs +26 -6
- package/template/.agents/skills/design/impeccable/scripts/live-manual-edit-evidence.mjs +6 -1
- package/template/.agents/skills/design/impeccable/scripts/live-poll.mjs +61 -16
- package/template/.agents/skills/design/impeccable/scripts/live-resume.mjs +39 -10
- package/template/.agents/skills/design/impeccable/scripts/live-server.mjs +573 -47
- package/template/.agents/skills/design/impeccable/scripts/live-status.mjs +17 -7
- package/template/.agents/skills/design/impeccable/scripts/live-wrap.mjs +124 -91
- package/template/.agents/skills/design/impeccable/scripts/live.mjs +88 -26
- package/template/.agents/skills/design/impeccable/scripts/palette.mjs +76 -81
- package/template/.agents/skills/design/impeccable/scripts/pin.mjs +18 -11
- package/template/.agents/skills/design/impeccable/scripts/serve-question.mjs +932 -0
- package/template/.agents/skills/design/impeccable/scripts/surface-brief.mjs +74 -0
- package/template/.agents/skills/design/shadcn/SKILL.md +46 -11
- package/template/.agents/skills/design/shadcn/cli.md +49 -16
- package/template/.agents/skills/design/shadcn/customization.md +14 -7
- package/template/.agents/skills/design/shadcn/evals/evals.json +30 -0
- package/template/.agents/skills/design/shadcn/mcp.md +27 -16
- package/template/.agents/skills/design/shadcn/registry.md +277 -0
- package/template/.agents/skills/design/shadcn/rules/chat.md +224 -0
- package/template/.agents/skills/design/shadcn/rules/composition.md +20 -2
- package/template/.agents/skills/design/shadcn/rules/styling.md +23 -0
- package/template/.agents/skills/find-skills/SKILL.md +2 -3
- package/template/.agents/skills/hono/SKILL.md +579 -0
- package/template/.agents/skills/integrations/langfuse/SKILL.md +10 -6
- package/template/.agents/skills/integrations/langfuse/references/ci-cd.md +41 -0
- package/template/.agents/skills/integrations/langfuse/references/cli.md +8 -0
- package/template/.agents/skills/integrations/langfuse/references/error-analysis.md +15 -27
- package/template/.agents/skills/integrations/langfuse/references/instrumentation.md +39 -52
- package/template/.agents/skills/integrations/langfuse/references/judge-calibration.md +5 -2
- package/template/.agents/skills/integrations/langfuse/references/prompt-engineering.md +35 -0
- package/template/.agents/skills/integrations/langfuse/references/prompt-migration.md +41 -196
- package/template/.agents/skills/integrations/langfuse/references/skill-feedback.md +3 -0
- package/template/.agents/skills/integrations/langfuse/references/trace-evaluator-upgrade.md +76 -0
- package/template/.agents/skills/integrations/langfuse/references/user-feedback.md +4 -0
- package/template/.agents/skills/integrations/langfuse/references/v4-project-migration.md +73 -0
- package/template/.agents/skills/supabase/CHANGELOG.md +71 -0
- package/template/.agents/skills/supabase/SKILL.md +145 -0
- package/template/.agents/skills/supabase/assets/feedback-issue-template.md +17 -0
- package/template/.agents/skills/supabase/references/skill-feedback.md +17 -0
- package/template/.agents/skills/supabase-postgres-best-practices/CHANGELOG.md +73 -0
- package/template/.agents/skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/_template.md +34 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/template/.agents/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
- package/template/.agents/upstreams.json +34 -12
- package/template/.agents/skills/design/impeccable/reference/brand.md +0 -108
- package/template/.agents/skills/design/impeccable/reference/codex.md +0 -105
- package/template/.agents/skills/design/impeccable/reference/interaction-design.md +0 -189
- package/template/.agents/skills/integrations/langfuse/references/sdk-upgrade.md +0 -175
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# Brand register
|
|
2
|
-
|
|
3
|
-
When design IS the product: brand sites, landing pages, marketing surfaces, campaign pages, portfolios, long-form content, about pages. The deliverable is the design itself; a visitor's impression is the thing being made.
|
|
4
|
-
|
|
5
|
-
The register spans every genre. A tech brand (Stripe, Linear, Vercel). A luxury brand (a hotel, a fashion house). A consumer product (a restaurant, a travel site, a CPG packaging page). A creative studio, an agency portfolio, a band's album page. They all share the stance (*communicate, not transact*) and diverge wildly in aesthetic. Don't collapse them into a single look.
|
|
6
|
-
|
|
7
|
-
## The brand slop test
|
|
8
|
-
|
|
9
|
-
If someone could look at this and say "AI made that" without hesitation, it's failed. The bar is distinctiveness; a visitor should ask "how was this made?", not "which AI made this?"
|
|
10
|
-
|
|
11
|
-
Brand isn't a neutral register. AI-generated landing pages have flooded the internet, and average is no longer findable. Restraint without intent now reads as mediocre, not refined. Brand surfaces need a POV, a specific audience, a willingness to risk strangeness. Go big or go home.
|
|
12
|
-
|
|
13
|
-
**The second slop test: aesthetic lane.** Before committing to moves, name the reference. A Klim-style specimen page is one lane; Stripe-minimal is another; Liquid-Death-acid-maximalism is another. Don't drift into editorial-magazine aesthetics on a brief that isn't editorial. A hiking brand with Cormorant italic drop caps has the wrong register within the register.
|
|
14
|
-
|
|
15
|
-
Then the inverse test: in one sentence, describe what you're about to build the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart.
|
|
16
|
-
|
|
17
|
-
## Typography
|
|
18
|
-
|
|
19
|
-
### Font selection procedure
|
|
20
|
-
|
|
21
|
-
Every project. Never skip.
|
|
22
|
-
|
|
23
|
-
1. Read the brief. Write three concrete brand-voice words. Not "modern" or "elegant," but "warm and mechanical and opinionated" or "calm and clinical and careful." Physical-object words.
|
|
24
|
-
2. List the three fonts you'd reach for by reflex. If any appear in the reflex-reject list below, reject them; they are training-data defaults and they create monoculture.
|
|
25
|
-
3. Browse a real catalog (Google Fonts, Pangram Pangram, Future Fonts, Adobe Fonts, ABC Dinamo, Klim, Velvetyne) with the three words in mind. Find the font for the brand as a *physical object*: a museum caption, a 1970s terminal manual, a fabric label, a cheap-newsprint children's book, a concert poster, a receipt from a mid-century diner. Reject the first thing that "looks designy."
|
|
26
|
-
4. Cross-check. "Elegant" is not necessarily serif. "Technical" is not necessarily sans. "Warm" is not Fraunces. If the final pick lines up with the original reflex, start over.
|
|
27
|
-
|
|
28
|
-
### Reflex-reject list
|
|
29
|
-
|
|
30
|
-
Training-data defaults. Ban list. Look further:
|
|
31
|
-
|
|
32
|
-
Fraunces · Newsreader · Lora · Crimson · Crimson Pro · Crimson Text · Playfair Display · Cormorant · Cormorant Garamond · Syne · IBM Plex Mono · IBM Plex Sans · IBM Plex Serif · Space Mono · Space Grotesk · Inter · DM Sans · DM Serif Display · DM Serif Text · Outfit · Plus Jakarta Sans · Instrument Sans · Instrument Serif
|
|
33
|
-
|
|
34
|
-
### Reflex-reject aesthetic lanes
|
|
35
|
-
|
|
36
|
-
Parallel to the font list. Currently saturated aesthetic families that have flooded brand surfaces. If a brief lands in one of these lanes without a register reason that *requires* it (a literal magazine, a literal terminal, a literal industrial signage system), it's the second-order training reflex: the trap one tier deeper than picking a Fraunces font. Look further.
|
|
37
|
-
|
|
38
|
-
- **Editorial-typographic.** Display serif (often italic) + small mono labels + ruled separators + monochromatic restraint. Klim-influenced, magazine-cover affectation. By 2026, every Stripe-adjacent and Notion-adjacent brand has landed here. The fingerprint: three rule-separated columns, an italic Fraunces / Recoleta / Newsreader headline, lowercase track-spaced metadata, no imagery.
|
|
39
|
-
|
|
40
|
-
(More entries land here on the same cadence the font list updates. Brutalist-utility and acid-maximalism may join when they saturate. Removing entries when they fall back below saturation is also fine.)
|
|
41
|
-
|
|
42
|
-
The reflex-reject lists apply to **new design choices**. When the existing brand has already committed to a font or a lane as part of its identity, identity-preservation wins; variants on an existing surface don't second-guess what's already shipping. The reflex-reject lists are for greenfield decisions and for departure-mode variants in [live.md](live.md).
|
|
43
|
-
|
|
44
|
-
### Pairing and voice
|
|
45
|
-
|
|
46
|
-
Distinctive + refined is the goal. The specific shape depends on the brand, not on the brand's category. A category ("restaurant", "dev tool", "magazine", "fintech") is not a recipe; treating it as one is the first-order reflex SKILL.md warns against.
|
|
47
|
-
|
|
48
|
-
Two families minimum is the rule *only* when the voice needs it. A single well-chosen family with committed weight/size contrast is stronger than a timid display+body pair.
|
|
49
|
-
|
|
50
|
-
### Scale
|
|
51
|
-
|
|
52
|
-
Modular scale, fluid `clamp()` for headings, ≥1.25 ratio between steps. Flat scales (1.1× apart) read as uncommitted.
|
|
53
|
-
|
|
54
|
-
Light text on dark backgrounds: add 0.05–0.1 to line-height. Light type reads as lighter weight and needs more breathing room.
|
|
55
|
-
|
|
56
|
-
## Color
|
|
57
|
-
|
|
58
|
-
Brand surfaces have permission for Committed, Full palette, and Drenched strategies. Use them. A single saturated color spread across a hero is not excess; it's voice. A beige-and-muted-slate landing page ignores the register.
|
|
59
|
-
|
|
60
|
-
- Name a real reference before picking a strategy. "Klim Type Foundry #ff4500 orange drench", "Stripe purple-on-white restraint", "Liquid Death acid-green full palette", "Mailchimp yellow full palette", "Condé Nast Traveler muted navy restraint", "Vercel pure black monochrome". Unnamed ambition becomes beige.
|
|
61
|
-
- Palette IS voice. A calm brand and a restless brand should not share palette mechanics.
|
|
62
|
-
- When the strategy is Committed or Drenched, color carries the brand. Don't hedge with neutrals around the edges. Commit.
|
|
63
|
-
- Don't converge across projects. Each brand surface differentiates from the last.
|
|
64
|
-
- When a cultural-symbol palette is the obvious pull, reach past it. Let the cultural reading come from typography, imagery, and copy, not the palette.
|
|
65
|
-
|
|
66
|
-
## Layout
|
|
67
|
-
|
|
68
|
-
- Asymmetric compositions are one option. Break the grid intentionally for emphasis.
|
|
69
|
-
- Fluid spacing with `clamp()` that breathes on larger viewports. Vary for rhythm: generous separations, tight groupings.
|
|
70
|
-
- For image-led briefs (hotels, restaurants, magazines, photography), full-bleed hero imagery with overlaid menu and centered headline is a canonical move; let the photograph be the design.
|
|
71
|
-
- When cards ARE the right affordance, use `grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))` for breakpoint-free responsiveness.
|
|
72
|
-
|
|
73
|
-
## Imagery
|
|
74
|
-
|
|
75
|
-
Brand surfaces lean on imagery. A restaurant, hotel, magazine, or product landing page without any imagery reads as incomplete, not as restrained. A solid-color rectangle where a hero image should go is worse than a representative stock photo.
|
|
76
|
-
|
|
77
|
-
**When the brief implies imagery, you must ship imagery.** Zero images is a bug, not a design choice. "Restraint" is not an excuse. If the approved comp or brief is image-led, ship real project assets, generated raster assets, or a credible canvas/SVG/WebGL scene. Do not replace photographic, architectural, product, or place imagery with generic CSS panels, decorative diagrams, cards, bullets, or copy.
|
|
78
|
-
|
|
79
|
-
- **For greenfield work without local assets, use stock imagery.** Unsplash is the default. The URL shape is `https://images.unsplash.com/photo-{id}?auto=format&fit=crop&w=1600&q=80`. **Verify the URLs before referencing them.** If you have an image-search MCP, web-fetch tool, or browser access, use it to find real photo IDs and confirm they resolve. Guessed IDs (even ones that look real) often 404 and ship as broken-image placeholders. Without a verification path, pick fewer photos you're confident exist over more that you guessed; never substitute colored `<div>` placeholders.
|
|
80
|
-
- **Search for the brand's physical object**, not the generic category: "handmade pasta on a scratched wooden table" beats "Italian food"; "cypress trees above a limestone hotel facade at dusk" beats "luxury hotel".
|
|
81
|
-
- **One decisive photo beats five mediocre ones.** Hero imagery should commit to a mood; padding with more stock doesn't rescue an indecisive one.
|
|
82
|
-
- **Alt text is part of the voice.** "Coastal fettuccine, hand-cut, served on the terrace" beats "pasta dish".
|
|
83
|
-
|
|
84
|
-
"Imagery" here is broader than stock photography: product screenshots, custom data visualizations, generated SVG, and canvas/WebGL scenes are all imagery. Text-only pages where typography alone carries the entire visual weight are the failure mode.
|
|
85
|
-
|
|
86
|
-
## Motion
|
|
87
|
-
|
|
88
|
-
- One well-orchestrated page-load beats scattered micro-interactions, when the brand invites it. Some brands skip entrance motion entirely; the restraint is the voice.
|
|
89
|
-
|
|
90
|
-
## Brand bans (on top of the shared absolute bans)
|
|
91
|
-
|
|
92
|
-
- Monospace as lazy shorthand for "technical / developer." If the brand isn't technical, mono reads as costume.
|
|
93
|
-
- Large rounded-corner icons above every heading. Screams template.
|
|
94
|
-
- Single-family pages that picked the family by reflex, not voice. (A single family chosen deliberately is fine.)
|
|
95
|
-
- All-caps body copy. Reserve caps for short labels and headings.
|
|
96
|
-
- Timid palettes and average layouts. Safe = invisible.
|
|
97
|
-
- Zero imagery on a brief that implies imagery (restaurant, hotel, food, travel, fashion, photography, hobbyist). Colored blocks where a hero photo belongs.
|
|
98
|
-
- Defaulting to editorial-magazine aesthetics (display serif + italic + drop caps + broadsheet grid) on briefs that aren't magazine-shaped. Editorial is ONE aesthetic lane, not the default brand aesthetic.
|
|
99
|
-
- Repeated tiny uppercase tracked labels above every section heading. A single strong kicker can be voice; repeating it as section grammar is AI scaffolding unless it's a deliberate, named brand system.
|
|
100
|
-
|
|
101
|
-
## Brand permissions
|
|
102
|
-
|
|
103
|
-
Brand can afford things product can't. Take them.
|
|
104
|
-
|
|
105
|
-
- Ambitious first-load motion. Reveals and typographic choreography that earn their place; not fade-on-scroll for every section.
|
|
106
|
-
- Single-purpose viewports. One dominant idea per fold, long scroll, deliberate pacing.
|
|
107
|
-
- Unexpected color strategies. Palette IS voice; a calm brand and a restless brand should not share palette mechanics.
|
|
108
|
-
- Art direction per section. Different sections can have different visual worlds if the narrative demands it. Consistency of voice beats consistency of treatment.
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# Codex: Visual Direction & Asset Production
|
|
2
|
-
|
|
3
|
-
This file is loaded by `/impeccable craft` when the harness has native image generation (currently Codex via `image_gen`). Other harnesses skip it. It covers the two craft steps that depend on real image generation: landing the visual direction, and producing the raster assets the implementation will compose.
|
|
4
|
-
|
|
5
|
-
Read this *before* generating any images. The order matters, and the per-step user pauses are what keep generated imagery from drifting away from the brief.
|
|
6
|
-
|
|
7
|
-
### Four stop points before code
|
|
8
|
-
|
|
9
|
-
Steps A through D each end with the user. Do not advance past any of them on your own read of the situation.
|
|
10
|
-
|
|
11
|
-
1. **STOP after Step A questions.** Wait for answers.
|
|
12
|
-
2. **STOP after Step B palette generation.** Wait for "confirm palette."
|
|
13
|
-
3. **STOP after Step C mocks.** Wait for direction approval or delegation.
|
|
14
|
-
4. **Only after Step D approves a direction** do you return to craft.md Step 4 and write code.
|
|
15
|
-
|
|
16
|
-
Prior shape approval does **not** satisfy any of these. Shape's "confirm or override" advances you into Step A; it is not a substitute for it.
|
|
17
|
-
|
|
18
|
-
## Step A: Explore Directions with the User
|
|
19
|
-
|
|
20
|
-
Before generating anything, run a brief direction conversation grounded in the shape brief.
|
|
21
|
-
|
|
22
|
-
**Step A is required even when shape just produced a confirmed brief.** The shape questions and Step A questions cover different ground: shape pins purpose, content, scope; Step A pins palette, atmosphere, and named visual references for the comps you're about to generate. The only time you can skip Step A is when the user has already answered these exact palette/atmosphere/reference questions in the same session.
|
|
23
|
-
|
|
24
|
-
Ask **2-3 targeted questions** about visual lane, color strategy, atmosphere, and named anchor references. Don't enumerate generic menus; tie each question to the shape brief's answers. Example shape-grounded questions:
|
|
25
|
-
|
|
26
|
-
- "Brief says 'specimen-page restraint.' Are we closer to a quiet typographic page or a wider editorial spread with hero imagery?"
|
|
27
|
-
- "Palette strategy from shape was 'Committed.' Which one color carries the surface (a brand-driven pick rather than a default warm-or-cool framing)? (And no, the answer isn't a cream/sand body bg; that's the saturated AI default.)"
|
|
28
|
-
|
|
29
|
-
**STOP and wait for answers.** These pin the palette before any pixel gets generated. Do not proceed to Step B until the user has responded.
|
|
30
|
-
|
|
31
|
-
## Step B: Generate the Brand Palette First
|
|
32
|
-
|
|
33
|
-
Generate **one** palette artifact before any mocks. This is a small, focused image: typography pairing on the chosen background, primary + accent color swatches, one signature ornament or motif. Single image, single pass.
|
|
34
|
-
|
|
35
|
-
Why palette first: mocks generated against a vague color sense produce noise that drowns out the structural decisions. A confirmed palette is the first concrete contract for everything downstream.
|
|
36
|
-
|
|
37
|
-
Show the palette to the user. Ask one question: "This is the palette I'm locking in for the mocks. Confirm, or call out what to shift?"
|
|
38
|
-
|
|
39
|
-
**STOP and wait for confirmation.** Do not generate mocks against an unconfirmed palette. "Probably good enough" is the wrong call here; the palette is the contract for everything downstream.
|
|
40
|
-
|
|
41
|
-
## Step C: Generate 1-3 Visual Mocks Against the Palette
|
|
42
|
-
|
|
43
|
-
Once the palette is confirmed, generate **1 to 3** high-fidelity north-star comps. Each mock must use the confirmed palette and typography. Mocks differ in *structural* direction (hierarchy, topology, density, composition), not in color or motif.
|
|
44
|
-
|
|
45
|
-
- Brand work: push visual identity, composition, mood, and signature motifs.
|
|
46
|
-
- Product work: push hierarchy, topology, density, tone, grounded in realistic product structure.
|
|
47
|
-
- Landing pages and long-form brand surfaces: show enough of the second fold to establish the system beyond the hero.
|
|
48
|
-
|
|
49
|
-
Use the `image_gen` tool directly (or via the imagegen skill when available). Don't ask the user to install anything.
|
|
50
|
-
|
|
51
|
-
## Step D: Approval Loop
|
|
52
|
-
|
|
53
|
-
Show the comps. Ask what carries forward. Iterate until **one direction is approved** or the user explicitly delegates.
|
|
54
|
-
|
|
55
|
-
**STOP and wait for the approval or the delegation.** Do not begin Step E or return to craft.md Step 4 until a single direction is named. If the user delegates, pick the strongest direction and explain it from the brief, not personal taste.
|
|
56
|
-
|
|
57
|
-
Before moving to assets, summarize what to carry into code and what *not* to literalize from the mock. This is the handoff between visual exploration and semantic implementation.
|
|
58
|
-
|
|
59
|
-
## Step E: Mock Fidelity Inventory
|
|
60
|
-
|
|
61
|
-
Inventory the approved mock's major visible ingredients. For each, decide implementation: semantic HTML/CSS/SVG, generated raster, sourced raster, icon library, canvas/WebGL, or accepted omission.
|
|
62
|
-
|
|
63
|
-
Common ingredients to inventory:
|
|
64
|
-
|
|
65
|
-
- Hero silhouette and dominant composition
|
|
66
|
-
- Signature motifs (planets, devices, portraits, charts, route lines, insets, badges, etc.)
|
|
67
|
-
- Nav and primary CTA treatment
|
|
68
|
-
- Section sequence, especially the second fold
|
|
69
|
-
- Image-native content the concept depends on
|
|
70
|
-
- Typography, density, color/material treatment, motion cues
|
|
71
|
-
|
|
72
|
-
Treat the mock as a north star, not a screenshot to trace. Don't rasterize core UI text. But if the live result lacks the mock's major ingredients, the implementation is wrong.
|
|
73
|
-
|
|
74
|
-
If a photographic, architectural, product, or place-led mock becomes generic CSS scenery, decorative diagrams, bullets, or copy, stop and fix it. That's a broken implementation, not a harmless interpretation.
|
|
75
|
-
|
|
76
|
-
Don't substitute a different hero composition or visual driver post-approval without user sign-off.
|
|
77
|
-
|
|
78
|
-
## Step F: Asset Slicing via the Asset Producer
|
|
79
|
-
|
|
80
|
-
Raster ingredients identified in Step E need clean production assets. Use the bundled `impeccable_asset_producer` subagent rather than producing inline.
|
|
81
|
-
|
|
82
|
-
Spawn it as a scoped subagent. If you do not have explicit permission to use agents, stop and ask:
|
|
83
|
-
|
|
84
|
-
```text
|
|
85
|
-
Asset production will work better as a scoped subagent job. Should I spawn the Impeccable asset producer subagent for this step?
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Pass to the agent:
|
|
89
|
-
|
|
90
|
-
- Approved mock path or screenshot reference
|
|
91
|
-
- Crop paths or a contact sheet with crop ids
|
|
92
|
-
- Output directory
|
|
93
|
-
- Required dimensions, format, transparency needs
|
|
94
|
-
- Avoid list
|
|
95
|
-
- Notes on what should remain semantic HTML/CSS/SVG instead of raster
|
|
96
|
-
|
|
97
|
-
Attach image generation capability to the spawned agent when the harness supports it. Do **not** load image-generation reference material into the parent thread.
|
|
98
|
-
|
|
99
|
-
Inline asset production is allowed only if the user declines subagents, the harness cannot spawn the authorized agent, or the user explicitly asks for single-thread mode.
|
|
100
|
-
|
|
101
|
-
Prefer HTML/CSS/SVG/canvas when they can credibly reproduce an ingredient; reach for real, generated, or stock imagery when the mock or subject matter calls for actual visual content.
|
|
102
|
-
|
|
103
|
-
## After This File
|
|
104
|
-
|
|
105
|
-
Once Steps A through F are complete, return to `craft.md` Step 5 (Build to Production Quality). The implementation builds against the confirmed palette, approved mock, and the assets the producer wrote.
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
# Interaction Design
|
|
2
|
-
|
|
3
|
-
## The Eight Interactive States
|
|
4
|
-
|
|
5
|
-
Every interactive element needs these states designed:
|
|
6
|
-
|
|
7
|
-
| State | When | Visual Treatment |
|
|
8
|
-
|-------|------|------------------|
|
|
9
|
-
| **Default** | At rest | Base styling |
|
|
10
|
-
| **Hover** | Pointer over (not touch) | Subtle lift, color shift |
|
|
11
|
-
| **Focus** | Keyboard/programmatic focus | Visible ring (see below) |
|
|
12
|
-
| **Active** | Being pressed | Pressed in, darker |
|
|
13
|
-
| **Disabled** | Not interactive | Reduced opacity, no pointer |
|
|
14
|
-
| **Loading** | Processing | Spinner, skeleton |
|
|
15
|
-
| **Error** | Invalid state | Red border, icon, message |
|
|
16
|
-
| **Success** | Completed | Green check, confirmation |
|
|
17
|
-
|
|
18
|
-
**The common miss**: Designing hover without focus, or vice versa. They're different. Keyboard users never see hover states.
|
|
19
|
-
|
|
20
|
-
## Focus Rings: Do Them Right
|
|
21
|
-
|
|
22
|
-
**Never `outline: none` without replacement.** It's an accessibility violation. Instead, use `:focus-visible` to show focus only for keyboard users:
|
|
23
|
-
|
|
24
|
-
```css
|
|
25
|
-
/* Hide focus ring for mouse/touch */
|
|
26
|
-
button:focus {
|
|
27
|
-
outline: none;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/* Show focus ring for keyboard */
|
|
31
|
-
button:focus-visible {
|
|
32
|
-
outline: 2px solid var(--color-accent);
|
|
33
|
-
outline-offset: 2px;
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
**Focus ring design**:
|
|
38
|
-
- High contrast (3:1 minimum against adjacent colors)
|
|
39
|
-
- 2-3px thick
|
|
40
|
-
- Offset from element (not inside it)
|
|
41
|
-
- Consistent across all interactive elements
|
|
42
|
-
|
|
43
|
-
## Form Design: The Non-Obvious
|
|
44
|
-
|
|
45
|
-
**Placeholders aren't labels.** They disappear on input. Always use visible `<label>` elements. **Validate on blur**, not on every keystroke (exception: password strength). Place errors **below** fields with `aria-describedby` connecting them.
|
|
46
|
-
|
|
47
|
-
## Loading States
|
|
48
|
-
|
|
49
|
-
**Optimistic updates**: Show success immediately, rollback on failure. Use for low-stakes actions (likes, follows), not payments or destructive actions. **Skeleton screens > spinners**: they preview content shape and feel faster than generic spinners.
|
|
50
|
-
|
|
51
|
-
## Modals: The Inert Approach
|
|
52
|
-
|
|
53
|
-
Focus trapping in modals used to require complex JavaScript. Now use the `inert` attribute:
|
|
54
|
-
|
|
55
|
-
```html
|
|
56
|
-
<!-- When modal is open -->
|
|
57
|
-
<main inert>
|
|
58
|
-
<!-- Content behind modal can't be focused or clicked -->
|
|
59
|
-
</main>
|
|
60
|
-
<dialog open>
|
|
61
|
-
<h2>Modal Title</h2>
|
|
62
|
-
<!-- Focus stays inside modal -->
|
|
63
|
-
</dialog>
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
Or use the native `<dialog>` element:
|
|
67
|
-
|
|
68
|
-
```javascript
|
|
69
|
-
const dialog = document.querySelector('dialog');
|
|
70
|
-
dialog.showModal(); // Opens with focus trap, closes on Escape
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## The Popover API
|
|
74
|
-
|
|
75
|
-
For tooltips, dropdowns, and non-modal overlays, use native popovers:
|
|
76
|
-
|
|
77
|
-
```html
|
|
78
|
-
<button popovertarget="menu">Open menu</button>
|
|
79
|
-
<div id="menu" popover>
|
|
80
|
-
<button>Option 1</button>
|
|
81
|
-
<button>Option 2</button>
|
|
82
|
-
</div>
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**Benefits**: Light-dismiss (click outside closes), proper stacking, no z-index wars, accessible by default.
|
|
86
|
-
|
|
87
|
-
## Dropdown & Overlay Positioning
|
|
88
|
-
|
|
89
|
-
Dropdowns rendered with `position: absolute` inside a container that has `overflow: hidden` or `overflow: auto` will be clipped. This is the single most common dropdown bug in generated code.
|
|
90
|
-
|
|
91
|
-
### CSS Anchor Positioning
|
|
92
|
-
|
|
93
|
-
The modern solution uses the CSS Anchor Positioning API to tether an overlay to its trigger without JavaScript:
|
|
94
|
-
|
|
95
|
-
```css
|
|
96
|
-
.trigger {
|
|
97
|
-
anchor-name: --menu-trigger;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.dropdown {
|
|
101
|
-
position: fixed;
|
|
102
|
-
position-anchor: --menu-trigger;
|
|
103
|
-
position-area: block-end span-inline-end;
|
|
104
|
-
margin-top: 4px;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/* Flip above if no room below */
|
|
108
|
-
@position-try --flip-above {
|
|
109
|
-
position-area: block-start span-inline-end;
|
|
110
|
-
margin-bottom: 4px;
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Because the dropdown uses `position: fixed`, it escapes any `overflow` clipping on ancestor elements. The `@position-try` block handles viewport edges automatically. **Browser support**: Chrome 125+, Edge 125+. Not yet in Firefox or Safari - use a fallback for those browsers.
|
|
115
|
-
|
|
116
|
-
### Popover + Anchor Combo
|
|
117
|
-
|
|
118
|
-
Combining the Popover API with anchor positioning gives you stacking, light-dismiss, accessibility, and correct positioning in one pattern:
|
|
119
|
-
|
|
120
|
-
```html
|
|
121
|
-
<button popovertarget="menu" class="trigger">Open</button>
|
|
122
|
-
<div id="menu" popover class="dropdown">
|
|
123
|
-
<button>Option 1</button>
|
|
124
|
-
<button>Option 2</button>
|
|
125
|
-
</div>
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
The `popover` attribute places the element in the **top layer**, which sits above all other content regardless of z-index or overflow. No portal needed.
|
|
129
|
-
|
|
130
|
-
### Portal / Teleport Pattern
|
|
131
|
-
|
|
132
|
-
In component frameworks, render the dropdown at the document root and position it with JavaScript:
|
|
133
|
-
|
|
134
|
-
- **React**: `createPortal(dropdown, document.body)`
|
|
135
|
-
- **Vue**: `<Teleport to="body">`
|
|
136
|
-
- **Svelte**: Use a portal library or mount to `document.body`
|
|
137
|
-
|
|
138
|
-
Calculate position from the trigger's `getBoundingClientRect()`, then apply `position: fixed` with `top` and `left` values. Recalculate on scroll and resize.
|
|
139
|
-
|
|
140
|
-
### Fixed Positioning Fallback
|
|
141
|
-
|
|
142
|
-
For browsers without anchor positioning support, `position: fixed` with manual coordinates avoids overflow clipping:
|
|
143
|
-
|
|
144
|
-
```css
|
|
145
|
-
.dropdown {
|
|
146
|
-
position: fixed;
|
|
147
|
-
/* top/left set via JS from trigger's getBoundingClientRect() */
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Check viewport boundaries before rendering. If the dropdown would overflow the bottom edge, flip it above the trigger. If it would overflow the right edge, align it to the trigger's right side instead.
|
|
152
|
-
|
|
153
|
-
## Destructive Actions: Undo > Confirm
|
|
154
|
-
|
|
155
|
-
**Undo is better than confirmation dialogs.** Users click through confirmations mindlessly. Remove from UI immediately, show undo toast, actually delete after toast expires. Use confirmation only for truly irreversible actions (account deletion), high-cost actions, or batch operations.
|
|
156
|
-
|
|
157
|
-
## Keyboard Navigation Patterns
|
|
158
|
-
|
|
159
|
-
### Roving Tabindex
|
|
160
|
-
|
|
161
|
-
For component groups (tabs, menu items, radio groups), one item is tabbable; arrow keys move within:
|
|
162
|
-
|
|
163
|
-
```html
|
|
164
|
-
<div role="tablist">
|
|
165
|
-
<button role="tab" tabindex="0">Tab 1</button>
|
|
166
|
-
<button role="tab" tabindex="-1">Tab 2</button>
|
|
167
|
-
<button role="tab" tabindex="-1">Tab 3</button>
|
|
168
|
-
</div>
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
Arrow keys move `tabindex="0"` between items. Tab moves to the next component entirely.
|
|
172
|
-
|
|
173
|
-
### Skip Links
|
|
174
|
-
|
|
175
|
-
Provide skip links (`<a href="#main-content">Skip to main content</a>`) for keyboard users to jump past navigation. Hide off-screen, show on focus.
|
|
176
|
-
|
|
177
|
-
## Gesture Discoverability
|
|
178
|
-
|
|
179
|
-
Swipe-to-delete and similar gestures are invisible. Hint at their existence:
|
|
180
|
-
|
|
181
|
-
- **Partially reveal**: Show delete button peeking from edge
|
|
182
|
-
- **Onboarding**: Coach marks on first use
|
|
183
|
-
- **Alternative**: Always provide a visible fallback (menu with "Delete")
|
|
184
|
-
|
|
185
|
-
Don't rely on gestures as the only way to perform actions.
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
**Avoid**: Removing focus indicators without alternatives. Using placeholder text as labels. Touch targets <44x44px. Generic error messages. Custom controls without ARIA/keyboard support.
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: langfuse-sdk-upgrade
|
|
3
|
-
description: Upgrade Langfuse SDKs from older versions to the latest. Use when migrating Python SDK v2/v3 to v4, or JS/TS SDK v3/v4 to v5.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Langfuse SDK Upgrade Guide
|
|
7
|
-
|
|
8
|
-
Assist users in upgrading their Langfuse SDK to the latest version. The Python and JS/TS SDKs share the same architectural changes but differ in syntax.
|
|
9
|
-
|
|
10
|
-
## Migration Docs
|
|
11
|
-
|
|
12
|
-
Always fetch the latest migration guide before starting — these pages are the source of truth:
|
|
13
|
-
|
|
14
|
-
- **Python (v3 → v4):** https://langfuse.com/docs/observability/sdk/upgrade-path/python-v3-to-v4
|
|
15
|
-
- **JS/TS (v4 → v5):** https://langfuse.com/docs/observability/sdk/upgrade-path/js-v4-to-v5
|
|
16
|
-
|
|
17
|
-
Fetch the relevant page as markdown before implementing any changes:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
curl -s "https://langfuse.com/docs/observability/sdk/upgrade-path/python-v3-to-v4.md"
|
|
21
|
-
curl -s "https://langfuse.com/docs/observability/sdk/upgrade-path/js-v4-to-v5.md"
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Upgrade Checklist
|
|
25
|
-
|
|
26
|
-
Work through each item in order. Skip items that don't apply to the user's codebase.
|
|
27
|
-
|
|
28
|
-
### Both SDKs
|
|
29
|
-
|
|
30
|
-
- [ ] **Update the SDK package** to the latest version
|
|
31
|
-
- [ ] **Audit span filtering**: Non-LLM spans (HTTP, DB, queues) no longer export by default. If the user relied on these, configure a custom `should_export_span` / `shouldExportSpan` filter
|
|
32
|
-
- [ ] **Replace `update_current_trace()` / `updateActiveTrace()`**: Split into three calls:
|
|
33
|
-
- `propagate_attributes()` / `propagateAttributes()` for correlating attributes (`user_id`, `session_id`, `tags`, `metadata`, `trace_name`)
|
|
34
|
-
- `set_current_trace_io()` / `setActiveTraceIO()` for input/output (deprecated — prefer setting I/O on root observation directly)
|
|
35
|
-
- `set_current_trace_as_public()` / `setActiveTraceAsPublic()` for public flag
|
|
36
|
-
- [ ] **Replace `.update_trace()` / `.updateTrace()`** on observation objects (same decomposition as above)
|
|
37
|
-
- [ ] **Update API namespace references**: `observations_v_2` / `observationsV2` → `observations`, `score_v_2` / `scoreV2` → `scores`, `metrics_v_2` / `metricsV2` → `metrics`. Legacy v1 APIs moved to `api.legacy.*`
|
|
38
|
-
- [ ] **Validate metadata format**: Must be `dict[str, str]` / `Record<string, string>` with values ≤200 characters
|
|
39
|
-
- [ ] **Move `release` and `environment`** from code parameters to environment variables (`LANGFUSE_RELEASE`, `LANGFUSE_TRACING_ENVIRONMENT`)
|
|
40
|
-
- [ ] **Enable debug logging** during migration to catch issues (`debug=True` in Python, `LANGFUSE_DEBUG="true"` in JS/TS)
|
|
41
|
-
- [ ] **Test trace hierarchies** to verify no spans are unexpectedly dropped
|
|
42
|
-
|
|
43
|
-
### Python-specific
|
|
44
|
-
|
|
45
|
-
- [ ] **Replace `start_span()` / `start_generation()`** with `start_observation()` (use `as_type="generation"` for generations)
|
|
46
|
-
- [ ] **Replace `start_as_current_span()` / `start_as_current_generation()`** with `start_as_current_observation()`
|
|
47
|
-
- [ ] **Replace dataset `item.run()`** with `dataset.run_experiment(name=..., task=...)`
|
|
48
|
-
- [ ] **Remove `CallbackHandler(update_trace=...)`** parameter — use `propagate_attributes()` wrapper instead
|
|
49
|
-
- [ ] **Upgrade to Pydantic v2** — the SDK now requires it. Use `pydantic.v1` compatibility shim if migrating gradually
|
|
50
|
-
- [ ] **Update removed types**: `TraceMetadata`, `ObservationParams` removed from `langfuse.types`. Import `MapValue`, `ModelUsage`, `PromptClient` from `langfuse.model`
|
|
51
|
-
|
|
52
|
-
### JS/TS-specific
|
|
53
|
-
|
|
54
|
-
- [ ] **Update LangChain `CallbackHandler`** — `traceMetadata` now requires string values; internal behavior uses `propagateAttributes()` instead of direct trace updates
|
|
55
|
-
- [ ] **Update OpenAI integration** — `traceMethod` wrapper now uses `propagateAttributes()` internally; wrap entire execution in `propagateAttributes()` if relying on parent attribute inheritance
|
|
56
|
-
|
|
57
|
-
## Key API Changes Reference
|
|
58
|
-
|
|
59
|
-
### Correlating attributes (both SDKs)
|
|
60
|
-
|
|
61
|
-
**Before:**
|
|
62
|
-
```python
|
|
63
|
-
# Python
|
|
64
|
-
langfuse.update_current_trace(name="trace-name", user_id="user-123", session_id="session-abc", tags=["tag1"])
|
|
65
|
-
```
|
|
66
|
-
```typescript
|
|
67
|
-
// JS/TS
|
|
68
|
-
updateActiveTrace({ name: "trace-name", userId: "user-123", sessionId: "session-456", tags: ["prod"] });
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
**After:**
|
|
72
|
-
```python
|
|
73
|
-
# Python
|
|
74
|
-
from langfuse import propagate_attributes
|
|
75
|
-
|
|
76
|
-
with propagate_attributes(trace_name="trace-name", user_id="user-123", session_id="session-abc", tags=["tag1"]):
|
|
77
|
-
result = call_llm("hello")
|
|
78
|
-
```
|
|
79
|
-
```typescript
|
|
80
|
-
// JS/TS
|
|
81
|
-
import { propagateAttributes } from "langfuse";
|
|
82
|
-
|
|
83
|
-
await propagateAttributes(
|
|
84
|
-
{ traceName: "trace-name", userId: "user-123", sessionId: "session-456", tags: ["prod"] },
|
|
85
|
-
async () => { /* traced code */ }
|
|
86
|
-
);
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Span/Generation creation (Python)
|
|
90
|
-
|
|
91
|
-
**Before:**
|
|
92
|
-
```python
|
|
93
|
-
langfuse.start_span(name="x")
|
|
94
|
-
langfuse.start_generation(name="x", model="gpt-4")
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**After:**
|
|
98
|
-
```python
|
|
99
|
-
langfuse.start_observation(name="x")
|
|
100
|
-
langfuse.start_observation(name="x", as_type="generation", model="gpt-4")
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Dataset experiments (Python)
|
|
104
|
-
|
|
105
|
-
**Before:**
|
|
106
|
-
```python
|
|
107
|
-
for item in dataset.items:
|
|
108
|
-
with item.run(run_name="my-run") as span:
|
|
109
|
-
result = my_llm(item.input)
|
|
110
|
-
span.update(output=result)
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**After:**
|
|
114
|
-
```python
|
|
115
|
-
def my_task(*, item, **kwargs):
|
|
116
|
-
return my_llm(item.input)
|
|
117
|
-
|
|
118
|
-
dataset.run_experiment(name="my-run", task=my_task)
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### Span filtering (both SDKs)
|
|
122
|
-
|
|
123
|
-
To restore pre-upgrade "export all" behavior:
|
|
124
|
-
|
|
125
|
-
```python
|
|
126
|
-
# Python
|
|
127
|
-
langfuse = Langfuse(should_export_span=lambda span: True)
|
|
128
|
-
```
|
|
129
|
-
```typescript
|
|
130
|
-
// JS/TS
|
|
131
|
-
const spanProcessor = new LangfuseSpanProcessor({ shouldExportSpan: () => true });
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
To extend defaults with custom scopes:
|
|
135
|
-
|
|
136
|
-
```python
|
|
137
|
-
# Python
|
|
138
|
-
from langfuse.span_filter import is_default_export_span
|
|
139
|
-
|
|
140
|
-
langfuse = Langfuse(
|
|
141
|
-
should_export_span=lambda span: (
|
|
142
|
-
is_default_export_span(span)
|
|
143
|
-
or span.instrumentation_scope.name.startswith("my_framework")
|
|
144
|
-
)
|
|
145
|
-
)
|
|
146
|
-
```
|
|
147
|
-
```typescript
|
|
148
|
-
// JS/TS
|
|
149
|
-
import { isDefaultExportSpan } from "@langfuse/otel";
|
|
150
|
-
|
|
151
|
-
shouldExportSpan: ({ otelSpan }) =>
|
|
152
|
-
isDefaultExportSpan(otelSpan) || otelSpan.instrumentationScope.name.startsWith("my_framework")
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
## Common Pitfalls
|
|
156
|
-
|
|
157
|
-
| Pitfall | Impact | Fix |
|
|
158
|
-
| --- | --- | --- |
|
|
159
|
-
| Dropping intermediate spans via filtering | Breaks trace trees — child spans become orphaned | Use `is_default_export_span` as base and only add/remove specific scopes |
|
|
160
|
-
| Metadata with non-string values | Values silently coerced or dropped | Ensure all metadata values are strings ≤200 characters |
|
|
161
|
-
| Setting attributes outside `propagate_attributes()` callback | Attributes don't attach to observations | Wrap all traced code inside the callback |
|
|
162
|
-
| Using deprecated `set_current_trace_io()` for new code | Will be removed in future versions | Set input/output directly on the root observation |
|
|
163
|
-
| Forgetting Pydantic v2 upgrade (Python) | Import errors or runtime failures | Upgrade Pydantic or use `pydantic.v1` shim |
|
|
164
|
-
| `release`/`environment` still passed as parameters | Silently ignored | Use `LANGFUSE_RELEASE` and `LANGFUSE_TRACING_ENVIRONMENT` env vars |
|
|
165
|
-
| LangChain/OpenAI attribute propagation direction changed | Attributes propagate downward only, not upward to parent traces | Wrap outer call in `propagate_attributes()` |
|
|
166
|
-
|
|
167
|
-
## Best Practices
|
|
168
|
-
|
|
169
|
-
1. **Always fetch the migration docs first** — they are the canonical source and may have been updated since this guide was written
|
|
170
|
-
2. **Enable debug logging during migration** to surface dropped spans and trace hierarchy issues
|
|
171
|
-
3. **Use `propagate_attributes()` as the primary mechanism** for setting trace-level correlating attributes
|
|
172
|
-
4. **Set input/output on root observations directly** rather than using deprecated trace-level setters
|
|
173
|
-
5. **Compose custom span filters** with `is_default_export_span` / `isDefaultExportSpan` to extend defaults rather than replacing them entirely
|
|
174
|
-
6. **Test thoroughly** — run the application with debug logging, check the Langfuse UI for missing or orphaned spans, verify metadata appears correctly
|
|
175
|
-
7. **Migrate incrementally** — upgrade the SDK first, fix breaking changes, then adopt new patterns
|