@integrity-labs/agt-cli 0.28.817 → 0.28.818

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.
@@ -16,7 +16,7 @@ import {
16
16
  parseEnvIntegrations,
17
17
  shellQuote,
18
18
  summarizeUnanswerablePane
19
- } from "./chunk-5RZBTMBD.js";
19
+ } from "./chunk-ZDV575SW.js";
20
20
  import {
21
21
  BIND_FAILURE_QUARANTINE_THRESHOLD,
22
22
  INTEGRATIONS_SECTION_END,
@@ -71,7 +71,7 @@ import {
71
71
  sessionTranscriptDir,
72
72
  worseConnectivityOutcome,
73
73
  wrapScheduledTaskPrompt
74
- } from "./chunk-SZ47B4KO.js";
74
+ } from "./chunk-NVUWRJWX.js";
75
75
  import {
76
76
  parsePsRows
77
77
  } from "./chunk-XWVM4KPK.js";
@@ -6523,7 +6523,7 @@ function exchangeFailureKind(err) {
6523
6523
  }
6524
6524
 
6525
6525
  // src/lib/api-client.ts
6526
- var agtCliVersion = true ? "0.28.817" : "dev";
6526
+ var agtCliVersion = true ? "0.28.818" : "dev";
6527
6527
  var lastConfigHash = null;
6528
6528
  function setConfigHash(hash) {
6529
6529
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -10818,4 +10818,4 @@ export {
10818
10818
  managerInstallSystemUnitCommand,
10819
10819
  managerUninstallSystemUnitCommand
10820
10820
  };
10821
- //# sourceMappingURL=chunk-356JFTPK.js.map
10821
+ //# sourceMappingURL=chunk-Y3CAZCIA.js.map
@@ -18,7 +18,7 @@ import {
18
18
  rotateDailySession,
19
19
  sessionFileExists,
20
20
  todayLocalIso
21
- } from "./chunk-SZ47B4KO.js";
21
+ } from "./chunk-NVUWRJWX.js";
22
22
  import {
23
23
  reapOrphanChannelMcps
24
24
  } from "./chunk-XWVM4KPK.js";
@@ -134,9 +134,9 @@ function hardBoundedCapture(file, args, opts) {
134
134
  }
135
135
 
136
136
  // src/lib/persistent-session.ts
137
- import { join as join6, dirname as dirname5 } from "path";
137
+ import { join as join7, dirname as dirname5 } from "path";
138
138
  import { homedir as homedir5, platform, userInfo as userInfo2 } from "os";
139
- import { existsSync as existsSync5, readFileSync as readFileSync6, readdirSync as readdirSync2, writeFileSync as writeFileSync4, appendFileSync as appendFileSync2, mkdirSync as mkdirSync5, chmodSync as chmodSync3, copyFileSync, rmSync as rmSync3, lstatSync as lstatSync3, realpathSync as realpathSync2, renameSync as renameSync2, statSync } from "fs";
139
+ import { existsSync as existsSync6, readFileSync as readFileSync7, readdirSync as readdirSync2, writeFileSync as writeFileSync5, appendFileSync as appendFileSync2, mkdirSync as mkdirSync6, chmodSync as chmodSync3, copyFileSync, rmSync as rmSync3, lstatSync as lstatSync3, realpathSync as realpathSync2, renameSync as renameSync3, statSync } from "fs";
140
140
 
141
141
  // src/lib/mcp-sanitize.ts
142
142
  import { readFileSync, writeFileSync } from "fs";
@@ -3429,6 +3429,23 @@ var CLAUDE_CODE_SLOT_ENV = /* @__PURE__ */ new Map([
3429
3429
  ["primary", "ANTHROPIC_MODEL"],
3430
3430
  ["small_fast", "ANTHROPIC_SMALL_FAST_MODEL"]
3431
3431
  ]);
