@alisio/plugin-subagents 0.1.0-alpha.9 → 0.1.1

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.
@@ -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;
@@ -41,8 +43,9 @@ export interface CliAgent {
41
43
  }
42
44
  /**
43
45
  * Discovery, first match wins by name: CLI `--agents` > project `.alisio/agents` >
44
- * `.agents/agents` (speculative convention) > compat `.claude/agents`, `.opencode/agent(s)`
45
- * > 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
46
49
  * directories (namespaced `plugin:name`) > built-ins. Project sources require trust.
47
50
  */
48
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) {
@@ -242,6 +249,7 @@ export async function discoverAgents(options) {
242
249
  { dir: join(options.workspace, ".opencode", "agent"), source: "compat", project: true },
243
250
  { dir: join(options.workspace, ".opencode", "agents"), source: "compat", project: true },
244
251
  { dir: join(options.configHome, "agents"), source: "user", project: false },
252
+ { dir: join(options.home, ".agents", "agents"), source: "user", project: false },
245
253
  { dir: join(options.home, ".claude", "agents"), source: "user", project: false },
246
254
  { dir: join(options.home, ".config", "opencode", "agent"), source: "user", project: false },
247
255
  { dir: join(options.home, ".config", "opencode", "agents"), source: "user", project: false },
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ export { BUILTIN_AGENTS, discoverAgents, parseAgentDefinition } from "./definiti
4
4
  export { SubagentManager } from "./manager.ts";
5
5
  /** Plugin-state key under which the plugin publishes main-session-capable (mode primary/all) agents. */
6
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";
7
9
  export interface SubagentsPluginContext {
8
10
  workspace: string;
9
11
  stateHome: string;
package/dist/index.js CHANGED
@@ -13,6 +13,8 @@ export { BUILTIN_AGENTS, discoverAgents, parseAgentDefinition } from "./definiti
13
13
  export { SubagentManager } from "./manager.js";
14
14
  /** Plugin-state key under which the plugin publishes main-session-capable (mode primary/all) agents. */
15
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";
16
18
  const schema = (properties, required) => ({
17
19
  type: "object",
18
20
  properties,
@@ -36,39 +38,54 @@ export function createSubagentsPlugin(rawOptions, context) {
36
38
  id: "subagents",
37
39
  name: "Subagents",
38
40
  description: "Delegation to specialized agents in isolated child sessions",
41
+ categories: ["subagents"],
39
42
  version: loadVersion(import.meta.url),
40
43
  apiVersion: 1,
41
44
  async setup(api) {
42
- const found = await discoverAgents({
43
- workspace: context.workspace,
44
- home: context.home,
45
- configHome: context.configHome,
46
- trusted: context.trusted,
47
- cli: config.agents,
48
- plugins: api.resources.list("agents"),
49
- });
50
- warnings = found.warnings;
51
- // Publish the main-session-capable definitions (mode `primary`/`all`) for the TUI's `/agents`
52
- // picker. The host reads them through `pluginState`, so the TUI never imports this package.
53
- // Only the fields the ACTIVE agent needs are persisted; prompts stay bounded.
54
- api.state.set(MAIN_AGENTS_STATE_KEY, [...found.agents.values()]
55
- .filter((a) => a.mode !== "subagent" && !a.hidden)
56
- .map((a) => ({
57
- name: a.name,
58
- description: a.description,
59
- prompt: a.prompt.slice(0, 24_000),
60
- ...(a.model ? { model: a.model } : {}),
61
- ...(a.readOnly ? { readOnly: true } : {}),
62
- source: a.source,
63
- ...(a.path ? { path: a.path } : {}),
64
- })));
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();
65
82
  const m = new SubagentManager(api, config, context, found.agents);
66
83
  manager = m;
67
84
  const status = () => {
68
85
  const all = [...m.tasks.values()];
69
86
  const running = all.filter((t) => t.status === "running").length;
70
87
  const queued = all.filter((t) => t.status === "queued").length;
71
- 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`);
72
89
  };
73
90
  m.refresh = status;
74
91
  api.events.on((event) => {
@@ -203,6 +220,16 @@ export function createSubagentsPlugin(rawOptions, context) {
203
220
  "`/agents open|cancel|kill|resume <id>` · `/agents merge|discard <id>` (worktrees) · `/agents defs`",
204
221
  ].join("\n");
205
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
+ }
206
233
  case "defs":
207
234
  return [
208
235
  "**Agent definitions**",
@@ -247,7 +274,7 @@ export function createSubagentsPlugin(rawOptions, context) {
247
274
  return `Discarded ${wt.branch} and removed its worktree.`;
248
275
  }
249
276
  default:
250
- 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]";
251
278
  }
252
279
  }
253
280
  catch (error) {
@@ -255,7 +282,7 @@ export function createSubagentsPlugin(rawOptions, context) {
255
282
  }
256
283
  }, {
257
284
  description: "List and manage subagents (open, cancel, resume, merge, discard, defs)",
258
- argumentHint: "[open|cancel|kill|resume|merge|discard|defs] [id]",
285
+ argumentHint: "[open|cancel|kill|resume|merge|discard|defs|reload] [id]",
259
286
  });
260
287
  status();
261
288
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alisio/plugin-subagents",
3
- "version": "0.1.0-alpha.9",
3
+ "version": "0.1.1",
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.8"
49
+ "@alisio/sdk": "^0.1.1"
50
50
  },
51
51
  "devDependencies": {
52
- "@alisio/sdk": "0.1.0-alpha.8"
52
+ "@alisio/sdk": "0.1.1"
53
53
  },
54
54
  "publishConfig": {
55
55
  "access": "public",