@integrity-labs/agt-cli 0.9.0 → 0.9.2

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.
@@ -9,7 +9,7 @@ import {
9
9
  provisionStopHook,
10
10
  requireHost,
11
11
  resolveChannels
12
- } from "../chunk-55TMBRXT.js";
12
+ } from "../chunk-AMB6FJLZ.js";
13
13
  import {
14
14
  findTaskByTemplate,
15
15
  getProjectDir,
@@ -18,48 +18,24 @@ import {
18
18
  markTaskFired,
19
19
  syncTasksToScheduler
20
20
  } from "../chunk-2TSCVXHE.js";
21
+ import {
22
+ getProjectDir as getProjectDir2,
23
+ injectMessage,
24
+ isSessionHealthy,
25
+ resetRestartCount,
26
+ sanitizeMcpJson,
27
+ startPersistentSession,
28
+ stopAllSessionsAndWait,
29
+ stopPersistentSession
30
+ } from "../chunk-JOAT4JQN.js";
21
31
 
22
32
  // src/lib/manager-worker.ts
23
33
  import { createHash } from "crypto";
24
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, existsSync as existsSync2, rmSync, readdirSync, statSync, unlinkSync, copyFileSync } from "fs";
34
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, rmSync, readdirSync, statSync, unlinkSync, copyFileSync } from "fs";
25
35
  import https from "https";
26
- import { join as join2, dirname as dirname2 } from "path";
27
- import { homedir as homedir2 } from "os";
28
- import { fileURLToPath as fileURLToPath2 } from "url";
29
-
30
- // src/lib/mcp-sanitize.ts
31
- import { readFileSync, writeFileSync } from "fs";
32
- function sanitizeMcpJson(mcpConfigPath, apiHost) {
33
- try {
34
- const mcpRaw = JSON.parse(readFileSync(mcpConfigPath, "utf-8"));
35
- const servers = mcpRaw.mcpServers;
36
- if (!servers) return false;
37
- let changed = false;
38
- for (const [key, val] of Object.entries(servers)) {
39
- if (typeof val?.url !== "string") continue;
40
- if (val.url.startsWith("/")) {
41
- if (apiHost) {
42
- val.url = `${apiHost}${val.url}`;
43
- changed = true;
44
- } else {
45
- delete servers[key];
46
- changed = true;
47
- continue;
48
- }
49
- }
50
- const url = val.url;
51
- delete val.url;
52
- delete val.type;
53
- val.command = "npx";
54
- val.args = ["-y", "mcp-remote", url, "--allow-http"];
55
- changed = true;
56
- }
57
- if (changed) writeFileSync(mcpConfigPath, JSON.stringify(mcpRaw, null, 2));
58
- return changed;
59
- } catch {
60
- return false;
61
- }
62
- }
36
+ import { join, dirname } from "path";
37
+ import { homedir } from "os";
38
+ import { fileURLToPath } from "url";
63
39
 
64
40
  // src/lib/gateway-client.ts
65
41
  import { EventEmitter } from "events";
@@ -330,345 +306,6 @@ var GatewayClientPool = class extends EventEmitter {
330
306
  }
331
307
  };
332
308
 
