@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 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
@@ -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` (speculative convention) > compat `.claude/agents`, `.opencode/agent(s)`
44
- * > user `<config>/agents`, `~/.claude/agents`, `~/.config/opencode/agent(s)` > plugin
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: {
@@ -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` (speculative convention) > compat `.claude/agents`, `.opencode/agent(s)`
213
- * > user `<config>/agents`, `~/.claude/agents`, `~/.config/opencode/agent(s)` > plugin
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({ name, description: spec.description, ...(spec.tools ? { tools: spec.tools } : {}), ...(spec.model ? { model: spec.model } : {}) })}\n---\n${spec.prompt ?? ""}`, { source: "cli" });
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
- const found = await discoverAgents({
41
- workspace: context.workspace,
42
- home: context.home,
43
- configHome: context.configHome,
44
- trusted: context.trusted,
45
- cli: config.agents,
46
- plugins: api.resources.list("agents"),
47
- });
48
- warnings = found.warnings;
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 · ${found.agents.size} definitions`);
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-alpha.8",
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-alpha.7"
49
+ "@alisio/sdk": "^0.1.0"
50
50
  },
51
51
  "devDependencies": {
52
- "@alisio/sdk": "0.1.0-alpha.7"
52
+ "@alisio/sdk": "0.1.0"
53
53
  },
54
54
  "publishConfig": {
55
55
  "access": "public",