@divaltor/academy 0.4.6 → 0.5.0
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 +4 -1
- package/package.json +2 -2
- package/src/index.ts +35 -2
- package/src/session-communication.ts +8 -1
package/README.md
CHANGED
|
@@ -29,6 +29,9 @@ Add Academy to `opencode.jsonc`. All options are optional. Omit the version to t
|
|
|
29
29
|
"color": "#8994B8",
|
|
30
30
|
"model": "opencode/claude-opus-5#max",
|
|
31
31
|
},
|
|
32
|
+
"cafe": {
|
|
33
|
+
"disabled": true,
|
|
34
|
+
},
|
|
32
35
|
},
|
|
33
36
|
"experimental": {
|
|
34
37
|
"communication": {
|
|
@@ -43,7 +46,7 @@ Add Academy to `opencode.jsonc`. All options are optional. Omit the version to t
|
|
|
43
46
|
}
|
|
44
47
|
```
|
|
45
48
|
|
|
46
|
-
Each agent under `agents` accepts `name`, `color`, and `
|
|
49
|
+
Each agent under `agents` accepts `name`, `color`, `model`, and `disabled`. Colors may be six-digit hex values or OpenCode theme colors. Model references use `provider/model` or `provider/model#variant`. Set `disabled` to `true` to hide an agent and prevent new subagent or Academy thread creation while retaining its definition so existing sessions can continue. Disabling Rudolf restores OpenCode's Build agent as the default.
|
|
47
50
|
|
|
48
51
|
Without a version suffix OpenCode resolves `latest` on install; run `opencode plugin update` to pull newer releases.
|
|
49
52
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@divaltor/academy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
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": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"fix": "ultracite fix"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@ff-labs/fff-bun": "0.
|
|
32
|
+
"@ff-labs/fff-bun": "0.11.0",
|
|
33
33
|
"@opencode/plugin": "2.0.11",
|
|
34
34
|
"@opencode/schema": "2.0.11",
|
|
35
35
|
"effect": "4.0.0-rc.112"
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ const parseModel = (reference: string | undefined) =>
|
|
|
14
14
|
|
|
15
15
|
const AgentOptions = Schema.Struct({
|
|
16
16
|
color: Schema.optionalKey(Agent.Color),
|
|
17
|
+
disabled: Schema.optionalKey(Schema.Boolean),
|
|
17
18
|
model: Schema.optionalKey(ModelReference),
|
|
18
19
|
name: Schema.optionalKey(Schema.NonEmptyString),
|
|
19
20
|
});
|
|
@@ -53,6 +54,12 @@ const setup = Effect.fn("Academy.setup")(function* setup(ctx: Plugin.Context) {
|
|
|
53
54
|
const agentID = (id: (typeof agents)[number]["id"]) =>
|
|
54
55
|
Agent.ID.make(agentOptions[id]?.name ?? id);
|
|
55
56
|
const configuredAgentIDs = agents.map((agent) => agentID(agent.id));
|
|
57
|
+
const disabledAgentIDs = new Set(
|
|
58
|
+
agents
|
|
59
|
+
.filter((agent) => agentOptions[agent.id]?.disabled === true)
|
|
60
|
+
.map((agent) => agentID(agent.id))
|
|
61
|
+
);
|
|
62
|
+
const rudolfDisabled = disabledAgentIDs.has(agentID("rudolf"));
|
|
56
63
|
const communication = options.experimental?.communication;
|
|
57
64
|
const communicationEnabled = communication?.enabled === true;
|
|
58
65
|
|
|
@@ -85,7 +92,7 @@ const setup = Effect.fn("Academy.setup")(function* setup(ctx: Plugin.Context) {
|
|
|
85
92
|
yield* ctx.agent.transform((editor) => {
|
|
86
93
|
for (const id of ["build", "plan", "explore", "general"]) {
|
|
87
94
|
editor.update(id, (agent) => {
|
|
88
|
-
agent.hidden =
|
|
95
|
+
agent.hidden = !(id === "build" && rudolfDisabled);
|
|
89
96
|
});
|
|
90
97
|
}
|
|
91
98
|
|
|
@@ -102,6 +109,7 @@ const setup = Effect.fn("Academy.setup")(function* setup(ctx: Plugin.Context) {
|
|
|
102
109
|
);
|
|
103
110
|
agent.description = definition.description;
|
|
104
111
|
agent.mode = definition.mode;
|
|
112
|
+
agent.hidden = disabledAgentIDs.has(agentID(definition.id));
|
|
105
113
|
agent.color =
|
|
106
114
|
agentOptions[definition.id]?.color ?? agent.color ?? definition.color;
|
|
107
115
|
const base =
|
|
@@ -133,11 +141,36 @@ const setup = Effect.fn("Academy.setup")(function* setup(ctx: Plugin.Context) {
|
|
|
133
141
|
});
|
|
134
142
|
}
|
|
135
143
|
|
|
144
|
+
for (const agent of editor.list()) {
|
|
145
|
+
editor.update(agent.id, (editable) => {
|
|
146
|
+
editable.permissions.push(
|
|
147
|
+
...disabledAgentIDs.values().map((id) => ({
|
|
148
|
+
action: "subagent",
|
|
149
|
+
effect: "deny" as const,
|
|
150
|
+
resource: id,
|
|
151
|
+
}))
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (rudolfDisabled) {
|
|
157
|
+
editor.default(
|
|
158
|
+
editor.list().find((agent) => agent.mode === "primary" && !agent.hidden)
|
|
159
|
+
?.id
|
|
160
|
+
);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
136
164
|
editor.default(agentID("rudolf"));
|
|
137
165
|
});
|
|
138
166
|
|
|
139
167
|
if (communication !== undefined && communicationEnabled) {
|
|
140
|
-
yield* SessionCommunication.register(
|
|
168
|
+
yield* SessionCommunication.register(
|
|
169
|
+
ctx,
|
|
170
|
+
communication,
|
|
171
|
+
agentID("rudolf"),
|
|
172
|
+
disabledAgentIDs
|
|
173
|
+
);
|
|
141
174
|
}
|
|
142
175
|
});
|
|
143
176
|
|
|
@@ -206,7 +206,8 @@ export namespace SessionCommunication {
|
|
|
206
206
|
function* register(
|
|
207
207
|
ctx: Plugin.Context,
|
|
208
208
|
options: Options,
|
|
209
|
-
primaryAgent: Agent.ID
|
|
209
|
+
primaryAgent: Agent.ID,
|
|
210
|
+
disabledAgentIDs: ReadonlySet<Agent.ID>
|
|
210
211
|
) {
|
|
211
212
|
const scanRecords = Effect.fn("SessionCommunication.scanThreadRecords")(
|
|
212
213
|
function* scanThreadRecords(
|
|
@@ -340,6 +341,12 @@ export namespace SessionCommunication {
|
|
|
340
341
|
"only the primary Academy session can create threads"
|
|
341
342
|
);
|
|
342
343
|
}
|
|
344
|
+
if (
|
|
345
|
+
input.agent !== undefined &&
|
|
346
|
+
disabledAgentIDs.has(input.agent)
|
|
347
|
+
) {
|
|
348
|
+
return failure(`agent ${input.agent} is disabled`);
|
|
349
|
+
}
|
|
343
350
|
|
|
344
351
|
const detached = input.detached ?? false;
|
|
345
352
|
const depth = yield* threadDepthFor(
|