Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions agents/designer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# @corbits/code-agent-designer

## What this is

Ready `@corbits/code-agent-designer` agent + independently importable components:
`agent`, `defineAgent`, `director`, `tools`, `systemPrompt`, `config`.

## Consume (runLocal)

```ts
import { agent } from "@corbits/code-agent-designer";
const run = runLocal(defining(agent), env);
```

## Consume (deploy runWorkflow / hub / sidecar)

Hand the same `AgentDefinition` to a workflow — the package never exports a
workflow itself.

## Remix components

```ts
import { director, tools, systemPrompt, config } from "@corbits/code-agent-designer";
defineAgent({ director, ... }); // or swap tools / systemPrompt / config
```

Each of `director`, `tools`, `systemPrompt`, and `config` is a named,
independently importable part.

## Single authority

`prompt.ts` `systemPrompt.build()` is byte-stable (the raw card, no formatting).
`toolset.ts` `tools` literal equals the `REVIEW_TOOLS` surface constant in
`src/agent/directors/tool-sets.ts`; drift is enforced by the in-tree drift-guard
`src/agent/directors/designer/package.test.ts`.
13 changes: 13 additions & 0 deletions agents/designer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@corbits/code-agent-designer",
"version": "0.1.0",
"private": true,
"type": "module",
"license": "SEE LICENSE IN LICENSE.md",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
}
}
}
17 changes: 17 additions & 0 deletions agents/designer/src/agent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {
defineAgent as coreDefineAgent,
type AgentDefinition,
} from "@intx/agent";
import { systemPrompt } from "./prompt.js";

export const agent: AgentDefinition = defineAgent();

export function defineAgent(): AgentDefinition {
return coreDefineAgent({
id: "designer",
systemPrompt: systemPrompt.build(),
tools: [], // tool mounting is consumer/app-side; surface enforced by drift-guard
capabilities: [],
inference: { sources: [] },
});
}
9 changes: 9 additions & 0 deletions agents/designer/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const config = {
spawn: { maySpawn: false },
tier: "leaf",
modelRole: "implement",
} as const satisfies {
spawn: { maySpawn: boolean };
tier: string;
modelRole: string;
};
22 changes: 22 additions & 0 deletions agents/designer/src/director.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { tools } from "./toolset.js";
import { systemPrompt } from "./prompt.js";
import { config } from "./config.js";

export const director = {
id: "designer",
primaryIntent:
"Own DESIGN.md create/use, design tokens, UI styling, and impeccable.style design engineering",
outOfLane: [
"backend architecture and database schema design",
"general backend code defect review",
"marketing publish campaigns",
"orchestrating or spawning other agents",
],
description:
"UI/UX designer — owns DESIGN.md, impeccable style design laws, tokens, and interface polish",
systemPrompt: systemPrompt.build(),
tools: { allow: [...tools] },
spawn: config.spawn,
tier: config.tier,
modelRole: config.modelRole,
} as const;
5 changes: 5 additions & 0 deletions agents/designer/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { agent, defineAgent } from "./agent.js";
export { director } from "./director.js";
export { tools } from "./toolset.js";
export { systemPrompt } from "./prompt.js";
export { config } from "./config.js";
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
import type { DirectorPackage } from "../types.js";
import { BUILD_TOOLS } from "../tool-sets.js";

