claude-code-controller 0.1.1 → 0.3.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/index.d.ts CHANGED
@@ -1,399 +1,7 @@
1
- import { EventEmitter } from 'node:events';
1
+ import { L as Logger, I as InboxMessage, S as StructuredMessage, a as LogLevel } from './controller-CqCBbQYK.js';
2
+ export { A as AgentHandle, b as AgentType, C as ClaudeCodeController, c as ControllerEvents, d as ControllerOptions, e as IdleNotificationMessage, P as PermissionMode, f as PermissionRequestMessage, g as PermissionResponseMessage, h as PlainTextMessage, i as PlanApprovalRequestMessage, j as PlanApprovalResponseMessage, R as ReceiveOptions, k as ShutdownApprovedMessage, l as ShutdownRequestMessage, m as SpawnAgentOptions, T as TaskAssignmentMessage, n as TaskFile, o as TaskManager, p as TaskStatus, q as TeamConfig, r as TeamManager, s as TeamMember } from './controller-CqCBbQYK.js';
2
3
  import { ChildProcess } from 'node:child_process';
3
-
4
- interface InboxMessage {
5
- from: string;
6
- text: string;
7
- timestamp: string;
8
- color?: string;
9
- read: boolean;
10
- summary?: string;
11
- }
12
- type StructuredMessage = TaskAssignmentMessage | ShutdownRequestMessage | ShutdownApprovedMessage | IdleNotificationMessage | PlanApprovalRequestMessage | PlanApprovalResponseMessage | PermissionRequestMessage | PermissionResponseMessage | PlainTextMessage;
13
- interface TaskAssignmentMessage {
14
- type: "task_assignment";
15
- taskId: string;
16
- subject: string;
17
- description: string;
18
- assignedBy: string;
19
- timestamp: string;
20
- }
21
- interface ShutdownRequestMessage {
22
- type: "shutdown_request";
23
- requestId: string;
24
- from: string;
25
- reason?: string;
26
- timestamp: string;
27
- }
28
- interface ShutdownApprovedMessage {
29
- type: "shutdown_approved";
30
- requestId: string;
31
- from: string;
32
- timestamp: string;
33
- paneId?: string;
34
- backendType?: string;
35
- }
36
- interface IdleNotificationMessage {
37
- type: "idle_notification";
38
- from: string;
39
- timestamp: string;
40
- idleReason: string;
41
- }
42
- interface PlanApprovalRequestMessage {
43
- type: "plan_approval_request";
44
- requestId: string;
45
- from: string;
46
- planContent?: string;
47
- timestamp: string;
48
- }
49
- interface PlanApprovalResponseMessage {
50
- type: "plan_approval_response";
51
- requestId: string;
52
- from: string;
53
- approved: boolean;
54
- feedback?: string;
55
- timestamp: string;
56
- }
57
- interface PermissionRequestMessage {
58
- type: "permission_request";
59
- requestId: string;
60
- from: string;
61
- toolName: string;
62
- toolUseId?: string;
63
- description: string;
64
- input?: unknown;
65
- permissionSuggestions?: string[];
66
- timestamp: string;
67
- }
68
- interface PermissionResponseMessage {
69
- type: "permission_response";
70
- requestId: string;
71
- from: string;
72
- approved: boolean;
73
- timestamp: string;
74
- }
75
- interface PlainTextMessage {
76
- type: "plain_text";
77
- text: string;
78
- }
79
- interface TeamConfig {
80
- name: string;
81
- description?: string;
82
- createdAt: number;
83
- leadAgentId: string;
84
- leadSessionId: string;
85
- members: TeamMember[];
86
- }
87
- interface TeamMember {
88
- agentId: string;
89
- name: string;
90
- agentType: string;
91
- model?: string;
92
- joinedAt: number;
93
- tmuxPaneId?: string;
94
- cwd: string;
95
- subscriptions?: string[];
96
- }
97
- interface TaskFile {
98
- id: string;
99
- subject: string;
100
- description: string;
101
- activeForm?: string;
102
- owner?: string;
103
- status: TaskStatus;
104
- blocks: string[];
105
- blockedBy: string[];
106
- metadata?: Record<string, unknown>;
107
- }
108
- type TaskStatus = "pending" | "in_progress" | "completed";
109
- type AgentType = "general-purpose" | "Bash" | "Explore" | "Plan" | string;
110
- interface SpawnAgentOptions {
111
- name: string;
112
- type?: AgentType;
113
- model?: string;
114
- cwd?: string;
115
- prompt?: string;
116
- permissions?: string[];
117
- /** Environment variables to inject into the agent's process */
118
- env?: Record<string, string>;
119
- }
120
- interface ControllerOptions {
121
- teamName?: string;
122
- cwd?: string;
123
- claudeBinary?: string;
124
- logger?: Logger;
125
- /** Default environment variables for all spawned agents */
126
- env?: Record<string, string>;
127
- }
128
- interface ReceiveOptions {
129
- timeout?: number;
130
- pollInterval?: number;
131
- /** If true, return all unread messages, not just the first one */
132
- all?: boolean;
133
- }
134
- interface ControllerEvents {
135
- message: [agentName: string, message: InboxMessage];
136
- idle: [agentName: string];
137
- "shutdown:approved": [agentName: string, message: ShutdownApprovedMessage];
138
- "plan:approval_request": [agentName: string, message: PlanApprovalRequestMessage];
139
- "permission:request": [agentName: string, message: PermissionRequestMessage];
140
- "task:completed": [task: TaskFile];
141
- "agent:spawned": [agentName: string, pid: number];
142
- "agent:exited": [agentName: string, code: number | null];
143
- error: [error: Error];
144
- }
145
- type LogLevel = "debug" | "info" | "warn" | "error" | "silent";
146
- interface Logger {
147
- debug(msg: string, ...args: unknown[]): void;
148
- info(msg: string, ...args: unknown[]): void;
149
- warn(msg: string, ...args: unknown[]): void;
150
- error(msg: string, ...args: unknown[]): void;
151
- }
152
-
153
- declare class TeamManager {
154
- readonly teamName: string;
155
- readonly sessionId: string;
156
- private log;
157
- constructor(teamName: string, logger: Logger);
158
- /**
159
- * Create the team directory structure and config.json.
160
- * The controller registers itself as the lead member.
161
- */
162
- create(opts?: {
163
- description?: string;
164
- cwd?: string;
165
- }): Promise<TeamConfig>;
166
- /**
167
- * Add a member to the team config.
168
- */
169
- addMember(member: TeamMember): Promise<void>;
170
- /**
171
- * Remove a member from the team config.
172
- */
173
- removeMember(name: string): Promise<void>;
174
- /**
175
- * Read the current team config.
176
- */
177
- getConfig(): Promise<TeamConfig>;
178
- /**
179
- * Check if the team already exists on disk.
180
- */
181
- exists(): boolean;
182
- /**
183
- * Destroy the team: remove all team directories and task directories.
184
- */
185
- destroy(): Promise<void>;
186
- private writeConfig;
187
- }
188
-
189
- declare class TaskManager {
190
- private teamName;
191
- private log;
192
- private nextId;
193
- constructor(teamName: string, log: Logger);
194
- /**
195
- * Initialize the task directory. Call after team creation.
196
- * Also scans for existing tasks to set the next ID correctly.
197
- */
198
- init(): Promise<void>;
199
- /**
200
- * Create a new task. Returns the assigned task ID.
201
- */
202
- create(task: Omit<TaskFile, "id" | "blocks" | "blockedBy" | "status"> & {
203
- blocks?: string[];
204
- blockedBy?: string[];
205
- status?: TaskStatus;
206
- }): Promise<string>;
207
- /**
208
- * Get a task by ID.
209
- */
210
- get(taskId: string): Promise<TaskFile>;
211
- /**
212
- * Update a task. Merges the provided fields.
213
- */
214
- update(taskId: string, updates: Partial<Pick<TaskFile, "subject" | "description" | "activeForm" | "owner" | "status" | "blocks" | "blockedBy" | "metadata">>): Promise<TaskFile>;
215
- /**
216
- * Add blocking relationships.
217
- */
218
- addBlocks(taskId: string, blockedTaskIds: string[]): Promise<void>;
219
- /**
220
- * List all tasks.
221
- */
222
- list(): Promise<TaskFile[]>;
223
- /**
224
- * Delete a task file.
225
- */
226
- delete(taskId: string): Promise<void>;
227
- /**
228
- * Wait for a task to reach a target status.
229
- */
230
- waitFor(taskId: string, targetStatus?: TaskStatus, opts?: {
231
- timeout?: number;
232
- pollInterval?: number;
233
- }): Promise<TaskFile>;
234
- private writeTask;
235
- }
236
-
237
- /**
238
- * Interface for the controller methods that AgentHandle needs.
239
- * This avoids a circular dependency with the full controller.
240
- */
241
- interface AgentController {
242
- send(agentName: string, message: string, summary?: string): Promise<void>;
243
- receive(agentName: string, opts?: ReceiveOptions): Promise<InboxMessage[]>;
244
- killAgent(agentName: string): Promise<void>;
245
- sendShutdownRequest(agentName: string): Promise<void>;
246
- isAgentRunning(agentName: string): boolean;
247
- }
248
- /**
249
- * Proxy object for interacting with a specific agent.
250
- */
251
- declare class AgentHandle {
252
- readonly name: string;
253
- readonly pid: number | undefined;
254
- private controller;
255
- constructor(controller: AgentController, name: string, pid: number | undefined);
256
- /**
257
- * Send a message to this agent.
258
- */
259
- send(message: string, summary?: string): Promise<void>;
260
- /**
261
- * Wait for a response from this agent.
262
- * Returns the text of the first unread plain-text message.
263
- */
264
- receive(opts?: ReceiveOptions): Promise<string>;
265
- /**
266
- * Send a message and wait for the response. Convenience method.
267
- */
268
- ask(question: string, opts?: ReceiveOptions): Promise<string>;
269
- /**
270
- * Check if the agent process is still running.
271
- */
272
- get isRunning(): boolean;
273
- /**
274
- * Request the agent to shut down gracefully.
275
- */
276
- shutdown(): Promise<void>;
277
- /**
278
- * Force-kill the agent process.
279
- */
280
- kill(): Promise<void>;
281
- /**
282
- * Async iterator for agent events (messages from this agent).
283
- * Polls the controller's inbox for messages from this agent.
284
- */
285
- events(opts?: {
286
- pollInterval?: number;
287
- timeout?: number;
288
- }): AsyncGenerator<InboxMessage>;
289
- }
290
-
291
- declare class ClaudeCodeController extends EventEmitter<ControllerEvents> implements AgentController {
292
- readonly teamName: string;
293
- readonly team: TeamManager;
294
- readonly tasks: TaskManager;
295
- private processes;
296
- private poller;
297
- private log;
298
- private cwd;
299
- private claudeBinary;
300
- private defaultEnv;
301
- private colorIndex;
302
- private initialized;
303
- constructor(opts?: ControllerOptions & {
304
- logLevel?: LogLevel;
305
- });
306
- /**
307
- * Initialize the controller: create the team and start polling.
308
- * Must be called before any other operations.
309
- */
310
- init(): Promise<this>;
311
- /**
312
- * Graceful shutdown:
313
- * 1. Send shutdown requests to all agents
314
- * 2. Wait briefly for acknowledgment
315
- * 3. Kill remaining processes
316
- * 4. Clean up team files
317
- */
318
- shutdown(): Promise<void>;
319
- /**
320
- * Spawn a new Claude Code agent.
321
- */
322
- spawnAgent(opts: SpawnAgentOptions): Promise<AgentHandle>;
323
- /**
324
- * Send a message to a specific agent.
325
- */
326
- send(agentName: string, message: string, summary?: string): Promise<void>;
327
- /**
328
- * Send a structured shutdown request to an agent.
329
- */
330
- sendShutdownRequest(agentName: string): Promise<void>;
331
- /**
332
- * Broadcast a message to all registered agents (except controller).
333
- */
334
- broadcast(message: string, summary?: string): Promise<void>;
335
- /**
336
- * Wait for messages from a specific agent.
337
- * Polls the controller's inbox for messages from the given agent.
338
- *
339
- * Returns when:
340
- * - A non-idle message is received (SendMessage from agent), OR
341
- * - An idle_notification is received (agent finished its turn),
342
- * in which case the idle message is returned.
343
- */
344
- receive(agentName: string, opts?: ReceiveOptions): Promise<InboxMessage[]>;
345
- /**
346
- * Wait for any message from any agent.
347
- */
348
- receiveAny(opts?: ReceiveOptions): Promise<InboxMessage>;
349
- /**
350
- * Create a task and optionally notify the assigned agent.
351
- */
352
- createTask(task: Omit<TaskFile, "id" | "blocks" | "blockedBy" | "status"> & {
353
- blocks?: string[];
354
- blockedBy?: string[];
355
- status?: TaskStatus;
356
- }): Promise<string>;
357
- /**
358
- * Assign a task to an agent.
359
- */
360
- assignTask(taskId: string, agentName: string): Promise<void>;
361
- /**
362
- * Approve or reject a teammate's plan.
363
- * Send this in response to a `plan:approval_request` event.
364
- */
365
- sendPlanApproval(agentName: string, requestId: string, approve: boolean, feedback?: string): Promise<void>;
366
- /**
367
- * Approve or reject a teammate's permission/tool-use request.
368
- * Send this in response to a `permission:request` event.
369
- */
370
- sendPermissionResponse(agentName: string, requestId: string, approve: boolean): Promise<void>;
371
- /**
372
- * Wait for a task to be completed.
373
- */
374
- waitForTask(taskId: string, timeout?: number): Promise<TaskFile>;
375
- /**
376
- * Check if an agent process is still running.
377
- */
378
- isAgentRunning(name: string): boolean;
379
- /**
380
- * Kill a specific agent.
381
- */
382
- killAgent(name: string): Promise<void>;
383
- /**
384
- * Get the installed Claude Code version.
385
- */
386
- getClaudeVersion(): string | null;
387
- /**
388
- * Verify that the required CLI flags exist in the installed version.
389
- */
390
- verifyCompatibility(): {
391
- compatible: boolean;
392
- version: string | null;
393
- };
394
- private handlePollEvents;
395
- private ensureInitialized;
396
- }
4
+ import 'node:events';
397
5
 
