multiagents 0.1.6 → 0.1.7

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/cli/dashboard.ts CHANGED
@@ -168,14 +168,27 @@ interface DashboardState {
168
168
  }
169
169
 
170
170
  export async function dashboard(sessionId?: string): Promise<void> {
171
- const sid = sessionId ?? readLocalSession()?.session_id ?? null;
172
171
  const client = new BrokerClient(BROKER_URL);
173
172
 
174
173
  if (!(await client.isAlive())) {
175
- console.error("Broker is not running. Start it with: bun broker.ts");
174
+ console.error("Broker is not running. Start it with: multiagents broker start");
176
175
  process.exit(1);
177
176
  }
178
177
 
178
+ // Resolve session ID: explicit arg > local file > most recent active session from broker > null
179
+ let sid = sessionId ?? readLocalSession()?.session_id ?? null;
180
+ if (!sid) {
181
+ try {
182
+ const sessions = await client.listSessions();
183
+ const active = sessions.filter((s: any) => s.status === "active" || s.status === "paused");
184
+ if (active.length > 0) {
185
+ // Pick the most recently active session
186
+ active.sort((a: any, b: any) => (b.last_active_at ?? 0) - (a.last_active_at ?? 0));
187
+ sid = active[0].id;
188
+ }
189
+ } catch { /* broker doesn't support listSessions or no sessions */ }
190
+ }
191
+
179
192
  const state: DashboardState = {
180
193
  session: null,
181
194
  slots: [],
@@ -14,6 +14,7 @@ import {
14
14
  } from "@modelcontextprotocol/sdk/types.js";
15
15
  import type { Subprocess } from "bun";
16
16
 
17
+ import * as fs from "node:fs";
17
18
  import { BrokerClient } from "../shared/broker-client.ts";
18
19
  import type { AgentLaunchConfig } from "../shared/types.ts";
19
20
  import { log, getGitRoot, slugify } from "../shared/utils.ts";
@@ -205,12 +206,12 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
205
206
  tools: [
206
207
  {
207
208
  name: "create_team",
208
- description: "Create a new multi-agent team session. Launches headless agents with assigned roles and file ownership.",
209
+ description: "Create a new multi-agent team session. Launches headless agents (separate Claude/Codex/Gemini CLI processes) with assigned roles and file ownership. The project_dir will be created if it does not exist, and git will be initialized if needed. Returns a session_id to use with all other orchestrator tools.",
209
210
  inputSchema: {
210
211
  type: "object" as const,
211
212
  properties: {
212
- project_dir: { type: "string", description: "Absolute path to the project directory" },
213
- session_name: { type: "string", description: "Human-readable session name (e.g. 'Auth Implementation')" },
213
+ project_dir: { type: "string", description: "Absolute path where agents will work. Will be created if it does not exist. Example: /Users/me/my-project" },
214
+ session_name: { type: "string", description: "Short name for this session. Used to generate session_id. Example: 'calculator-app'" },
214
215
  agents: {
215
216
  type: "array",
216
217
  items: {
@@ -244,7 +245,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
244
245
  },
245
246
  {
246
247
  name: "get_team_status",
247
- description: "Get current status of all agents in a session, including health, progress, and issues.",
248
+ description: "Get current status of all agents in a multiagents session — their roles, connection state, task state (idle/working/done/addressing_feedback), and what they are working on. Use the session_id returned by create_team.",
248
249
  inputSchema: {
249
250
  type: "object" as const,
250
251
  properties: {
@@ -255,7 +256,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
255
256
  },
256
257
  {
257
258
  name: "broadcast_to_team",
258
- description: "Send a message to all connected agents in the session.",
259
+ description: "Send a message to ALL connected agents in a multiagents session. Use for requirement changes, priority shifts, or announcements that every team member must see.",
259
260
  inputSchema: {
260
261
  type: "object" as const,
261
262
  properties: {
@@ -268,7 +269,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
268
269
  },
269
270
  {
270
271
  name: "direct_agent",
271
- description: "Send a direct message to a specific agent by name, role, or slot ID.",
272
+ description: "Send a direct message to a specific agent by name, role, or slot ID. The agent receives this as a peer message and must respond.",
272
273
  inputSchema: {
273
274
  type: "object" as const,
274
275
  properties: {
@@ -281,7 +282,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
281
282
  },
282
283
  {
283
284
  name: "add_agent",
284
- description: "Add a new agent to an existing session.",
285
+ description: "Spawn and add a new agent (Claude/Codex/Gemini CLI process) to an existing multiagents session. The agent auto-connects to the broker and receives team context.",
285
286
  inputSchema: {
286
287
  type: "object" as const,
287
288
  properties: {
@@ -298,7 +299,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
298
299
  },
299
300
  {
300
301
  name: "remove_agent",
301
- description: "Gracefully stop and remove an agent from the session.",
302
+ description: "Gracefully stop and remove an agent from the session. Kills the CLI process and marks the slot as disconnected.",
302
303
  inputSchema: {
303
304
  type: "object" as const,
304
305
  properties: {
@@ -310,7 +311,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
310
311
  },
311
312
  {
312
313
  name: "control_session",
313
- description: "Control the session: pause_all, resume_all, pause_agent, resume_agent, extend_budget, set_budget, status.",
314
+ description: "Control a multiagents session. Actions: pause_all (pause every agent), resume_all (resume every agent), pause_agent (pause one by name/role), resume_agent (resume one), extend_budget (add minutes to time limit), set_budget (set exact time limit), status (get control state).",
314
315
  inputSchema: {
315
316
  type: "object" as const,
316
317
  properties: {
@@ -324,7 +325,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
324
325
  },
325
326
  {
326
327
  name: "adjust_guardrail",
327
- description: "View or update guardrail limits for a session.",
328
+ description: "View or update multiagents session guardrail limits (e.g. max restarts per agent). Use action='view' to see all guardrails, action='update' to change one.",
328
329
  inputSchema: {
329
330
  type: "object" as const,
330
331
  properties: {
@@ -338,7 +339,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
338
339
  },
339
340
  {
340
341
  name: "get_session_log",
341
- description: "Get the message history for a session.",
342
+ description: "Get the inter-agent message history for a multiagents session. Returns timestamped messages between agents with sender/recipient info.",
342
343
  inputSchema: {
343
344
  type: "object" as const,
344
345
  properties: {
@@ -351,7 +352,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
351
352
  },
352
353
  {
353
354
  name: "release_agent",
354
- description: "Release a specific agent, allowing it to disconnect. Use after their work is approved and complete.",
355
+ description: "Release a specific agent from the multiagents session, allowing it to disconnect. Only use after their work is approved and complete. Agents cannot self-disconnect — only the orchestrator can release them.",
355
356
  inputSchema: {
356
357
  type: "object" as const,
357
358
  properties: {
@@ -364,7 +365,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
364
365
  },
365
366
  {
366
367
  name: "release_all",
367
- description: "Release all agents in a session, allowing them to disconnect. Use when the entire team's work is complete.",
368
+ description: "Release ALL agents in a multiagents session, allowing them to disconnect. Use when the entire team's work is complete and production-grade.",
368
369
  inputSchema: {
369
370
  type: "object" as const,
370
371
  properties: {
@@ -376,7 +377,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
376
377
  },
377
378
  {
378
379
  name: "end_session",
379
- description: "End a session: stop all agents, archive the session. Optionally create a PR.",
380
+ description: "End a multiagents session: releases and stops all agents, archives the session. Use when the project is complete.",
380
381
  inputSchema: {
381
382
  type: "object" as const,
382
383
  properties: {
@@ -426,7 +427,22 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
426
427
  }
427
428
 
428
429
  const sessionId = slugify(session_name);
429
- const gitRoot = await getGitRoot(project_dir);
430
+
431
+ // Auto-create project directory if it doesn't exist
432
+ if (!fs.existsSync(project_dir)) {
433
+ fs.mkdirSync(project_dir, { recursive: true });
434
+ }
435
+
436
+ // Init git if not already a repo (needed for file coordination, but session works without it)
437
+ let gitRoot = await getGitRoot(project_dir);
438
+ if (!gitRoot) {
439
+ try {
440
+ const initProc = Bun.spawnSync(["git", "init"], { cwd: project_dir });
441
+ if (initProc.exitCode === 0) {
442
+ gitRoot = project_dir;
443
+ }
444
+ } catch { /* git not installed — session still works without it */ }
445
+ }
430
446
 
431
447
  // Create session in broker
432
448
  await brokerClient.createSession({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multiagents",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Multi-agent orchestration platform for Claude Code, Codex CLI, and Gemini CLI",
5
5
  "module": "index.ts",
6
6
  "type": "module",