@integrity-labs/agt-cli 0.9.0 → 0.9.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.
@@ -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-HTBIKZKS.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,32 @@ 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-ZCB562FN.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
+ }
1441
1097
  await api.post("/host/heartbeat", {
1442
1098
  host_id: hostId,
1443
1099
  framework_version: cachedFrameworkVersion ?? void 0,
1444
1100
  host_security: detectHostSecurity() ?? void 0,
1445
- agent_runtime_authenticated: agentRuntimeAuthenticated
1101
+ agent_runtime_authenticated: agentRuntimeAuthenticated,
1102
+ agent_diagnostics: agentDiagnostics,
1103
+ hostname: tailscaleHostname
1446
1104
  });
1447
1105
  } catch (err) {
1448
1106
  log(`Heartbeat failed: ${err.message}`);
@@ -1501,7 +1159,7 @@ async function pollCycle() {
1501
1159
  const adapter = resolveAgentFramework(prev.codeName);
1502
1160
  await stopGatewayIfRunning(prev.codeName, adapter);
1503
1161
  freePort(prev.codeName);
1504
- const agentDir = join2(config.configDir, prev.codeName, "provision");
1162
+ const agentDir = join(config.configDir, prev.codeName, "provision");
1505
1163
  await cleanupAgentFiles(prev.codeName, agentDir);
1506
1164
  clearAgentCaches(prev.agentId, prev.codeName);
1507
1165
  }
@@ -1568,7 +1226,7 @@ async function processAgent(agent, agentStates) {
1568
1226
  agentFrameworkCache.set(agent.code_name, agent.framework);
1569
1227
  }
1570
1228
  const now = (/* @__PURE__ */ new Date()).toISOString();
1571
- const agentDir = join2(config.configDir, agent.code_name, "provision");
1229
+ const agentDir = join(config.configDir, agent.code_name, "provision");
1572
1230
  const adapter = resolveAgentFramework(agent.code_name);
1573
1231
  if (agent.status === "draft" || agent.status === "paused") {
1574
1232
  log(`Agent '${agent.code_name}' is ${agent.status}, skipping provisioning`);
@@ -1719,9 +1377,9 @@ async function processAgent(agent, agentStates) {
1719
1377
  try {
1720
1378
  const artifacts = generateArtifacts(agent, refreshData, frameworkAdapter);
1721
1379
  const changedFiles = [];
1722
- mkdirSync2(agentDir, { recursive: true });
1380
+ mkdirSync(agentDir, { recursive: true });
1723
1381
  for (const artifact of artifacts) {
1724
- const filePath = join2(agentDir, artifact.relativePath);
1382
+ const filePath = join(agentDir, artifact.relativePath);
1725
1383
  const newHash = sha256(artifact.content);
1726
1384
  const existingHash = hashFile(filePath);
1727
1385
  if (newHash !== existingHash) {
@@ -1729,19 +1387,19 @@ async function processAgent(agent, agentStates) {
1729
1387
  }
1730
1388
  }
1731
1389
  if (changedFiles.length > 0) {
1732
- const isFirst = !existsSync2(join2(agentDir, "CHARTER.md"));
1390
+ const isFirst = !existsSync(join(agentDir, "CHARTER.md"));
1733
1391
  const verb = isFirst ? "Provisioning" : "Updating";
1734
1392
  const fileNames = changedFiles.map((f) => f.relativePath).join(", ");
1735
1393
  log(`${verb} '${agent.code_name}': ${fileNames}`);
1736
1394
  for (const file of changedFiles) {
1737
- writeFileSync3(join2(agentDir, file.relativePath), file.content);
1395
+ writeFileSync(join(agentDir, file.relativePath), file.content);
1738
1396
  }
1739
1397
  lastProvisionAt = (/* @__PURE__ */ new Date()).toISOString();
1740
1398
  knownVersions.set(agent.agent_id, { charterVersion, toolsVersion });
1741
1399
  const trackedFiles = frameworkAdapter.driftTrackedFiles();
1742
1400
  const hashes = /* @__PURE__ */ new Map();
1743
1401
  for (const file of trackedFiles) {
1744
- const h = hashFile(join2(agentDir, file));
1402
+ const h = hashFile(join(agentDir, file));
1745
1403
  if (h) hashes.set(file, h);
1746
1404
  }
1747
1405
  writtenHashes.set(agent.agent_id, hashes);
@@ -1785,10 +1443,10 @@ async function processAgent(agent, agentStates) {
1785
1443
  }
1786
1444
  let lastDriftCheckAt = now;
1787
1445
  const written = writtenHashes.get(agent.agent_id);
1788
- if (written && existsSync2(agentDir)) {
1446
+ if (written && existsSync(agentDir)) {
1789
1447
  const driftedFiles = [];
1790
1448
  for (const [file, expectedHash] of written) {
1791
- const localHash = hashFile(join2(agentDir, file));
1449
+ const localHash = hashFile(join(agentDir, file));
1792
1450
  if (localHash && localHash !== expectedHash) {
1793
1451
  driftedFiles.push(file);
1794
1452
  }
@@ -1799,7 +1457,7 @@ async function processAgent(agent, agentStates) {
1799
1457
  try {
1800
1458
  const localHashes = {};
1801
1459
  for (const file of driftedFiles) {
1802
- localHashes[file] = hashFile(join2(agentDir, file));
1460
+ localHashes[file] = hashFile(join(agentDir, file));
1803
1461
  }
1804
1462
  await api.post("/host/drift", {
1805
1463
  agent_id: agent.agent_id,
@@ -1952,11 +1610,11 @@ async function processAgent(agent, agentStates) {
1952
1610
  }
1953
1611
  if (frameworkAdapter.removeMcpServer) {
1954
1612
  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"));
1613
+ const { readFileSync: readFileSync2 } = await import("fs");
1614
+ const { join: join2 } = await import("path");
1615
+ const { homedir: homedir2 } = await import("os");
1616
+ const mcpPath = join2(homedir2(), ".augmented", "agents", agent.code_name, "provision", ".mcp.json");
1617
+ const mcpConfig = JSON.parse(readFileSync2(mcpPath, "utf-8"));
1960
1618
  if (mcpConfig.mcpServers) {
1961
1619
  const managedPrefixes = ["composio-", "one-", "nango-", "paragon-"];
1962
1620
  for (const key of Object.keys(mcpConfig.mcpServers)) {
@@ -2009,18 +1667,18 @@ async function processAgent(agent, agentStates) {
2009
1667
  "@tobilu/qmd"
2010
1668
  ]);
2011
1669
  if (intHash !== prevIntHash) {
2012
- const { execFileSync: execFileSync2 } = await import("child_process");
1670
+ const { execFileSync } = await import("child_process");
2013
1671
  for (const tool of capData.cliTools) {
2014
1672
  if (!ALLOWED_CLI_PACKAGES.has(tool.package)) {
2015
1673
  log(`Skipping CLI tool '${tool.package}' for '${agent.code_name}' \u2014 not on the allowed packages list`);
2016
1674
  continue;
2017
1675
  }
2018
1676
  try {
2019
- execFileSync2("which", [tool.binary], { stdio: "ignore" });
1677
+ execFileSync("which", [tool.binary], { stdio: "ignore" });
2020
1678
  } catch {
2021
1679
  log(`Installing CLI tool '${tool.package}' for '${agent.code_name}'...`);
2022
1680
  try {
2023
- execFileSync2("npm", ["install", "-g", tool.package], { stdio: "ignore", timeout: 6e4 });
1681
+ execFileSync("npm", ["install", "-g", tool.package], { stdio: "ignore", timeout: 6e4 });
2024
1682
  log(`CLI tool '${tool.binary}' installed successfully`);
2025
1683
  } catch (installErr) {
2026
1684
  log(`Failed to install CLI tool '${tool.package}': ${installErr.message}`);
@@ -2028,8 +1686,8 @@ async function processAgent(agent, agentStates) {
2028
1686
  }
2029
1687
  if (tool.binary === "qmd") {
2030
1688
  try {
2031
- const agentDir2 = join2(process.env["HOME"] ?? "/tmp", ".augmented", agent.code_name);
2032
- execFileSync2("qmd", ["collection", "add", agent.code_name, "project"], {
1689
+ const agentDir2 = join(process.env["HOME"] ?? "/tmp", ".augmented", agent.code_name);
1690
+ execFileSync("qmd", ["collection", "add", agent.code_name, "project"], {
2033
1691
  stdio: "ignore",
2034
1692
  timeout: 3e4,
2035
1693
  cwd: agentDir2
@@ -2089,8 +1747,8 @@ async function processAgent(agent, agentStates) {
2089
1747
  if (agent.status === "active") {
2090
1748
  if (frameworkAdapter.installPlugin) {
2091
1749
  try {
2092
- const pluginPath = join2(process.cwd(), "packages", "openclaw-plugin-augmented", "src", "index.ts");
2093
- if (existsSync2(pluginPath)) {
1750
+ const pluginPath = join(process.cwd(), "packages", "openclaw-plugin-augmented", "src", "index.ts");
1751
+ if (existsSync(pluginPath)) {
2094
1752
  frameworkAdapter.installPlugin(agent.code_name, "augmented", pluginPath, {
2095
1753
  agtHost: requireHost(),
2096
1754
  agtApiKey: getApiKey() ?? void 0,
@@ -2205,10 +1863,10 @@ async function processAgent(agent, agentStates) {
2205
1863
  lastWorkTriggerAt.set(agent.code_name, triggerTs);
2206
1864
  if (agentFw === "openclaw" && gatewayRunning && gatewayPort) {
2207
1865
  const homeDir = process.env["HOME"] ?? "/tmp";
2208
- const jobsPath = join2(homeDir, `.openclaw-${agent.code_name}`, "cron", "jobs.json");
2209
- if (existsSync2(jobsPath)) {
1866
+ const jobsPath = join(homeDir, `.openclaw-${agent.code_name}`, "cron", "jobs.json");
1867
+ if (existsSync(jobsPath)) {
2210
1868
  try {
2211
- const jobsData = JSON.parse(readFileSync3(jobsPath, "utf-8"));
1869
+ const jobsData = JSON.parse(readFileSync(jobsPath, "utf-8"));
2212
1870
  const kanbanJob = (jobsData.jobs ?? []).find(
2213
1871
  (j) => typeof j.name === "string" && j.name.includes("kanban-work")
2214
1872
  );
@@ -2353,19 +2011,19 @@ function cleanupStaleSessions(codeName) {
2353
2011
  lastCleanupAt.set(codeName, Date.now());
2354
2012
  const homeDir = process.env["HOME"] ?? "/tmp";
2355
2013
  for (const agentDir of ["main", codeName]) {
2356
- const sessionsDir = join2(homeDir, `.openclaw-${codeName}`, "agents", agentDir, "sessions");
2014
+ const sessionsDir = join(homeDir, `.openclaw-${codeName}`, "agents", agentDir, "sessions");
2357
2015
  cleanupCronSessions(sessionsDir, CRON_SESSION_KEEP_COUNT);
2358
2016
  }
2359
- const cronRunsDir = join2(homeDir, `.openclaw-${codeName}`, "cron", "runs");
2017
+ const cronRunsDir = join(homeDir, `.openclaw-${codeName}`, "cron", "runs");
2360
2018
  cleanupOldFiles(cronRunsDir, CRON_RUN_RETENTION_DAYS, ".jsonl");
2361
- const cronJobsPath = join2(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
2019
+ const cronJobsPath = join(homeDir, `.openclaw-${codeName}`, "cron", "jobs.json");
2362
2020
  clearStaleCronRunState(cronJobsPath);
2363
2021
  }
2364
2022
  function cleanupCronSessions(sessionsDir, keepCount) {
2365
- const indexPath = join2(sessionsDir, "sessions.json");
2366
- if (!existsSync2(indexPath)) return;
2023
+ const indexPath = join(sessionsDir, "sessions.json");
2024
+ if (!existsSync(indexPath)) return;
2367
2025
  try {
2368
- const raw = readFileSync3(indexPath, "utf-8");
2026
+ const raw = readFileSync(indexPath, "utf-8");
2369
2027
  const index = JSON.parse(raw);
2370
2028
  const cronRunKeys = Object.keys(index).filter((k) => k.includes(":cron:") && k.includes(":run:")).map((k) => ({
2371
2029
  key: k,
@@ -2378,9 +2036,9 @@ function cleanupCronSessions(sessionsDir, keepCount) {
2378
2036
  for (const entry of toDelete) {
2379
2037
  delete index[entry.key];
2380
2038
  if (entry.sessionId) {
2381
- const sessionFile = join2(sessionsDir, `${entry.sessionId}.jsonl`);
2039
+ const sessionFile = join(sessionsDir, `${entry.sessionId}.jsonl`);
2382
2040
  try {
2383
- if (existsSync2(sessionFile)) {
2041
+ if (existsSync(sessionFile)) {
2384
2042
  unlinkSync(sessionFile);
2385
2043
  deletedFiles++;
2386
2044
  }
@@ -2400,8 +2058,8 @@ function cleanupCronSessions(sessionsDir, keepCount) {
2400
2058
  delete index[parentKey];
2401
2059
  if (parentSessionId) {
2402
2060
  try {
2403
- const f = join2(sessionsDir, `${parentSessionId}.jsonl`);
2404
- if (existsSync2(f)) {
2061
+ const f = join(sessionsDir, `${parentSessionId}.jsonl`);
2062
+ if (existsSync(f)) {
2405
2063
  unlinkSync(f);
2406
2064
  deletedFiles++;
2407
2065
  }
@@ -2410,7 +2068,7 @@ function cleanupCronSessions(sessionsDir, keepCount) {
2410
2068
  }
2411
2069
  }
2412
2070
  }
2413
- writeFileSync3(indexPath, JSON.stringify(index));
2071
+ writeFileSync(indexPath, JSON.stringify(index));
2414
2072
  if (toDelete.length > 0) {
2415
2073
  log(`Cleaned ${toDelete.length} cron session(s) and ${deletedFiles} file(s) from ${sessionsDir}`);
2416
2074
  }
@@ -2419,9 +2077,9 @@ function cleanupCronSessions(sessionsDir, keepCount) {
2419
2077
  }
2420
2078
  var STALE_RUN_TIMEOUT_MS = 5 * 6e4;
2421
2079
  function clearStaleCronRunState(jobsPath) {
2422
- if (!existsSync2(jobsPath)) return;
2080
+ if (!existsSync(jobsPath)) return;
2423
2081
  try {
2424
- const raw = readFileSync3(jobsPath, "utf-8");
2082
+ const raw = readFileSync(jobsPath, "utf-8");
2425
2083
  const data = JSON.parse(raw);
2426
2084
  const jobs = data.jobs ?? data;
2427
2085
  if (!Array.isArray(jobs)) return;
@@ -2446,19 +2104,19 @@ function clearStaleCronRunState(jobsPath) {
2446
2104
  }
2447
2105
  }
2448
2106
  if (changed) {
2449
- writeFileSync3(jobsPath, JSON.stringify(data, null, 2));
2107
+ writeFileSync(jobsPath, JSON.stringify(data, null, 2));
2450
2108
  }
2451
2109
  } catch {
2452
2110
  }
2453
2111
  }
2454
2112
  function cleanupOldFiles(dir, maxAgeDays, ext) {
2455
- if (!existsSync2(dir)) return;
2113
+ if (!existsSync(dir)) return;
2456
2114
  const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1e3;
2457
2115
  let removed = 0;
2458
2116
  try {
2459
2117
  for (const f of readdirSync(dir)) {
2460
2118
  if (!f.endsWith(ext)) continue;
2461
- const fullPath = join2(dir, f);
2119
+ const fullPath = join(dir, f);
2462
2120
  try {
2463
2121
  const st = statSync(fullPath);
2464
2122
  if (st.mtimeMs < cutoff) {
@@ -2549,16 +2207,16 @@ async function syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData
2549
2207
  }
2550
2208
  async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
2551
2209
  const projectDir = getProjectDir(codeName);
2552
- const mcpConfigPath = join2(projectDir, ".mcp.json");
2210
+ const mcpConfigPath = join(projectDir, ".mcp.json");
2553
2211
  sanitizeMcpJson(mcpConfigPath, requireHost());
2554
2212
  try {
2555
- const claudeMdPath = join2(projectDir, "CLAUDE.md");
2213
+ const claudeMdPath = join(projectDir, "CLAUDE.md");
2556
2214
  const serverNames = [];
2557
- const channelsConfigPath = join2(projectDir, ".mcp-channels.json");
2215
+ const channelsConfigPath = join(projectDir, ".mcp-channels.json");
2558
2216
  for (const p of [mcpConfigPath, channelsConfigPath]) {
2559
- if (existsSync2(p)) {
2217
+ if (existsSync(p)) {
2560
2218
  try {
2561
- const d = JSON.parse(readFileSync3(p, "utf-8"));
2219
+ const d = JSON.parse(readFileSync(p, "utf-8"));
2562
2220
  if (d.mcpServers) serverNames.push(...Object.keys(d.mcpServers));
2563
2221
  } catch {
2564
2222
  }
@@ -2577,15 +2235,15 @@ async function executeAndProcessClaudeTask(codeName, agentId, task, prompt) {
2577
2235
  "--allowedTools",
2578
2236
  allowedTools
2579
2237
  ];
2580
- if (existsSync2(channelsConfigPath)) claudeArgs.push("--mcp-config", channelsConfigPath);
2581
- if (existsSync2(claudeMdPath)) {
2238
+ if (existsSync(channelsConfigPath)) claudeArgs.push("--mcp-config", channelsConfigPath);
2239
+ if (existsSync(claudeMdPath)) {
2582
2240
  claudeArgs.push("--system-prompt-file", claudeMdPath);
2583
2241
  }
2584
2242
  const childEnv = { ...process.env };
2585
- const envIntPath = join2(projectDir, ".env.integrations");
2586
- if (existsSync2(envIntPath)) {
2243
+ const envIntPath = join(projectDir, ".env.integrations");
2244
+ if (existsSync(envIntPath)) {
2587
2245
  try {
2588
- for (const line of readFileSync3(envIntPath, "utf-8").split("\n")) {
2246
+ for (const line of readFileSync(envIntPath, "utf-8").split("\n")) {
2589
2247
  if (!line || line.startsWith("#") || !line.includes("=")) continue;
2590
2248
  const eqIdx = line.indexOf("=");
2591
2249
  childEnv[line.slice(0, eqIdx)] = line.slice(eqIdx + 1);
@@ -2688,8 +2346,8 @@ var persistentSessionAgents = /* @__PURE__ */ new Set();
2688
2346
  async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
2689
2347
  const codeName = agent.code_name;
2690
2348
  const projectDir = getProjectDir2(codeName);
2691
- const mcpConfigPath = join2(projectDir, ".mcp.json");
2692
- const claudeMdPath = join2(projectDir, "CLAUDE.md");
2349
+ const mcpConfigPath = join(projectDir, ".mcp.json");
2350
+ const claudeMdPath = join(projectDir, "CLAUDE.md");
2693
2351
  const channelConfigs = refreshData.channel_configs;
2694
2352
  const channels = [];
2695
2353
  const devChannels = [];
@@ -2705,8 +2363,8 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
2705
2363
  }
2706
2364
  }
2707
2365
  if (!agentRuntimeAuthenticated) {
2708
- const { execFileSync: execFileSync2 } = await import("child_process");
2709
- agentRuntimeAuthenticated = checkClaudeAuth(execFileSync2);
2366
+ const { execFileSync } = await import("child_process");
2367
+ agentRuntimeAuthenticated = checkClaudeAuth(execFileSync);
2710
2368
  if (!agentRuntimeAuthenticated) {
2711
2369
  log(`[persistent-session] Skipping '${codeName}' \u2014 Claude Code not authenticated`);
2712
2370
  return;
@@ -3022,13 +2680,13 @@ async function processDirectChatMessage(agent, msg) {
3022
2680
  if (fw === "claude-code") {
3023
2681
  const { getProjectDir: ccProjectDir } = await import("../claude-scheduler-VFBZFE6U.js");
3024
2682
  const projDir = ccProjectDir(agent.codeName);
3025
- const mcpConfigPath = join2(projDir, ".mcp.json");
3026
- const channelsConfigPath = join2(projDir, ".mcp-channels.json");
2683
+ const mcpConfigPath = join(projDir, ".mcp.json");
2684
+ const channelsConfigPath = join(projDir, ".mcp-channels.json");
3027
2685
  const serverNames = [];
3028
2686
  for (const p of [mcpConfigPath, channelsConfigPath]) {
3029
- if (existsSync2(p)) {
2687
+ if (existsSync(p)) {
3030
2688
  try {
3031
- const d = JSON.parse(readFileSync3(p, "utf-8"));
2689
+ const d = JSON.parse(readFileSync(p, "utf-8"));
3032
2690
  if (d.mcpServers) serverNames.push(...Object.keys(d.mcpServers));
3033
2691
  } catch {
3034
2692
  }
@@ -3047,16 +2705,16 @@ async function processDirectChatMessage(agent, msg) {
3047
2705
  "--allowedTools",
3048
2706
  allowedTools
3049
2707
  ];
3050
- if (existsSync2(channelsConfigPath)) chatArgs.push("--mcp-config", channelsConfigPath);
3051
- const chatClaudeMd = join2(projDir, "CLAUDE.md");
3052
- if (existsSync2(chatClaudeMd)) {
2708
+ if (existsSync(channelsConfigPath)) chatArgs.push("--mcp-config", channelsConfigPath);
2709
+ const chatClaudeMd = join(projDir, "CLAUDE.md");
2710
+ if (existsSync(chatClaudeMd)) {
3053
2711
  chatArgs.push("--system-prompt-file", chatClaudeMd);
3054
2712
  }
3055
- const envIntPath = join2(projDir, ".env.integrations");
2713
+ const envIntPath = join(projDir, ".env.integrations");
3056
2714
  const childEnv = { ...process.env };
3057
- if (existsSync2(envIntPath)) {
2715
+ if (existsSync(envIntPath)) {
3058
2716
  try {
3059
- for (const line of readFileSync3(envIntPath, "utf-8").split("\n")) {
2717
+ for (const line of readFileSync(envIntPath, "utf-8").split("\n")) {
3060
2718
  if (!line || line.startsWith("#") || !line.includes("=")) continue;
3061
2719
  const eqIdx = line.indexOf("=");
3062
2720
  childEnv[line.slice(0, eqIdx)] = line.slice(eqIdx + 1);
@@ -3328,12 +2986,12 @@ function getBuiltInSkillContent(skillId) {
3328
2986
  if (builtInSkillCache.has(skillId)) return builtInSkillCache.get(skillId);
3329
2987
  try {
3330
2988
  const candidates = [
3331
- join2(process.cwd(), "skills", skillId, "SKILL.md"),
3332
- join2(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "skills", skillId, "SKILL.md")
2989
+ join(process.cwd(), "skills", skillId, "SKILL.md"),
2990
+ join(new URL(".", import.meta.url).pathname, "..", "..", "..", "..", "skills", skillId, "SKILL.md")
3333
2991
  ];
3334
2992
  for (const candidate of candidates) {
3335
- if (existsSync2(candidate)) {
3336
- const content = readFileSync3(candidate, "utf-8");
2993
+ if (existsSync(candidate)) {
2994
+ const content = readFileSync(candidate, "utf-8");
3337
2995
  const files = [{ relativePath: "SKILL.md", content }];
3338
2996
  builtInSkillCache.set(skillId, files);
3339
2997
  return files;
@@ -3749,7 +3407,7 @@ function generateArtifacts(agent, refreshData, adapter) {
3749
3407
  return provisionOutput.artifacts;
3750
3408
  }
3751
3409
  async function cleanupAgentFiles(codeName, agentDir) {
3752
- if (existsSync2(agentDir)) {
3410
+ if (existsSync(agentDir)) {
3753
3411
  try {
3754
3412
  rmSync(agentDir, { recursive: true, force: true });
3755
3413
  log(`Removed provision directory for '${codeName}'`);
@@ -3808,8 +3466,8 @@ var caffeinateProc = null;
3808
3466
  async function startCaffeinate() {
3809
3467
  if (process.platform !== "darwin") return;
3810
3468
  try {
3811
- const { spawn: spawn2 } = await import("child_process");
3812
- caffeinateProc = spawn2("caffeinate", ["-dims"], {
3469
+ const { spawn } = await import("child_process");
3470
+ caffeinateProc = spawn("caffeinate", ["-dims"], {
3813
3471
  stdio: "ignore",
3814
3472
  detached: false
3815
3473
  });
@@ -3860,8 +3518,8 @@ async function killAllAgtTmuxSessions() {
3860
3518
  ["list-sessions", "-F", "#{session_name}"],
3861
3519
  { timeout: 2e3, stdin: "ignore" }
3862
3520
  );
3863
- const sessions2 = output.trim().split("\n").filter((s) => s.startsWith("agt-"));
3864
- for (const session of sessions2) {
3521
+ const sessions = output.trim().split("\n").filter((s) => s.startsWith("agt-"));
3522
+ for (const session of sessions) {
3865
3523
  try {
3866
3524
  await execFilePromiseLong("tmux", ["kill-session", "-t", session], {
3867
3525
  timeout: 2e3,
@@ -3871,8 +3529,8 @@ async function killAllAgtTmuxSessions() {
3871
3529
  } catch {
3872
3530
  }
3873
3531
  }
3874
- if (sessions2.length > 0) {
3875
- log(`Cleaned up ${sessions2.length} agt-* tmux session(s)`);
3532
+ if (sessions.length > 0) {
3533
+ log(`Cleaned up ${sessions.length} agt-* tmux session(s)`);
3876
3534
  }
3877
3535
  } catch {
3878
3536
  }
@@ -3904,18 +3562,18 @@ function startManager(opts) {
3904
3562
  startPolling();
3905
3563
  }
3906
3564
  function deployMcpAssets() {
3907
- const targetDir = join2(homedir2(), ".augmented", "_mcp");
3908
- mkdirSync2(targetDir, { recursive: true });
3909
- const moduleDir = dirname2(fileURLToPath2(import.meta.url));
3565
+ const targetDir = join(homedir(), ".augmented", "_mcp");
3566
+ mkdirSync(targetDir, { recursive: true });
3567
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
3910
3568
  let mcpSourceDir = "";
3911
3569
  let dir = moduleDir;
3912
3570
  for (let i = 0; i < 6; i++) {
3913
- const candidate = join2(dir, "mcp");
3914
- if (existsSync2(join2(candidate, "index.js"))) {
3571
+ const candidate = join(dir, "mcp");
3572
+ if (existsSync(join(candidate, "index.js"))) {
3915
3573
  mcpSourceDir = candidate;
3916
3574
  break;
3917
3575
  }
3918
- const parent = dirname2(dir);
3576
+ const parent = dirname(dir);
3919
3577
  if (parent === dir) break;
3920
3578
  dir = parent;
3921
3579
  }
@@ -3924,9 +3582,9 @@ function deployMcpAssets() {
3924
3582
  return;
3925
3583
  }
3926
3584
  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;
3585
+ const src = join(mcpSourceDir, file);
3586
+ const dst = join(targetDir, file);
3587
+ if (!existsSync(src)) continue;
3930
3588
  try {
3931
3589
  copyFileSync(src, dst);
3932
3590
  } catch (err) {