@alisio/plugin-subagents 0.1.0-alpha.8 → 0.1.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/dist/config.d.ts +5 -0
- package/dist/config.js +2 -0
- package/dist/definitions.d.ts +6 -2
- package/dist/definitions.js +17 -3
- package/dist/index.d.ts +4 -0
- package/dist/index.js +55 -12
- package/package.json +3 -3
package/dist/config.d.ts
CHANGED
|
@@ -23,6 +23,11 @@ export declare const subagentsConfigSchema: z.ZodObject<{
|
|
|
23
23
|
prompt: z.ZodDefault<z.ZodString>;
|
|
24
24
|
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
25
25
|
model: z.ZodOptional<z.ZodString>;
|
|
26
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
27
|
+
all: "all";
|
|
28
|
+
primary: "primary";
|
|
29
|
+
subagent: "subagent";
|
|
30
|
+
}>>;
|
|
26
31
|
}, z.core.$strip>>>;
|
|
27
32
|
worktreeDir: z.ZodOptional<z.ZodString>;
|
|
28
33
|
}, z.core.$strict>;
|
package/dist/config.js
CHANGED
|
@@ -4,6 +4,8 @@ const cliAgent = z.object({
|
|
|
4
4
|
prompt: z.string().default(""),
|
|
5
5
|
tools: z.array(z.string()).optional(),
|
|
6
6
|
model: z.string().optional(),
|
|
7
|
+
/** `primary`/`all` makes the definition available as an ACTIVE (main-session) agent in `/agents`. */
|
|
8
|
+
mode: z.enum(["subagent", "primary", "all"]).optional(),
|
|
7
9
|
});
|
|
8
10
|
/** Options under `builtinPlugins.subagents`. */
|
|
9
11
|
export const subagentsConfigSchema = z
|
package/dist/definitions.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export interface AgentDefinition {
|
|
|
20
20
|
hidden: boolean;
|
|
21
21
|
background: boolean;
|
|
22
22
|
skills?: string[];
|
|
23
|
+
/** Default reasoning effort (`alisio.reasoning.effort`, written by the Alisio agent manager). */
|
|
24
|
+
effort?: string;
|
|
23
25
|
/** builtin | cli | project | convention | compat | user | plugin:<id> */
|
|
24
26
|
source: string;
|
|
25
27
|
path?: string;
|
|
@@ -37,11 +39,13 @@ export interface CliAgent {
|
|
|
37
39
|
prompt: string;
|
|
38
40
|
tools?: string[];
|
|
39
41
|
model?: string;
|
|
42
|
+
mode?: "subagent" | "primary" | "all";
|
|
40
43
|
}
|
|
41
44
|
/**
|
|
42
45
|
* Discovery, first match wins by name: CLI `--agents` > project `.alisio/agents` >
|
|
43
|
-
* `.agents/agents` (
|
|
44
|
-
*
|
|
46
|
+
* `.agents/agents` (shared convention, written by the Alisio agent manager) > compat
|
|
47
|
+
* `.claude/agents`, `.opencode/agent(s)` > user `<config>/agents`, `~/.agents/agents`,
|
|
48
|
+
* `~/.claude/agents`, `~/.config/opencode/agent(s)` > plugin
|
|
45
49
|
* directories (namespaced `plugin:name`) > built-ins. Project sources require trust.
|
|
46
50
|
*/
|
|
47
51
|
export declare function discoverAgents(options: {
|
package/dist/definitions.js
CHANGED
|
@@ -22,6 +22,8 @@ const KNOWN = new Set([
|
|
|
22
22
|
"background",
|
|
23
23
|
"skills",
|
|
24
24
|
"readOnly",
|
|
25
|
+
// Alisio-only settings written by the agent manager (other harnesses ignore this key).
|
|
26
|
+
"alisio",
|
|
25
27
|
// Compat keys accepted silently.
|
|
26
28
|
"temperature",
|
|
27
29
|
"top_p",
|
|
@@ -137,6 +139,10 @@ export function parseAgentDefinition(text, meta) {
|
|
|
137
139
|
const skills = list(front.skills);
|
|
138
140
|
if (skills)
|
|
139
141
|
definition.skills = skills;
|
|
142
|
+
const effort = front.alisio?.reasoning
|
|
143
|
+
?.effort;
|
|
144
|
+
if (typeof effort === "string" && /^[a-z][a-z_-]{0,19}$/.test(effort))
|
|
145
|
+
definition.effort = effort;
|
|
140
146
|
return { definition, warnings };
|
|
141
147
|
}
|
|
142
148
|
export const BUILTIN_AGENTS = [
|
|
@@ -209,8 +215,9 @@ async function readDir(dir) {
|
|
|
209
215
|
}
|
|
210
216
|
/**
|
|
211
217
|
* Discovery, first match wins by name: CLI `--agents` > project `.alisio/agents` >
|
|
212
|
-
* `.agents/agents` (
|
|
213
|
-
*
|
|
218
|
+
* `.agents/agents` (shared convention, written by the Alisio agent manager) > compat
|
|
219
|
+
* `.claude/agents`, `.opencode/agent(s)` > user `<config>/agents`, `~/.agents/agents`,
|
|
220
|
+
* `~/.claude/agents`, `~/.config/opencode/agent(s)` > plugin
|
|
214
221
|
* directories (namespaced `plugin:name`) > built-ins. Project sources require trust.
|
|
215
222
|
*/
|
|
216
223
|
export async function discoverAgents(options) {
|
|
@@ -224,7 +231,13 @@ export async function discoverAgents(options) {
|
|
|
224
231
|
agents.set(definition.name, definition);
|
|
225
232
|
};
|
|
226
233
|
for (const [name, spec] of Object.entries(options.cli ?? {})) {
|
|
227
|
-
const { definition, warnings: w } = parseAgentDefinition(`---\n${JSON.stringify({
|
|
234
|
+
const { definition, warnings: w } = parseAgentDefinition(`---\n${JSON.stringify({
|
|
235
|
+
name,
|
|
236
|
+
description: spec.description,
|
|
237
|
+
...(spec.tools ? { tools: spec.tools } : {}),
|
|
238
|
+
...(spec.model ? { model: spec.model } : {}),
|
|
239
|
+
...(spec.mode ? { mode: spec.mode } : {}),
|
|
240
|
+
})}\n---\n${spec.prompt ?? ""}`, { source: "cli" });
|
|
228
241
|
warnings.push(...w);
|
|
229
242
|
if (definition)
|
|
230
243
|
add(definition);
|
|
@@ -236,6 +249,7 @@ export async function discoverAgents(options) {
|
|
|
236
249
|
{ dir: join(options.workspace, ".opencode", "agent"), source: "compat", project: true },
|
|
237
250
|
{ dir: join(options.workspace, ".opencode", "agents"), source: "compat", project: true },
|
|
238
251
|
{ dir: join(options.configHome, "agents"), source: "user", project: false },
|
|
252
|
+
{ dir: join(options.home, ".agents", "agents"), source: "user", project: false },
|
|
239
253
|
{ dir: join(options.home, ".claude", "agents"), source: "user", project: false },
|
|
240
254
|
{ dir: join(options.home, ".config", "opencode", "agent"), source: "user", project: false },
|
|
241
255
|
{ dir: join(options.home, ".config", "opencode", "agents"), source: "user", project: false },
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,10 @@ import { type Plugin } from "@alisio/sdk";
|
|
|
2
2
|
export type { AgentDefinition } from "./definitions.ts";
|
|
3
3
|
export { BUILTIN_AGENTS, discoverAgents, parseAgentDefinition } from "./definitions.ts";
|
|
4
4
|
export { SubagentManager } from "./manager.ts";
|
|
5
|
+
/** Plugin-state key under which the plugin publishes main-session-capable (mode primary/all) agents. */
|
|
6
|
+
export declare const MAIN_AGENTS_STATE_KEY = "mainAgents";
|
|
7
|
+
/** Plugin-state key listing every loaded definition (name, mode, source, path). */
|
|
8
|
+
export declare const DEFINITIONS_STATE_KEY = "definitions";
|
|
5
9
|
export interface SubagentsPluginContext {
|
|
6
10
|
workspace: string;
|
|
7
11
|
stateHome: string;
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,10 @@ import { SubagentManager } from "./manager.js";
|
|
|
11
11
|
import { loadVersion } from "./version.js";
|
|
12
12
|
export { BUILTIN_AGENTS, discoverAgents, parseAgentDefinition } from "./definitions.js";
|
|
13
13
|
export { SubagentManager } from "./manager.js";
|
|
14
|
+
/** Plugin-state key under which the plugin publishes main-session-capable (mode primary/all) agents. */
|
|
15
|
+
export const MAIN_AGENTS_STATE_KEY = "mainAgents";
|
|
16
|
+
/** Plugin-state key listing every loaded definition (name, mode, source, path). */
|
|
17
|
+
export const DEFINITIONS_STATE_KEY = "definitions";
|
|
14
18
|
const schema = (properties, required) => ({
|
|
15
19
|
type: "object",
|
|
16
20
|
properties,
|
|
@@ -34,25 +38,54 @@ export function createSubagentsPlugin(rawOptions, context) {
|
|
|
34
38
|
id: "subagents",
|
|
35
39
|
name: "Subagents",
|
|
36
40
|
description: "Delegation to specialized agents in isolated child sessions",
|
|
41
|
+
categories: ["subagents"],
|
|
37
42
|
version: loadVersion(import.meta.url),
|
|
38
43
|
apiVersion: 1,
|
|
39
44
|
async setup(api) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Discovers the definitions and publishes them: the main-session-capable ones (mode
|
|
47
|
+
* `primary`/`all`) for the host's ACTIVE-agent catalog, and every loaded file path so the
|
|
48
|
+
* host can tell whether a just-saved agent file is live. The host reads both through
|
|
49
|
+
* `pluginState`, so it never imports this package. Prompts stay bounded.
|
|
50
|
+
*/
|
|
51
|
+
const load = async () => {
|
|
52
|
+
const found = await discoverAgents({
|
|
53
|
+
workspace: context.workspace,
|
|
54
|
+
home: context.home,
|
|
55
|
+
configHome: context.configHome,
|
|
56
|
+
trusted: context.trusted,
|
|
57
|
+
cli: config.agents,
|
|
58
|
+
plugins: api.resources.list("agents"),
|
|
59
|
+
});
|
|
60
|
+
warnings = found.warnings;
|
|
61
|
+
api.state.set(MAIN_AGENTS_STATE_KEY, [...found.agents.values()]
|
|
62
|
+
.filter((a) => a.mode !== "subagent" && !a.hidden)
|
|
63
|
+
.map((a) => ({
|
|
64
|
+
name: a.name,
|
|
65
|
+
description: a.description,
|
|
66
|
+
prompt: a.prompt.slice(0, 24_000),
|
|
67
|
+
...(a.model ? { model: a.model } : {}),
|
|
68
|
+
...(a.readOnly ? { readOnly: true } : {}),
|
|
69
|
+
...(a.effort ? { effort: a.effort } : {}),
|
|
70
|
+
source: a.source,
|
|
71
|
+
...(a.path ? { path: a.path } : {}),
|
|
72
|
+
})));
|
|
73
|
+
api.state.set(DEFINITIONS_STATE_KEY, [...found.agents.values()].map((a) => ({
|
|
74
|
+
name: a.name,
|
|
75
|
+
mode: a.mode,
|
|
76
|
+
source: a.source,
|
|
77
|
+
...(a.path ? { path: a.path } : {}),
|
|
78
|
+
})));
|
|
79
|
+
return found;
|
|
80
|
+
};
|
|
81
|
+
const found = await load();
|
|
49
82
|
const m = new SubagentManager(api, config, context, found.agents);
|
|
50
83
|
manager = m;
|
|
51
84
|
const status = () => {
|
|
52
85
|
const all = [...m.tasks.values()];
|
|
53
86
|
const running = all.filter((t) => t.status === "running").length;
|
|
54
87
|
const queued = all.filter((t) => t.status === "queued").length;
|
|
55
|
-
api.ui.status("agents", running || queued ? `agents ${running}▶${queued ? ` ${queued}⧗` : ""}` : undefined, `${all.length} subagent task(s) this process · ${running} running · ${queued} queued · ${
|
|
88
|
+
api.ui.status("agents", running || queued ? `agents ${running}▶${queued ? ` ${queued}⧗` : ""}` : undefined, `${all.length} subagent task(s) this process · ${running} running · ${queued} queued · ${m.agents.size} definitions`);
|
|
56
89
|
};
|
|
57
90
|
m.refresh = status;
|
|
58
91
|
api.events.on((event) => {
|
|
@@ -187,6 +220,16 @@ export function createSubagentsPlugin(rawOptions, context) {
|
|
|
187
220
|
"`/agents open|cancel|kill|resume <id>` · `/agents merge|discard <id>` (worktrees) · `/agents defs`",
|
|
188
221
|
].join("\n");
|
|
189
222
|
}
|
|
223
|
+
case "reload": {
|
|
224
|
+
// Hot-reload after agent files change (the host calls this after each save).
|
|
225
|
+
// Running tasks keep their definition; new delegations and the ACTIVE-agent
|
|
226
|
+
// catalog use the rediscovered set. The `task` tool's description (its list of
|
|
227
|
+
// advertised subagent types) is fixed at startup.
|
|
228
|
+
const reloaded = await load();
|
|
229
|
+
m.agents = reloaded.agents;
|
|
230
|
+
status();
|
|
231
|
+
return `Reloaded ${reloaded.agents.size} agent definitions${reloaded.warnings.length ? ` (${reloaded.warnings.length} warnings, see /agents defs)` : ""}.`;
|
|
232
|
+
}
|
|
190
233
|
case "defs":
|
|
191
234
|
return [
|
|
192
235
|
"**Agent definitions**",
|
|
@@ -231,7 +274,7 @@ export function createSubagentsPlugin(rawOptions, context) {
|
|
|
231
274
|
return `Discarded ${wt.branch} and removed its worktree.`;
|
|
232
275
|
}
|
|
233
276
|
default:
|
|
234
|
-
return "Usage: /agents [list|defs|open|cancel|kill|resume|merge|discard] [id]";
|
|
277
|
+
return "Usage: /agents [list|defs|reload|open|cancel|kill|resume|merge|discard] [id]";
|
|
235
278
|
}
|
|
236
279
|
}
|
|
237
280
|
catch (error) {
|
|
@@ -239,7 +282,7 @@ export function createSubagentsPlugin(rawOptions, context) {
|
|
|
239
282
|
}
|
|
240
283
|
}, {
|
|
241
284
|
description: "List and manage subagents (open, cancel, resume, merge, discard, defs)",
|
|
242
|
-
argumentHint: "[open|cancel|kill|resume|merge|discard|defs] [id]",
|
|
285
|
+
argumentHint: "[open|cancel|kill|resume|merge|discard|defs|reload] [id]",
|
|
243
286
|
});
|
|
244
287
|
status();
|
|
245
288
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alisio/plugin-subagents",
|
|
3
|
-
"version": "0.1.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Subagents for Alisio: delegate tasks to specialized agents in separate child sessions with narrowed permissions, parallel execution, git worktree isolation and a live agent tree. Built-in, disableable plugin.",
|
|
5
5
|
"author": "Gustavo Gutiérrez",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"zod": "4.6.5"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@alisio/sdk": "^0.1.0
|
|
49
|
+
"@alisio/sdk": "^0.1.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@alisio/sdk": "0.1.0
|
|
52
|
+
"@alisio/sdk": "0.1.0"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public",
|