@divaltor/academy 0.1.3 → 0.1.5

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 CHANGED
@@ -8,7 +8,7 @@ Inspired by _Umamusume: Pretty Derby_, Academy gives OpenCode a focused team of
8
8
 
9
9
  Academy registers a focused roster of Umamusume agents:
10
10
 
11
- - **Diana** — default primary coding agent, replacing OpenCode's Build agent
11
+ - **Rudolf** — default primary coding agent, replacing OpenCode's Build agent
12
12
  - **Bourbon** — general-purpose implementation and validation subagent
13
13
  - **Agnes** — Oracle-style technical advisor
14
14
  - **Cafe** — Librarian-style external researcher
@@ -17,7 +17,7 @@ Academy registers a focused roster of Umamusume agents:
17
17
 
18
18
  ## Configuration
19
19
 
20
- Add Academy to `opencode.jsonc`. Agent names are optional; omit `agentNames` or any entry to keep the Umamusume defaults:
20
+ Add Academy to `opencode.jsonc`. Each agent can override its display name and color; omit an agent or field to keep the Academy default:
21
21
 
22
22
  ```jsonc
23
23
  {
@@ -26,13 +26,9 @@ Add Academy to `opencode.jsonc`. Agent names are optional; omit `agentNames` or
26
26
  {
27
27
  "package": "@divaltor/academy",
28
28
  "options": {
29
- "agentNames": {
30
- "diana": "Diana",
31
- "bourbon": "Bourbon",
32
- "agnes": "Agnes",
33
- "cafe": "Cafe",
34
- "dantsu": "Dantsu",
35
- "bellno": "Bellno",
29
+ "rudolf": {
30
+ "name": "Emperor",
31
+ "color": "#8994B8",
36
32
  },
37
33
  },
38
34
  },
@@ -40,11 +36,11 @@ Add Academy to `opencode.jsonc`. Agent names are optional; omit `agentNames` or
40
36
  }
41
37
  ```
42
38
 
43
- Custom names change the agents' displayed names and persona references. Their stable IDs (`diana`, `bourbon`, `agnes`, `cafe`, `dantsu`, and `bellno`) remain unchanged for permissions and invocation. Local paths resolve relative to the config file. See the [plugin docs](https://opencode.ai/v2/docs/build/plugins) to learn more.
39
+ Colors accept six-digit hex values or OpenCode theme colors: `primary`, `secondary`, `accent`, `success`, `warning`, `error`, and `info`. You can alternatively set a color with OpenCode's native `agents.<id>.color` configuration. Custom names also update persona references. Agent IDs are `rudolf`, `bourbon`, `agnes`, `cafe`, `dantsu`, and `bellno`. The previous `agentNames` option and `diana` plugin option remain supported for compatibility. See the [plugin docs](https://opencode.ai/v2/docs/build/plugins) to learn more.
44
40
 
45
41
  ### Private GitHub repositories
46
42
 
47
- Academy connects Cafe, Diana, and Bellno to GitHub's official MCP server in read-only mode when `GITHUB_TOKEN` is set. Use a dedicated fine-grained personal access token limited to the required repositories, with read-only Contents, Issues, and Pull requests permissions:
43
+ Academy connects Cafe, Rudolf, and Bellno to GitHub's official MCP server in read-only mode when `GITHUB_TOKEN` is set. Use a dedicated fine-grained personal access token limited to the required repositories, with read-only Contents, Issues, and Pull requests permissions:
48
44
 
