@nightowlsdev/agent-designer
Pre-built agentsDesign directions you choose from: proposes 2-3 named approaches via the ask tool, then applies the chosen one from an 18-skill curated design library read on demand, impeccable, ui-ux-pro-max, the taste-skill family.
What it does
@nightowlsdev/agent-designer solves 'give the design agent ALL the skills' without prompt explosion: a small taste core (design-taste-frontend, Vercel web-design-guidelines) is always granted, and the full curated library, Anthropic frontend-design/canvas-design/brand-guidelines, ui-ux-pro-max, the taste-skill family (high-end, minimalist, brutalist, brandkit, redesign), the impeccable family (impeccable, critique, audit, typeset, layout), extract-design-system, design-an-interface, rides the kit's skill_library_list/read tools: held at ~zero prompt cost, read on demand as fenced third-party reference, scoped to the curated names (never whole-tenant). The flow is human-in-the-loop by design: interrogate the project's goal, survey the library, propose 2-3 NAMED approaches with trade-offs via the built-in ask tool, and only after the human picks, read that approach's skills and deliver a complete design direction, typography, color, spacing, per-section wireframes, component inventory, and the five don'ts that would break it. Structured text out; no image generation, no code emission.
Install
pnpm add @nightowlsdev/agent-designerKey exports
- createDesigner ({ skillLibrary?: SkillRepo, libraryNames? })
- manifest / DESIGNER_CURATED_SKILLS (18 pinned refs: taste core + approach library)
- DESIGNER_PERSONA (interrogate → propose via ask → read on demand → layout spec)
Usage
import { createDesigner, manifest } from "@nightowlsdev/agent-designer";
import { importCuratedSkills, PREBUILT_READONLY_TOOL_NAMES } from "@nightowlsdev/agent-kit";
import { materializeSkillStore, skillsShProvider } from "@nightowlsdev/skills";
import { defineSwarm, DEFAULT_READ_ONLY_TOOLS } from "@nightowlsdev/core";
// 1. Import the 18-skill design library once per tenant (impeccable, ui-ux-pro-max, taste-skill…).
await importCuratedSkills({ sets: manifest.curatedSkills, providers: { "skills.sh": skillsShProvider() }, storage, tenantId, actor });
// 2. The designer holds the library at ~zero prompt cost (skill_library_list/read, fenced,
// curated-scoped), proposes 2-3 named approaches via the ask tool, and applies the pick.
const designer = createDesigner({ skillLibrary: storage.skills });
const swarm = defineSwarm({
storage,
agents: [designer],
dynamicSkills: materializeSkillStore(storage.skills), // the always-on taste core injects via grants
models: { allow: ["openai/gpt-5.5-mini"], tier: { tiers: { swift: "openai/gpt-5.5-mini" } } },
modelFactory,
cost: { maxSteps: 30, maxCostUsd: 0.5 },
// strict hosts: allowlist the read-only library tools so reads don't suspend
toolApproval: { mode: "all-side-effecting", readOnly: [...DEFAULT_READ_ONLY_TOOLS, ...PREBUILT_READONLY_TOOL_NAMES] },
});
// The full journey: /docs/adopt-prebuilt-agentsWhat it provides
agent-designer is a pre-built design agent that proposes 2–3 NAMED directions (with trade-offs) you choose from, then delivers a complete layout spec — typography, color, spacing, per-section wireframes, component inventory, and the don'ts that would break it. It solves 'give the design agent ALL the skills' without prompt explosion: a small taste core is always granted, and the full 18-skill curated library (impeccable, ui-ux-pro-max, the taste-skill family, Anthropic + Vercel design skills) is read on demand through the kit's progressive-disclosure tools.
When to use it
- You want structured design direction and layout specs, human-in-the-loop — the agent proposes named approaches and waits for a pick.
- You want a large curated design library available without paying its full prompt cost on every turn.
- You want usable taste even without a store — the always-granted taste core runs standalone.
When not to
- You want generated images or emitted code — the designer outputs structured text only.
- You want a one-shot answer with no approach-selection step — the flow is deliberately human-in-the-loop.
- You haven't imported the library and expect all 18 skills — without a SkillRepo it runs on the taste core only (and says so).
Alternatives
- A hand-authored agent granted one design skillYou want a single fixed design skill inline, with no approach-proposal flow and no on-demand library.
- agent-writerYou need the words for the approved direction, not the visual design — the designer produces layout, the writer produces copy.
Strengths
- Progressive disclosure: the 18-skill library is held at ~zero prompt cost via skill_library_list / skill_library_read and read on demand as fenced third-party reference, scoped to the curated names (never whole-tenant).
- Human-in-the-loop by design: interrogate the goal → survey the library → propose 2–3 NAMED approaches with trade-offs via the built-in ask tool → read only the picked approach's skills (2–3 reads) → deliver the direction.
- Degrades honestly: without a SkillRepo it runs on the always-granted taste core and says so; an empty library yields a legible message naming importCuratedSkills, never silent pretending.
- Curated-scoped by default: the library tools attach only with a SkillRepo and default to this package's curated names.
Limits & trade-offs
- Structured text only — no image generation, no code emission. It specifies; it doesn't render.
- The full library needs the per-tenant import (importCuratedSkills) PLUS a SkillRepo passed as skillLibrary — without it you get the taste core, not the 18 skills.
- Tag-driven approach sets aren't in v1 — the refs carry approach:* / craft:* tags but the library tools filter by name only.
- Strict-approval hosts must allowlist the read-only library tools (toolApproval.readOnly) or on-demand reads suspend.
How it works
createDesigner({ skillLibrary?, libraryNames? }) attaches skillLibraryTools only when you pass a SkillRepo, scoped to libraryNames (default: this package's curated names). The persona always carries the taste core as default grants, so the agent has taste even with no library. In a run it interrogates the goal, lists the library (skill_library_list), proposes named approaches via the built-in ask tool, and after the human picks reads just that approach's skills (skill_library_read, fenced) before emitting the layout spec. You import the curated library once per tenant with importCuratedSkills.
Examples
Designer over the imported library
Import the 18-skill library once per tenant; then hold it at ~zero prompt cost.
import { createDesigner, manifest } from "@nightowlsdev/agent-designer";
import { importCuratedSkills } from "@nightowlsdev/agent-kit";
import { skillsShProvider } from "@nightowlsdev/skills";
await importCuratedSkills({ sets: manifest.curatedSkills, providers: { "skills.sh": skillsShProvider() }, storage, tenantId, actor });
const designer = createDesigner({ skillLibrary: storage.skills });Standalone taste core (no store)
Without skillLibrary it runs on the always-granted taste core and its persona says so.
import { createDesigner } from "@nightowlsdev/agent-designer";
const designer = createDesigner();Strict-host approval wiring
Allowlist the read-only library tools so on-demand reads don't suspend.
import { createDesigner } from "@nightowlsdev/agent-designer";
import { PREBUILT_READONLY_TOOL_NAMES } from "@nightowlsdev/agent-kit";
import { defineSwarm, DEFAULT_READ_ONLY_TOOLS } from "@nightowlsdev/core";
const swarm = defineSwarm({
storage,
agents: [createDesigner({ skillLibrary: storage.skills })],
toolApproval: { mode: "all-side-effecting", readOnly: [...DEFAULT_READ_ONLY_TOOLS, ...PREBUILT_READONLY_TOOL_NAMES] },
// …models, modelFactory, dynamicSkills
});Doing the parts it doesn't support
- Generating images or codeThe designer emits structured text (specs). Wire your own image/codegen tool as an extra skill via extraSkills, or hand the spec to a separate codegen agent.
- Scoping the library by tag/approachv1 filters by name. Pass libraryNames with the subset you want in scope, or build the name list from the manifest's refs.
- Skipping the approach-selection stepThe flow is human-in-the-loop by design. If you want a direct answer, prompt the agent to pick and proceed — but the value is in the named-approach trade-off it surfaces first.
Related
- agent-kit — skillLibraryTools + importCuratedSkills — the progressive-disclosure machinery the designer rides.
- skills — The SkillRepo the library is read from and the materializeSkillStore that injects the taste core.
- approval-modes — Why the read-only library tools go on toolApproval.readOnly so reads don't suspend.
- agent-writer — Copy for the approved design direction.
- adopt-prebuilt-agents — The full four-step host-wiring journey.