import { e as getGlobalConfigPath, f as getConfigPath } from './paths-2M_UxD_H.js';
import { a as atomicWriteJson, r as readJson, s as saveJson } from './json-DXl7iDYg.js';
import { existsSync } from 'node:fs';

//#region ../core/dist/llm/fallback-model.js
/**
* Dependency-free leaf holding the implicit fallback model literal.
*
* Hoisted out of `./role-resolver.ts` (T11359 follow-up) to break a circular
* import. `config.ts` reads {@link IMPLICIT_FALLBACK_MODEL} eagerly while
* initializing its module-level `DEFAULTS` const, but `role-resolver.ts` pulls
* a heavy runtime import chain (credentials / credentials-store / transports)
* that participates in a cycle with `config.ts`. When the relocation in T11359
* changed module-init order so `config.js` evaluated ahead of `role-resolver.js`
* within that cycle, the eager read crashed with
* `ReferenceError: Cannot access 'IMPLICIT_FALLBACK_MODEL' before initialization`
* (a temporal-dead-zone error the type checker cannot catch — only the
* Build & Verify runtime smoke does). A leaf module with ZERO local imports
* always finishes initialization first, so `config.ts` can import the literal
* directly and read it safely regardless of cycle order.
*
* The literal lives here (and ONLY under `packages/core/src/llm/`) so the T9255
* grep guard stays clean. `role-resolver.ts` re-exports it for back-compat with
* existing `from './role-resolver.js'` consumers.
*
* @task T9255
* @task T11359
*/
var IMPLICIT_FALLBACK_MODEL = "claude-haiku-4-5-20251001";
//#endregion
//#region ../core/dist/config.js
/**
* Configuration engine for CLEO V2.
*
* Resolution priority: CLI flags > Environment vars > Project config > Global config > Defaults
*
* @epic T4454
* @task T4458
* @task T067
*/
/** Default configuration values. */
var DEFAULTS = {
	version: "2.10.0",
	output: {
		defaultFormat: "json",
		showColor: true,
		showUnicode: true,
		showProgressBars: true,
		dateFormat: "relative"
	},
	backup: {
		maxOperationalBackups: 10,
		maxSafetyBackups: 5,
		compressionEnabled: false
	},
	hierarchy: {
		maxDepth: 3,
		maxSiblings: 0,
		cascadeDelete: false,
		maxActiveSiblings: 0,
		countDoneInLimit: false,
		enforcementProfile: "llm-agent-first"
	},
	session: {
		autoStart: false,
		requireNotes: false,
		multiSession: false
	},
	enforcement: {
		acceptance: {
			mode: "block",
			requiredForPriorities: [
				"critical",
				"high",
				"medium",
				"low"
			],
			minimumCriteria: 3
		},
		session: { requiredForMutate: true }
	},
	verification: {
		enabled: true,
		maxRounds: 3,
		requiredGates: [
			"implemented",
			"testsPassed",
			"qaPassed"
		]
	},
	lifecycle: { mode: "strict" },
	logging: {
		level: "info",
		filePath: "logs/cleo.log",
		maxFileSize: 10 * 1024 * 1024,
		maxFiles: 5,
		auditRetentionDays: 90,
		archiveBeforePrune: true
	},
	sharing: {
		mode: "none",
		commitAllowlist: [],
		denylist: []
	},
	signaldock: {
		enabled: false,
		mode: "http",
		endpoint: "http://localhost:4000",
		agentPrefix: "cleo-",
		privacyTier: "private"
	},
	brain: {
		autoCapture: true,
		captureFiles: false,
		captureWork: false,
		embedding: {
			enabled: true,
			provider: "local"
		},
		memoryBridge: {
			autoRefresh: true,
			contextAware: true,
			maxTokens: 2e3,
			mode: "cli"
		},
		summarization: { enabled: true },
		llmExtraction: {
			enabled: true,
			model: IMPLICIT_FALLBACK_MODEL,
			minImportance: .6,
			maxExtractions: 7,
			maxTranscriptChars: 6e4
		}
	},
	auth: {
		claudeCodeConsentGiven: false,
		cooperativeWriteBack: true
	},
	leadRollup: { mode: "passive" },
	daemon: { autoStart: true }
};
/** Environment variable to config path mapping. */
var ENV_MAP = {
	CLEO_FORMAT: "output.defaultFormat",
	CLEO_OUTPUT_DEFAULT_FORMAT: "output.defaultFormat",
	CLEO_OUTPUT_SHOW_COLOR: "output.showColor",
	CLEO_OUTPUT_SHOW_UNICODE: "output.showUnicode",
	CLEO_OUTPUT_SHOW_PROGRESS_BARS: "output.showProgressBars",
	CLEO_OUTPUT_DATE_FORMAT: "output.dateFormat",
	CLEO_HIERARCHY_MAX_DEPTH: "hierarchy.maxDepth",
	CLEO_HIERARCHY_MAX_SIBLINGS: "hierarchy.maxSiblings",
	CLEO_HIERARCHY_MAX_ACTIVE_SIBLINGS: "hierarchy.maxActiveSiblings",
	CLEO_HIERARCHY_ENFORCEMENT_PROFILE: "hierarchy.enforcementProfile",
	CLEO_SESSION_AUTO_START: "session.autoStart",
	CLEO_SESSION_REQUIRE_NOTES: "session.requireNotes",
	CLEO_LIFECYCLE_MODE: "lifecycle.mode",
	CLEO_LOG_LEVEL: "logging.level",
	CLEO_LOG_FILE: "logging.filePath",
	CLEO_AUDIT_RETENTION_DAYS: "logging.auditRetentionDays",
	CLEO_SIGNALDOCK_ENABLED: "signaldock.enabled",
	CLEO_SIGNALDOCK_ENDPOINT: "signaldock.endpoint"
};
/**
* Get a value at a dotted path from an object.
*/
function getNestedValue(obj, path) {
	const parts = path.split(".");
	let current = obj;
	for (const part of parts) {
		if (current === null || current === void 0 || typeof current !== "object") return;
		current = current[part];
	}
	return current;
}
/**
* Set a value at a dotted path in an object (mutates).
*/
function setNestedValue(obj, path, value) {
	const parts = path.split(".");
	let current = obj;
	for (let i = 0; i < parts.length - 1; i++) {
		const part = parts[i];
		if (current[part] === void 0 || typeof current[part] !== "object") current[part] = {};
		current = current[part];
	}
	current[parts[parts.length - 1]] = value;
}
/**
* Deep merge two objects. Source values override target values.
* Arrays are replaced (not merged).
*/
function deepMerge(target, source) {
	const result = { ...target };
	for (const key of Object.keys(source)) {
		const sourceVal = source[key];
		const targetVal = result[key];
		if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal !== null && typeof targetVal === "object" && !Array.isArray(targetVal)) result[key] = deepMerge(targetVal, sourceVal);
		else result[key] = sourceVal;
	}
	return result;
}
/**
* Parse an environment variable value to the appropriate type.
*/
function parseEnvValue(value) {
	if (value === "true") return true;
	if (value === "false") return false;
	const num = Number(value);
	if (!Number.isNaN(num) && value.trim() !== "") return num;
	return value;
}
/**
* Load and merge configuration from all sources.
* Priority: defaults < global config < project config < environment vars
*
* @deprecated Use `resolveCleoConfig` from `@cleocode/core/config/registry` instead.
*   The new resolver is driven by the ConfigManifest contract (T9876) and is the
*   SSoT for cascade resolution. Tracked for rewire under T9879.
*/
async function loadConfig(cwd) {
	let merged = JSON.parse(JSON.stringify(DEFAULTS));
	const globalConfig = await readJson(getGlobalConfigPath());
	if (globalConfig) merged = deepMerge(merged, globalConfig);
	const projectConfig = await readJson(getConfigPath(cwd));
	if (projectConfig) {
		if (projectConfig.pinoLogging && typeof projectConfig.pinoLogging === "object") merged.logging = deepMerge(merged.logging ?? {}, projectConfig.pinoLogging);
		merged = deepMerge(merged, projectConfig);
	}
	for (const [envKey, configPath] of Object.entries(ENV_MAP)) {
		const envValue = process.env[envKey];
		if (envValue !== void 0) setNestedValue(merged, configPath, parseEnvValue(envValue));
	}
	return merged;
}
/**
* Get a single config value with source tracking.
* Returns the value and which source it came from.
*
* @deprecated Use `getConfigValue` from `@cleocode/core/config/registry` instead.
*   The registry helper resolves over the ConfigManifest cascade (T9876). The
*   ResolvedValue source-tracking shape is being reconsidered under T9879 —
*   callers that need provenance should follow that thread.
*/
async function getConfigValue(path, cwd) {
	for (const [envKey, configPath] of Object.entries(ENV_MAP)) if (configPath === path && process.env[envKey] !== void 0) return {
		value: parseEnvValue(process.env[envKey]),
		source: "env"
	};
	const projectConfig = await readJson(getConfigPath(cwd));
	if (projectConfig) {
		const val = getNestedValue(projectConfig, path);
		if (val !== void 0) return {
			value: val,
			source: "project"
		};
	}
	const globalConfig = await readJson(getGlobalConfigPath());
	if (globalConfig) {
		const val = getNestedValue(globalConfig, path);
		if (val !== void 0) return {
			value: val,
			source: "global"
		};
	}
	return {
		value: getNestedValue({ ...DEFAULTS }, path),
		source: "default"
	};
}
/**
* Get a raw config value from the project config file only (no cascade).
* Returns undefined if the key is not found.
* Used by the engine layer for simple key lookups without source tracking.
*
* @deprecated Use `getConfigValue` from `@cleocode/core/config/registry` with
*   `scope: 'project'` instead. Tracked for rewire under T9879.
* @task T4789
*/
async function getRawConfigValue(key, cwd) {
	const config = await readJson(getConfigPath(cwd));
	if (!config) return void 0;
	if (!key) return config;
	return getNestedValue(config, key);
}
/**
* Parse a string value into its appropriate JS type.
* Handles booleans, null, integers, floats, and JSON.
* @task T4789
*/
function parseConfigValue(value) {
	if (typeof value !== "string") return value;
	if (value === "true") return true;
	if (value === "false") return false;
	if (value === "null") return null;
	if (/^-?\d+$/.test(value)) return parseInt(value, 10);
	if (/^-?\d+\.\d+$/.test(value)) return parseFloat(value);
	try {
		return JSON.parse(value);
	} catch {
		return value;
	}
}
/**
* Set a config value in the project or global config file (dot-notation supported).
* Creates intermediate objects as needed. Parses string values into
* appropriate types (boolean, number, null, JSON).
* @task T4789
* @task T4795
*/
async function setConfigValue(key, value, cwd, opts) {
	const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
	if (!existsSync(configPath)) await atomicWriteJson(configPath, {});
	const config = await readJson(configPath) ?? {};
	const parsedValue = parseConfigValue(value);
	setNestedValue(config, key, parsedValue);
	await saveJson(configPath, config);
	return {
		key,
		value: parsedValue,
		scope: opts?.global ? "global" : "project"
	};
}
/**
* All three strictness presets.
*
* strict   — block on missing AC, require sessions, enforce lifecycle pipeline
* standard — warn on missing AC, optional sessions, advisory pipeline
* minimal  — no AC checking, no session requirement, lifecycle off
*/
var STRICTNESS_PRESETS = {
	strict: {
		description: "Block on missing acceptance criteria, require sessions, enforce lifecycle pipeline.",
		values: {
			"session.autoStart": false,
			"session.requireNotes": true,
			"session.multiSession": false,
			"enforcement.acceptance.mode": "block",
			"lifecycle.mode": "strict"
		}
	},
	standard: {
		description: "Warn on missing acceptance criteria, optional sessions, advisory lifecycle pipeline.",
		values: {
			"session.autoStart": false,
			"session.requireNotes": false,
			"session.multiSession": true,
			"enforcement.acceptance.mode": "warn",
			"lifecycle.mode": "advisory"
		}
	},
	minimal: {
		description: "No acceptance criteria checking, no session requirement, lifecycle pipeline off.",
		values: {
			"session.autoStart": false,
			"session.requireNotes": false,
			"session.multiSession": true,
			"enforcement.acceptance.mode": "off",
			"lifecycle.mode": "off"
		}
	}
};
/**
* Apply a strictness preset to the project (or global) config.
* Merges preset values over existing config — keys not covered by the preset
* are preserved unchanged.
* Idempotent: applying the same preset twice yields the same config.
*
* @task T067
*/
async function applyStrictnessPreset(preset, cwd, opts) {
	const definition = STRICTNESS_PRESETS[preset];
	const configPath = getConfigPath(cwd);
	if (!existsSync(configPath)) await atomicWriteJson(configPath, {});
	const config = await readJson(configPath) ?? {};
	for (const [key, value] of Object.entries(definition.values)) setNestedValue(config, key, value);
	await saveJson(configPath, config);
	return {
		preset,
		description: definition.description,
		applied: definition.values,
		scope: opts?.global ? "global" : "project"
	};
}

export { IMPLICIT_FALLBACK_MODEL as I, getConfigValue as a, applyStrictnessPreset as b, getRawConfigValue as g, loadConfig as l, setConfigValue as s };
//# sourceMappingURL=config-B0nEjgSh.js.map