333
- // src/lib/persistent-session.ts
334
- import { spawn, execSync, execFileSync } from "child_process";
335
- import { join, dirname } from "path";
336
- import { homedir } from "os";
337
- import { existsSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync } from "fs";
338
- import { fileURLToPath } from "url";
339
- function collectMcpServerNames(mcpConfigPath, channelsConfigPath) {
340
- const names = [];
341
- for (const path of [mcpConfigPath, channelsConfigPath]) {
342
- if (!existsSync(path)) continue;
343
- try {
344
- const data = JSON.parse(readFileSync2(path, "utf-8"));
345
- const servers = data.mcpServers;
346
- if (servers) names.push(...Object.keys(servers));
347
- } catch {
348
- }
349
- }
350
- return names;
351
- }
352
- var _acpxBin = null;
353
- function getAcpxBin() {
354
- if (_acpxBin) return _acpxBin;
355
- const moduleDir = dirname(fileURLToPath(import.meta.url));
356
- let dir = moduleDir;
357
- for (let i = 0; i < 6; i++) {
358
- const candidate = join(dir, "node_modules", ".bin", "acpx");
359
- if (existsSync(candidate)) {
360
- _acpxBin = candidate;
361
- return _acpxBin;
362
- }
363
- const parent = dirname(dir);
364
- if (parent === dir) break;
365
- dir = parent;
366
- }
367
- try {
368
- execSync("which acpx", { stdio: "ignore" });
369
- _acpxBin = "acpx";
370
- return _acpxBin;
371
- } catch {
372
- return "";
373
- }
374
- }
375
- var sessions = /* @__PURE__ */ new Map();
376
- function startPersistentSession(config2) {
377
- const existing = sessions.get(config2.codeName);
378
- if (existing && existing.status === "running") {
379
- return existing;
380
- }
381
- const restartCount = existing?.restartCount ?? 0;
382
- if (existing?.status === "crashed" && existing.startedAt) {
383
- const backoffMs = Math.min(5e3 * Math.pow(2, restartCount), 6e4);
384
- if (Date.now() - existing.startedAt < backoffMs) {
385
- return existing;
386
- }
387
- }
388
- const session = {
389
- codeName: config2.codeName,
390
- startedAt: null,
391
- restartCount,
392
- status: "starting"
393
- };
394
- sessions.set(config2.codeName, session);
395
- spawnSession(config2, session);
396
- return session;
397
- }
398
- function spawnSession(config2, session) {
399
- const { codeName, projectDir, mcpConfigPath, claudeMdPath, channels, devChannels, apiHost, log: log2 } = config2;
400
- const tmuxSession = `agt-${codeName}`;
401
- log2(`[persistent-session] Starting tmux session '${tmuxSession}' for '${codeName}'`);
402
- try {
403
- sanitizeMcpJson(mcpConfigPath, apiHost);
404
- writeAcpxConfig(config2);
405
- try {
406
- execSync(`tmux kill-session -t ${tmuxSession} 2>/dev/null`, { stdio: "ignore" });
407
- } catch {
408
- }
409
- const args = [];
410
- if (channels.length > 0) args.push("--channels", ...channels);
411
- if (devChannels.length > 0) args.push("--dangerously-load-development-channels", ...devChannels);
412
- args.push("--mcp-config", mcpConfigPath);
413
- const channelsConfigPath = join(projectDir, ".mcp-channels.json");
414
- if (existsSync(channelsConfigPath)) args.push("--mcp-config", channelsConfigPath);
415
- if (existsSync(claudeMdPath)) args.push("--system-prompt-file", claudeMdPath);
416
- args.push("--allow-dangerously-skip-permissions");
417
- args.push("--dangerously-skip-permissions");
418
- args.push("--strict-mcp-config");
419
- args.push("--name", tmuxSession);
420
- const mcpServerNames = collectMcpServerNames(mcpConfigPath, channelsConfigPath);
421
- const mcpPatterns = mcpServerNames.map((name) => `mcp__${name.replace(/-/g, "_")}__*`);
422
- const allowedTools = [
423
- ...mcpPatterns,
424
- "Bash",
425
- "Read",
426
- "Write",
427
- "Edit",
428
- "Grep",
429
- "Glob",
430
- "Agent",
431
- "Skill"
432
- ].join(",");
433
- args.push("--allowedTools", allowedTools);
434
- let envPrefix = "";
435
- const envIntegrationsPath = join(projectDir, ".env.integrations");
436
- if (existsSync(envIntegrationsPath)) {
437
- try {
438
- const envContent = readFileSync2(envIntegrationsPath, "utf-8");
439
- const envVars = envContent.split("\n").filter((line) => line && !line.startsWith("#") && line.includes("=")).map((line) => {
440
- const eqIdx = line.indexOf("=");
441
- const key = line.slice(0, eqIdx);
442
- const value = line.slice(eqIdx + 1);
443
- return `${key}=${JSON.stringify(value)}`;
444
- }).join(" ");
445
- if (envVars) envPrefix = `${envVars} `;
446
- } catch {
447
- }
448
- }
449
- const initPrompt = "You are now online. Wait for messages from your channels (Telegram, Slack) and respond to them. Use your kanban tools to track work.";
450
- const claudeCmd = `${envPrefix}claude ${JSON.stringify(initPrompt)} ${args.map((a) => a.includes(" ") || a.includes("*") ? JSON.stringify(a) : a).join(" ")}`;
451
- const child = spawn("tmux", [
452
- "new-session",
453
- "-d",
454
- "-s",
455
- tmuxSession,
456
- "-c",
457
- projectDir,
458
- claudeCmd
459
- ], {
460
- cwd: projectDir,
461
- stdio: ["ignore", "pipe", "pipe"],
462
- env: process.env
463
- });
464
- child.on("close", (code) => {
465
- if (code !== 0) {
466
- log2(`[persistent-session] Failed to create tmux session for '${codeName}' (exit ${code})`);
467
- session.status = "crashed";
468
- session.startedAt = Date.now();
469
- session.restartCount++;
470
- return;
471
- }
472
- log2(`[persistent-session] tmux session '${tmuxSession}' created for '${codeName}'`);
473
- acceptDialogs(tmuxSession, codeName, log2).catch(() => {
474
- });
475
- });
476
- child.on("error", (err) => {
477
- log2(`[persistent-session] Failed to start tmux for '${codeName}': ${err.message}`);
478
- session.status = "crashed";
479
- session.startedAt = Date.now();
480
- session.restartCount++;
481
- });
482
- session.startedAt = Date.now();
483
- session.status = "running";
484
- session.restartCount = 0;
485
- } catch (err) {
486
- log2(`[persistent-session] Failed to start session for '${codeName}': ${err.message}`);
487
- session.status = "crashed";
488
- session.startedAt = Date.now();
489
- session.restartCount++;
490
- }
491
- }
492
- async function acceptDialogs(tmuxSession, codeName, log2) {
493
- for (let i = 0; i < 15; i++) {
494
- await new Promise((r) => setTimeout(r, 2e3));
495
- try {
496
- const screen = execSync(`tmux capture-pane -t ${tmuxSession} -p 2>/dev/null`, { encoding: "utf-8" });
497
- if (screen.includes("Yes, I trust this folder")) {
498
- execSync(`tmux send-keys -t ${tmuxSession} Enter`, { stdio: "ignore" });
499
- log2(`[persistent-session] Auto-accepted workspace trust for '${codeName}'`);
500
- continue;
501
- }
502
- if (screen.includes("I am using this for local development")) {
503
- execSync(`tmux send-keys -t ${tmuxSession} Enter`, { stdio: "ignore" });
504
- log2(`[persistent-session] Auto-accepted dev channels for '${codeName}'`);
505
- continue;
506
- }
507
- if (screen.includes("Enter to confirm") && screen.includes("MCP")) {
508
- execSync(`tmux send-keys -t ${tmuxSession} Enter`, { stdio: "ignore" });
509
- log2(`[persistent-session] Auto-accepted MCP servers for '${codeName}'`);
510
- continue;
511
- }
512
- if (screen.includes("Yes, I accept") && screen.includes("Bypass Permissions")) {
513
- execSync(`tmux send-keys -t ${tmuxSession} 2`, { stdio: "ignore" });
514
- await new Promise((r) => setTimeout(r, 300));
515
- execSync(`tmux send-keys -t ${tmuxSession} Enter`, { stdio: "ignore" });
516
- log2(`[persistent-session] Auto-accepted bypass permissions for '${codeName}'`);
517
- continue;
518
- }
519
- if (screen.includes("\u276F") && !screen.includes("Enter to confirm")) {
520
- log2(`[persistent-session] Session ready for '${codeName}' \u2014 no more dialogs`);
521
- break;
522
- }
523
- } catch {
524
- break;
525
- }
526
- }
527
- }
528
- async function injectMessage(codeName, type, content, meta, log2) {
529
- const _log = log2 ?? ((_) => {
530
- });
531
- const session = sessions.get(codeName);
532
- if (!session || session.status !== "running") {
533
- _log(`[inject] SKIP '${codeName}' \u2014 session ${session ? `status=${session.status}` : "not found in Map"}`);
534
- return false;
535
- }
536
- const prefix = meta?.task_name ? `[Task: ${meta.task_name}] ` : "";
537
- const text = prefix + content;
538
- const projectDir = getProjectDir2(codeName);
539
- const acpx = getAcpxBin();
540
- if (acpx) {
541
- try {
542
- const tmpDir = join(projectDir, ".claude");
543
- mkdirSync(tmpDir, { recursive: true });
544
- const tmpFile = join(tmpDir, ".agt-inject-prompt.txt");
545
- writeFileSync2(tmpFile, text);
546
- _log(`[inject] acpx exec (fire-and-forget): cwd=${projectDir}, file=${tmpFile}`);
547
- const child = spawn(acpx, ["claude", "exec", "-f", tmpFile], {
548
- cwd: projectDir,
549
- stdio: "ignore",
550
- detached: true
551
- });
552
- child.on("error", (err) => {
553
- _log(`[inject] acpx spawn error for '${codeName}': ${err.message}`);
554
- });
555
- child.unref();
556
- return true;
557
- } catch (err) {
558
- _log(`[inject] acpx exec failed for '${codeName}': ${err.message}`);
559
- }
560
- } else {
561
- _log(`[inject] acpx binary not found \u2014 falling back to tmux send-keys`);
562
- }
563
- try {
564
- execFileSync("tmux", ["send-keys", "-t", `agt-${codeName}`, text, "Enter"], { stdio: "ignore" });
565
- _log(`[inject] tmux send-keys sent for '${codeName}' \u2014 unverified (returning false)`);
566
- return false;
567
- } catch (err) {
568
- _log(`[inject] tmux send-keys failed for '${codeName}': ${err.message}`);
569
- return false;
570
- }
571
- }
572
- function stopPersistentSession(codeName, log2) {
573
- const session = sessions.get(codeName);
574
- if (!session) return;
575
- log2(`[persistent-session] Stopping session for '${codeName}'`);
576
- session.status = "stopped";
577
- try {
578
- execSync(`tmux kill-session -t agt-${codeName} 2>/dev/null`, { stdio: "ignore" });
579
- } catch {
580
- }
581
- try {
582
- const acpx = getAcpxBin();
583
- if (acpx) {
584
- execFileSync(acpx, ["claude", "sessions", "close", `agt-${codeName}`], {
585
- cwd: getProjectDir2(codeName),
586
- timeout: 5e3,
587
- stdio: "ignore"
588
- });
589
- }
590
- } catch {
591
- }
592
- sessions.delete(codeName);
593
- }
594
- function isSessionHealthy(codeName) {
595
- const tmuxSession = `agt-${codeName}`;
596
- try {
597
- execSync(`tmux has-session -t ${tmuxSession} 2>/dev/null`, { stdio: "ignore" });
598
- } catch {
599
- const session2 = sessions.get(codeName);
600
- if (session2 && session2.status === "running") {
601
- session2.status = "crashed";
602
- }
603
- return false;
604
- }
605
- if (!sessions.has(codeName)) {
606
- sessions.set(codeName, {
607
- codeName,
608
- startedAt: Date.now(),
609
- restartCount: 0,
610
- status: "running"
611
- });
612
- }
613
- const session = sessions.get(codeName);
614
- if (session.status !== "running") {
615
- session.status = "running";
616
- }
617
- return true;
618
- }
619
- function resetRestartCount(codeName) {
620
- const session = sessions.get(codeName);
621
- if (session) session.restartCount = 0;
622
- }
623
- async function stopAllSessionsAndWait(log2, opts) {
624
- const codeNames = [...sessions.keys()];
625
- if (codeNames.length === 0) return;
626
- for (const codeName of codeNames) {
627
- stopPersistentSession(codeName, log2);
628
- }
629
- await new Promise((resolve) => setTimeout(resolve, Math.min(opts.timeoutMs, 2e3)));
630
- }
631
- function getProjectDir2(codeName) {
632
- return join(homedir(), ".augmented", codeName, "project");
633
- }
634
- function writeAcpxConfig(config2) {
635
- const { projectDir, mcpConfigPath, claudeMdPath, channels, devChannels } = config2;
636
- const claudeArgs = [];
637
- if (channels.length > 0) claudeArgs.push("--channels", ...channels);
638
- if (devChannels.length > 0) claudeArgs.push("--dangerously-load-development-channels", ...devChannels);
639
- claudeArgs.push("--mcp-config", mcpConfigPath);
640
- const channelsConfigPath = join(projectDir, ".mcp-channels.json");
641
- if (existsSync(channelsConfigPath)) claudeArgs.push("--mcp-config", channelsConfigPath);
642
- if (existsSync(claudeMdPath)) claudeArgs.push("--system-prompt-file", claudeMdPath);
643
- claudeArgs.push("--allow-dangerously-skip-permissions");
644
- claudeArgs.push("--dangerously-skip-permissions");
645
- claudeArgs.push("--strict-mcp-config");
646
- const mcpServerNames2 = collectMcpServerNames(mcpConfigPath, channelsConfigPath);
647
- const mcpPatterns2 = mcpServerNames2.map((name) => `mcp__${name.replace(/-/g, "_")}__*`);
648
- const allowedTools2 = [...mcpPatterns2, "Bash", "Read", "Write", "Edit", "Grep", "Glob", "Agent", "Skill"].join(",");
649
- claudeArgs.push("--allowedTools", allowedTools2);
650
- const acpCmd = `npx -y @agentclientprotocol/claude-agent-acp ${claudeArgs.map((a) => a.includes(" ") || a.includes("*") ? JSON.stringify(a) : a).join(" ")}`;
651
- const envIntegrationsPath = join(projectDir, ".env.integrations");
652
- const wrapperPath = join(projectDir, ".claude", "acpx-agent.sh");
653
- const wrapperLines = ["#!/usr/bin/env bash"];
654
- if (existsSync(envIntegrationsPath)) {
655
- wrapperLines.push(`set -a`, `source ${JSON.stringify(envIntegrationsPath)}`, `set +a`);
656
- }
657
- wrapperLines.push(`exec ${acpCmd}`);
658
- mkdirSync(join(projectDir, ".claude"), { recursive: true });
659
- writeFileSync2(wrapperPath, wrapperLines.join("\n") + "\n", { mode: 493 });
660
- const acpxConfig = {
661
- defaultAgent: "claude",
662
- defaultPermissions: "approve-all",
663
- agents: {
664
- claude: {
665
- command: wrapperPath
666
- }
667
- }
668
- };
669
- writeFileSync2(join(projectDir, ".acpxrc.json"), JSON.stringify(acpxConfig, null, 2));
670
- }
671
-
672
309
  // src/lib/realtime-chat.ts
