Imported from kanishka-namdeo/AgentCanvas (
src/lib/AGENTS.md). Install upstream withnpx skills add kanishka-namdeo/AgentCanvas --skill lib. Copyright stays with the author.
AGENTS.md — src/lib/
Purpose
Shared library layer root. Owns the Prisma client singleton and the shared UI utility directly, and indexes the nine lib subfolders that have their own AGENTS.md contracts (agent, canvas, design-systems, llm, pen, sessions, settings, web, icons) plus the nested agent/v3 child doc.
Ownership
db.ts— Prisma 7 client singleton using the@prisma/adapter-libsqldriver adapter. ReadsDATABASE_URL(defaultfile:./db/custom.db; the z.ai sandbox forces the absolutefile:/home/z/my-project/db/custom.db— seedocs/zai-sandbox-setup.md). Caches the client onglobalThisin dev to survive Next.js hot reloads. Shared by all Prisma-touching API routes (/api/sessions*).utils.ts— the shadcncn()class-merge helper (clsx + tailwind-merge), the most-imported UI utility in the component tree.storage/quota-aware.ts— shared localStorage write wrapper: detects QuotaExceededError (DOMException name/codes 22 + 1014, string fallback), tracks consecutive failures, escalates toast severity (first failure → warning toast + optional emergency callback; 3+ → persistent banner). Non-quota errors re-throw. Consumed bysessions/store.ts(throttled persist) +settings/store.ts(custom persist storage). SSR-safe (returns false whenwindowis absent). Guarded bytests/unit/quota-aware.test.ts.validation/status-enums.ts— canonical status unions + type guards (isValidSessionStatus/isValidMessageStatus/isValidRunStatus/isValidToolCallStatus) mirroringsrc/lib/sessions/types.ts; enforced at the sessions PATCH + messages/runs POST API boundaries (invalid → 400). Guarded bytests/unit/status-enums.test.ts.agent-error.ts— shared agent-error classification (importable from both server and client with no server-only deps). ExportsclassifyAgentError(message)(maps a raw error string to a stableAgentErrorClasswithcode,retryable,title,hint),classifiedAgentError(message)(the wire shape foragent:errorSyncEvents), andagentErrorClassForCode(code)(client-side display lookup). No Prisma, no Pi-SDK, no fetch — safe in the browser bundle.onboarding/store.ts— ZustanduseOnboardingstore (persisted toagentcanvas.onboarding.v1): tracks first-time user onboarding state (hasCompleted,skipped,completedAt,selectedTemplateId);complete()/skip()/reset()actions;ONBOARDING_TEMPLATESexports the curated starter prompts with tier badges.icons/— Lucide icon library runtime:index.tsexportsgetLucideIcon,searchLucideIcons,lucidePromptCatalog,lucideIconGroupSvg,lucideIconInlineSvg(SVG string emitters for server-side render paths + the agent toolpen_search_icons).lucide-registry.generated.tsis a GENERATED file (194 curated icons fromlucide-react__iconNodedata; do not hand-edit) — regenerate vianpx tsx scripts/generate-lucide-registry.ts(no package.json script alias; see the script's header +docs/lucide-icons.md).
Local Contracts
- Import shared lib modules from feature code via the
@/lib/...alias only. db.tsis the ONLY place aPrismaClientmay be constructed — never instantiate Prisma elsewhere.- Schema changes start in
prisma/schema.prisma+prisma.config.ts(repo root), thenbun run db:generate+bun run db:push(seeprisma/AGENTS.md).
Work Guidance
- New shared modules that don't fit an existing subfolder land here with an Ownership entry; prefer extending the owning subfolder when one exists.
- A new subfolder becomes a child doc when it grows its own contracts (follow the DOX rules in the root
AGENTS.md).
Verification
bunx tsc --noEmit— typecheck.bun run db:push— schema in sync (uses the same client config).- Manual:
curl http://localhost:3000/api/sessionsreturns session JSON — proves the db singleton initializes inside a route.
Mistakes & Lessons
Failure Modes
- Check the Child DOX Index here against the actual subfolder list before relying on it — a new durable subfolder with no row here is invisible to the DOX reader.
- Check that single-file utility folders (
storage/,validation/,onboarding/,icons/) are still owned from this root before adding a child doc — promoting too early fragments contracts that fit a single Ownership bullet.
Lessons Learned
- Add a child doc only when a folder grows its own contracts/workflow/quality standards; the parent's Ownership row stays the cheaper home for a single-file folder.
- Do not duplicate the Prisma client or
cn()helper elsewhere —db.tsandutils.tsare intentionally the single owners; reach for an existing subfolder's contract before creating a new top-level module.
Child DOX Index
| Path | Scope |
|---|---|
agent/AGENTS.md |
Agent layer: two engines behind one AgentStreamEvent seam — v3 pi-agent-core tool loop (default) + v2 two-lane fallback — over the shared ScreenDoc/edit-ops/patch moat; event journal, turn diffs, model catalog, chat-input affordances |
agent/v3/AGENTS.md |
The pi-powered engine: runner bridge (event translation, patch draining, heartbeat, abort), settings→pi-ai provider, the 4-tool design toolkit with runtime read-gate, TOOLCELL prompts + full-state conditioning, doc lint |
canvas/AGENTS.md |
Canvas state: Zustand store, types/patches, clipboard, export utilities, gestures hook, Socket.IO service |
llm/AGENTS.md |
LLM provider abstraction: 29 providers (28 named + 1 generic custom), unified LLMClient, registry + factories |
pen/AGENTS.md |
.pen format layer: canonical schema (v2.17), tree resolver, document helpers, converters, Pages abstraction |
design-systems/AGENTS.md |
Design-system packs: registry, loader, token export, agent helper (5 packs: shadcn-default, radix-themes, vercel-geist, tailwind-catalyst, mantine-default) |
sessions/AGENTS.md |
Session persistence: Zustand localStorage store + server-sync bridge, fork/restore, sweep/enforce |
settings/AGENTS.md |
Settings store: AppSettings + AgentRunSettings types, defaults, PALETTES |
web/AGENTS.md |
Web search + fetch: 4-provider search chain, 3-backend fetch pipeline, quality gates |
icons/AGENTS.md |
Lucide icon library runtime: registry + index helpers (generated catalog + semantic search) |