claude-code-controller 0.4.0 → 0.5.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.
@@ -1,5 +1,5 @@
1
1
  import { Hono } from 'hono';
2
- import { C as ClaudeCodeController, j as PermissionPreset, z as TaskStatus, a as LogLevel, d as AgentType } from '../claude-DectLQVR.cjs';
2
+ import { C as ClaudeCodeController, j as PermissionPreset, E as TaskStatus, a as LogLevel, d as AgentType } from '../claude-0cg912ch.cjs';
3
3
  import 'node:events';
4
4
 
5
5
  interface PendingApproval {
@@ -1,5 +1,5 @@
1
1
  import { Hono } from 'hono';
2
- import { C as ClaudeCodeController, j as PermissionPreset, z as TaskStatus, a as LogLevel, d as AgentType } from '../claude-DectLQVR.js';
2
+ import { C as ClaudeCodeController, j as PermissionPreset, E as TaskStatus, a as LogLevel, d as AgentType } from '../claude-0cg912ch.js';
3
3
  import 'node:events';
4
4
 
5
5
  interface PendingApproval {
package/dist/api/index.js CHANGED
@@ -109,6 +109,8 @@ import { Hono } from "hono";
109
109
  import { EventEmitter } from "events";
110
110
  import { execSync as execSync2 } from "child_process";
111
111
  import { randomUUID as randomUUID2 } from "crypto";
112
+ import { mkdirSync, existsSync as existsSync4, writeFileSync } from "fs";
113
+ import { join as join2 } from "path";
112
114
 
113
115
  // src/team-manager.ts
114
116
  import { readFile, writeFile, mkdir, rm } from "fs/promises";
@@ -441,6 +443,8 @@ if pid == 0:
441
443
  else:
442
444
  signal.signal(signal.SIGTERM, lambda *a: (os.kill(pid, signal.SIGTERM), sys.exit(0)))
443
445
  signal.signal(signal.SIGINT, lambda *a: (os.kill(pid, signal.SIGTERM), sys.exit(0)))
446
+ buf = b""
447
+ trust_sent = False
444
448
  try:
445
449
  while True:
446
450
  r, _, _ = select.select([fd, 0], [], [], 1.0)
@@ -450,6 +454,12 @@ else:
450
454
  if not data:
451
455
  break
452
456
  os.write(1, data)
457
+ if not trust_sent:
458
+ buf += data
459
+ if b"Yes" in buf and b"trust" in buf:
460
+ os.write(fd, b"\\r")
461
+ trust_sent = True
462
+ buf = b""
453
463
  except OSError:
454
464
  break
455
465
  if 0 in r:
@@ -475,6 +485,7 @@ else:
475
485
  stdio: ["pipe", "pipe", "pipe"],
476
486
  env: {
477
487
  ...process.env,
488
+ CLAUDECODE: "1",
478
489
  CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1",
479
490
  ...opts.env
480
491
  }
@@ -792,7 +803,10 @@ function createLogger(level = "info") {
792
803
  var PROTOCOL_ONLY_TYPES = /* @__PURE__ */ new Set([
793
804
  "shutdown_approved",
794
805
  "plan_approval_response",
795
- "permission_response"
806
+ "permission_response",
807
+ "task_completed",
808
+ "sandbox_permission_request",
809
+ "sandbox_permission_response"
796
810
  ]);
797
811
  var AGENT_COLORS = [
798
812
  "#00FF00",
@@ -900,12 +914,17 @@ var ClaudeCodeController = class extends EventEmitter {
900
914
  name: opts.name,
901
915
  agentType: opts.type || "general-purpose",
902
916
  model: opts.model,
917
+ prompt: opts.prompt,
918
+ color,
919
+ planModeRequired: false,
920
+ backendType: "in-process",
903
921
  joinedAt: Date.now(),
904
922
  tmuxPaneId: "",
905
923
  cwd,
906
924
  subscriptions: []
907
925
  };
908
926
  await this.team.addMember(member);
927
+ this.ensureWorkspaceTrusted(cwd);
909
928
  const env = Object.keys(this.defaultEnv).length > 0 || opts.env ? { ...this.defaultEnv, ...opts.env } : void 0;
910
929
  const proc = this.processes.spawn({
911
930
  teamName: this.teamName,
@@ -1142,7 +1161,7 @@ var ClaudeCodeController = class extends EventEmitter {
1142
1161
  const { raw, parsed } = event;
1143
1162
  switch (parsed.type) {
1144
1163
  case "idle_notification":
1145
- this.emit("idle", raw.from);
1164
+ this.emit("idle", raw.from, parsed);
1146
1165
  break;
1147
1166
  case "shutdown_approved":
1148
1167
  this.log.info(
@@ -1162,6 +1181,9 @@ var ClaudeCodeController = class extends EventEmitter {
1162
1181
  );
1163
1182
  this.emit("permission:request", raw.from, parsed);
1164
1183
  break;
1184
+ case "task_completed":
1185
+ this.emit("message", raw.from, raw);
1186
+ break;
1165
1187
  case "plain_text":
1166
1188
  this.emit("message", raw.from, raw);
1167
1189
  break;
@@ -1170,6 +1192,19 @@ var ClaudeCodeController = class extends EventEmitter {
1170
1192
  }
1171
1193
  }
1172
1194
  }
1195
+ /**
1196
+ * Ensure the agent's cwd has a .claude/settings.local.json so the
1197
+ * CLI skips the interactive workspace trust prompt.
1198
+ */
1199
+ ensureWorkspaceTrusted(cwd) {
1200
+ const claudeDir = join2(cwd, ".claude");
1201
+ const settingsPath = join2(claudeDir, "settings.local.json");
1202
+ if (!existsSync4(settingsPath)) {
1203
+ mkdirSync(claudeDir, { recursive: true });
1204
+ writeFileSync(settingsPath, "{}\n");
1205
+ this.log.debug(`Created ${settingsPath} for workspace trust`);
1206
+ }
1207
+ }
1173
1208
  ensureInitialized() {
1174
1209
  if (!this.initialized) {
1175
1210
  throw new Error(
@@ -1218,7 +1253,7 @@ function waitForReady(controller, agentName, timeoutMs = 15e3) {
1218
1253
  )
1219
1254
  );
1220
1255
  }, timeoutMs);
1221
- const onReady = (name) => {
1256
+ const onReady = (name, ..._rest) => {
1222
1257
  if (name === agentName && !settled) {
1223
1258
  settled = true;
1224
1259
  cleanup();
@@ -1349,14 +1384,22 @@ var Agent = class _Agent extends EventEmitter2 {
1349
1384
  this.ensureNotDisposed();
1350
1385
  const timeout = opts?.timeout ?? 12e4;
1351
1386
  const responsePromise = new Promise((resolve, reject) => {
1387
+ let gotMessage = false;
1352
1388
  const timer = setTimeout(() => {
1353
1389
  cleanup();
1354
1390
  reject(new Error(`Timeout (${timeout}ms) waiting for response`));
1355
1391
  }, timeout);
1356
1392
  const onMsg = (text) => {
1393
+ gotMessage = true;
1357
1394
  cleanup();
1358
1395
  resolve(text);
1359
1396
  };
1397
+ const onIdle = () => {
1398
+ if (!gotMessage) {
1399
+ cleanup();
1400
+ resolve("");
1401
+ }
1402
+ };
1360
1403
  const onExit = (code) => {
1361
1404
  cleanup();
1362
1405
  reject(new Error(`Agent exited (code=${code}) before responding`));
@@ -1364,9 +1407,11 @@ var Agent = class _Agent extends EventEmitter2 {
1364
1407
  const cleanup = () => {
1365
1408
  clearTimeout(timer);
1366
1409
  this.removeListener("message", onMsg);
1410
+ this.removeListener("idle", onIdle);
1367
1411
  this.removeListener("exit", onExit);
1368
1412
  };
1369
1413
  this.on("message", onMsg);
1414
+ this.on("idle", onIdle);
1370
1415
  this.on("exit", onExit);
1371
1416
  });
1372
1417
  const wrapped = `${question}
@@ -1385,14 +1430,22 @@ IMPORTANT: You MUST send your complete answer back using the SendMessage tool. D
1385
1430
  this.ensureNotDisposed();
1386
1431
  const timeout = opts?.timeout ?? 12e4;
1387
1432
  return new Promise((resolve, reject) => {
1433
+ let gotMessage = false;
1388
1434
  const timer = setTimeout(() => {
1389
1435
  cleanup();
1390
1436
  reject(new Error(`Timeout (${timeout}ms) waiting for response`));
1391
1437
  }, timeout);
1392
1438
  const onMsg = (text) => {
1439
+ gotMessage = true;
1393
1440
  cleanup();
1394
1441
  resolve(text);
1395
1442
  };
1443
+ const onIdle = () => {
1444
+ if (!gotMessage) {
1445
+ cleanup();
1446
+ resolve("");
1447
+ }
1448
+ };
1396
1449
  const onExit = (code) => {
1397
1450
  cleanup();
1398
1451
  reject(new Error(`Agent exited (code=${code}) before responding`));
@@ -1400,9 +1453,11 @@ IMPORTANT: You MUST send your complete answer back using the SendMessage tool. D
1400
1453
  const cleanup = () => {
1401
1454
  clearTimeout(timer);
1402
1455
  this.removeListener("message", onMsg);
1456
+ this.removeListener("idle", onIdle);
1403
1457
  this.removeListener("exit", onExit);
1404
1458
  };
1405
1459
  this.on("message", onMsg);
1460
+ this.on("idle", onIdle);
1406
1461
  this.on("exit", onExit);
1407
1462
  });
1408
1463
  }
@@ -1433,7 +1488,7 @@ IMPORTANT: You MUST send your complete answer back using the SendMessage tool. D
1433
1488
  const onMessage = (name, msg) => {
1434
1489
  if (name === agentName) this.emit("message", msg.text);
1435
1490
  };
1436
- const onIdle = (name) => {
1491
+ const onIdle = (name, _details) => {
1437
1492
  if (name === agentName) this.emit("idle");
1438
1493
  };
1439
1494
  const onPermission = (name, parsed) => {