From f691024350362858e00b97248ac68e356d2331c2 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Thu, 11 Sep 2025 08:47:33 -0400 Subject: [PATCH] Load managed-settings.json (#42) The SDK doesn't currently load [Claude Code's `managed-settings.json`](https://docs.anthropic.com/en/docs/claude-code/settings#settings-files) - now the adapter does (following [the rules in the docs](https://docs.anthropic.com/en/docs/claude-code/settings#settings-files)), but we can remove this once the SDK supports it. --- src/index.ts | 8 ++++++++ src/utils.ts | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/index.ts b/src/index.ts index 08540af8..fa4fd197 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,13 @@ #!/usr/bin/env node +// Load managed settings and apply environment variables +import { loadManagedSettings, applyEnvironmentSettings } from "./utils.js"; + +const managedSettings = loadManagedSettings(); +if (managedSettings) { + applyEnvironmentSettings(managedSettings); +} + // stdout is used to send messages to the client // we redirect everything else to stderr to make sure it doesn't interfere with ACP console.log = console.error; diff --git a/src/utils.ts b/src/utils.ts index 008ddd12..6ddfe351 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,6 +2,8 @@ import { Readable, Writable } from "node:stream"; import { WritableStream, ReadableStream } from "node:stream/web"; +import { readFileSync } from "node:fs"; +import { platform } from "node:os"; // Useful for bridging push-based and async-iterator-based code. export class Pushable implements AsyncIterable { @@ -80,3 +82,43 @@ export function unreachable(value: never): never { export function sleep(time: number): Promise { return new Promise((resolve) => setTimeout(resolve, time)); } + +interface ManagedSettings { + permissions?: { + allow?: string[]; + deny?: string[]; + }; + env?: Record; +} + +// Following the rules in https://docs.anthropic.com/en/docs/claude-code/settings#settings-files +// This can be removed once the SDK supports it natively. +function getManagedSettingsPath(): string { + const os = platform(); + switch (os) { + case "darwin": + return "/Library/Application Support/ClaudeCode/managed-settings.json"; + case "linux": // including WSL + return "/etc/claude-code/managed-settings.json"; + case "win32": + return "C:\\ProgramData\\ClaudeCode\\managed-settings.json"; + default: + return "/etc/claude-code/managed-settings.json"; + } +} + +export function loadManagedSettings(): ManagedSettings | null { + try { + return JSON.parse(readFileSync(getManagedSettingsPath(), "utf8")) as ManagedSettings; + } catch { + return null; + } +} + +export function applyEnvironmentSettings(settings: ManagedSettings): void { + if (settings.env) { + for (const [key, value] of Object.entries(settings.env)) { + process.env[key] = value; + } + } +}