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

## What this is

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

## Consume (runLocal)

```ts
import { agent } from "@corbits/code-agent-shakespeare";
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-shakespeare";
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 `DOCS_TOOLS` surface constant in
`src/agent/directors/tool-sets.ts` (no `run_shell`); drift is enforced by the
in-tree drift-guard `src/agent/directors/shakespeare/package.test.ts`.
13 changes: 13 additions & 0 deletions agents/shakespeare/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@corbits/code-agent-shakespeare",
"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/shakespeare/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: "shakespeare",
systemPrompt: systemPrompt.build(),
tools: [],
capabilities: [],
inference: { sources: [] },
});
}
9 changes: 9 additions & 0 deletions agents/shakespeare/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: "docs",
} as const satisfies {
spawn: { maySpawn: boolean };
tier: string;
modelRole: string;
};
20 changes: 20 additions & 0 deletions agents/shakespeare/src/director.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { tools } from "./toolset.js";
import { systemPrompt } from "./prompt.js";
import { config } from "./config.js";

export const director = {
id: "shakespeare",
primaryIntent: "Maintain product, architecture, and implementation docs",
outOfLane: [
"shipping product features",
"pure code review",
"orchestration / fleet control",
"acting as reviewer or implementer",
],
description: "Docs maintenance — PRODUCT / ARCHITECTURE / IMPLEMENTATION",
systemPrompt: systemPrompt.build(),
tools: { allow: [...tools] },
spawn: config.spawn,
tier: config.tier,
modelRole: config.modelRole,
} as const;
5 changes: 5 additions & 0 deletions agents/shakespeare/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,22 +1,6 @@
import type { DirectorPackage } from "../types.js";
import { DOCS_TOOLS } from "../tool-sets.js";

/**
* Shakespeare worker (CL-7029).
* Docs maintenance — PRODUCT / ARCHITECTURE / IMPLEMENTATION only; docs core baked in.
* Package id/path stays `shakespeare` (global rename is out of scope).
*/
export const shakespearePackage: DirectorPackage = {
id: "shakespeare",
primaryIntent: "Maintain product, architecture, and implementation docs",
outOfLane: [
"shipping product features",
"pure code review",
"orchestration / fleet control",
"acting as reviewer or implementer",
],
description: "Docs maintenance — PRODUCT / ARCHITECTURE / IMPLEMENTATION",
systemPrompt: `You are ShakespeareDirector (Shakespeare), a specialist in Corbits Code.
// The app formats the identity header via formatDirectorSystemPrompt.

const CARD = `You are ShakespeareDirector (Shakespeare), a specialist in Corbits Code.

PRIMARY INTENT: maintain PRODUCT.md, ARCHITECTURE.md, and IMPLEMENTATION.md. Route input to the correct doc, detect gaps, surface questions for completeness, and keep cross-doc consistency. You are the docs lane only — not Coder, not Reviewer, not an orchestrator.

Expand Down Expand Up @@ -72,9 +56,9 @@ Confirm what changed and where. Summarize consistency/gap follow-ups. Map each s

DONE GATE: Stop when every success_criteria item from the brief is met OR explicitly blocked under Blockers. Do not invent architecture campaigns or expand the brief after criteria are satisfied. If the ask needs product code, review, or brand/DESIGN.md, report Blockers — do not become Coder, Reviewer, or Designer.

OUT OF LANE: shipping product features, pure code review, orchestration, treating docs as optional, DESIGN.md ownership, becoming Coder or Reviewer as primary.`,
tools: { allow: DOCS_TOOLS },
spawn: { maySpawn: false },
tier: "leaf",
modelRole: "docs",
OUT OF LANE: shipping product features, pure code review, orchestration, treating docs as optional, DESIGN.md ownership, becoming Coder or Reviewer as primary.`;

export const systemPrompt = {
theme: "shakespeare",
build: (): string => CARD,
};
14 changes: 14 additions & 0 deletions agents/shakespeare/src/toolset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const tools: readonly string[] = [
"read_file",
"grep",
"search_files",
"list_dir",
"lsp",
"web_fetch",
"web_search",
"skill_search",
"use_skill",
"write_file",
"edit_file",
"delete_file",
] as const;
7 changes: 7 additions & 0 deletions agents/shakespeare/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"]
}
4 changes: 4 additions & 0 deletions bun.lock

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

4 changes: 4 additions & 0 deletions scripts/dead-export-allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@ agents/artist/src/index.ts: agent
agents/artist/src/index.ts: defineAgent
agents/artist/src/config.ts: satisfies
agents/artist/src/config.ts: boolean
agents/shakespeare/src/index.ts: agent
agents/shakespeare/src/index.ts: defineAgent
agents/shakespeare/src/config.ts: satisfies
agents/shakespeare/src/config.ts: boolean
4 changes: 2 additions & 2 deletions src/agent/directors/registry.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { director as shakespeareDirector } from "@corbits/code-agent-shakespeare";
import type { AgentProfile, CapabilityFilter } from "../profile-types.js";
import { director as artistDirector } from "@corbits/code-agent-artist";
import { coderPackage } from "./coder/package.js";
Expand All @@ -8,7 +9,6 @@ import { plannerPackage } from "./planner/package.js";
import { proberPackage } from "./prober/package.js";
import { qaLeadPackage } from "./qa-lead/package.js";
import { reviewerPackage } from "./reviewer/package.js";
import { shakespearePackage } from "./shakespeare/package.js";
import { wardenPackage } from "./warden/package.js";
import { formatDirectorSystemPrompt } from "./identity.js";
import {
Expand Down Expand Up @@ -45,7 +45,7 @@ export const DIRECTOR_REGISTRY: Readonly<Record<DirectorId, DirectorPackage>> =
designer: designerPackage,
artist: artistDirector,
warden: wardenPackage,
shakespeare: shakespearePackage,
shakespeare: shakespeareDirector,
prober: proberPackage,
"qa-lead": qaLeadPackage,
};
Expand Down
48 changes: 48 additions & 0 deletions src/agent/directors/shakespeare/package.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { describe, expect, test } from "bun:test";

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

describe("shakespearePackage", () => {
test("workspace package satisfies the director contract and feeds the registry", () => {
const asDirector: DirectorPackage = director;
expect(asDirector.id).toBe("shakespeare");
expect(DIRECTOR_REGISTRY.shakespeare).toBe(director);
expect([...director.tools.allow]).toEqual([...DOCS_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("docs surface omits run_shell and stays leaf-scoped", () => {
expect([...tools]).toEqual([...DOCS_TOOLS]);
expect(tools).not.toContain("run_shell");
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);
});
});
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"baseUrl": ".",
"paths": {
"@corbits/code-agent-artist": ["./agents/artist/src/index.ts"],
"@corbits/code-agent-shakespeare": ["./agents/shakespeare/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