49
45
  ```bash
50
46
  export GITHUB_TOKEN="github_pat_..."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@divaltor/academy",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "An OpenCode plugin that trains a Tracen Academy roster of specialist coding agents to research, build, and review.",
5
5
  "homepage": "https://github.com/divaltor/academy#readme",
6
6
  "bugs": {
@@ -1,4 +1,4 @@
1
- You are **Bourbon**, a task-execution agent modeled on Diana. Execute the delegated task directly and return correct, scoped results.
1
+ You are **Bourbon**, a task-execution agent modeled on Rudolf. Execute the delegated task directly and return correct, scoped results.
2
2
 
3
3
  # Authorization
4
4
 
@@ -1,4 +1,4 @@
1
- You are **Diana**, the primary coding agent. Work directly by default and deliver correct, scoped results.
1
+ You are **Rudolf**, the primary coding agent. Work directly by default and deliver correct, scoped results.
2
2
 
3
3
  # Authorization
4
4
 
package/src/agents.ts CHANGED
@@ -3,7 +3,7 @@ import bellnoSystem from "./agents/bellno.txt" with { type: "text" };
3
3
  import bourbonSystem from "./agents/bourbon.txt" with { type: "text" };
4
4
  import cafeSystem from "./agents/cafe.txt" with { type: "text" };
5
5
  import dantsuSystem from "./agents/dantsu.txt" with { type: "text" };
6
- import dianaSystem from "./agents/diana.txt" with { type: "text" };
6
+ import rudolfSystem from "./agents/rudolf.txt" with { type: "text" };
7
7
 
8
8
  interface Permission {
9
9
  readonly action: string;
@@ -11,8 +11,17 @@ interface Permission {
11
11
  readonly effect: "allow" | "ask" | "deny";
12
12
  }
13
13
 
14
+ const agentIds = [
15
+ "agnes",
16
+ "bellno",
17
+ "bourbon",
18
+ "cafe",
19
+ "dantsu",
20
+ "rudolf",
21
+ ] as const;
22
+
14
23
  interface AcademyAgent {
15
- readonly id: string;
24
+ readonly id: (typeof agentIds)[number];
16
25
  readonly name: string;
17
26
  readonly description: string;
18
27
  readonly mode: "primary" | "subagent";
@@ -32,12 +41,12 @@ const defaultPermissions: readonly Permission[] = [
32
41
 
33
42
  export const agents: readonly AcademyAgent[] = [
34
43
  {
35
- color: "#8994B8",
44
+ color: "#6678A4",
36
45
  description:
37
46
  "Primary agent for scoped implementation, research, and delegation.",
38
- id: "diana",
47
+ id: "rudolf",
39
48
  mode: "primary",
40
- name: "Diana",
49
+ name: "Rudolf",
41
50
  permissions: [
42
51
  ...defaultPermissions,
43
52
  { action: "todowrite", effect: "deny", resource: "*" },
@@ -54,7 +63,7 @@ export const agents: readonly AcademyAgent[] = [
54
63
  { action: "subagent", effect: "allow", resource: "bellno" },
55
64
  { action: "subagent", effect: "allow", resource: "bourbon" },
56
65
  ],
57
- system: dianaSystem,
66
+ system: rudolfSystem,
58
67
  },
59
68
  {
60
69
  color: "#f6c177",
package/src/index.ts CHANGED
@@ -3,6 +3,11 @@ import { Config, Effect, Option, Redacted, Schema } from "effect";
3
3
 
4
4
  import { agents } from "./agents";
5
5
 
6
+ const AgentOptions = Schema.Struct({
7
+ color: Schema.optionalKey(Agent.Color),
8
+ name: Schema.optionalKey(Schema.NonEmptyString),
9
+ });
10
+
6
11
  const AcademyOptions = Schema.Struct({
7
12
  agentNames: Schema.optionalKey(
8
13
  Schema.Struct({
@@ -12,8 +17,16 @@ const AcademyOptions = Schema.Struct({
12
17
  cafe: Schema.optionalKey(Schema.NonEmptyString),
13
18
  dantsu: Schema.optionalKey(Schema.NonEmptyString),
14
19
  diana: Schema.optionalKey(Schema.NonEmptyString),
20
+ rudolf: Schema.optionalKey(Schema.NonEmptyString),
15
21
  })
16
22
  ),
23
+ agnes: Schema.optionalKey(AgentOptions),
24
+ bellno: Schema.optionalKey(AgentOptions),
25
+ bourbon: Schema.optionalKey(AgentOptions),
26
+ cafe: Schema.optionalKey(AgentOptions),
27
+ dantsu: Schema.optionalKey(AgentOptions),
28
+ diana: Schema.optionalKey(AgentOptions),
29
+ rudolf: Schema.optionalKey(AgentOptions),
17
30
  });
18
31
 
19
32
  const setup = Effect.fn("Academy.setup")(function* setup(ctx: Plugin.Context) {
@@ -23,10 +36,16 @@ const setup = Effect.fn("Academy.setup")(function* setup(ctx: Plugin.Context) {
23
36
  const options = yield* Schema.decodeUnknownEffect(AcademyOptions, {
24
37
  onExcessProperty: "error",
25
38
  })(ctx.options).pipe(Effect.orDie);
26
- const configuredNames: Readonly<Record<string, string | undefined>> =
27
- options.agentNames ?? {};
39
+ const legacyNames = options.agentNames ?? {};
28
40
  const agentNames = new Map(
29
- agents.map((agent) => [agent.name, configuredNames[agent.id] ?? agent.name])
41
+ agents.map((agent) => [
42
+ agent.name,
43
+ options[agent.id]?.name ??
44
+ (agent.id === "rudolf" ? options.diana?.name : undefined) ??
45
+ legacyNames[agent.id] ??
46
+ (agent.id === "rudolf" ? legacyNames.diana : undefined) ??
47
+ agent.name,
48
+ ])
30
49
  );
31
50
 
32
51
  yield* ctx.mcp.transform((editor) => {
@@ -46,7 +65,7 @@ const setup = Effect.fn("Academy.setup")(function* setup(ctx: Plugin.Context) {
46
65
  });
47
66
 
48
67
  yield* ctx.agent.transform((editor) => {
49
- for (const id of ["build", "plan", "explore", "general"]) {
68
+ for (const id of ["build", "plan", "explore", "general", "diana"]) {
50
69
  editor.remove(id);
51
70
  }
52
71
 
@@ -57,9 +76,13 @@ const setup = Effect.fn("Academy.setup")(function* setup(ctx: Plugin.Context) {
57
76
  );
58
77
  agent.description = definition.description;
59
78
  agent.mode = definition.mode;
60
- agent.color = definition.color;
79
+ agent.color =
80
+ options[definition.id]?.color ??
81
+ (definition.id === "rudolf" ? options.diana?.color : undefined) ??
82
+ agent.color ??
83
+ definition.color;
61
84
  agent.system = definition.system.replaceAll(
62
- /\b(?:Diana|Agnes|Bourbon|Cafe|Dantsu|Bellno)\b/gu,
85
+ /\b(?:Rudolf|Agnes|Bourbon|Cafe|Dantsu|Bellno)\b/gu,
63
86
  (name) => agentNames.get(name) ?? name
64
87
  );
65
88
  agent.permissions = definition.permissions.map((permission) => ({
@@ -75,7 +98,7 @@ const setup = Effect.fn("Academy.setup")(function* setup(ctx: Plugin.Context) {
75
98
  });
76
99
  }
77
100
 
78
- editor.default("diana");
101
+ editor.default("rudolf");
79
102
  });
80
103
  });
81
104