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; + } + } +}