/**
* Designer worker: UI/UX design engineering specialist.
* Owns DESIGN.md creation and updates, impeccable.style design laws,
* design tokens, typography, spatial layout, and micro-interaction polish.
*/
export const designerPackage: DirectorPackage = {
id: "designer",
primaryIntent:
"Own DESIGN.md create/use, design tokens, UI styling, and impeccable.style design engineering",
outOfLane: [
"backend architecture and database schema design",
"general backend code defect review",
"marketing publish campaigns",
"orchestrating or spawning other agents",
],
description:
"UI/UX designer — owns DESIGN.md, impeccable style design laws, tokens, and interface polish",
tools: { allow: BUILD_TOOLS },
spawn: { maySpawn: false },
tier: "leaf",
modelRole: "implement",
systemPrompt: `You are DesignerDirector (Designer), a specialist in Corbits Code.
// Designer card. Byte-stable build, single prompt authority.
const CARD = `You are DesignerDirector (Designer), a specialist in Corbits Code.

PRIMARY INTENT: own interface design, design tokens, styling, and DESIGN.md. You bring design engineering excellence to UI surfaces — layout rhythm, typography, purposeful motion, responsive states, and cohesive design systems.

Expand All @@ -44,5 +21,11 @@ Workflow:
3. Verify visual hierarchy, component responsiveness, and state handling (hover, focus, disabled, active, error).
4. Report changes with Summary / Findings / Blockers / Paths.

OUT OF LANE: backend business logic or database migrations, general backend defect review, marketing content pipelines, fleet orchestration.`,
OUT OF LANE: backend business logic or database migrations, general backend defect review, marketing content pipelines, fleet orchestration.`;

export const theme = "designer";

export const systemPrompt = {
theme,
build: (): string => CARD,
};
17 changes: 17 additions & 0 deletions agents/designer/src/toolset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// BUILD_TOOLS literal (= REVIEW_TOOLS); drift-guarded against REVIEW_TOOLS
// by src/agent/directors/designer/package.test.ts.
export const tools = [
"read_file",
"grep",
"search_files",
"list_dir",
"lsp",
"run_shell",
"web_fetch",
"web_search",
"skill_search",
"use_skill",
"write_file",
"edit_file",
"delete_file",
] as const;
7 changes: 7 additions & 0 deletions agents/designer/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"noEmit": true
},
"include": ["src/**/*.ts"]
}
5 changes: 5 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@
"@modelcontextprotocol/sdk": "^1.29.0",
"@opentui/core": "0.5.12",
"arktype": "catalog:",
"isomorphic-git": "catalog:"
"isomorphic-git": "catalog:",
"@corbits/code-agent-designer": "workspace:*"
},
"devDependencies": {
"@intx/inference-testing": "0.3.0",
Expand Down
8 changes: 8 additions & 0 deletions scripts/dead-export-allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ agents/warden/src/index.ts: agent
agents/warden/src/index.ts: defineAgent
agents/warden/src/config.ts: satisfies
agents/warden/src/config.ts: boolean
agents/designer/src/index.ts: agent
agents/designer/src/index.ts: defineAgent
agents/designer/src/index.ts: director
agents/designer/src/index.ts: tools
agents/designer/src/index.ts: systemPrompt
agents/designer/src/index.ts: config
agents/designer/src/config.ts: satisfies
agents/designer/src/config.ts: boolean

# Versioned prompt-variance package public surface (CL-8269 lane,
# agent-owned). Family rows data re-exported through the package entry point;
Expand Down
49 changes: 49 additions & 0 deletions src/agent/directors/designer/package.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { describe, expect, test } from "bun:test";

import {
director,
tools,
config,
systemPrompt,
} from "@corbits/code-agent-designer";
import { REVIEW_TOOLS } from "../tool-sets.js";
import { DIRECTOR_REGISTRY } from "../registry.js";
import type { DirectorPackage } from "../types.js";

describe("designerPackage", () => {
test("workspace package satisfies the director contract and feeds the registry", () => {
const asDirector: DirectorPackage = director;
expect(asDirector.id).toBe("designer");
expect(DIRECTOR_REGISTRY.designer).toBe(director);
expect([...director.tools.allow]).toEqual([...REVIEW_TOOLS]);
expect(new Set(director.tools.allow).size).toBe(
director.tools.allow.length,
);
});

test("spawn/tier/modelRole match config", () => {
expect(director.spawn).toEqual(config.spawn);
expect(director.tier).toBe(config.tier);
expect(director.modelRole).toBe(config.modelRole);
expect(director.spawn.maySpawn).toBe(false);
expect(director.tier).toBe("leaf");
expect(director.modelRole).toBe("implement");
});

test("prompt authority is byte-stable", () => {
expect(director.systemPrompt).toBe(systemPrompt.build());
expect(systemPrompt.build()).toBe(systemPrompt.build());
});

test("tools surface matches REVIEW_TOOLS and is leaf-scoped", () => {
expect([...tools]).toEqual([...REVIEW_TOOLS]);
expect(tools).not.toContain("spawn_agent");
expect(tools).not.toContain("ask_operator");
expect(tools).not.toContain("wait_agents");
expect(tools).not.toContain("search_agents");
});

test("tools allowlist has no duplicates", () => {
expect(new Set([...tools]).size).toBe(tools.length);
});
});
4 changes: 2 additions & 2 deletions src/agent/directors/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { director as shakespeareDirector } from "@corbits/code-agent-shakespeare
import { director as proberDirector } from "@corbits/code-agent-prober";
import { director as dispatchDirector } from "@corbits/code-agent-dispatch";
import { director as wardenDirector } from "@corbits/code-agent-warden";
import { director as designerDirector } from "@corbits/code-agent-designer";
import type { AgentProfile, CapabilityFilter } from "../profile-types.js";
import { director as artistDirector } from "@corbits/code-agent-artist";
import { coderPackage } from "./coder/package.js";
import { designerPackage } from "./designer/package.js";
import { explorerPackage } from "./explorer/package.js";
import { plannerPackage } from "./planner/package.js";
import { qaLeadPackage } from "./qa-lead/package.js";
Expand Down Expand Up @@ -42,7 +42,7 @@ export const DIRECTOR_REGISTRY: Readonly<Record<DirectorId, DirectorPackage>> =
planner: plannerPackage,
coder: coderPackage,
reviewer: reviewerPackage,
designer: designerPackage,
designer: designerDirector,
artist: artistDirector,
warden: wardenDirector,
shakespeare: shakespeareDirector,
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"@corbits/code-agent-prober": ["./agents/prober/src/index.ts"],
"@corbits/code-agent-dispatch": ["./agents/dispatch/src/index.ts"],
"@corbits/code-agent-warden": ["./agents/warden/src/index.ts"],
"@corbits/agent-designer": ["./agents/designer/src/index.ts"],
"@corbits/provider-opencode-go": ["./packages/opencode-go/src/index.ts"],
"@corbits/first-class-providers": [
"./packages/first-class-providers/src/index.ts"
Expand Down
Loading