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/artist/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# @corbits/code-agent-artist

## What this is

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

## Consume (runLocal)

```ts
import { agent } from "@corbits/code-agent-artist";
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-artist";
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/artist/package.test.ts`.
13 changes: 13 additions & 0 deletions agents/artist/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@corbits/code-agent-artist",
"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/artist/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: "artist",
systemPrompt: systemPrompt.build(),
tools: [],
capabilities: [],
inference: { sources: [] },
});
}
9 changes: 9 additions & 0 deletions agents/artist/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;
};
21 changes: 21 additions & 0 deletions agents/artist/src/director.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { tools } from "./toolset.js";
import { systemPrompt } from "./prompt.js";
import { config } from "./config.js";

export const director = {
id: "artist",
primaryIntent:
"Author hand-crafted SVGs, visual diagrams, and generative graphic prompts",
outOfLane: [
"backend or core product implementation",
"code defect review or testing",
"fleet orchestration or spawning",
],
description:
"Visual asset specialist — SVGs, visual diagrams, and generative graphic prompts",
systemPrompt: systemPrompt.build(),
tools: { allow: [...tools] },
spawn: config.spawn,
tier: config.tier,
modelRole: config.modelRole,
} as const;
5 changes: 5 additions & 0 deletions agents/artist/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,27 +1,6 @@
import type { DirectorPackage } from "../types.js";
import { BUILD_TOOLS } from "../tool-sets.js";
// The app formats the identity header via formatDirectorSystemPrompt.

/**
* Artist worker: visual asset specialist.
* Hand-crafts SVGs, visual diagrams (Mermaid, ASCII art), and structured
* generative graphic prompts for image generation models.
*/
export const artistPackage: DirectorPackage = {
id: "artist",
primaryIntent:
"Author hand-crafted SVGs, visual diagrams, and generative graphic prompts",
outOfLane: [
"backend or core product implementation",
"code defect review or testing",
"fleet orchestration or spawning",
],
description:
"Visual asset specialist — SVGs, visual diagrams, and generative graphic prompts",
tools: { allow: BUILD_TOOLS },
spawn: { maySpawn: false },
tier: "leaf",
modelRole: "implement",
systemPrompt: `You are ArtistDirector (Artist), a specialist in Corbits Code.
const CARD = `You are ArtistDirector (Artist), a specialist in Corbits Code.

PRIMARY INTENT: create visual assets — clean vector SVGs, technical and architectural diagrams, and structured generative image prompts.

Expand All @@ -48,5 +27,9 @@ Workflow:
3. Validate vector validity (well-formed XML for SVGs, valid syntax for Mermaid).
4. Report completed visual deliverables under Summary / Findings / Blockers / Paths.

OUT OF LANE: non-visual code implementation, backend logic, code defect review, fleet orchestration.`,
OUT OF LANE: non-visual code implementation, backend logic, code defect review, fleet orchestration.`;

export const systemPrompt = {
theme: "artist",
build: (): string => CARD,
};
15 changes: 15 additions & 0 deletions agents/artist/src/toolset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const tools: readonly string[] = [
"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/artist/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"]
}
6 changes: 6 additions & 0 deletions bun.lock

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

10 changes: 10 additions & 0 deletions scripts/dead-export-allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,13 @@ packages/prompt-variance/src/index.ts: FAMILY_IDS
packages/prompt-variance/src/index.ts: FAMILY_ROWS
packages/prompt-variance/src/index.ts: PromptVarianceFamily
packages/prompt-variance/src/index.ts: PromptVarianceRow

# Agent-package public API (CL-9800 extraction wave): each @corbits/code-agent-*
# workspace package's public surface (agent/defineAgent + the config card) is
# consumed by the app registry/barrel once the fleet merges; on a per-extract
# branch they have no in-repo consumer yet. Public API by design — owned by the
# agent-template lane; remove with the code if the package is deleted.
agents/artist/src/index.ts: agent
agents/artist/src/index.ts: defineAgent
agents/artist/src/config.ts: satisfies
agents/artist/src/config.ts: boolean
47 changes: 47 additions & 0 deletions src/agent/directors/artist/package.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { describe, expect, test } from "bun:test";

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

describe("artistPackage", () => {
test("workspace package satisfies the director contract and feeds the registry", () => {
const asDirector: DirectorPackage = director;
expect(asDirector.id).toBe("artist");
expect(DIRECTOR_REGISTRY.artist).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);
});

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

test("tools surface matches the tool-sets constant 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
@@ -1,5 +1,5 @@
import type { AgentProfile, CapabilityFilter } from "../profile-types.js";
import { artistPackage } from "./artist/package.js";
import { director as artistDirector } from "@corbits/code-agent-artist";
import { coderPackage } from "./coder/package.js";
import { designerPackage } from "./designer/package.js";
import { dispatchPackage } from "./dispatch/package.js";
Expand Down Expand Up @@ -43,7 +43,7 @@ export const DIRECTOR_REGISTRY: Readonly<Record<DirectorId, DirectorPackage>> =
coder: coderPackage,
reviewer: reviewerPackage,
designer: designerPackage,
artist: artistPackage,
artist: artistDirector,
warden: wardenPackage,
shakespeare: shakespearePackage,
prober: proberPackage,
Expand Down
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"composite": false,
"baseUrl": ".",
"paths": {
"@corbits/code-agent-artist": ["./agents/artist/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 All @@ -19,7 +20,8 @@
"packages/**/*.ts",
"e2e/**/*.ts",
"evals/**/*.ts",
"scripts/**/*.ts"
"scripts/**/*.ts",
"agents/**/*.ts"
],
// Excluded: hermetic sandbox repos for the capability eval suite, not real
// application code. They own their own package.json and are copied into
Expand Down
Loading