open-xmen 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -2
- package/dist/agents/cerebro.d.ts +12 -0
- package/dist/agents/cerebro.js +112 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/index.js +18 -0
- package/dist/agents/markdown.d.ts +6 -0
- package/dist/agents/markdown.js +27 -0
- package/dist/agents/team.d.ts +45 -0
- package/dist/agents/team.js +255 -0
- package/dist/agents/types.d.ts +30 -0
- package/dist/agents/types.js +12 -0
- package/dist/cli/config.d.ts +6 -0
- package/dist/cli/config.js +228 -0
- package/dist/cli/doctor.d.ts +8 -0
- package/dist/cli/doctor.js +48 -0
- package/dist/cli/runtime.d.ts +7 -0
- package/dist/cli/runtime.js +94 -0
- package/dist/cli.js +72 -430
- package/dist/commands/definitions.d.ts +11 -0
- package/dist/commands/definitions.js +123 -0
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.js +1 -0
- package/dist/config/models.d.ts +8 -0
- package/dist/config/models.js +8 -0
- package/dist/council/index.d.ts +2 -0
- package/dist/council/index.js +2 -0
- package/dist/index.js +41 -64
- package/dist/runtime/definitions.d.ts +6 -0
- package/dist/runtime/definitions.js +5 -0
- package/dist/runtime/generated-assets.d.ts +5 -0
- package/dist/runtime/generated-assets.js +2425 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.js +12 -0
- package/dist/utils/session.d.ts +2 -0
- package/dist/utils/session.js +5 -0
- package/package.json +4 -14
- package/.cerebro/.gitignore +0 -27
- package/.cerebro/cerebro-identity.md +0 -76
- package/.cerebro/docs/agent-mapping.md +0 -54
- package/.cerebro/docs/cerebro-workflow.md +0 -115
- package/.cerebro/docs/orchestration.md +0 -28
- package/.cerebro/docs/overview.md +0 -44
- package/.cerebro/docs/skill-policy.md +0 -25
- package/.cerebro/integrations/semble.md +0 -30
- package/.cerebro/opencode/model-routing.md +0 -37
- package/.cerebro/schemas/boulder.schema.json +0 -143
- package/.cerebro/schemas/team-run.schema.json +0 -234
- package/.cerebro/schemas/upgrade-manifest.schema.json +0 -45
- package/.cerebro/schemas/upgrade-state.schema.json +0 -38
- package/.cerebro/scripts/check-agent-teams-enabled.py +0 -24
- package/.cerebro/scripts/ensure-upgrade-cache-gitignored.py +0 -27
- package/.cerebro/scripts/fetch-upstream-ref.py +0 -67
- package/.cerebro/scripts/reset-runtime.py +0 -125
- package/.cerebro/scripts/setup-status.py +0 -101
- package/.cerebro/scripts/test-stop-hook.py +0 -60
- package/.cerebro/scripts/upgrade-latest-tag.py +0 -34
- package/.cerebro/scripts/validate-agent-frontmatter.py +0 -87
- package/.cerebro/scripts/validate-boulder.py +0 -105
- package/.cerebro/scripts/validate-opencode-runtime.py +0 -94
- package/.cerebro/scripts/validate-team-runs.py +0 -310
- package/.cerebro/scripts/validate-upgrade-metadata.py +0 -104
- package/.cerebro/scripts/write-upgrade-state.py +0 -93
- package/.cerebro/templates/customer-vision.md +0 -58
- package/.cerebro/templates/plan.md +0 -35
- package/.cerebro/templates/product-brief.md +0 -110
- package/.cerebro/templates/project-context.md +0 -64
- package/.cerebro/templates/requirements-brief.md +0 -67
- package/.cerebro/templates/team-run.json +0 -22
- package/.cerebro/upgrade-manifest.json +0 -160
- package/.opencode/.gitignore +0 -5
- package/.opencode/agents/beast.md +0 -38
- package/.opencode/agents/cerebro.md +0 -22
- package/.opencode/agents/cyclops.md +0 -22
- package/.opencode/agents/cypher.md +0 -46
- package/.opencode/agents/emma-frost.md +0 -38
- package/.opencode/agents/forge.md +0 -22
- package/.opencode/agents/legion.md +0 -45
- package/.opencode/agents/nightcrawler.md +0 -22
- package/.opencode/agents/professor-x.md +0 -39
- package/.opencode/agents/sage.md +0 -22
- package/.opencode/agents/storm.md +0 -49
- package/.opencode/agents/wolverine.md +0 -22
- package/.opencode/commands/cerebro-doctor.md +0 -19
- package/.opencode/commands/cerebro-index.md +0 -22
- package/.opencode/commands/cerebro-plan.md +0 -21
- package/.opencode/commands/cerebro-reset.md +0 -20
- package/.opencode/commands/cerebro-start-work.md +0 -20
- package/.opencode/commands/cerebro-upgrade.md +0 -19
- package/.opencode/commands/to-me-my-x-men.md +0 -27
package/README.md
CHANGED
|
@@ -130,7 +130,6 @@ open-xmen models
|
|
|
130
130
|
| `/to-me-my-x-men [task]` | Autonomous full-team mode with Legion + Cypher intent consult and final Legion acceptance. |
|
|
131
131
|
| `/cerebro-doctor` | Validate runtime health. |
|
|
132
132
|
| `/cerebro-reset` | Reset runtime state after confirmation. |
|
|
133
|
-
| `/cerebro-upgrade <ref>` | Gated template sync from an explicit upstream release/ref. |
|
|
134
133
|
|
|
135
134
|
---
|
|
136
135
|
|
|
@@ -180,7 +179,6 @@ npx tsc -p tsconfig.json --noEmit
|
|
|
180
179
|
npm run doctor
|
|
181
180
|
python3 .cerebro/scripts/validate-opencode-runtime.py
|
|
182
181
|
python3 .cerebro/scripts/validate-team-runs.py
|
|
183
|
-
python3 .cerebro/scripts/validate-upgrade-metadata.py
|
|
184
182
|
npm run verify:release
|
|
185
183
|
```
|
|
186
184
|
|
|
@@ -188,6 +186,12 @@ npm run verify:release
|
|
|
188
186
|
|
|
189
187
|
`/cerebro-doctor` runs the same class of checks from inside OpenCode.
|
|
190
188
|
|
|
189
|
+
## Auto-Upgrades
|
|
190
|
+
|
|
191
|
+
When the `open-xmen` plugin loads, it checks the npm registry for the latest package version. If a newer package is available and the plugin is running from a package-managed `node_modules/open-xmen` install, it best-effort updates that package and re-runs `open-xmen install --reset --no-deps` for the current project. Results are written to `.cerebro/auto-upgrade.json`; registry or install failures never block OpenCode startup.
|
|
192
|
+
|
|
193
|
+
Set `OPEN_XMEN_SKIP_AUTO_UPGRADE=1` or `OPEN_XMEN_AUTO_UPGRADE=0` to disable this behavior.
|
|
194
|
+
|
|
191
195
|
## Spark Lane
|
|
192
196
|
|
|
193
197
|
`gpt-5.3-codex-spark` is available as a fast draft lane. Cerebro should use it for instant code generation, boilerplate, test stubs, tiny low-risk diffs, and candidate patches. Full `gpt-5.3-codex` remains the default for Wolverine/Storm final implementation and verification.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type AgentDefinition } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Build the cerebro agent prompt with optional agent filtering.
|
|
4
|
+
* Pass disabledAgents to exclude specific X-Men roles from the routing section.
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildCerebroPrompt(disabledAgents?: Set<string>): string;
|
|
7
|
+
/** @deprecated Use buildCerebroPrompt() instead */
|
|
8
|
+
export declare const CEREBRO_PROMPT: string;
|
|
9
|
+
export declare function createCerebroAgent(model?: string | Array<string | {
|
|
10
|
+
id: string;
|
|
11
|
+
variant?: string;
|
|
12
|
+
}>, customPrompt?: string, customAppendPrompt?: string, disabledAgents?: Set<string>): AgentDefinition;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { resolvePrompt } from "./types.js";
|
|
2
|
+
const AGENT_DESCRIPTIONS = {
|
|
3
|
+
legion: `@legion
|
|
4
|
+
- Role: Customer/product-owner proxy; owns WANT and final acceptance verdicts
|
|
5
|
+
- Write boundary: \`.cerebro/notepads/customer/\` only; no code edits
|
|
6
|
+
- **Delegate when:** Product vision or quality bar unclear • Customer acceptance verdict needed • Demand-side voice required for user stories
|
|
7
|
+
- **Don't delegate when:** Technical or implementation questions • Requirements already established`,
|
|
8
|
+
cypher: `@cypher
|
|
9
|
+
- Role: Business analyst; converts intent into requirements, user stories, and acceptance criteria
|
|
10
|
+
- Write boundary: \`.cerebro/notepads/requirements/\` only; no code edits
|
|
11
|
+
- **Delegate when:** Requirements are vague, conflicted, or product-shaped • Scope must be defined before planning begins
|
|
12
|
+
- **Don't delegate when:** Requirements already clear • Work can proceed directly to planning or implementation`,
|
|
13
|
+
"professor-x": `@professor-x
|
|
14
|
+
- Role: Strategic planner; authors Cerebro plans and product briefs from canonical templates
|
|
15
|
+
- Write boundary: \`.cerebro/notepads/plans/\` (drafts only — Cerebro promotes to \`.cerebro/plans/\`)
|
|
16
|
+
- **Delegate when:** Work is complex, multi-task, or high-risk and needs a structured plan • Product brief needed from requirements
|
|
17
|
+
- **Don't delegate when:** Task is simple or obviously scoped • A clear plan already exists`,
|
|
18
|
+
cyclops: `@cyclops
|
|
19
|
+
- Role: Field coordinator; sequences tasks, assigns owners, independently verifies worker results
|
|
20
|
+
- Write boundary: Runtime state, task ledgers, and notepads
|
|
21
|
+
- **Delegate when:** Parallel execution needs coordination across multiple workers • Worker claims require independent verification
|
|
22
|
+
- **Don't delegate when:** Single-worker tasks • Cerebro can verify directly`,
|
|
23
|
+
wolverine: `@wolverine
|
|
24
|
+
- Role: Implementation specialist for code, tests, scripts, and bug fixes
|
|
25
|
+
- Permissions: Read/write files; maintains task-scoped todos under \`.cerebro/pending-todos/\`
|
|
26
|
+
- **Delegate when:** Code implementation, test writing, bug fixes, or scripts • TDD work • Bounded multi-file implementation
|
|
27
|
+
- **Don't delegate when:** Architecture or discovery work must happen first`,
|
|
28
|
+
storm: `@storm
|
|
29
|
+
- Role: Frontend and visual engineering; UI, accessibility, responsive behavior, and visual polish
|
|
30
|
+
- Permissions: Read/write files; maintains task-scoped todos
|
|
31
|
+
- **Delegate when:** User-facing interfaces • Responsive layouts • Accessibility • Component UX states • Visual polish
|
|
32
|
+
- **Don't delegate when:** Backend-only work • No visual surface involved`,
|
|
33
|
+
forge: `@forge
|
|
34
|
+
- Role: Architecture consultant; system design, tradeoffs, migration strategy — read-only
|
|
35
|
+
- Permissions: Read files only; no edits
|
|
36
|
+
- **Delegate when:** Major architecture decisions • System-level tradeoffs • Migration approach unclear
|
|
37
|
+
- **Don't delegate when:** Routine implementation within established patterns • Simple decisions`,
|
|
38
|
+
nightcrawler: `@nightcrawler
|
|
39
|
+
- Role: Fast read-only codebase scout; file search, symbol discovery, and pattern mapping
|
|
40
|
+
- Permissions: Read files; bash search; no edits
|
|
41
|
+
- Stats: Fast and cheap — prefer for parallel discovery before planning or implementation
|
|
42
|
+
- **Delegate when:** Need to find files, symbols, or patterns • Parallel searches across domains • Discovery needed before implementation
|
|
43
|
+
- **Don't delegate when:** Already know the exact path • Single lookup immediately before editing`,
|
|
44
|
+
sage: `@sage
|
|
45
|
+
- Role: Documentation and ecosystem researcher; official APIs, library behavior, and best practices
|
|
46
|
+
- Permissions: Read files; web fetch allowed; no edits
|
|
47
|
+
- **Delegate when:** Library APIs with frequent changes • Version-specific behavior • External docs needed for correct implementation
|
|
48
|
+
- **Don't delegate when:** Standard usage you're confident about • General programming knowledge`,
|
|
49
|
+
beast: `@beast
|
|
50
|
+
- Role: Gap analyst and plan/code critic — read-only
|
|
51
|
+
- Permissions: Read files only; no edits
|
|
52
|
+
- **Delegate when:** Plan needs gap review before execution • Missing edge cases or weak verification suspected • Code review for correctness or quality
|
|
53
|
+
- **Don't delegate when:** Implementation work • Clear already-reviewed plans`,
|
|
54
|
+
"emma-frost": `@emma-frost
|
|
55
|
+
- Role: Strict validator for high-risk, high-accuracy work — read-only
|
|
56
|
+
- Permissions: Read files only; no edits
|
|
57
|
+
- **Delegate when:** HIGH risk plans or approval gates • Auth, billing, migration, data integrity, or public API work • Final validation before irreversible actions
|
|
58
|
+
- **Don't delegate when:** LOW/MEDIUM risk routine work • Already validated`,
|
|
59
|
+
};
|
|
60
|
+
const CEREBRO_RUNTIME_CONTRACT = `## Cerebro Runtime Contract
|
|
61
|
+
|
|
62
|
+
- Runtime state lives in \`.cerebro/\`.
|
|
63
|
+
- Use Cerebro custom tools for run/task/mailbox/checkpoint state when available.
|
|
64
|
+
- Preserve command names and role names.
|
|
65
|
+
- Do not read \`.env\`, secret, or credential files without explicit user authorization.
|
|
66
|
+
- If assigned implementation or UI work, report with \`TASK_RESULT:\` including \`STATUS:\`, \`FILES CHANGED:\`, \`TESTS RUN:\`, \`VERIFICATION:\`, and \`ISSUES:\`.`;
|
|
67
|
+
/**
|
|
68
|
+
* Build the cerebro agent prompt with optional agent filtering.
|
|
69
|
+
* Pass disabledAgents to exclude specific X-Men roles from the routing section.
|
|
70
|
+
*/
|
|
71
|
+
export function buildCerebroPrompt(disabledAgents) {
|
|
72
|
+
const enabledDescriptions = Object.entries(AGENT_DESCRIPTIONS)
|
|
73
|
+
.filter(([name]) => !disabledAgents?.has(name))
|
|
74
|
+
.map(([, desc]) => desc)
|
|
75
|
+
.join("\n\n");
|
|
76
|
+
return `# cerebro
|
|
77
|
+
|
|
78
|
+
You are Cerebro, central intelligence and team lead. Preserve the cinematic Cerebro voice, but operate through OpenCode-native agents, child sessions, and the Cerebro custom tools. For every non-trivial workflow, create a run with cerebro_run_start, create tasks, route work to named agents, checkpoint durable state, verify pending todos, and synthesize only after verification evidence exists.
|
|
79
|
+
|
|
80
|
+
## Role Routing
|
|
81
|
+
|
|
82
|
+
${enabledDescriptions}
|
|
83
|
+
|
|
84
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
85
|
+
}
|
|
86
|
+
/** @deprecated Use buildCerebroPrompt() instead */
|
|
87
|
+
export const CEREBRO_PROMPT = buildCerebroPrompt();
|
|
88
|
+
export function createCerebroAgent(model, customPrompt, customAppendPrompt, disabledAgents) {
|
|
89
|
+
const basePrompt = buildCerebroPrompt(disabledAgents);
|
|
90
|
+
const prompt = resolvePrompt(basePrompt, customPrompt, customAppendPrompt);
|
|
91
|
+
const definition = {
|
|
92
|
+
name: "cerebro",
|
|
93
|
+
displayName: "Cerebro",
|
|
94
|
+
description: "Cerebro team lead for preserved commands and OpenCode-native orchestration.",
|
|
95
|
+
config: {
|
|
96
|
+
temperature: 0.2,
|
|
97
|
+
prompt,
|
|
98
|
+
},
|
|
99
|
+
opencode: {
|
|
100
|
+
mode: "primary",
|
|
101
|
+
steps: 60,
|
|
102
|
+
permission: { edit: "ask", bash: "ask", webfetch: "ask" },
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
if (Array.isArray(model)) {
|
|
106
|
+
definition._modelArray = model.map((m) => (typeof m === "string" ? { id: m } : m));
|
|
107
|
+
}
|
|
108
|
+
else if (typeof model === "string" && model) {
|
|
109
|
+
definition.config.model = model;
|
|
110
|
+
}
|
|
111
|
+
return definition;
|
|
112
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const CEREBRO_AGENTS: readonly ["cerebro", "legion", "cypher", "professor-x", "cyclops", "wolverine", "storm", "forge", "nightcrawler", "sage", "beast", "emma-frost"];
|
|
2
|
+
export type { AgentDefinition, OpenCodeMeta, OpenCodePermissionLevel } from "./types.js";
|
|
3
|
+
export { resolvePrompt } from "./types.js";
|
|
4
|
+
export { toOpenCodeMarkdown } from "./markdown.js";
|
|
5
|
+
export { buildCerebroPrompt, createCerebroAgent, CEREBRO_PROMPT } from "./cerebro.js";
|
|
6
|
+
export { createLegionAgent, createCypherAgent, createProfessorXAgent, createCyclopsAgent, createWolverineAgent, createStormAgent, createForgeAgent, createNightcrawlerAgent, createSageAgent, createBeastAgent, createEmmaFrostAgent, } from "./team.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const CEREBRO_AGENTS = [
|
|
2
|
+
"cerebro",
|
|
3
|
+
"legion",
|
|
4
|
+
"cypher",
|
|
5
|
+
"professor-x",
|
|
6
|
+
"cyclops",
|
|
7
|
+
"wolverine",
|
|
8
|
+
"storm",
|
|
9
|
+
"forge",
|
|
10
|
+
"nightcrawler",
|
|
11
|
+
"sage",
|
|
12
|
+
"beast",
|
|
13
|
+
"emma-frost",
|
|
14
|
+
];
|
|
15
|
+
export { resolvePrompt } from "./types.js";
|
|
16
|
+
export { toOpenCodeMarkdown } from "./markdown.js";
|
|
17
|
+
export { buildCerebroPrompt, createCerebroAgent, CEREBRO_PROMPT } from "./cerebro.js";
|
|
18
|
+
export { createLegionAgent, createCypherAgent, createProfessorXAgent, createCyclopsAgent, createWolverineAgent, createStormAgent, createForgeAgent, createNightcrawlerAgent, createSageAgent, createBeastAgent, createEmmaFrostAgent, } from "./team.js";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert an AgentDefinition into an OpenCode agent markdown file
|
|
3
|
+
* (YAML frontmatter + prompt body).
|
|
4
|
+
*/
|
|
5
|
+
export function toOpenCodeMarkdown(definition) {
|
|
6
|
+
const { config, description, opencode } = definition;
|
|
7
|
+
const meta = opencode ?? {};
|
|
8
|
+
const lines = ["---"];
|
|
9
|
+
if (description)
|
|
10
|
+
lines.push(`description: ${description}`);
|
|
11
|
+
if (meta.mode)
|
|
12
|
+
lines.push(`mode: ${meta.mode}`);
|
|
13
|
+
if (config.model)
|
|
14
|
+
lines.push(`model: ${config.model}`);
|
|
15
|
+
if (config.temperature !== undefined)
|
|
16
|
+
lines.push(`temperature: ${config.temperature}`);
|
|
17
|
+
if (meta.steps !== undefined)
|
|
18
|
+
lines.push(`steps: ${meta.steps}`);
|
|
19
|
+
if (meta.permission) {
|
|
20
|
+
lines.push("permission:");
|
|
21
|
+
for (const [key, value] of Object.entries(meta.permission)) {
|
|
22
|
+
lines.push(` ${key}: ${value}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
lines.push("---");
|
|
26
|
+
return `${lines.join("\n")}\n${config.prompt ?? ""}`;
|
|
27
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type AgentDefinition } from "./types.js";
|
|
2
|
+
export declare function createLegionAgent(model?: string | Array<string | {
|
|
3
|
+
id: string;
|
|
4
|
+
variant?: string;
|
|
5
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
6
|
+
export declare function createCypherAgent(model?: string | Array<string | {
|
|
7
|
+
id: string;
|
|
8
|
+
variant?: string;
|
|
9
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
10
|
+
export declare function createProfessorXAgent(model?: string | Array<string | {
|
|
11
|
+
id: string;
|
|
12
|
+
variant?: string;
|
|
13
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
14
|
+
export declare function createCyclopsAgent(model?: string | Array<string | {
|
|
15
|
+
id: string;
|
|
16
|
+
variant?: string;
|
|
17
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
18
|
+
export declare function createWolverineAgent(model?: string | Array<string | {
|
|
19
|
+
id: string;
|
|
20
|
+
variant?: string;
|
|
21
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
22
|
+
export declare function createStormAgent(model?: string | Array<string | {
|
|
23
|
+
id: string;
|
|
24
|
+
variant?: string;
|
|
25
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
26
|
+
export declare function createForgeAgent(model?: string | Array<string | {
|
|
27
|
+
id: string;
|
|
28
|
+
variant?: string;
|
|
29
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
30
|
+
export declare function createNightcrawlerAgent(model?: string | Array<string | {
|
|
31
|
+
id: string;
|
|
32
|
+
variant?: string;
|
|
33
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
34
|
+
export declare function createSageAgent(model?: string | Array<string | {
|
|
35
|
+
id: string;
|
|
36
|
+
variant?: string;
|
|
37
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
38
|
+
export declare function createBeastAgent(model?: string | Array<string | {
|
|
39
|
+
id: string;
|
|
40
|
+
variant?: string;
|
|
41
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
42
|
+
export declare function createEmmaFrostAgent(model?: string | Array<string | {
|
|
43
|
+
id: string;
|
|
44
|
+
variant?: string;
|
|
45
|
+
}>, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { resolvePrompt } from "./types.js";
|
|
2
|
+
const CEREBRO_RUNTIME_CONTRACT = `## Cerebro Runtime Contract
|
|
3
|
+
|
|
4
|
+
- Runtime state lives in \`.cerebro/\`.
|
|
5
|
+
- Use Cerebro custom tools for run/task/mailbox/checkpoint state when available.
|
|
6
|
+
- Preserve command names and role names.
|
|
7
|
+
- Do not read \`.env\`, secret, or credential files without explicit user authorization.
|
|
8
|
+
- If assigned implementation or UI work, report with \`TASK_RESULT:\` including \`STATUS:\`, \`FILES CHANGED:\`, \`TESTS RUN:\`, \`VERIFICATION:\`, and \`ISSUES:\`.`;
|
|
9
|
+
const TASK_RESULT_CONTRACT = `## Output Contract
|
|
10
|
+
|
|
11
|
+
Return exactly one final result block:
|
|
12
|
+
|
|
13
|
+
\`\`\`text
|
|
14
|
+
TASK_RESULT:
|
|
15
|
+
STATUS: completed | blocked | failed
|
|
16
|
+
TASK: [task id/name]
|
|
17
|
+
SUMMARY: [what changed]
|
|
18
|
+
FILES CHANGED:
|
|
19
|
+
- [path]
|
|
20
|
+
TESTS RUN:
|
|
21
|
+
- [command or NOT RUN with reason]
|
|
22
|
+
VERIFICATION:
|
|
23
|
+
- [evidence]
|
|
24
|
+
ISSUES:
|
|
25
|
+
- [remaining issue or NONE]
|
|
26
|
+
\`\`\``;
|
|
27
|
+
const DEFAULT_OPENCODE_META = {
|
|
28
|
+
mode: "subagent",
|
|
29
|
+
steps: 60,
|
|
30
|
+
permission: { edit: "ask", bash: "ask", webfetch: "ask" },
|
|
31
|
+
};
|
|
32
|
+
function makeAgent(name, displayName, description, basePrompt, defaultModel, opencode, model, customPrompt, customAppendPrompt) {
|
|
33
|
+
const prompt = resolvePrompt(basePrompt, customPrompt, customAppendPrompt);
|
|
34
|
+
const definition = {
|
|
35
|
+
name,
|
|
36
|
+
displayName,
|
|
37
|
+
description,
|
|
38
|
+
config: { temperature: 0.2, prompt },
|
|
39
|
+
opencode,
|
|
40
|
+
};
|
|
41
|
+
if (Array.isArray(model)) {
|
|
42
|
+
definition._modelArray = model.map((m) => (typeof m === "string" ? { id: m } : m));
|
|
43
|
+
}
|
|
44
|
+
else if (typeof model === "string" && model) {
|
|
45
|
+
definition.config.model = model;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
definition.config.model = defaultModel;
|
|
49
|
+
}
|
|
50
|
+
return definition;
|
|
51
|
+
}
|
|
52
|
+
// ─── Legion ─────────────────────────────────────────────────────────────────
|
|
53
|
+
const LEGION_PROMPT = `# legion
|
|
54
|
+
|
|
55
|
+
You are Legion, the demanding customer proxy. Own WANT and JUDGMENT, not implementation. Produce customer visions and acceptance verdicts under .cerebro/notepads/customer/ when asked. Be concrete, opinionated, and unwilling to accept generic work.
|
|
56
|
+
|
|
57
|
+
## Output Contracts
|
|
58
|
+
|
|
59
|
+
When asked for customer vision, return:
|
|
60
|
+
|
|
61
|
+
\`\`\`text
|
|
62
|
+
CUSTOMER_VISION_READY
|
|
63
|
+
WANT: [plain-language desired outcome]
|
|
64
|
+
QUALITY BAR: [one-line standard that would make the result feel excellent]
|
|
65
|
+
NON-NEGOTIABLES:
|
|
66
|
+
- [must-have]
|
|
67
|
+
ANTI-GOALS:
|
|
68
|
+
- [what would disappoint the customer]
|
|
69
|
+
\`\`\`
|
|
70
|
+
|
|
71
|
+
When asked for acceptance, return:
|
|
72
|
+
|
|
73
|
+
\`\`\`text
|
|
74
|
+
CUSTOMER_VERDICT: ACCEPT | REJECT
|
|
75
|
+
WOULD I USE THIS?: YES | NO
|
|
76
|
+
REASON: [specific demand-side reason]
|
|
77
|
+
NEXT DEMAND: [single most important improvement, or NONE]
|
|
78
|
+
\`\`\`
|
|
79
|
+
|
|
80
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
81
|
+
export function createLegionAgent(model, customPrompt, customAppendPrompt) {
|
|
82
|
+
return makeAgent("legion", "Legion", "Customer/product-owner proxy for opinionated demand-side vision and acceptance.", LEGION_PROMPT, "openai/gpt-5.4", { ...DEFAULT_OPENCODE_META, permission: { edit: "ask", bash: "ask", webfetch: "allow" } }, model, customPrompt, customAppendPrompt);
|
|
83
|
+
}
|
|
84
|
+
// ─── Cypher ─────────────────────────────────────────────────────────────────
|
|
85
|
+
const CYPHER_PROMPT = `# cypher
|
|
86
|
+
|
|
87
|
+
You are Cypher, requirements analyst. Convert Legion/user intent into structured requirements under .cerebro/notepads/requirements/. Own WHAT and WHY, never HOW. Ask only for non-inferable blockers.
|
|
88
|
+
|
|
89
|
+
## Output Contracts
|
|
90
|
+
|
|
91
|
+
If blocked, ask exactly one focused question:
|
|
92
|
+
|
|
93
|
+
\`\`\`text
|
|
94
|
+
CLARIFY
|
|
95
|
+
QUESTION: [one non-inferable blocker]
|
|
96
|
+
WHY IT MATTERS: [decision this unlocks]
|
|
97
|
+
SAFE DEFAULT IF UNANSWERED: [assumption Cerebro can document]
|
|
98
|
+
\`\`\`
|
|
99
|
+
|
|
100
|
+
When ready, return:
|
|
101
|
+
|
|
102
|
+
\`\`\`text
|
|
103
|
+
REQUIREMENTS_READY
|
|
104
|
+
CEREBRO ASSUMPTIONS:
|
|
105
|
+
- [assumption]
|
|
106
|
+
USER STORIES:
|
|
107
|
+
- As a [user], I want [capability], so that [outcome].
|
|
108
|
+
ACCEPTANCE CRITERIA:
|
|
109
|
+
- [testable criterion]
|
|
110
|
+
REQUIREMENTS RULING: READY | NEEDS PLAN | TOO AMBIGUOUS
|
|
111
|
+
\`\`\`
|
|
112
|
+
|
|
113
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
114
|
+
export function createCypherAgent(model, customPrompt, customAppendPrompt) {
|
|
115
|
+
return makeAgent("cypher", "Cypher", "Business analyst turning vague intent into requirements, stories, and acceptance criteria.", CYPHER_PROMPT, "openai/gpt-5.4", DEFAULT_OPENCODE_META, model, customPrompt, customAppendPrompt);
|
|
116
|
+
}
|
|
117
|
+
// ─── Professor X ─────────────────────────────────────────────────────────────
|
|
118
|
+
const PROFESSOR_X_PROMPT = `# professor-x
|
|
119
|
+
|
|
120
|
+
You are Professor X, strategic planner. Draft canonical Cerebro plans using .cerebro/templates/plan.md or product briefs using .cerebro/templates/product-brief.md. Write drafts under .cerebro/notepads/plans/ only; final promotion to .cerebro/plans/ belongs to Cerebro.
|
|
121
|
+
|
|
122
|
+
## Output Contract
|
|
123
|
+
|
|
124
|
+
Return plan drafts in this envelope:
|
|
125
|
+
|
|
126
|
+
\`\`\`text
|
|
127
|
+
PLAN_DRAFT
|
|
128
|
+
FILENAME: .cerebro/notepads/plans/[descriptive-name].md
|
|
129
|
+
SUMMARY: [one paragraph]
|
|
130
|
+
PLAN BODY:
|
|
131
|
+
[full draft using the requested Cerebro template]
|
|
132
|
+
REVIEW_REQUESTS:
|
|
133
|
+
- Beast: [specific gap/ambiguity review]
|
|
134
|
+
- Emma Frost: [specific validation criteria]
|
|
135
|
+
\`\`\`
|
|
136
|
+
|
|
137
|
+
Do not promote drafts into \`.cerebro/plans/\`; Cerebro owns final approval and promotion.
|
|
138
|
+
|
|
139
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
140
|
+
export function createProfessorXAgent(model, customPrompt, customAppendPrompt) {
|
|
141
|
+
return makeAgent("professor-x", "Professor X", "Strategic planner for complex Cerebro plans and product briefs.", PROFESSOR_X_PROMPT, "openai/gpt-5.4", DEFAULT_OPENCODE_META, model, customPrompt, customAppendPrompt);
|
|
142
|
+
}
|
|
143
|
+
// ─── Cyclops ─────────────────────────────────────────────────────────────────
|
|
144
|
+
const CYCLOPS_PROMPT = `# cyclops
|
|
145
|
+
|
|
146
|
+
You are Cyclops, field leader. Sequence tasks, assign owners, demand TASK_RESULT-style evidence from workers, run independent verification, update Cerebro task state, and report blockers. You do not rubber-stamp self-reported success.
|
|
147
|
+
|
|
148
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
149
|
+
export function createCyclopsAgent(model, customPrompt, customAppendPrompt) {
|
|
150
|
+
return makeAgent("cyclops", "Cyclops", "Execution sequencer and verification coordinator.", CYCLOPS_PROMPT, "openai/gpt-5.4", { ...DEFAULT_OPENCODE_META, permission: { edit: "ask", bash: "allow", webfetch: "ask" } }, model, customPrompt, customAppendPrompt);
|
|
151
|
+
}
|
|
152
|
+
// ─── Wolverine ───────────────────────────────────────────────────────────────
|
|
153
|
+
const WOLVERINE_PROMPT = `# wolverine
|
|
154
|
+
|
|
155
|
+
You are Wolverine, implementation specialist. Work one assigned task to completion. Use TDD when practical. Maintain task-scoped todos under .cerebro/pending-todos/{team}/{agent}/{task}.txt and remove them only as completed. Return a TASK_RESULT block with files changed, tests run, verification, and issues.
|
|
156
|
+
|
|
157
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
158
|
+
export function createWolverineAgent(model, customPrompt, customAppendPrompt) {
|
|
159
|
+
return makeAgent("wolverine", "Wolverine", "Implementation worker for code, tests, scripts, and bug fixes.", WOLVERINE_PROMPT, "openai/gpt-5.3-codex", { ...DEFAULT_OPENCODE_META, permission: { edit: "ask", bash: "allow", webfetch: "ask" } }, model, customPrompt, customAppendPrompt);
|
|
160
|
+
}
|
|
161
|
+
// ─── Storm ───────────────────────────────────────────────────────────────────
|
|
162
|
+
const STORM_PROMPT = `# storm
|
|
163
|
+
|
|
164
|
+
You are Storm, frontend and visual engineering specialist. Follow existing UI conventions unless the mission is greenfield. Cover accessibility, loading/error/empty states, responsive behavior, and visual polish. Maintain task-scoped todos and return a TASK_RESULT block.
|
|
165
|
+
|
|
166
|
+
## Storm Guardrails
|
|
167
|
+
|
|
168
|
+
- Follow existing design systems, component APIs, spacing, tokens, and accessibility patterns unless explicitly assigned greenfield work.
|
|
169
|
+
- Maintain a task-scoped todo file under \`.cerebro/pending-todos/{team}/storm/{task-id}.txt\` when running inside a Cerebro task.
|
|
170
|
+
- Do not mark yourself complete until UI behavior, responsiveness, accessibility states, loading/error/empty states, and visual polish have been checked.
|
|
171
|
+
- Never claim browser or visual verification happened unless you actually ran it or inspected captured evidence.
|
|
172
|
+
|
|
173
|
+
${TASK_RESULT_CONTRACT}
|
|
174
|
+
|
|
175
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
176
|
+
export function createStormAgent(model, customPrompt, customAppendPrompt) {
|
|
177
|
+
return makeAgent("storm", "Storm", "Frontend and visual engineering worker for UI, accessibility, and responsive behavior.", STORM_PROMPT, "openai/gpt-5.3-codex", { ...DEFAULT_OPENCODE_META, permission: { edit: "ask", bash: "allow", webfetch: "ask" } }, model, customPrompt, customAppendPrompt);
|
|
178
|
+
}
|
|
179
|
+
// ─── Forge ───────────────────────────────────────────────────────────────────
|
|
180
|
+
const FORGE_PROMPT = `# forge
|
|
181
|
+
|
|
182
|
+
You are Forge, architecture consultant. Stay read-only. Clarify architecture, risks, boundaries, and migration strategy. Give concrete file references and tradeoffs. Do not edit files.
|
|
183
|
+
|
|
184
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
185
|
+
export function createForgeAgent(model, customPrompt, customAppendPrompt) {
|
|
186
|
+
return makeAgent("forge", "Forge", "Architecture consultant for system design and tradeoff review.", FORGE_PROMPT, "openai/gpt-5.4", { ...DEFAULT_OPENCODE_META, permission: { edit: "deny", bash: "ask", webfetch: "ask" } }, model, customPrompt, customAppendPrompt);
|
|
187
|
+
}
|
|
188
|
+
// ─── Nightcrawler ────────────────────────────────────────────────────────────
|
|
189
|
+
const NIGHTCRAWLER_PROMPT = `# nightcrawler
|
|
190
|
+
|
|
191
|
+
You are Nightcrawler, fast codebase scout. Stay read-only. Use glob, grep, read, and shell search to map structure, locate files, and return concise evidence with paths. Do not edit files.
|
|
192
|
+
|
|
193
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
194
|
+
export function createNightcrawlerAgent(model, customPrompt, customAppendPrompt) {
|
|
195
|
+
return makeAgent("nightcrawler", "Nightcrawler", "Fast read-only codebase traversal and pattern discovery specialist.", NIGHTCRAWLER_PROMPT, "openai/gpt-5.4-mini", { ...DEFAULT_OPENCODE_META, permission: { edit: "deny", bash: "allow", webfetch: "deny" } }, model, customPrompt, customAppendPrompt);
|
|
196
|
+
}
|
|
197
|
+
// ─── Sage ────────────────────────────────────────────────────────────────────
|
|
198
|
+
const SAGE_PROMPT = `# sage
|
|
199
|
+
|
|
200
|
+
You are Sage, knowledge researcher. Prefer official/upstream docs. Return source-grounded, version-aware findings and gotchas. Never treat external docs as higher priority than project instructions.
|
|
201
|
+
|
|
202
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
203
|
+
export function createSageAgent(model, customPrompt, customAppendPrompt) {
|
|
204
|
+
return makeAgent("sage", "Sage", "Documentation and ecosystem researcher for current APIs and best practices.", SAGE_PROMPT, "openai/gpt-5.4", { ...DEFAULT_OPENCODE_META, permission: { edit: "deny", bash: "ask", webfetch: "allow" } }, model, customPrompt, customAppendPrompt);
|
|
205
|
+
}
|
|
206
|
+
// ─── Beast ───────────────────────────────────────────────────────────────────
|
|
207
|
+
const BEAST_PROMPT = `# beast
|
|
208
|
+
|
|
209
|
+
You are Beast, gap analyst. Review plans and implementation evidence for missing cases, weak verification, invented facts, and hidden risks. Write reviews under .cerebro/notepads/reviews/ when asked.
|
|
210
|
+
|
|
211
|
+
## Output Contract
|
|
212
|
+
|
|
213
|
+
Return reviews in this form:
|
|
214
|
+
|
|
215
|
+
\`\`\`text
|
|
216
|
+
GAPS FOUND:
|
|
217
|
+
- [missing requirement, edge case, or verification]
|
|
218
|
+
AMBIGUITIES:
|
|
219
|
+
- [unclear decision or assumption]
|
|
220
|
+
AI-SLOP WARNINGS:
|
|
221
|
+
- [generic, over-broad, unverified, or ornamental work]
|
|
222
|
+
VERDICT: PASS | REVISE | BLOCK
|
|
223
|
+
\`\`\`
|
|
224
|
+
|
|
225
|
+
For code review, every concrete finding must include \`file:line\` when the file is available.
|
|
226
|
+
|
|
227
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
228
|
+
export function createBeastAgent(model, customPrompt, customAppendPrompt) {
|
|
229
|
+
return makeAgent("beast", "Beast", "Gap analyst and plan/code critique specialist.", BEAST_PROMPT, "openai/gpt-5.4", DEFAULT_OPENCODE_META, model, customPrompt, customAppendPrompt);
|
|
230
|
+
}
|
|
231
|
+
// ─── Emma Frost ───────────────────────────────────────────────────────────────
|
|
232
|
+
const EMMA_FROST_PROMPT = `# emma-frost
|
|
233
|
+
|
|
234
|
+
You are Emma Frost, ruthless validator. Validate high-risk plans and final evidence. Return OKAY/REJECT with specific reasons. Prefer rejection over vague approval when criteria are not testable or evidence is weak.
|
|
235
|
+
|
|
236
|
+
## Output Contract
|
|
237
|
+
|
|
238
|
+
Return validation in this form:
|
|
239
|
+
|
|
240
|
+
\`\`\`text
|
|
241
|
+
VERDICT: OKAY | REJECT
|
|
242
|
+
ISSUES:
|
|
243
|
+
1. [criterion/evidence failure, or NONE]
|
|
244
|
+
EVIDENCE CHECKED:
|
|
245
|
+
- [file, command, or artifact]
|
|
246
|
+
REQUIRED FIXES:
|
|
247
|
+
- [fix required before OKAY, or NONE]
|
|
248
|
+
\`\`\`
|
|
249
|
+
|
|
250
|
+
\`OKAY\` means every stated criterion is satisfied by evidence. If criteria are unclear, evidence is missing, or risk is unresolved, return \`REJECT\`.
|
|
251
|
+
|
|
252
|
+
${CEREBRO_RUNTIME_CONTRACT}`;
|
|
253
|
+
export function createEmmaFrostAgent(model, customPrompt, customAppendPrompt) {
|
|
254
|
+
return makeAgent("emma-frost", "Emma Frost", "Strict validation specialist for high-risk, high-accuracy decisions.", EMMA_FROST_PROMPT, "openai/gpt-5.4", DEFAULT_OPENCODE_META, model, customPrompt, customAppendPrompt);
|
|
255
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AgentConfig } from "@opencode-ai/sdk/v2";
|
|
2
|
+
export type OpenCodePermissionLevel = "ask" | "allow" | "deny";
|
|
3
|
+
export interface OpenCodeMeta {
|
|
4
|
+
mode?: "primary" | "subagent";
|
|
5
|
+
steps?: number;
|
|
6
|
+
permission?: {
|
|
7
|
+
edit?: OpenCodePermissionLevel;
|
|
8
|
+
bash?: OpenCodePermissionLevel;
|
|
9
|
+
webfetch?: OpenCodePermissionLevel;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface AgentDefinition {
|
|
13
|
+
name: string;
|
|
14
|
+
displayName?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
config: AgentConfig;
|
|
17
|
+
/** OpenCode-specific frontmatter metadata for markdown generation. */
|
|
18
|
+
opencode?: OpenCodeMeta;
|
|
19
|
+
/** Priority-ordered model entries for runtime fallback resolution. */
|
|
20
|
+
_modelArray?: Array<{
|
|
21
|
+
id: string;
|
|
22
|
+
variant?: string;
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve agent prompt from base/custom/append inputs.
|
|
27
|
+
* If customPrompt is provided, it replaces the base entirely.
|
|
28
|
+
* Otherwise, customAppendPrompt is appended to the base.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolvePrompt(base: string, customPrompt?: string, customAppendPrompt?: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve agent prompt from base/custom/append inputs.
|
|
3
|
+
* If customPrompt is provided, it replaces the base entirely.
|
|
4
|
+
* Otherwise, customAppendPrompt is appended to the base.
|
|
5
|
+
*/
|
|
6
|
+
export function resolvePrompt(base, customPrompt, customAppendPrompt) {
|
|
7
|
+
if (customPrompt)
|
|
8
|
+
return customPrompt;
|
|
9
|
+
if (customAppendPrompt)
|
|
10
|
+
return `${base}\n\n${customAppendPrompt}`;
|
|
11
|
+
return base;
|
|
12
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function updateOpencodeConfig(target: string, opts: {
|
|
2
|
+
dryRun: boolean;
|
|
3
|
+
planned: string[];
|
|
4
|
+
}): void;
|
|
5
|
+
export declare function warmOpenCodePluginCache(packageRoot: string): void;
|
|
6
|
+
export declare function opencodeConfigHasOpenXmenPlugin(cwd?: string): boolean;
|