3432
+ var CLAUDE_CODE_SLOT_SETTINGS_KEY = /* @__PURE__ */ new Map([
3433
+ ["advisor", "advisorModel"]
3434
+ ]);
3435
+ var MANAGED_PROJECT_SETTINGS_KEYS = [
3436
+ ...CLAUDE_CODE_SLOT_SETTINGS_KEY.values()
3437
+ ];
3438
+ function projectSettingsForRole(policy, role) {
3439
+ if (!policy) return {};
3440
+ const out = {};
3441
+ for (const m of policy.models) {
3442
+ if (m.role !== role) continue;
3443
+ const key = CLAUDE_CODE_SLOT_SETTINGS_KEY.get(m.slot);
3444
+ if (!key) continue;
3445
+ out[key] = m.modelId;
3446
+ }
3447
+ return out;
3448
+ }
3432
3449
  function modelEnvForRole(policy, role) {
3433
3450
  if (!policy) return {};
3434
3451
  const out = {};
@@ -3443,7 +3460,7 @@ function modelEnvForRole(policy, role) {
3443
3460
  function resolveModelPolicySpawnEnv(input) {
3444
3461
  const { policy, openRouterMode, gatewayToken, codeName } = input;
3445
3462
  const active = activeBinding(policy);
3446
- if (!policy || !active) return { env: {}, modelEnv: {}, notice: null };
3463
+ if (!policy || !active) return { env: {}, modelEnv: {}, projectSettings: {}, notice: null };
3447
3464
  const roleNote = policy.activeRole === "primary" ? "" : ` role=${policy.activeRole} (FAILOVER)`;
3448
3465
  if (openRouterMode) {
3449
3466
  return {
@@ -3453,11 +3470,18 @@ function resolveModelPolicySpawnEnv(input) {
3453
3470
  // is how the "two actuators" problem above becomes a wrong model rather
3454
3471
  // than a logged conflict.
3455
3472
  modelEnv: {},
3473
+ // ENG-10075: and no advisor. OpenRouter wins the whole policy here, not
3474
+ // the env half of it — writing an advisor into the settings file for an
3475
+ // agent whose model selection this branch just refused would be the
3476
+ // half-applied state the `blocked` branch below spells out.
3477
+ projectSettings: {},
3456
3478
  notice: `[model-policy] '${codeName}' has policy '${policy.name}' but is in OpenRouter mode \u2014 OpenRouter wins, policy not applied (ENG-9483: unifying the two actuators is a separate migration)`
3457
3479
  };
3458
3480
  }
3459
3481
  const modelEnv = modelEnvForRole(policy, active.role);
3482
+ const projectSettings = projectSettingsForRole(policy, active.role);
3460
3483
  const modelNote = Object.keys(modelEnv).length > 0 ? ` models=${Object.entries(modelEnv).map(([k, v]) => `${k}=${v}`).join(" ")}` : "";
3484
+ const advisorNote = Object.keys(projectSettings).length > 0 ? ` project-settings=${Object.entries(projectSettings).map(([k, v]) => `${k}=${v}`).join(" ")}` : "";
3461
3485
  const resolution = resolveBindingCredential(active, gatewayToken);
3462
3486
  switch (resolution.kind) {
3463
3487
  case "gateway":
@@ -3467,7 +3491,8 @@ function resolveModelPolicySpawnEnv(input) {
3467
3491
  ANTHROPIC_AUTH_TOKEN: resolution.authToken
3468
3492
  },
3469
3493
  modelEnv,
3470
- notice: `[model-policy] '${codeName}' inference via gateway ${resolution.baseUrl} (policy '${policy.name}' rev ${policy.revision}, from ${policy.resolvedFrom})${roleNote}${modelNote}`
3494
+ projectSettings,
3495
+ notice: `[model-policy] '${codeName}' inference via gateway ${resolution.baseUrl} (policy '${policy.name}' rev ${policy.revision}, from ${policy.resolvedFrom})${roleNote}${modelNote}${advisorNote}`
3471
3496
  };
3472
3497
  case "blocked":
3473
3498
  return {
@@ -3478,13 +3503,17 @@ function resolveModelPolicySpawnEnv(input) {
3478
3503
  // somewhere else — a policy half-applied, which is the one outcome this
3479
3504
  // file has no branch for.
3480
3505
  modelEnv: {},
3506
+ // ENG-10075: and no advisor, for the identical reason. An advisor is a
3507
+ // model choice made for an endpoint this manager could not honour.
3508
+ projectSettings: {},
3481
3509
  notice: `[model-policy] '${codeName}' policy '${policy.name}' NOT applied \u2014 reason=${resolution.reason}; keeping existing auth (transport=${active.transport}, credential_source=${active.credentialSource})${roleNote}`
3482
3510
  };
3483
3511
  case "host-default":
3484
3512
  return {
3485
3513
  env: {},
3486
3514
  modelEnv,
3487
- notice: modelNote || roleNote ? `[model-policy] '${codeName}' model from policy '${policy.name}' rev ${policy.revision} (from ${policy.resolvedFrom})${roleNote};${modelNote || " no slot maps to an env var"}` : null
3515
+ projectSettings,
3516
+ notice: modelNote || roleNote || advisorNote ? `[model-policy] '${codeName}' model from policy '${policy.name}' rev ${policy.revision} (from ${policy.resolvedFrom})${roleNote};${modelNote || " no slot maps to an env var"}${advisorNote}` : null
3488
3517
  };
3489
3518
  }
3490
3519
  }
@@ -3506,13 +3535,81 @@ function roleFromAuthComponent(value) {
3506
3535
  return ROLES.includes(role) ? role : "primary";
3507
3536
  }
3508
3537
 
3538
+ // src/lib/project-claude-settings.ts
3539
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync4 } from "fs";
3540
+ import { join as join6 } from "path";
3541
+ function writeProjectClaudeSettings(args) {
3542
+ const { projectDir, managed } = args;
3543
+ const path = join6(projectDir, ".claude", "settings.json");
3544
+ try {
3545
+ const fileExists = existsSync5(path);
3546
+ if (Object.keys(managed).length === 0 && !fileExists) return { kind: "noop" };
3547
+ let existing = {};
3548
+ let backup = null;
3549
+ if (fileExists) {
3550
+ const raw = readFileSync6(path, "utf8");
3551
+ try {
3552
+ const parsed = JSON.parse(raw);
3553
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
3554
+ existing = parsed;
3555
+ } else {
3556
+ throw new Error("settings.json is not a JSON object");
3557
+ }
3558
+ } catch {
3559
+ backup = `${path}.corrupt-${Date.now()}`;
3560
+ renameSync2(path, backup);
3561
+ existing = {};
3562
+ }
3563
+ }
3564
+ const next = { ...existing };
3565
+ for (const key of MANAGED_PROJECT_SETTINGS_KEYS) {
3566
+ if (key in managed) next[key] = managed[key];
3567
+ else delete next[key];
3568
+ }
3569
+ if (Object.keys(next).length === 0) {
3570
+ if (backup) return { kind: "recovered", path, backup, rewritten: false };
3571
+ if (fileExists) {
3572
+ unlinkSync(path);
3573
+ return { kind: "removed", path };
3574
+ }
3575
+ return { kind: "noop" };
3576
+ }
3577
+ const serialized = `${JSON.stringify(next, null, 2)}
3578
+ `;
3579
+ if (!backup && fileExists && readFileSync6(path, "utf8") === serialized) {
3580
+ return { kind: "unchanged", path };
3581
+ }
3582
+ mkdirSync5(join6(projectDir, ".claude"), { recursive: true });
3583
+ writeFileSync4(path, serialized, { mode: 384 });
3584
+ if (backup) return { kind: "recovered", path, backup, rewritten: true };
3585
+ return { kind: "written", path, keys: Object.keys(managed) };
3586
+ } catch (err) {
3587
+ return { kind: "failed", path, error: err instanceof Error ? err.message : String(err) };
3588
+ }
3589
+ }
3590
+ function projectClaudeSettingsNotice(codeName, outcome) {
3591
+ switch (outcome.kind) {
3592
+ case "noop":
3593
+ case "unchanged":
3594
+ return null;
3595
+ case "written":
3596
+ return `[model-policy] '${codeName}' wrote ${outcome.keys.join(", ")} to ${outcome.path}`;
3597
+ case "removed":
3598
+ return `[model-policy] '${codeName}' policy no longer sets any project setting \u2014 removed ${outcome.path}`;
3599
+ case "recovered":
3600
+ return outcome.rewritten ? `[model-policy] '${codeName}' ${outcome.path} was not parseable JSON; moved to ${outcome.backup} and rewrote it` : `[model-policy] '${codeName}' ${outcome.path} was not parseable JSON; moved to ${outcome.backup} and did NOT replace it (the policy sets nothing)`;
3601
+ case "failed":
3602
+ return `[model-policy] '${codeName}' could NOT write ${outcome.path} (${outcome.error}) \u2014 agent spawns without it`;
3603
+ }
3604
+ }
3605
+
3509
3606
  // src/lib/persistent-session.ts
3510
3607
  var OPENROUTER_ANTHROPIC_BASE_URL = "https://openrouter.ai/api";
3511
3608
  function syncClaudeCredsToRoot() {
3512
3609
  if (platform() !== "linux") return true;
3513
3610
  if (typeof process.getuid !== "function" || process.getuid() !== 0) return true;
3514
3611
  for (const filename of [".credentials.json", "credentials.json"]) {
3515
- if (existsSync5(join6("/root/.claude", filename))) return true;
3612
+ if (existsSync6(join7("/root/.claude", filename))) return true;
3516
3613
  }
3517
3614
  let sourcePath = null;
3518
3615
  try {
@@ -3520,8 +3617,8 @@ function syncClaudeCredsToRoot() {
3520
3617
  outer: for (const entry of entries) {
3521
3618
  if (!entry.isDirectory()) continue;
3522
3619
  for (const filename of [".credentials.json", "credentials.json"]) {
3523
- const candidate = join6("/home", entry.name, ".claude", filename);
3524
- if (existsSync5(candidate)) {
3620
+ const candidate = join7("/home", entry.name, ".claude", filename);
3621
+ if (existsSync6(candidate)) {
3525
3622
  sourcePath = candidate;
3526
3623
  break outer;
3527
3624
  }
@@ -3532,9 +3629,9 @@ function syncClaudeCredsToRoot() {
3532
3629
  if (!sourcePath) return false;
3533
3630
  const targetDir = "/root/.claude";
3534
3631
  const sourceFilename = sourcePath.endsWith("credentials.json") && !sourcePath.endsWith(".credentials.json") ? "credentials.json" : ".credentials.json";
3535
- const targetPath = join6(targetDir, sourceFilename);
3632
+ const targetPath = join7(targetDir, sourceFilename);
3536
3633
  try {
3537
- if (!existsSync5(targetDir)) mkdirSync5(targetDir, { recursive: true, mode: 448 });
3634
+ if (!existsSync6(targetDir)) mkdirSync6(targetDir, { recursive: true, mode: 448 });
3538
3635
  copyFileSync(sourcePath, targetPath);
3539
3636
  chmodSync3(targetPath, 384);
3540
3637
  return true;
@@ -3551,13 +3648,13 @@ var cachedClaudePath = null;
3551
3648
  function resolveClaudeBinary() {
3552
3649
  if (cachedClaudePath) return cachedClaudePath;
3553
3650
  const override = process.env.CLAUDE_PATH;
3554
- if (override && existsSync5(override)) {
3651
+ if (override && existsSync6(override)) {
3555
3652
  cachedClaudePath = override;
3556
3653
  return override;
3557
3654
  }
3558
3655
  try {
3559
3656
  const out = execSync2("which claude 2>/dev/null", { encoding: "utf-8" }).trim();
3560
- if (out && existsSync5(out)) {
3657
+ if (out && existsSync6(out)) {
3561
3658
  cachedClaudePath = out;
3562
3659
  return out;
3563
3660
  }
@@ -3569,7 +3666,7 @@ function resolveClaudeBinary() {
3569
3666
  "/usr/local/bin/claude"
3570
3667
  ];
3571
3668
  for (const p of candidates) {
3572
- if (existsSync5(p)) {
3669
+ if (existsSync6(p)) {
3573
3670
  cachedClaudePath = p;
3574
3671
  return p;
3575
3672
  }
@@ -3660,12 +3757,12 @@ function buildEgressAllowlist(toolsFrontmatter, policyDomains = []) {
3660
3757
  }
3661
3758
  function egressAllowlistHostPath(codeName, homeDir) {
3662
3759
  const home = homeDir ?? (process.env.HOME?.trim() || homedir5());
3663
- return join6(home, ".augmented", "_egress", `${agentRuntimeKey(codeName, home)}.txt`);
3760
+ return join7(home, ".augmented", "_egress", `${agentRuntimeKey(codeName, home)}.txt`);
3664
3761
  }
3665
3762
  function writeEgressAllowlist(codeName, domains, homeDir) {
3666
3763
  const p = egressAllowlistHostPath(codeName, homeDir);
3667
- mkdirSync5(dirname5(p), { recursive: true });
3668
- writeFileSync4(p, domains.join("\n") + "\n", { mode: 420 });
3764
+ mkdirSync6(dirname5(p), { recursive: true });
3765
+ writeFileSync5(p, domains.join("\n") + "\n", { mode: 420 });
3669
3766
  return p;
3670
3767
  }
3671
3768
  var EGRESS_DOCKER_TIMEOUT_MS = 1e4;
@@ -3701,11 +3798,11 @@ function restartEgressSidecar(codeName) {
3701
3798
  function buildDockerRunCommand(args) {
3702
3799
  const { codeName, agentId, wrapperPath, projectDir, homeDir, runId, passApiKey, passOpenRouter, passModelPolicyGateway, passModelPolicyModel, egress, forwardSlackReplyBinding, forwardBlockTurnEndAllMarkers, forwardKanbanWaiting, forwardNotifyDispatch, forwardTurnFailureNotice, forwardChannelSecrets } = args;
3703
3800
  const q = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
3704
- const agentDir2 = join6(homeDir, ".augmented", codeName);
3705
- const agentIdDir = join6(homeDir, ".augmented", agentId);
3706
- const mcpDir = join6(homeDir, ".augmented", "_mcp");
3707
- const claudeHome = join6(homeDir, ".claude");
3708
- const claudeJson = join6(homeDir, ".claude.json");
3801
+ const agentDir2 = join7(homeDir, ".augmented", codeName);
3802
+ const agentIdDir = join7(homeDir, ".augmented", agentId);
3803
+ const mcpDir = join7(homeDir, ".augmented", "_mcp");
3804
+ const claudeHome = join7(homeDir, ".claude");
3805
+ const claudeJson = join7(homeDir, ".claude.json");
3709
3806
  const mounts = [
3710
3807
  `-v ${q(`${agentDir2}:${agentDir2}`)}`,
3711
3808
  `-v ${q(`${agentIdDir}:${agentIdDir}`)}`,
@@ -3718,7 +3815,7 @@ function buildDockerRunCommand(args) {
3718
3815
  const cpus = process.env.AGT_ISOLATION_CPUS || "1.0";
3719
3816
  const pids = process.env.AGT_ISOLATION_PIDS || "512";
3720
3817
  const envArgs = [`-e ${q(`HOME=${homeDir}`)}`];
3721
- envArgs.push(`-e ${q(`npm_config_cache=${join6(agentDir2, ".npm-cache")}`)}`);
3818
+ envArgs.push(`-e ${q(`npm_config_cache=${join7(agentDir2, ".npm-cache")}`)}`);
3722
3819
  envArgs.push(`-e ${q(`${CLAUDE_CODE_TMPDIR_ENV}=${agentTmpDirFor(agentDir2)}`)}`);
3723
3820
  if (passApiKey) envArgs.push("-e ANTHROPIC_API_KEY");
3724
3821
  if (passOpenRouter) {
@@ -3824,8 +3921,8 @@ function buildDockerRunCommand(args) {
3824
3921
  }
3825
3922
  function writePersistentClaudeWrapper(args) {
3826
3923
  const { projectDir, claudeBin, initPrompt, claudeArgsJoined } = args;
3827
- const envIntegrationsPath = join6(projectDir, ".env.integrations");
3828
- const wrapperPath = join6(projectDir, ".claude", "persistent-claude.sh");
3924
+ const envIntegrationsPath = join7(projectDir, ".env.integrations");
3925
+ const wrapperPath = join7(projectDir, ".claude", "persistent-claude.sh");
3829
3926
  const wrapperLines = [
3830
3927
  "#!/usr/bin/env bash",
3831
3928
  "set -e",
@@ -3833,7 +3930,7 @@ function writePersistentClaudeWrapper(args) {
3833
3930
  // --dangerously-skip-permissions on dedicated EC2 hosts.
3834
3931
  "export IS_SANDBOX=1"
3835
3932
  ];
3836
- if (existsSync5(envIntegrationsPath)) {
3933
+ if (existsSync6(envIntegrationsPath)) {
3837
3934
  wrapperLines.push(
3838
3935
  "set -a",
3839
3936
  `source ${JSON.stringify(envIntegrationsPath)}`,
@@ -3841,23 +3938,23 @@ function writePersistentClaudeWrapper(args) {
3841
3938
  );
3842
3939
  }
3843
3940
  wrapperLines.push("export DISABLE_AUTOUPDATER=1");
3844
- const brokerBinDir = join6(projectDir, ".claude", "agt-bin");
3845
- if (existsSync5(brokerBinDir)) {
3941
+ const brokerBinDir = join7(projectDir, ".claude", "agt-bin");
3942
+ if (existsSync6(brokerBinDir)) {
3846
3943
  wrapperLines.push(`export PATH=${JSON.stringify(brokerBinDir)}:"$PATH"`);
3847
3944
  }
3848
3945
  const initPromptArg = initPrompt ? `${JSON.stringify(initPrompt)} ` : "";
3849
3946
  wrapperLines.push(
3850
3947
  `exec ${JSON.stringify(claudeBin)} ${initPromptArg}${claudeArgsJoined}`
3851
3948
  );
3852
- mkdirSync5(join6(projectDir, ".claude"), { recursive: true });
3853
- writeFileSync4(wrapperPath, wrapperLines.join("\n") + "\n", { mode: 448 });
3949
+ mkdirSync6(join7(projectDir, ".claude"), { recursive: true });
3950
+ writeFileSync5(wrapperPath, wrapperLines.join("\n") + "\n", { mode: 448 });
3854
3951
  chmodSync3(wrapperPath, 448);
3855
3952
  return wrapperPath;
3856
3953
  }
3857
3954
  function collectMcpServerNames(mcpConfigPath) {
3858
- if (!existsSync5(mcpConfigPath)) return [];
3955
+ if (!existsSync6(mcpConfigPath)) return [];
3859
3956
  try {
3860
- const data = JSON.parse(readFileSync6(mcpConfigPath, "utf-8"));
3957
+ const data = JSON.parse(readFileSync7(mcpConfigPath, "utf-8"));
3861
3958
  const servers = data.mcpServers;
3862
3959
  return servers ? Object.keys(servers) : [];
3863
3960
  } catch {
@@ -3909,12 +4006,12 @@ function findForeignAgentIdsInMcpConfig(args) {
3909
4006
  return out;
3910
4007
  }
3911
4008
  var sessions2 = /* @__PURE__ */ new Map();
3912
- var PANE_LOG_DIR = join6(homedir5(), ".augmented");
4009
+ var PANE_LOG_DIR = join7(homedir5(), ".augmented");
3913
4010
  var PANE_TAIL_LINES = 20;
3914
4011
  function paneLogPath(codeName) {
3915
- return join6(PANE_LOG_DIR, codeName, "pane.log");
4012
+ return join7(PANE_LOG_DIR, codeName, "pane.log");
3916
4013
  }
3917
- var PANE_REDACTOR_SCRIPT = join6(PANE_LOG_DIR, "pane-log-redactor.pl");
4014
+ var PANE_REDACTOR_SCRIPT = join7(PANE_LOG_DIR, "pane-log-redactor.pl");
3918
4015
  var paneRedactorPerlAvailable = null;
3919
4016
  function paneSinkCommand(logPath, log2) {
3920
4017
  if (paneRedactorPerlAvailable === null) {
@@ -3928,12 +4025,12 @@ function paneSinkCommand(logPath, log2) {
3928
4025
  }
3929
4026
  if (paneRedactorPerlAvailable) {
3930
4027
  try {
3931
- mkdirSync5(dirname5(PANE_REDACTOR_SCRIPT), { recursive: true });
4028
+ mkdirSync6(dirname5(PANE_REDACTOR_SCRIPT), { recursive: true });
3932
4029
  const tmp = `${PANE_REDACTOR_SCRIPT}.${randomUUID()}.tmp`;
3933
4030
  try {
3934
- writeFileSync4(tmp, buildRedactorProgram(), { encoding: "utf-8", mode: 448 });
4031
+ writeFileSync5(tmp, buildRedactorProgram(), { encoding: "utf-8", mode: 448 });
3935
4032
  chmodSync3(tmp, 448);
3936
- renameSync2(tmp, PANE_REDACTOR_SCRIPT);
4033
+ renameSync3(tmp, PANE_REDACTOR_SCRIPT);
3937
4034
  } catch (e) {
3938
4035
  try {
3939
4036
  rmSync3(tmp, { force: true });
@@ -3955,7 +4052,7 @@ function paneSinkCommand(logPath, log2) {
3955
4052
  function setupPaneLog2(tmuxSession, codeName, log2) {
3956
4053
  const logPath = paneLogPath(codeName);
3957
4054
  try {
3958
- mkdirSync5(dirname5(logPath), { recursive: true });
4055
+ mkdirSync6(dirname5(logPath), { recursive: true });
3959
4056
  appendFileSync2(
3960
4057
  logPath,
3961
4058
  `
@@ -3974,17 +4071,17 @@ function setupPaneLog2(tmuxSession, codeName, log2) {
3974
4071
  function rotatePaneLogForDayRollover(codeName, log2, agentTimezone, now = /* @__PURE__ */ new Date()) {
3975
4072
  const logPath = paneLogPath(codeName);
3976
4073
  try {
3977
- if (!existsSync5(logPath)) return null;
4074
+ if (!existsSync6(logPath)) return null;
3978
4075
  if (statSync(logPath).size === 0) return null;
3979
4076
  const stamp = todayLocalIso(now, agentTimezone ?? void 0).replace(/-/g, "");
3980
4077
  const dir = dirname5(logPath);
3981
- let target = join6(dir, `pane.log-${stamp}`);
3982
- if (existsSync5(target)) {
4078
+ let target = join7(dir, `pane.log-${stamp}`);
4079
+ if (existsSync6(target)) {
3983
4080
  const hhmmss = now.toISOString().slice(11, 19).replace(/:/g, "");
3984
- target = join6(dir, `pane.log-${stamp}-${hhmmss}`);
4081
+ target = join7(dir, `pane.log-${stamp}-${hhmmss}`);
3985
4082
  }
3986
- renameSync2(logPath, target);
3987
- writeFileSync4(logPath, "", "utf-8");
4083
+ renameSync3(logPath, target);
4084
+ writeFileSync5(logPath, "", "utf-8");
3988
4085
  const rotated = target.slice(dir.length + 1);
3989
4086
  log2(`[persistent-session] Rotated pane.log for '${codeName}' \u2192 ${rotated} (day-rollover)`);
3990
4087
  return rotated;
@@ -3995,9 +4092,9 @@ function rotatePaneLogForDayRollover(codeName, log2, agentTimezone, now = /* @__
3995
4092
  }
3996
4093
  function readPaneLogTail(codeName, lines = PANE_TAIL_LINES) {
3997
4094
  const logPath = paneLogPath(codeName);
3998
- if (!existsSync5(logPath)) return null;
4095
+ if (!existsSync6(logPath)) return null;
3999
4096
  try {
4000
- const raw = readFileSync6(logPath, "utf-8");
4097
+ const raw = readFileSync7(logPath, "utf-8");
4001
4098
  if (!raw) return null;
4002
4099
  const stripped = raw.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, "");
4003
4100
  const all = stripped.split("\n").filter((l) => l.length > 0);
@@ -4071,11 +4168,11 @@ function resolveSessionSpawnDecision(args) {
4071
4168
  };
4072
4169
  }
4073
4170
  function directChatSessionStatePath(agentId) {
4074
- return join6(homedir5(), ".augmented", agentId, "direct-chat-session.json");
4171
+ return join7(homedir5(), ".augmented", agentId, "direct-chat-session.json");
4075
4172
  }
4076
4173
  function readDirectChatSessionState(agentId) {
4077
4174
  try {
4078
- const parsed = JSON.parse(readFileSync6(directChatSessionStatePath(agentId), "utf-8"));
4175
+ const parsed = JSON.parse(readFileSync7(directChatSessionStatePath(agentId), "utf-8"));
4079
4176
  if (!parsed || typeof parsed !== "object") return null;
4080
4177
  const state = parsed;
4081
4178
  state.mcpServerKeys = Array.isArray(state.mcpServerKeys) ? state.mcpServerKeys.filter((k) => typeof k === "string") : void 0;
@@ -4086,8 +4183,8 @@ function readDirectChatSessionState(agentId) {
4086
4183
  }
4087
4184
  function writeDirectChatSessionState(agentId, state) {
4088
4185
  const p = directChatSessionStatePath(agentId);
4089
- mkdirSync5(dirname5(p), { recursive: true });
4090
- writeFileSync4(p, JSON.stringify(state));
4186
+ mkdirSync6(dirname5(p), { recursive: true });
4187
+ writeFileSync5(p, JSON.stringify(state));
4091
4188
  }
4092
4189
  function spawnBackoffMs(restartCount) {
4093
4190
  return Math.min(5e3 * Math.pow(2, restartCount), 6e4);
@@ -4125,6 +4222,7 @@ function spawnSession(config, session) {
4125
4222
  const {
4126
4223
  env: policyEnv,
4127
4224
  modelEnv: policyModelEnv,
4225
+ projectSettings: policyProjectSettings,
4128
4226
  notice: policyNotice
4129
4227
  } = resolveModelPolicySpawnEnv({
4130
4228
  policy: config.modelPolicy ?? null,
@@ -4133,6 +4231,11 @@ function spawnSession(config, session) {
4133
4231
  codeName
4134
4232
  });
4135
4233
  if (policyNotice) log2(policyNotice);
4234
+ const projectSettingsNotice = projectClaudeSettingsNotice(
4235
+ codeName,
4236
+ writeProjectClaudeSettings({ projectDir, managed: policyProjectSettings })
4237
+ );
4238
+ if (projectSettingsNotice) log2(projectSettingsNotice);
4136
4239
  const policyEnvActive = Object.keys(policyEnv).length > 0;
4137
4240
  const policyModelActive = Object.keys(policyModelEnv).length > 0;
4138
4241
  const tmuxSession = `agt-${codeName}`;
@@ -4175,10 +4278,10 @@ function spawnSession(config, session) {
4175
4278
  log2(`[persistent-session] No Claude Code credentials found under /root/.claude or /home/*. Pair via browser from the host page, or run 'claude /login' on the host.`);
4176
4279
  }
4177
4280
  } else {
4178
- const claudeDir = join6(homedir5(), ".claude");
4281
+ const claudeDir = join7(homedir5(), ".claude");
4179
4282
  for (const filename of [".credentials.json", "credentials.json"]) {
4180
- const p = join6(claudeDir, filename);
4181
- if (existsSync5(p)) {
4283
+ const p = join7(claudeDir, filename);
4284
+ if (existsSync6(p)) {
4182
4285
  try {
4183
4286
  rmSync3(p, { force: true });
4184
4287
  log2(`[persistent-session] Removed ${p} (api_key mode active \u2014 preventing OAuth fallback)`);
@@ -4228,7 +4331,7 @@ function spawnSession(config, session) {
4228
4331
  if (channels.length > 0) args.push("--channels", ...channels);
4229
4332
  if (devChannels.length > 0) args.push("--dangerously-load-development-channels", ...devChannels);
4230
4333
  args.push("--mcp-config", mcpConfigPath);
4231
- if (existsSync5(claudeMdPath)) args.push("--system-prompt-file", claudeMdPath);
4334
+ if (existsSync6(claudeMdPath)) args.push("--system-prompt-file", claudeMdPath);
4232
4335
  if (!openRouterMode && !policyModelActive) {
4233
4336
  const modelAlias = claudeModelAlias(config.primaryModel);
4234
4337
  if (modelAlias) args.push("--model", modelAlias);
@@ -4407,7 +4510,7 @@ function spawnSession(config, session) {
4407
4510
  };
4408
4511
  for (const f of probeMcpEnvSubstitution({
4409
4512
  mcpConfigPath,
4410
- envIntegrationsPath: join6(projectDir, ".env.integrations"),
4513
+ envIntegrationsPath: join7(projectDir, ".env.integrations"),
4411
4514
  baseEnv: probeBaseEnv
4412
4515
  })) {
4413
4516
  log2(`[persistent-session] ${formatMissingVar(f)} agent=${codeName}`);
@@ -4420,7 +4523,7 @@ function spawnSession(config, session) {
4420
4523
  }
4421
4524
  try {
4422
4525
  const foreign = findForeignAgentIdsInMcpConfig({
4423
- mcpConfigText: readFileSync6(mcpConfigPath, "utf8"),
4526
+ mcpConfigText: readFileSync7(mcpConfigPath, "utf8"),
4424
4527
  agentId: config.agentId
4425
4528
  });
4426
4529
  if (foreign.length > 0) {
@@ -5109,7 +5212,7 @@ function resolveRealAgentPath(codeNamePath) {
5109
5212
  return codeNamePath;
5110
5213
  }
5111
5214
  function getProjectDir(codeName) {
5112
- return join6(resolveRealAgentPath(join6(homedir5(), ".augmented", codeName)), "project");
5215
+ return join7(resolveRealAgentPath(join7(homedir5(), ".augmented", codeName)), "project");
5113
5216
  }
5114
5217
 
5115
5218
  export {
@@ -5209,4 +5312,4 @@ export {
5209
5312
  stopAllSessionsAndWait,
5210
5313
  getProjectDir
5211
5314
  };
5212
- //# sourceMappingURL=chunk-5RZBTMBD.js.map
5315
+ //# sourceMappingURL=chunk-ZDV575SW.js.map