398
6
  interface SpawnOptions {
399
7
  teamName: string;
@@ -406,6 +14,7 @@ interface SpawnOptions {
406
14
  color?: string;
407
15
  claudeBinary?: string;
408
16
  permissions?: string[];
17
+ permissionMode?: string;
409
18
  teammateMode?: "auto" | "tmux" | "in-process";
410
19
  /** Extra environment variables to inject into the agent process */
411
20
  env?: Record<string, string>;
@@ -520,4 +129,4 @@ declare function taskPath(teamName: string, taskId: string): string;
520
129
  declare function createLogger(level?: LogLevel): Logger;
521
130
  declare const silentLogger: Logger;
522
131
 
523
- export { AgentHandle, type AgentType, ClaudeCodeController, type ControllerEvents, type ControllerOptions, type IdleNotificationMessage, type InboxMessage, InboxPoller, type LogLevel, type Logger, type PermissionRequestMessage, type PermissionResponseMessage, type PlainTextMessage, type PlanApprovalRequestMessage, type PlanApprovalResponseMessage, ProcessManager, type ReceiveOptions, type ShutdownApprovedMessage, type ShutdownRequestMessage, type SpawnAgentOptions, type StructuredMessage, type TaskAssignmentMessage, type TaskFile, TaskManager, type TaskStatus, type TeamConfig, TeamManager, type TeamMember, createLogger, inboxPath, inboxesDir, parseMessage, readInbox, readUnread, silentLogger, taskPath, tasksBaseDir, tasksDir, teamConfigPath, teamDir, teamsDir, writeInbox };
132
+ export { InboxMessage, InboxPoller, LogLevel, Logger, ProcessManager, StructuredMessage, createLogger, inboxPath, inboxesDir, parseMessage, readInbox, readUnread, silentLogger, taskPath, tasksBaseDir, tasksDir, teamConfigPath, teamDir, teamsDir, writeInbox };
package/dist/index.js CHANGED
@@ -312,6 +312,9 @@ var ProcessManager = class {
312
312
  if (opts.model) {
313
313
  claudeArgs.push("--model", opts.model);
314
314
  }
315
+ if (opts.permissionMode) {
316
+ claudeArgs.push("--permission-mode", opts.permissionMode);
317
+ }
315
318
  if (opts.permissions) {
316
319
  for (const perm of opts.permissions) {
317
320
  claudeArgs.push("--allowedTools", perm);
@@ -819,6 +822,7 @@ var ClaudeCodeController = class extends EventEmitter {
819
822
  color,
820
823
  claudeBinary: this.claudeBinary,
821
824
  permissions: opts.permissions,
825
+ permissionMode: opts.permissionMode,
822
826
  env
823
827
  });
824
828
  this.emit("agent:spawned", opts.name, proc.pid ?? 0);