673
310
  import { createClient } from "@supabase/supabase-js";
674
311
  var client = null;
@@ -911,8 +548,8 @@ function stopRealtimeChat() {
911
548
  var GATEWAY_PORT_BASE = 18800;
912
549
  var GATEWAY_PORT_STEP = 10;
913
550
  var GATEWAY_PORT_MAX = 18899;
914
- var AUGMENTED_DIR = join2(process.env["HOME"] ?? "/tmp", ".augmented");
915
- var GATEWAY_PORTS_FILE = join2(AUGMENTED_DIR, "gateway-ports.json");
551
+ var AUGMENTED_DIR = join(process.env["HOME"] ?? "/tmp", ".augmented");
552
+ var GATEWAY_PORTS_FILE = join(AUGMENTED_DIR, "gateway-ports.json");
916
553
  var config = null;
917
554
  var running = false;
918
555
  var pollTimer = null;
@@ -989,24 +626,24 @@ async function ensureFrameworkBinary(frameworkId) {
989
626
  if (frameworkId !== "claude-code") return;
990
627
  if (frameworkBinaryChecked.has(frameworkId)) return;
991
628
  frameworkBinaryChecked.add(frameworkId);
992
- const { execFileSync: execFileSync2 } = await import("child_process");
629
+ const { execFileSync } = await import("child_process");
993
630
  let brewPath;
994
631
  try {
995
- brewPath = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
632
+ brewPath = execFileSync("which", ["brew"], { timeout: 5e3 }).toString().trim();
996
633
  } catch {
997
634
  log("Homebrew not found \u2014 cannot auto-install/upgrade Claude Code. Install manually: https://claude.ai/download");
998
635
  return;
999
636
  }
1000
637
  let claudeExists = false;
1001
638
  try {
1002
- execFileSync2("which", ["claude"], { timeout: 5e3 });
639
+ execFileSync("which", ["claude"], { timeout: 5e3 });
1003
640
  claudeExists = true;
1004
641
  } catch {
1005
642
  }
1006
643
  if (!claudeExists) {
1007
644
  log("Claude Code binary not found \u2014 installing via Homebrew...");
1008
645
  try {
1009
- execFileSync2(brewPath, ["install", "--cask", "claude-code"], {
646
+ execFileSync(brewPath, ["install", "--cask", "claude-code"], {
1010
647
  timeout: 12e4,
1011
648
  stdio: "pipe"
1012
649
  });
@@ -1015,7 +652,7 @@ async function ensureFrameworkBinary(frameworkId) {
1015
652
  return;
1016
653
  }
1017
654
  try {
1018
- execFileSync2("which", ["claude"], { timeout: 5e3 });
655
+ execFileSync("which", ["claude"], { timeout: 5e3 });
1019
656
  log("Claude Code installed successfully");
1020
657
  } catch {
1021
658
  log("Claude Code install completed but binary not found on PATH \u2014 you may need to restart your terminal");
@@ -1023,7 +660,7 @@ async function ensureFrameworkBinary(frameworkId) {
1023
660
  } else {
1024
661
  log("Checking for Claude Code updates...");
1025
662
  try {
1026
- const output = execFileSync2(brewPath, ["upgrade", "--cask", "claude-code"], {
663
+ const output = execFileSync(brewPath, ["upgrade", "--cask", "claude-code"], {
1027
664
  timeout: 12e4,
1028
665
  stdio: "pipe"
1029
666
  }).toString();
@@ -1041,7 +678,7 @@ async function ensureFrameworkBinary(frameworkId) {
1041
678
  }
1042
679
  }
1043
680
  }
1044
- agentRuntimeAuthenticated = checkClaudeAuth(execFileSync2);
681
+ agentRuntimeAuthenticated = checkClaudeAuth(execFileSync);
1045
682
  }
1046
683
  var UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
1047
684
  var selfUpdateChecked = false;
@@ -1053,23 +690,23 @@ async function checkAndUpdateCli() {
1053
690
  const isDevMode = cliPath.includes("/src/") || cliPath.includes("tsx");
1054
691
  if (isDevMode) return;
1055
692
  if (!isHomebrew && !cliPath.includes("node_modules")) return;
1056
- const { homedir: homedir3 } = await import("os");
693
+ const { homedir: homedir2 } = await import("os");
1057
694
  const { readFileSync: readF, writeFileSync: writeF } = await import("fs");
1058
- const markerPath = join2(homedir3(), ".augmented", ".last-update-check");
695
+ const markerPath = join(homedir2(), ".augmented", ".last-update-check");
1059
696
  try {
1060
697
  const lastCheck = parseInt(readF(markerPath, "utf-8").trim(), 10);
1061
698
  if (Date.now() - lastCheck < UPDATE_CHECK_INTERVAL_MS) return;
1062
699
  } catch {
1063
700
  }
1064
- const { execFileSync: execFileSync2 } = await import("child_process");
701
+ const { execFileSync } = await import("child_process");
1065
702
  let brewPath;
1066
703
  try {
1067
- brewPath = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
704
+ brewPath = execFileSync("which", ["brew"], { timeout: 5e3 }).toString().trim();
1068
705
  } catch {
1069
706
  return;
1070
707
  }
1071
708
  try {
1072
- const outdated = execFileSync2(brewPath, ["outdated", "--json=v2"], {
709
+ const outdated = execFileSync(brewPath, ["outdated", "--json=v2"], {
1073
710
  timeout: 3e4,
1074
711
  encoding: "utf-8"
1075
712
  });
@@ -1080,7 +717,7 @@ async function checkAndUpdateCli() {
1080
717
  const latest = agtOutdated.current_version ?? "unknown";
1081
718
  log(`[self-update] agt CLI update available: ${installed} \u2192 ${latest}. Upgrading...`);
1082
719
  try {
1083
- execFileSync2(brewPath, ["upgrade", "integrity-labs/tap/agt"], {
720
+ execFileSync(brewPath, ["upgrade", "integrity-labs/tap/agt"], {
1084
721
  timeout: 12e4,
1085
722
  stdio: "pipe"
1086
723
  });
@@ -1096,9 +733,9 @@ async function checkAndUpdateCli() {
1096
733
  } catch {
1097
734
  }
1098
735
  }
1099
- function checkClaudeAuth(execFileSync2) {
736
+ function checkClaudeAuth(execFileSync) {
1100
737
  try {
1101
- const authOutput = execFileSync2("claude", ["auth", "status"], { timeout: 1e4, stdio: "pipe" }).toString().trim();
738
+ const authOutput = execFileSync("claude", ["auth", "status"], { timeout: 1e4, stdio: "pipe" }).toString().trim();
1102
739
  let loggedIn = null;
1103
740
  try {
1104
741
  const parsed = JSON.parse(authOutput);
@@ -1123,14 +760,14 @@ function checkClaudeAuth(execFileSync2) {
1123
760
  }
1124
761
  function loadGatewayPorts() {
1125
762
  try {
1126
- return JSON.parse(readFileSync3(GATEWAY_PORTS_FILE, "utf-8"));
763
+ return JSON.parse(readFileSync(GATEWAY_PORTS_FILE, "utf-8"));
1127
764
  } catch {
1128
765
  return {};
1129
766
  }
1130
767
  }
1131
768
  function saveGatewayPorts(ports) {
1132
- mkdirSync2(AUGMENTED_DIR, { recursive: true });
1133
- writeFileSync3(GATEWAY_PORTS_FILE, JSON.stringify(ports, null, 2));
769
+ mkdirSync(AUGMENTED_DIR, { recursive: true });
770
+ writeFileSync(GATEWAY_PORTS_FILE, JSON.stringify(ports, null, 2));
1134
771
  }
1135
772
  function allocatePort(codeName) {
1136
773
  const ports = loadGatewayPorts();
@@ -1152,11 +789,11 @@ function freePort(codeName) {
1152
789
  saveGatewayPorts(ports);
1153
790
  }
1154
791
  }
1155
- var STATE_FILE = join2(process.env["HOME"] ?? "/tmp", ".augmented", "manager-state.json");
792
+ var STATE_FILE = join(process.env["HOME"] ?? "/tmp", ".augmented", "manager-state.json");
1156
793
  function send(msg) {
1157
794
  if (msg.type === "state-update") {
1158
795
  try {
1159
- writeFileSync3(STATE_FILE, JSON.stringify(msg.state, null, 2));
796
+ writeFileSync(STATE_FILE, JSON.stringify(msg.state, null, 2));
1160
797
  } catch {
1161
798
  }
1162
799
  }
@@ -1178,7 +815,7 @@ function sha256(content) {
1178
815
  }
1179
816
  function hashFile(filePath) {
1180
817
  try {
1181
- const content = readFileSync3(filePath, "utf-8");
818
+ const content = readFileSync(filePath, "utf-8");
1182
819
  return sha256(content);
1183
820
  } catch {
1184
821
  return null;
@@ -1186,10 +823,10 @@ function hashFile(filePath) {
1186
823
  }
1187
824
  async function migrateToProfiles() {
1188
825
  const homeDir = process.env["HOME"] ?? "/tmp";
1189
- const sharedConfigPath = join2(homeDir, ".openclaw", "openclaw.json");
826
+ const sharedConfigPath = join(homeDir, ".openclaw", "openclaw.json");
1190
827
  let sharedConfig;
1191
828
  try {
1192
- sharedConfig = JSON.parse(readFileSync3(sharedConfigPath, "utf-8"));
829
+ sharedConfig = JSON.parse(readFileSync(sharedConfigPath, "utf-8"));
1193
830
  } catch {
1194
831
  return;
1195
832
  }
@@ -1202,19 +839,19 @@ async function migrateToProfiles() {
1202
839
  const codeName = agentEntry["id"];
1203
840
  if (!codeName) continue;
1204
841
  if (codeName === "main") continue;
1205
- const profileDir = join2(homeDir, `.openclaw-${codeName}`);
1206
- if (existsSync2(join2(profileDir, "openclaw.json"))) continue;
842
+ const profileDir = join(homeDir, `.openclaw-${codeName}`);
843
+ if (existsSync(join(profileDir, "openclaw.json"))) continue;
1207
844
  log(`Migrating agent '${codeName}' to per-agent profile`);
1208
845
  if (adapter.seedProfileConfig) {
1209
846
  adapter.seedProfileConfig(codeName);
1210
847
  }
1211
- const sharedAuthDir = join2(homeDir, ".openclaw", "agents", codeName, "agent");
1212
- const profileAuthDir = join2(profileDir, "agents", codeName, "agent");
1213
- const authFile = join2(sharedAuthDir, "auth-profiles.json");
1214
- if (existsSync2(authFile)) {
1215
- mkdirSync2(profileAuthDir, { recursive: true });
1216
- const authContent = readFileSync3(authFile, "utf-8");
1217
- writeFileSync3(join2(profileAuthDir, "auth-profiles.json"), authContent);
848
+ const sharedAuthDir = join(homeDir, ".openclaw", "agents", codeName, "agent");
849
+ const profileAuthDir = join(profileDir, "agents", codeName, "agent");
850
+ const authFile = join(sharedAuthDir, "auth-profiles.json");
851
+ if (existsSync(authFile)) {
852
+ mkdirSync(profileAuthDir, { recursive: true });
853
+ const authContent = readFileSync(authFile, "utf-8");
854
+ writeFileSync(join(profileAuthDir, "auth-profiles.json"), authContent);
1218
855
  }
1219
856
  allocatePort(codeName);
1220
857
  migrated++;
@@ -1252,7 +889,7 @@ function readGatewayToken(codeName) {
1252
889
  }
1253
890
  const homeDir = process.env["HOME"] ?? "/tmp";
1254
891
  try {
1255
- const cfg = JSON.parse(readFileSync3(join2(homeDir, `.openclaw-${codeName}`, "openclaw.json"), "utf-8"));
892
+ const cfg = JSON.parse(readFileSync(join(homeDir, `.openclaw-${codeName}`, "openclaw.json"), "utf-8"));
1256
893
  return cfg?.gateway?.auth?.token;
1257
894
  } catch {
1258
895
  return void 0;
@@ -1261,10 +898,10 @@ function readGatewayToken(codeName) {
1261
898
  var GATEWAY_HUNG_TIMEOUT_MS = 5 * 6e4;
1262
899
  function isGatewayHung(codeName) {
1263
900
  const homeDir = process.env["HOME"] ?? "/tmp";
1264
- const jobsPath = join2(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
1265
- if (!existsSync2(jobsPath)) return false;
901
+ const jobsPath = join(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
902
+ if (!existsSync(jobsPath)) return false;
1266
903
  try {
1267
- const data = JSON.parse(readFileSync3(jobsPath, "utf-8"));
904
+ const data = JSON.parse(readFileSync(jobsPath, "utf-8"));
1268
905
  const jobs = data.jobs ?? data;
1269
906
  if (!Array.isArray(jobs)) return false;
1270
907
  const now = Date.now();
@@ -1297,19 +934,19 @@ async function ensureGatewayRunning(codeName, adapter) {
1297
934
  }
1298
935
  await new Promise((r) => setTimeout(r, 2e3));
1299
936
  const homeDir = process.env["HOME"] ?? "/tmp";
1300
- const cronJobsPath = join2(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
937
+ const cronJobsPath = join(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
1301
938
  clearStaleCronRunState(cronJobsPath);
1302
939
  } else {
1303
940
  if (status.port) {
1304
941
  try {
1305
942
  const homeDir = process.env["HOME"] ?? "/tmp";
1306
- const configPath = join2(homeDir, `.openclaw-${codeName}`, "openclaw.json");
1307
- if (existsSync2(configPath)) {
1308
- const cfg = JSON.parse(readFileSync3(configPath, "utf-8"));
943
+ const configPath = join(homeDir, `.openclaw-${codeName}`, "openclaw.json");
944
+ if (existsSync(configPath)) {
945
+ const cfg = JSON.parse(readFileSync(configPath, "utf-8"));
1309
946
  if (cfg.gateway?.port !== status.port) {
1310
947
  if (!cfg.gateway) cfg.gateway = {};
1311
948
  cfg.gateway.port = status.port;
1312
- writeFileSync3(configPath, JSON.stringify(cfg, null, 2));
949
+ writeFileSync(configPath, JSON.stringify(cfg, null, 2));
1313
950
  }
1314
951
  }
1315
952
  } catch {
@@ -1329,12 +966,12 @@ async function ensureGatewayRunning(codeName, adapter) {
1329
966
  gatewaysStartedThisCycle.add(codeName);
1330
967
  try {
1331
968
  const homeDir = process.env["HOME"] ?? "/tmp";
1332
- const configPath = join2(homeDir, `.openclaw-${codeName}`, "openclaw.json");
1333
- if (existsSync2(configPath)) {
1334
- const cfg = JSON.parse(readFileSync3(configPath, "utf-8"));
969
+ const configPath = join(homeDir, `.openclaw-${codeName}`, "openclaw.json");
970
+ if (existsSync(configPath)) {
971
+ const cfg = JSON.parse(readFileSync(configPath, "utf-8"));
1335
972
  if (!cfg.gateway) cfg.gateway = {};
1336
973
  cfg.gateway.port = port;
1337
- writeFileSync3(configPath, JSON.stringify(cfg, null, 2));
974
+ writeFileSync(configPath, JSON.stringify(cfg, null, 2));
1338
975
  }
1339
976
  } catch {
1340
977
  }
@@ -1438,11 +1075,39 @@ async function pollCycle() {
1438
1075
  }
1439
1076
  try {
1440
1077
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
1078
+ const { collectDiagnostics } = await import("../persistent-session-M6GXAEQF.js");
1079
+ const diagCodeNames = [...persistentSessionAgents];
1080
+ const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
1081
+ let tailscaleHostname;
1082
+ try {
1083
+ const { execSync: es } = await import("child_process");
1084
+ const tsJson = es("tailscale status --self --json 2>/dev/null", {
1085
+ encoding: "utf-8",
1086
+ timeout: 3e3
1087
+ }).trim();
1088
+ const ts = JSON.parse(tsJson);
1089
+ tailscaleHostname = ts.Self?.DNSName?.replace(/\.$/, "") || void 0;
1090
+ } catch {
1091
+ try {
1092
+ const { execSync: es } = await import("child_process");
1093
+ tailscaleHostname = es("hostname", { encoding: "utf-8", timeout: 1e3 }).trim();
1094
+ } catch {
1095
+ }
1096
+ }
1097
+ let osUsername;
1098
+ try {
1099
+ const { userInfo } = await import("os");
1100
+ osUsername = userInfo().username;
1101
+ } catch {
1102
+ }
1441
1103
  await api.post("/host/heartbeat", {
1442
1104
  host_id: hostId,
1443
1105
  framework_version: cachedFrameworkVersion ?? void 0,
1444
1106
  host_security: detectHostSecurity() ?? void 0,
1445
- agent_runtime_authenticated: agentRuntimeAuthenticated
1107
+ agent_runtime_authenticated: agentRuntimeAuthenticated,
1108
+ agent_diagnostics: agentDiagnostics,
1109
+ hostname: tailscaleHostname,
1110
+ os_username: osUsername
1446
1111
  });
1447
1112
  } catch (err) {
1448
1113
  log(`Heartbeat failed: ${err.message}`);
@@ -1501,7 +1166,7 @@ async function pollCycle() {
1501
1166
  const adapter = resolveAgentFramework(prev.codeName);
1502
1167
  await stopGatewayIfRunning(prev.codeName, adapter);
1503
1168
  freePort(prev.codeName);
1504
- const agentDir = join2(config.configDir, prev.codeName, "provision");
1169
+ const agentDir = join(config.configDir, prev.codeName, "provision");
1505
1170
  await cleanupAgentFiles(prev.codeName, agentDir);
1506
1171
  clearAgentCaches(prev.agentId, prev.codeName);
1507
1172
  }
@@ -1568,7 +1233,7 @@ async function processAgent(agent, agentStates) {
1568
1233
  agentFrameworkCache.set(agent.code_name, agent.framework);
1569
1234
  }
1570
1235
  const now = (/* @__PURE__ */ new Date()).toISOString();
1571
- const agentDir = join2(config.configDir, agent.code_name, "provision");
1236
+ const agentDir = join(config.configDir, agent.code_name, "provision");
1572
1237
  const adapter = resolveAgentFramework(agent.code_name);
1573
1238
  if (agent.status === "draft" || agent.status === "paused") {
1574
1239
  log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
@@ -1719,9 +1384,9 @@ async function processAgent(agent, agentStates) {
1719
1384
  try {
1720
1385
  const artifacts = generateArtifacts(agent, refreshData, frameworkAdapter);
1721
1386
  const changedFiles = [];
1722
- mkdirSync2(agentDir, { recursive: true });
1387
+ mkdirSync(agentDir, { recursive: true });
1723
1388
  for (const artifact of artifacts) {
1724
- const filePath = join2(agentDir, artifact.relativePath);
1389
+ const filePath = join(agentDir, artifact.relativePath);
1725
1390
  const newHash = sha256(artifact.content);
1726
1391
  const existingHash = hashFile(filePath);
1727
1392
  if (newHash !== existingHash) {
@@ -1729,19 +1394,19 @@ async function processAgent(agent, agentStates) {
1729
1394
  }
1730
1395
  }
1731
1396
  if (changedFiles.length > 0) {
1732
- const isFirst = !existsSync2(join2(agentDir, "CHARTER.md"));
1397
+ const isFirst = !existsSync(join(agentDir, "CHARTER.md"));
1733
1398
  const verb = isFirst ? "Provisioning" : "Updating";
1734
1399
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
1735
1400
  log(`${verb} '${agent.code_name}': ${fileNames}`);
1736
1401
  for (const file of changedFiles) {
1737
- writeFileSync3(join2(agentDir, file.relativePath), file.content);
1402
+ writeFileSync(join(agentDir, file.relativePath), file.content);
1738
1403
  }
1739
1404
  lastProvisionAt = (/* @__PURE__ */ new Date()).toISOString();
1740
1405
  knownVersions.set(agent.agent_id, { charterVersion, toolsVersion });
1741
1406
  const trackedFiles = frameworkAdapter.driftTrackedFiles();
1742
1407
  const hashes = /* @__PURE__ */ new Map();
1743
1408
  for (const file of trackedFiles) {
1744
- const h = hashFile(join2(agentDir, file));
1409
+ const h = hashFile(join(agentDir, file));
1745
1410
  if (h) hashes.set(file, h);
1746
1411
  }
1747
1412
  writtenHashes.set(agent.agent_id, hashes);
@@ -1785,10 +1450,10 @@ async function processAgent(agent, agentStates) {
1785
1450
  }
1786
1451
  let lastDriftCheckAt = now;
1787
1452
  const written = writtenHashes.get(agent.agent_id);
1788
- if (written && existsSync2(agentDir)) {
1453
+ if (written && existsSync(agentDir)) {
1789
1454
  const driftedFiles = [];
1790
1455
  for (const [file, expectedHash] of written) {
1791
- const localHash = hashFile(join2(agentDir, file));
1456
+ const localHash = hashFile(join(agentDir, file));
1792
1457
  if (localHash && localHash !== expectedHash) {
1793
1458
  driftedFiles.push(file);
1794
1459
  }
@@ -1799,7 +1464,7 @@ async function processAgent(agent, agentStates) {
1799
1464
  try {
1800
1465
  const localHashes = {};
1801
1466
  for (const file of driftedFiles) {
1802
- localHashes[file] = hashFile(join2(agentDir, file));
1467
+ localHashes[file] = hashFile(join(agentDir, file));
1803
1468
  }
1804
1469
  await api.post("/host/drift", {
1805
1470
  agent_id: agent.agent_id,
@@ -1952,11 +1617,11 @@ async function processAgent(agent, agentStates) {
1952
1617
  }
1953
1618
  if (frameworkAdapter.removeMcpServer) {
1954
1619
  try {
1955
- const { readFileSync: readFileSync4 } = await import("fs");
1956
- const { join: join3 } = await import("path");
1957
- const { homedir: homedir3 } = await import("os");
1958
- const mcpPath = join3(homedir3(), ".augmented", "agents", agent.code_name, "provision", ".mcp.json");
1959
- const mcpConfig = JSON.parse(readFileSync4(mcpPath, "utf-8"));
1620
+ const { readFileSync: readFileSync2 } = await import("fs");
1621
+ const { join: join2 } = await import("path");
1622
+ const { homedir: homedir2 } = await import("os");
1623
+ const mcpPath = join2(homedir2(), ".augmented", "agents", agent.code_name, "provision", ".mcp.json");
1624
+ const mcpConfig = JSON.parse(readFileSync2(mcpPath, "utf-8"));
1960
1625
  if (mcpConfig.mcpServers) {
1961
1626
  const managedPrefixes = ["composio-", "one-", "nango-", "paragon-"];
1962
1627
  for (const key of Object.keys(mcpConfig.mcpServers)) {
@@ -2009,18 +1674,18 @@ async function processAgent(agent, agentStates) {
2009
1674
  "@tobilu/qmd"
2010
1675
  ]);
2011
1676
  if (intHash !== prevIntHash) {
2012
- const { execFileSync: execFileSync2 } = await import("child_process");
1677
+ const { execFileSync } = await import("child_process");
2013
1678
  for (const tool of capData.cliTools) {
2014
1679
  if (!ALLOWED_CLI_PACKAGES.has(tool.package)) {
2015
1680
  log(`Skipping CLI tool '${tool.package}' for '${agent.code_name}' \u2014 not on the allowed packages list`);
2016
1681
  continue;
2017
1682
  }
2018
1683
  try {
2019
- execFileSync2("which", [tool.binary], { stdio: "ignore" });
1684
+ execFileSync("which", [tool.binary], { stdio: "ignore" });
2020
1685
  } catch {
2021
1686
  log(`Installing CLI tool '${tool.package}' for '${agent.code_name}'...`);
2022
1687
  try {
2023
- execFileSync2("npm", ["install", "-g", tool.package], { stdio: "ignore", timeout: 6e4 });
1688
+ execFileSync("npm", ["install", "-g", tool.package], { stdio: "ignore", timeout: 6e4 });
2024
1689
  log(`CLI tool '${tool.binary}' installed successfully`);
2025
1690
  } catch (installErr) {
2026
1691
  log(`Failed to install CLI tool '${tool.package}': ${installErr.message}`);
@@ -2028,8 +1693,8 @@ async function processAgent(agent, agentStates) {
2028
1693
  }
2029
1694
  if (tool.binary === "qmd") {
2030
1695
  try {
2031
- const agentDir2 = join2(process.env["HOME"] ?? "/tmp", ".augmented", agent.code_name);
2032
- execFileSync2("qmd", ["collection", "add", agent.code_name, "project"], {
1696
+ const agentDir2 = join(process.env["HOME"] ?? "/tmp", ".augmented", agent.code_name);
1697
+ execFileSync("qmd", ["collection", "add", agent.code_name, "project"], {
2033
1698
  stdio: "ignore",
2034
1699
  timeout: 3e4,
2035
1700
  cwd: agentDir2
@@ -2089,8 +1754,8 @@ async function processAgent(agent, agentStates) {
2089
1754
  if (agent.status === "active") {
2090
1755
  if (frameworkAdapter.installPlugin) {
2091
1756
  try {
2092
- const pluginPath = join2(process.cwd(), "packages", "openclaw-plugin-augmented", "src", "index.ts");
2093
- if (existsSync2(pluginPath)) {
1757
+ const pluginPath = join(process.cwd(), "packages", "openclaw-plugin-augmented", "src", "index.ts");
1758
+ if (existsSync(pluginPath)) {
2094
1759
  frameworkAdapter.installPlugin(agent.code_name, "augmented", pluginPath, {
2095
1760
  agtHost: requireHost(),
2096
1761
  agtApiKey: getApiKey() ?? void 0,
@@ -2205,10 +1870,10 @@ async function processAgent(agent, agentStates) {
2205
1870
  lastWorkTriggerAt.set(agent.code_name, triggerTs);
2206
1871
  if (agentFw === "openclaw" && gatewayRunning && gatewayPort) {
2207
1872
  const homeDir = process.env["HOME"] ?? "/tmp";
2208
- const jobsPath = join2(homeDir, `.openclaw-${agent.code_name}`, "cron", "jobs.json");
2209
- if (existsSync2(jobsPath)) {
1873
+ const jobsPath = join(homeDir, `.openclaw-${agent.code_name}`, "cron", "jobs.json");
1874
+ if (existsSync(jobsPath)) {
2210
1875
  try {
2211
- const jobsData = JSON.parse(readFileSync3(jobsPath, "utf-8"));
1876
+ const jobsData = JSON.parse(readFileSync(jobsPath, "utf-8"));
2212
1877
  const kanbanJob = (jobsData.jobs ?? []).find(
2213
1878
  (j) => typeof j.name === "string" && j.name.includes("kanban-work")
2214
1879
  );
@@ -2353,19 +2018,19 @@ function cleanupStaleSessions(codeName) {
2353
2018
  lastCleanupAt.set(codeName, Date.now());
2354
2019
  const homeDir = process.env["HOME"] ?? "/tmp";
2355
2020
  for (const agentDir of ["main", codeName]) {
2356
- const sessionsDir = join2(homeDir, `.openclaw-${codeName}`, "agents", agentDir, "sessions");
2021
+ const sessionsDir = join(homeDir, `.openclaw-${codeName}`, "agents", agentDir, "sessions");
2357
2022
  cleanupCronSessions(sessionsDir, CRON_SESSION_KEEP_COUNT);
2358
2023
  }
2359
- const cronRunsDir = join2(homeDir, `.openclaw-${codeName}`, "cron", "runs");
2024
+ const cronRunsDir = join(homeDir, `.openclaw-${codeName}`, "cron", "runs");
2360
2025
  cleanupOldFiles(cronRunsDir, CRON_RUN_RETENTION_DAYS, ".jsonl");
2361
- const cronJobsPath = join2(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
2026
+ const cronJobsPath = join(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
2362
2027
  clearStaleCronRunState(cronJobsPath);
2363
2028
  }
2364
2029
  function cleanupCronSessions(sessionsDir, keepCount) {
2365
- const indexPath = join2(sessionsDir, "sessions.json");
2366
- if (!existsSync2(indexPath)) return;
2030
+ const indexPath = join(sessionsDir, "sessions.json");
2031
+ if (!existsSync(indexPath)) return;
2367
2032
  try {
2368
- const raw = readFileSync3(indexPath, "utf-8");
2033
+ const raw = readFileSync(indexPath, "utf-8");
2369
2034
  const index = JSON.parse(raw);
2370
2035
  const cronRunKeys = Object.keys(index).filter((k) => k.includes(":cron:") && k.includes(":run:")).map((k) => ({
2371
2036
  key: k,
@@ -2378,9 +2043,9 @@ function cleanupCronSessions(sessionsDir, keepCount) {
2378
2043
  for (const entry of toDelete) {
2379
2044
  delete index[entry.key];
2380
2045
  if (entry.sessionId) {
2381
- const sessionFile = join2(sessionsDir, `${entry.sessionId}.jsonl`);
2046
+ const sessionFile = join(sessionsDir, `${entry.sessionId}.jsonl`);
2382
2047
  try {
2383
- if (existsSync2(sessionFile)) {
2048
+ if (existsSync(sessionFile)) {
2384
2049
  unlinkSync(sessionFile);
2385
2050
  deletedFiles++;
2386
2051
  }
@@ -2400,8 +2065,8 @@ function cleanupCronSessions(sessionsDir, keepCount) {
2400
2065
  delete index[parentKey];
2401
2066
  if (parentSessionId) {
2402
2067
  try {
2403
- const f = join2(sessionsDir, `${parentSessionId}.jsonl`);
2404
- if (existsSync2(f)) {
2068
+ const f = join(sessionsDir, `${parentSessionId}.jsonl`);
2069
+ if (existsSync(f)) {
2405
2070
  unlinkSync(f);
2406
2071
  deletedFiles++;
2407
2072
  }
@@ -2410,7 +2075,7 @@ function cleanupCronSessions(sessionsDir, keepCount) {
2410
2075
  }
2411
2076
  }
2412
2077
  }
2413
- writeFileSync3(indexPath, JSON.stringify(index));
2078
+ writeFileSync(indexPath, JSON.stringify(index));
2414
2079
  if (toDelete.length > 0) {
2415
2080
  log(`Cleaned ${toDelete.length} cron session(s) and ${deletedFiles} file(s) from ${sessionsDir}`);
2416
2081
  }
@@ -2419,9 +2084,9 @@ function cleanupCronSessions(sessionsDir, keepCount) {
2419
2084
  }
2420
2085
  var STALE_RUN_TIMEOUT_MS = 5 * 6e4;
2421
2086
  function clearStaleCronRunState(jobsPath) {
2422
- if (!existsSync2(jobsPath)) return;
2087
+ if (!existsSync(jobsPath)) return;
2423
2088
  try {
2424
- const raw = readFileSync3(jobsPath, "utf-8");
2089
+ const raw = readFileSync(jobsPath, "utf-8");
2425
2090
  const data = JSON.parse(raw);
2426
2091
  const jobs = data.jobs ?? data;
2427
2092
  if (!Array.isArray(jobs)) return;
@@ -2446,19 +2111,19 @@ function clearStaleCronRunState(jobsPath) {
2446
2111
  }
2447
2112
  }
2448
2113
  if (changed) {
2449
- writeFileSync3(jobsPath, JSON.stringify(data, null, 2));
2114
+ writeFileSync(jobsPath, JSON.stringify(data, null, 2));
2450
2115
  }
2451
2116
  } catch {
2452
2117
  }
2453
2118
  }
2454
2119
  function cleanupOldFiles(dir, maxAgeDays, ext) {
2455
- if (!existsSync2(dir)) return;
2120
+ if (!existsSync(dir)) return;
2456
2121
  const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1e3;
2457
2122
  let removed = 0;
2458
2123
  try {
2459
2124
  for (const f of readdirSync(dir)) {
2460
2125
  if (!f.endsWith(ext)) continue;
2461
- const fullPath = join2(dir, f);
2126
+ const fullPath = join(dir, f);
2462
2127
  try {
2463
2128
  const st = statSync(fullPath);
2464
2129
  if (st.mtimeMs < cutoff) {
@@ -2549,16 +2214,16 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
2549
2214
  }
2550
2215
  async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
2551
2216
  const projectDir = getProjectDir(codeName);
2552
- const mcpConfigPath = join2(projectDir, ".mcp.json");
2217
+ const mcpConfigPath = join(projectDir, ".mcp.json");
2553
2218
  sanitizeMcpJson(mcpConfigPath, requireHost());
2554
2219
  try {
2555
- const claudeMdPath = join2(projectDir, "CLAUDE.md");
2220
+ const claudeMdPath = join(projectDir, "CLAUDE.md");
2556
2221
  const serverNames = [];
2557
- const channelsConfigPath = join2(projectDir, ".mcp-channels.json");
2222
+ const channelsConfigPath = join(projectDir, ".mcp-channels.json");
2558
2223
  for (const p of [mcpConfigPath, channelsConfigPath]) {
2559
- if (existsSync2(p)) {
2224
+ if (existsSync(p)) {
2560
2225
  try {
2561
- const d = JSON.parse(readFileSync3(p, "utf-8"));
2226
+ const d = JSON.parse(readFileSync(p, "utf-8"));
2562
2227
  if (d.mcpServers) serverNames.push(...Object.keys(d.mcpServers));
2563
2228
  } catch {
2564
2229
  }
@@ -2577,15 +2242,15 @@ async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
2577
2242
  "--allowedTools",
2578
2243
  allowedTools
2579
2244
  ];
2580
- if (existsSync2(channelsConfigPath)) claudeArgs.push("--mcp-config", channelsConfigPath);
2581
- if (existsSync2(claudeMdPath)) {
2245
+ if (existsSync(channelsConfigPath)) claudeArgs.push("--mcp-config", channelsConfigPath);
2246
+ if (existsSync(claudeMdPath)) {
2582
2247
  claudeArgs.push("--system-prompt-file", claudeMdPath);
2583
2248
  }
2584
2249
  const childEnv = { ...process.env };
2585
- const envIntPath = join2(projectDir, ".env.integrations");
2586
- if (existsSync2(envIntPath)) {
2250
+ const envIntPath = join(projectDir, ".env.integrations");
2251
+ if (existsSync(envIntPath)) {
2587
2252
  try {
2588
- for (const line of readFileSync3(envIntPath, "utf-8").split("\n")) {
2253
+ for (const line of readFileSync(envIntPath, "utf-8").split("\n")) {
2589
2254
  if (!line || line.startsWith("#") || !line.includes("=")) continue;
2590
2255
  const eqIdx = line.indexOf("=");
2591
2256
  childEnv[line.slice(0, eqIdx)] = line.slice(eqIdx + 1);
@@ -2688,8 +2353,8 @@ var persistentSessionAgents = /* @__PURE__ */ new Set();
2688
2353
  async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
2689
2354
  const codeName = agent.code_name;
2690
2355
  const projectDir = getProjectDir2(codeName);
2691
- const mcpConfigPath = join2(projectDir, ".mcp.json");
2692
- const claudeMdPath = join2(projectDir, "CLAUDE.md");
2356
+ const mcpConfigPath = join(projectDir, ".mcp.json");
2357
+ const claudeMdPath = join(projectDir, "CLAUDE.md");
2693
2358
  const channelConfigs = refreshData.channel_configs;
2694
2359
  const channels = [];
2695
2360
  const devChannels = [];
@@ -2705,8 +2370,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
2705
2370
  }
2706
2371
  }
2707
2372
  if (!agentRuntimeAuthenticated) {
2708
- const { execFileSync: execFileSync2 } = await import("child_process");
2709
- agentRuntimeAuthenticated = checkClaudeAuth(execFileSync2);
2373
+ const { execFileSync } = await import("child_process");
2374
+ agentRuntimeAuthenticated = checkClaudeAuth(execFileSync);
2710
2375
  if (!agentRuntimeAuthenticated) {
2711
2376
  log(`[persistent-session] Skipping '${codeName}' \u2014 Claude Code not authenticated`);
2712
2377
  return;
@@ -3022,13 +2687,13 @@ async function processDirectChatMessage(agent, msg) {
3022
2687
  if (fw === "claude-code") {
3023
2688
  const { getProjectDir: ccProjectDir } = await import("../claude-scheduler-VFBZFE6U.js");
3024
2689
  const projDir = ccProjectDir(agent.codeName);
3025
- const mcpConfigPath = join2(projDir, ".mcp.json");
3026
- const channelsConfigPath = join2(projDir, ".mcp-channels.json");
2690
+ const mcpConfigPath = join(projDir, ".mcp.json");
2691
+ const channelsConfigPath = join(projDir, ".mcp-channels.json");
3027
2692
  const serverNames = [];
3028
2693
  for (const p of [mcpConfigPath, channelsConfigPath]) {
3029
- if (existsSync2(p)) {
2694
+ if (existsSync(p)) {
3030
2695
  try {
3031
- const d = JSON.parse(readFileSync3(p, "utf-8"));
2696
+ const d = JSON.parse(readFileSync(p, "utf-8"));
3032
2697
  if (d.mcpServers) serverNames.push(...Object.keys(d.mcpServers));
3033
2698
  } catch {
3034
2699
  }
@@ -3047,16 +2712,16 @@ async function processDirectChatMessage(agent, msg) {
3047
2712
  "--allowedTools",
3048
2713
  allowedTools
3049
2714
  ];
3050
- if (existsSync2(channelsConfigPath)) chatArgs.push("--mcp-config", channelsConfigPath);
3051
- const chatClaudeMd = join2(projDir, "CLAUDE.md");
3052
- if (existsSync2(chatClaudeMd)) {
2715
+ if (existsSync(channelsConfigPath)) chatArgs.push("--mcp-config", channelsConfigPath);
2716
+ const chatClaudeMd = join(projDir, "CLAUDE.md");
2717
+ if (existsSync(chatClaudeMd)) {
3053
2718
  chatArgs.push("--system-prompt-file", chatClaudeMd);
3054
2719
  }
3055
- const envIntPath = join2(projDir, ".env.integrations");
2720
+ const envIntPath = join(projDir, ".env.integrations");
3056
2721
  const childEnv = { ...process.env };
3057
- if (existsSync2(envIntPath)) {
2722
+ if (existsSync(envIntPath)) {
3058
2723
  try {
3059
- for (const line of readFileSync3(envIntPath, "utf-8").split("\n")) {
2724
+ for (const line of readFileSync(envIntPath, "utf-8").split("\n")) {
3060
2725
  if (!line || line.startsWith("#") || !line.includes("=")) continue;
3061
2726
  const eqIdx = line.indexOf("=");
3062
2727
  childEnv[line.slice(0, eqIdx)] = line.slice(eqIdx + 1);
@@ -3328,12 +2993,12 @@ function getBuiltInSkillContent(skillId) {
3328
2993
  if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
3329
2994
  try {
3330
2995
  const candidates = [
3331
- join2(process.cwd(), "skills", skillId, "SKILL.md"),
3332
- join2(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "skills", skillId, "SKILL.md")
2996
+ join(process.cwd(), "skills", skillId, "SKILL.md"),
2997
+ join(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "skills", skillId, "SKILL.md")
3333
2998
  ];
3334
2999
  for (const candidate of candidates) {
3335
- if (existsSync2(candidate)) {
3336
- const content = readFileSync3(candidate, "utf-8");
3000
+ if (existsSync(candidate)) {
3001
+ const content = readFileSync(candidate, "utf-8");
3337
3002
  const files = [{ relativePath: "SKILL.md", content }];
3338
3003
  builtInSkillCache.set(skillId, files);
3339
3004
  return files;
@@ -3749,7 +3414,7 @@ function generateArtifacts(agent, refreshData, adapter) {
3749
3414
  return provisionOutput.artifacts;
3750
3415
  }
3751
3416
  async function cleanupAgentFiles(codeName, agentDir) {
3752
- if (existsSync2(agentDir)) {
3417
+ if (existsSync(agentDir)) {
3753
3418
  try {
3754
3419
  rmSync(agentDir, { recursive: true, force: true });
3755
3420
  log(`Removed provision directory for '${codeName}'`);
@@ -3808,8 +3473,8 @@ var caffeinateProc = null;
3808
3473
  async function startCaffeinate() {
3809
3474
  if (process.platform !== "darwin") return;
3810
3475
  try {
3811
- const { spawn: spawn2 } = await import("child_process");
3812
- caffeinateProc = spawn2("caffeinate", ["-dims"], {
3476
+ const { spawn } = await import("child_process");
3477
+ caffeinateProc = spawn("caffeinate", ["-dims"], {
3813
3478
  stdio: "ignore",
3814
3479
  detached: false
3815
3480
  });
@@ -3860,8 +3525,8 @@ async function killAllAgtTmuxSessions() {
3860
3525
  ["list-sessions", "-F", "#{session_name}"],
3861
3526
  { timeout: 2e3, stdin: "ignore" }
3862
3527
  );
3863
- const sessions2 = output.trim().split("\n").filter((s) => s.startsWith("agt-"));
3864
- for (const session of sessions2) {
3528
+ const sessions = output.trim().split("\n").filter((s) => s.startsWith("agt-"));
3529
+ for (const session of sessions) {
3865
3530
  try {
3866
3531
  await execFilePromiseLong("tmux", ["kill-session", "-t", session], {
3867
3532
  timeout: 2e3,
@@ -3871,8 +3536,8 @@ async function killAllAgtTmuxSessions() {
3871
3536
  } catch {
3872
3537
  }
3873
3538
  }
3874
- if (sessions2.length > 0) {
3875
- log(`Cleaned up ${sessions2.length} agt-* tmux session(s)`);
3539
+ if (sessions.length > 0) {
3540
+ log(`Cleaned up ${sessions.length} agt-* tmux session(s)`);
3876
3541
  }
3877
3542
  } catch {
3878
3543
  }
@@ -3904,18 +3569,18 @@ function startManager(opts) {
3904
3569
  startPolling();
3905
3570
  }
3906
3571
  function deployMcpAssets() {
3907
- const targetDir = join2(homedir2(), ".augmented", "_mcp");
3908
- mkdirSync2(targetDir, { recursive: true });
3909
- const moduleDir = dirname2(fileURLToPath2(import.meta.url));
3572
+ const targetDir = join(homedir(), ".augmented", "_mcp");
3573
+ mkdirSync(targetDir, { recursive: true });
3574
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
3910
3575
  let mcpSourceDir = "";
3911
3576
  let dir = moduleDir;
3912
3577
  for (let i = 0; i < 6; i++) {
3913
- const candidate = join2(dir, "mcp");
3914
- if (existsSync2(join2(candidate, "index.js"))) {
3578
+ const candidate = join(dir, "mcp");
3579
+ if (existsSync(join(candidate, "index.js"))) {
3915
3580
  mcpSourceDir = candidate;
3916
3581
  break;
3917
3582
  }
3918
- const parent = dirname2(dir);
3583
+ const parent = dirname(dir);
3919
3584
  if (parent === dir) break;
3920
3585
  dir = parent;
3921
3586
  }
@@ -3924,9 +3589,9 @@ function deployMcpAssets() {
3924
3589
  return;
3925
3590
  }
3926
3591
  for (const file of ["index.js", "slack-channel.js"]) {
3927
- const src = join2(mcpSourceDir, file);
3928
- const dst = join2(targetDir, file);
3929
- if (!existsSync2(src)) continue;
3592
+ const src = join(mcpSourceDir, file);
3593
+ const dst = join(targetDir, file);
3594
+ if (!existsSync(src)) continue;
3930
3595
  try {
3931
3596
  copyFileSync(src, dst);
3932
3597
  } catch (err) {