import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync } from 'fs';
import { join } from 'path';
import { homedir, hostname } from 'os';
import { randomUUID, randomBytes, createHmac, timingSafeEqual } from 'crypto';
function getConfigDir() {
    const override = process.env.SHIELDCORTEX_CONFIG_DIR?.trim();
    if (override)
        return override;
    return join(homedir(), '.shieldcortex');
}
function getConfigFile() {
    return join(getConfigDir(), 'config.json');
}
function getSigFile() {
    return join(getConfigDir(), '.config-sig');
}
function getIntegrityKeyFile() {
    return join(getConfigDir(), '.integrity-key');
}
const DEFAULT_BASE_URL = 'https://api.shieldcortex.ai';
const DEFAULT_SYNC_CONTROLS = {
    projectMode: 'all',
    projects: [],
    contentMode: 'full',
    excludeSensitive: false,
};
const DEFAULT_REVIEW_COPILOT_CONFIG = {
    enabled: false,
    modelId: 'onnx-community/Qwen2.5-0.5B-Instruct',
    modelCacheDir: '',
    telemetryPath: '',
    inferenceTimeoutMs: 10000,
    workerHeapMB: 2048,
};
// Cache to avoid repeated file reads
let cachedConfig = null;
let cachedConfigFile = null;
// ── Config Integrity (HMAC) ──────────────────────────────
let cachedIntegrityKey = null;
let cachedIntegrityKeyFile = null;
let configTampered = false;
function getIntegrityKey() {
    const integrityKeyFile = getIntegrityKeyFile();
    const configDir = getConfigDir();
    if (cachedIntegrityKey && cachedIntegrityKeyFile === integrityKeyFile)
        return cachedIntegrityKey;
    try {
        if (existsSync(integrityKeyFile)) {
            cachedIntegrityKey = readFileSync(integrityKeyFile, 'utf-8').trim();
            cachedIntegrityKeyFile = integrityKeyFile;
            return cachedIntegrityKey;
        }
    }
    catch { /* ignore */ }
    // Generate new key on first run
    const key = randomBytes(32).toString('hex');
    mkdirSync(configDir, { recursive: true });
    writeFileSync(integrityKeyFile, key, { mode: 0o600 });
    try {
        chmodSync(integrityKeyFile, 0o600);
    }
    catch { /* best-effort */ }
    cachedIntegrityKey = key;
    cachedIntegrityKeyFile = integrityKeyFile;
    return key;
}
function signConfig(jsonContent) {
    return createHmac('sha256', getIntegrityKey()).update(jsonContent, 'utf-8').digest('hex');
}
function writeConfigSignature(jsonContent) {
    const sig = signConfig(jsonContent);
    const sigFile = getSigFile();
    writeFileSync(sigFile, sig, { mode: 0o600 });
    try {
        chmodSync(sigFile, 0o600);
    }
    catch { /* best-effort */ }
}
function verifyConfigIntegrity(jsonContent) {
    try {
        const sigFile = getSigFile();
        if (!existsSync(sigFile)) {
            // First run after upgrade — create signature, don't flag tamper
            writeConfigSignature(jsonContent);
            return true;
        }
        const storedSig = readFileSync(sigFile, 'utf-8').trim();
        const computedSig = signConfig(jsonContent);
        const a = Buffer.from(storedSig, 'utf-8');
        const b = Buffer.from(computedSig, 'utf-8');
        if (a.length !== b.length)
            return false;
        return timingSafeEqual(a, b);
    }
    catch {
        return false;
    }
}
/** Returns true if config file tampering was detected. */
export function isConfigTampered() {
    return configTampered;
}
export function getCloudConfig() {
    const configFile = getConfigFile();
    if (cachedConfig && cachedConfigFile === configFile)
        return cachedConfig;
    try {
        if (!existsSync(configFile)) {
            return { cloudApiKey: null, cloudBaseUrl: DEFAULT_BASE_URL, cloudEnabled: false };
        }
        const raw = JSON.parse(readFileSync(configFile, 'utf-8'));
        cachedConfig = {
            cloudApiKey: raw.cloudApiKey ?? null,
            cloudBaseUrl: raw.cloudBaseUrl ?? DEFAULT_BASE_URL,
            cloudEnabled: raw.cloudEnabled ?? false,
        };
        cachedConfigFile = configFile;
        return cachedConfig;
    }
    catch {
        return { cloudApiKey: null, cloudBaseUrl: DEFAULT_BASE_URL, cloudEnabled: false };
    }
}
export function setCloudConfig(updates) {
    let existing = {};
    try {
        const configFile = getConfigFile();
        if (existsSync(configFile)) {
            existing = JSON.parse(readFileSync(configFile, 'utf-8'));
        }
    }
    catch {
        // Start fresh if parse fails
    }
    if (updates.cloudApiKey !== undefined)
        existing.cloudApiKey = updates.cloudApiKey;
    if (updates.cloudBaseUrl !== undefined)
        existing.cloudBaseUrl = updates.cloudBaseUrl;
    if (updates.cloudEnabled !== undefined)
        existing.cloudEnabled = updates.cloudEnabled;
    const configDir = getConfigDir();
    const configFile = getConfigFile();
    mkdirSync(configDir, { recursive: true });
    const content = JSON.stringify(existing, null, 2) + '\n';
    writeFileSync(configFile, content);
    writeConfigSignature(content);
    // Invalidate cache
    cachedConfig = null;
    cachedConfigFile = null;
    configTampered = false;
}
/** Reset the in-memory cache (useful for testing) */
export function clearCloudConfigCache() {
    cachedConfig = null;
    cachedConfigFile = null;
}
function normalizeProjectList(value) {
    if (!Array.isArray(value))
        return [];
    return [...new Set(value
            .filter((entry) => typeof entry === 'string')
            .map((entry) => entry.trim())
            .filter(Boolean))].sort((a, b) => a.localeCompare(b));
}
export function getCloudSyncControls() {
    const raw = readRawConfig();
    const projectMode = raw.cloudSyncProjectMode;
    const contentMode = raw.cloudSyncContentMode;
    return {
        projectMode: projectMode === 'include' || projectMode === 'exclude'
            ? projectMode
            : DEFAULT_SYNC_CONTROLS.projectMode,
        projects: normalizeProjectList(raw.cloudSyncProjects),
        contentMode: contentMode === 'metadata' ? 'metadata' : DEFAULT_SYNC_CONTROLS.contentMode,
        excludeSensitive: typeof raw.cloudSyncExcludeSensitive === 'boolean'
            ? raw.cloudSyncExcludeSensitive
            : DEFAULT_SYNC_CONTROLS.excludeSensitive,
    };
}
export function setCloudSyncControls(updates) {
    const raw = readRawConfig();
    if (updates.projectMode !== undefined)
        raw.cloudSyncProjectMode = updates.projectMode;
    if (updates.projects !== undefined)
        raw.cloudSyncProjects = normalizeProjectList(updates.projects);
    if (updates.contentMode !== undefined)
        raw.cloudSyncContentMode = updates.contentMode;
    if (updates.excludeSensitive !== undefined)
        raw.cloudSyncExcludeSensitive = updates.excludeSensitive;
    writeRawConfig(raw);
}
export function shouldSyncProject(project, controls = getCloudSyncControls()) {
    const normalized = (project ?? '').trim();
    if (controls.projectMode === 'all')
        return true;
    const included = controls.projects.includes(normalized);
    return controls.projectMode === 'include' ? included : !included;
}
export function isSensitiveLevel(level) {
    if (!level)
        return false;
    const normalized = level.trim().toUpperCase();
    return normalized.length > 0 && normalized !== 'PUBLIC' && normalized !== 'INTERNAL';
}
// ── Trusted Skills ──────────────────────────────────────
export function readRawConfig() {
    try {
        const configFile = getConfigFile();
        if (existsSync(configFile)) {
            const content = readFileSync(configFile, 'utf-8');
            const data = JSON.parse(content);
            // Verify HMAC integrity
            if (!verifyConfigIntegrity(content)) {
                configTampered = true;
                console.error('[ShieldCortex] WARNING: Config file integrity check failed — possible tampering detected. Falling back to strict mode.');
                // Force strict mode on tampered config
                data.defenceMode = 'strict';
            }
            return data;
        }
    }
    catch { /* ignore */ }
    return {};
}
function writeRawConfig(raw) {
    const configDir = getConfigDir();
    const configFile = getConfigFile();
    mkdirSync(configDir, { recursive: true });
    const content = JSON.stringify(raw, null, 2) + '\n';
    writeFileSync(configFile, content);
    // Sign the config after writing
    writeConfigSignature(content);
    cachedConfig = null;
    cachedConfigFile = null;
    // Clear tamper flag on legitimate write
    configTampered = false;
}
export function getTrustedSkills() {
    const raw = readRawConfig();
    return Array.isArray(raw.trustedSkills) ? raw.trustedSkills : [];
}
export function addTrustedSkill(path) {
    const raw = readRawConfig();
    const list = Array.isArray(raw.trustedSkills) ? raw.trustedSkills : [];
    if (!list.includes(path)) {
        list.push(path);
        raw.trustedSkills = list;
        writeRawConfig(raw);
    }
}
export function removeTrustedSkill(path) {
    const raw = readRawConfig();
    const list = Array.isArray(raw.trustedSkills) ? raw.trustedSkills : [];
    const idx = list.indexOf(path);
    if (idx !== -1) {
        list.splice(idx, 1);
        raw.trustedSkills = list;
        writeRawConfig(raw);
    }
}
// ── Cloud Iron Dome Cache ─────────────────────────────
/**
 * Persist cloud Iron Dome data (patterns + policy) to config.json with HMAC integrity.
 */
export function setCloudIronDomeCache(data) {
    const raw = readRawConfig();
    raw.cloudIronDome = data;
    writeRawConfig(raw);
}
/**
 * Read cached cloud Iron Dome data from config.json.
 */
export function getCloudIronDomeCache() {
    const raw = readRawConfig();
    if (raw.cloudIronDome && typeof raw.cloudIronDome === 'object') {
        return raw.cloudIronDome;
    }
    return null;
}
// ── Sync Timestamp ────────────────────────────────────
/**
 * Write lastSyncAt timestamp to config.json on successful cloud sync.
 */
export function updateLastSyncAt() {
    const raw = readRawConfig();
    raw.lastSyncAt = new Date().toISOString();
    writeRawConfig(raw);
}
const VALID_MODES = ['strict', 'balanced', 'permissive'];
/**
 * Returns the persisted defence mode, defaulting to 'balanced'.
 */
export function getDefenceMode() {
    const raw = readRawConfig();
    const mode = raw.defenceMode;
    if (typeof mode === 'string' && VALID_MODES.includes(mode)) {
        return mode;
    }
    return 'balanced';
}
/**
 * Persists the defence mode to ~/.shieldcortex/config.json.
 */
export function setDefenceMode(mode) {
    if (!VALID_MODES.includes(mode)) {
        throw new Error(`Invalid defence mode: ${mode}. Must be one of: ${VALID_MODES.join(', ')}`);
    }
    const raw = readRawConfig();
    raw.defenceMode = mode;
    writeRawConfig(raw);
}
const DEFAULT_VERIFY_CONFIG = {
    verifyEnabled: false,
    verifyMode: 'advisory',
    verifyTriggers: ['QUARANTINE'],
    verifyTimeoutMs: 5000,
};
/**
 * Returns the persisted LLM verification config.
 * Verify requires cloud to be configured (cloudEnabled + cloudApiKey).
 */
export function getVerifyConfig() {
    const raw = readRawConfig();
    return {
        verifyEnabled: typeof raw.verifyEnabled === 'boolean' ? raw.verifyEnabled : DEFAULT_VERIFY_CONFIG.verifyEnabled,
        verifyMode: raw.verifyMode === 'enforce' ? 'enforce' : DEFAULT_VERIFY_CONFIG.verifyMode,
        verifyTriggers: Array.isArray(raw.verifyTriggers) ? raw.verifyTriggers : DEFAULT_VERIFY_CONFIG.verifyTriggers,
        verifyTimeoutMs: typeof raw.verifyTimeoutMs === 'number' ? raw.verifyTimeoutMs : DEFAULT_VERIFY_CONFIG.verifyTimeoutMs,
    };
}
/**
 * Persists LLM verification config to ~/.shieldcortex/config.json.
 */
export function setVerifyConfig(updates) {
    const raw = readRawConfig();
    if (updates.verifyEnabled !== undefined)
        raw.verifyEnabled = updates.verifyEnabled;
    if (updates.verifyMode !== undefined)
        raw.verifyMode = updates.verifyMode;
    if (updates.verifyTriggers !== undefined)
        raw.verifyTriggers = updates.verifyTriggers;
    if (updates.verifyTimeoutMs !== undefined)
        raw.verifyTimeoutMs = updates.verifyTimeoutMs;
    writeRawConfig(raw);
}
// ── Review Copilot Config ───────────────────────────────
function readReviewCopilotRaw() {
    const raw = readRawConfig();
    return raw.reviewCopilot && typeof raw.reviewCopilot === 'object'
        ? raw.reviewCopilot
        : {};
}
function positiveNumber(value, fallback, min, max) {
    if (typeof value !== 'number' || !Number.isFinite(value))
        return fallback;
    return Math.max(min, Math.min(max, Math.floor(value)));
}
/**
 * Returns local Review Copilot config.
 * Disabled by default regardless of cloud key presence; users must opt in.
 */
export function getReviewCopilotConfig() {
    const raw = readReviewCopilotRaw();
    return {
        enabled: raw.enabled === true,
        modelId: typeof raw.modelId === 'string' && raw.modelId.trim()
            ? raw.modelId.trim()
            : DEFAULT_REVIEW_COPILOT_CONFIG.modelId,
        modelCacheDir: typeof raw.modelCacheDir === 'string' && raw.modelCacheDir.trim()
            ? raw.modelCacheDir.trim()
            : join(getConfigDir(), 'models', 'review-copilot'),
        telemetryPath: typeof raw.telemetryPath === 'string' && raw.telemetryPath.trim()
            ? raw.telemetryPath.trim()
            : join(getConfigDir(), 'review-copilot-telemetry.jsonl'),
        inferenceTimeoutMs: positiveNumber(raw.inferenceTimeoutMs, DEFAULT_REVIEW_COPILOT_CONFIG.inferenceTimeoutMs, 1000, 60000),
        workerHeapMB: positiveNumber(raw.workerHeapMB, DEFAULT_REVIEW_COPILOT_CONFIG.workerHeapMB, 256, 8192),
    };
}
/**
 * Persists local Review Copilot config.
 */
export function setReviewCopilotConfig(updates) {
    const raw = readRawConfig();
    const existing = raw.reviewCopilot && typeof raw.reviewCopilot === 'object'
        ? raw.reviewCopilot
        : {};
    raw.reviewCopilot = {
        ...existing,
        ...updates,
    };
    writeRawConfig(raw);
}
// ── Ranker Config ─────────────────────────────────────
const DEFAULT_RANKER_CONFIG = {
    engine: 'rrf',
    rrfK: 60,
    weights: { fts: 0.4, vector: 0.6, graph: 0.3 },
};
const VALID_RANKER_ENGINES = ['rrf', 'legacy'];
function parseEngine(value) {
    if (typeof value !== 'string')
        return null;
    const normalized = value.trim().toLowerCase();
    return VALID_RANKER_ENGINES.includes(normalized)
        ? normalized
        : null;
}
function parseWeights(value) {
    if (!value || typeof value !== 'object')
        return null;
    const v = value;
    const fts = typeof v.fts === 'number' ? v.fts : null;
    const vector = typeof v.vector === 'number' ? v.vector : null;
    const graph = typeof v.graph === 'number' ? v.graph : null;
    if (fts === null || vector === null || graph === null)
        return null;
    return { fts, vector, graph };
}
/**
 * Resolved ranker configuration.
 *
 * Resolution order (env wins so it can be flipped per-process without
 * editing config.json):
 *   1. `SHIELDCORTEX_RANKER` env var (`rrf` | `legacy`)
 *   2. `ranker.engine` in `~/.shieldcortex/config.json`
 *   3. Default (`rrf`)
 *
 * `rrfK` and `weights` only come from config.json (no env override) —
 * tuning these is a deliberate config change, not a per-process knob.
 */
export function getRankerConfig() {
    const raw = readRawConfig();
    const fileRanker = raw.ranker && typeof raw.ranker === 'object'
        ? raw.ranker
        : null;
    const envEngine = parseEngine(process.env.SHIELDCORTEX_RANKER);
    const fileEngine = fileRanker ? parseEngine(fileRanker.engine) : null;
    const engine = envEngine ?? fileEngine ?? DEFAULT_RANKER_CONFIG.engine;
    const fileK = fileRanker && typeof fileRanker.rrfK === 'number' && fileRanker.rrfK > 0
        ? fileRanker.rrfK
        : null;
    const rrfK = fileK ?? DEFAULT_RANKER_CONFIG.rrfK;
    const fileWeights = fileRanker ? parseWeights(fileRanker.weights) : null;
    const weights = fileWeights ?? DEFAULT_RANKER_CONFIG.weights;
    return { engine, rrfK, weights };
}
/**
 * Persists ranker config to `~/.shieldcortex/config.json`. Only the
 * fields supplied in `updates` are written; other fields are preserved.
 */
export function setRankerConfig(updates) {
    const raw = readRawConfig();
    const existing = raw.ranker && typeof raw.ranker === 'object'
        ? raw.ranker
        : {};
    if (updates.engine !== undefined)
        existing.engine = updates.engine;
    if (updates.rrfK !== undefined)
        existing.rrfK = updates.rrfK;
    if (updates.weights !== undefined)
        existing.weights = updates.weights;
    raw.ranker = existing;
    writeRawConfig(raw);
}
const DEFAULT_OPENCLAW_MEMORY_CONFIG = {
    autoMemory: true,
    dedupe: true,
    noveltyThreshold: 0.88,
    maxRecent: 300,
};
function clamp(value, min, max) {
    return Math.max(min, Math.min(max, value));
}
/**
 * Returns persisted OpenClaw memory integration config with safe defaults.
 */
export function getOpenClawMemoryConfig() {
    const raw = readRawConfig();
    const threshold = typeof raw.openclawAutoMemoryNoveltyThreshold === 'number'
        ? clamp(raw.openclawAutoMemoryNoveltyThreshold, 0.6, 0.99)
        : DEFAULT_OPENCLAW_MEMORY_CONFIG.noveltyThreshold;
    const maxRecent = typeof raw.openclawAutoMemoryMaxRecent === 'number'
        ? Math.floor(clamp(raw.openclawAutoMemoryMaxRecent, 50, 1000))
        : DEFAULT_OPENCLAW_MEMORY_CONFIG.maxRecent;
    return {
        autoMemory: raw.openclawAutoMemory === true,
        dedupe: raw.openclawAutoMemoryDedupe !== false,
        noveltyThreshold: threshold,
        maxRecent,
    };
}
/**
 * Persists OpenClaw memory integration config.
 */
export function setOpenClawMemoryConfig(updates) {
    const raw = readRawConfig();
    if (updates.autoMemory !== undefined)
        raw.openclawAutoMemory = updates.autoMemory;
    if (updates.dedupe !== undefined)
        raw.openclawAutoMemoryDedupe = updates.dedupe;
    if (updates.noveltyThreshold !== undefined) {
        raw.openclawAutoMemoryNoveltyThreshold = clamp(updates.noveltyThreshold, 0.6, 0.99);
    }
    if (updates.maxRecent !== undefined) {
        raw.openclawAutoMemoryMaxRecent = Math.floor(clamp(updates.maxRecent, 50, 1000));
    }
    writeRawConfig(raw);
}
/**
 * Returns whether OpenClaw auto-memory extraction is enabled.
 * Default is true (on by default, opt-out with --openclaw-auto-memory false).
 */
export function getOpenClawAutoMemory() {
    return getOpenClawMemoryConfig().autoMemory;
}
/**
 * Persists OpenClaw auto-memory extraction preference.
 */
export function setOpenClawAutoMemory(enabled) {
    setOpenClawMemoryConfig({ autoMemory: enabled });
}
// ── Proactive Recall ─────────────────────────────────
/**
 * Returns whether proactive memory recall is enabled on prompt submit.
 * Default is false since v4.11.0 — opt-in with --proactive-recall true.
 * Per-turn recall was found to be net-negative for fast agent loops; kept
 * available for interactive sessions that want it.
 */
export function isProactiveRecallEnabled() {
    const raw = readRawConfig();
    return raw.proactiveRecall === true;
}
/**
 * Persists proactive recall preference to ~/.shieldcortex/config.json.
 */
export function setProactiveRecall(enabled) {
    const raw = readRawConfig();
    raw.proactiveRecall = enabled;
    writeRawConfig(raw);
}
/**
 * Restores the v4.10.x defaults for users who preferred the old behaviour.
 * Writes explicit overrides for every default the v4.11.0 release flipped,
 * so the flip is a one-command undo.
 */
export function restore410Defaults() {
    const raw = readRawConfig();
    raw.proactiveRecall = true;
    const existingInterceptor = (raw.interceptor && typeof raw.interceptor === 'object')
        ? raw.interceptor
        : {};
    const existingSeverity = (existingInterceptor.severityActions && typeof existingInterceptor.severityActions === 'object')
        ? existingInterceptor.severityActions
        : {};
    raw.interceptor = {
        ...existingInterceptor,
        severityActions: {
            ...existingSeverity,
            low: 'log',
            medium: 'warn',
            high: 'require_approval',
            critical: 'require_approval',
        },
    };
    const existingSessionStart = (raw.sessionStart && typeof raw.sessionStart === 'object')
        ? raw.sessionStart
        : {};
    raw.sessionStart = {
        ...existingSessionStart,
        preamble: 'minimal',
    };
    writeRawConfig(raw);
}
/**
 * Returns the resolved on/off state of the opt-in auto-memory hooks.
 *
 * Default is false for both — preserves the OpenClaw-safe default that
 * shipped in v4.13.0. The install flags (`--with-stop-hook` /
 * `--with-session-end`) flip these to true so that wiring the hook in
 * settings.json and enabling the runtime gate are a single user action.
 */
export function getAutoMemoryEnableConfig() {
    const raw = readRawConfig();
    const am = raw.autoMemory && typeof raw.autoMemory === 'object'
        ? raw.autoMemory
        : {};
    return {
        enableStop: am.enableStop === true,
        enableSessionEnd: am.enableSessionEnd === true,
    };
}
/**
 * Persists the on/off state of the opt-in auto-memory hooks.
 *
 * Lives in `autoMemory.enableStop` / `autoMemory.enableSessionEnd` under
 * `~/.shieldcortex/config.json` — the same namespace `auto-memory-config.mjs`
 * reads from at hook fire time. Single source of truth: install flag +
 * runtime gate cannot disagree.
 */
export function setAutoMemoryEnableConfig(updates) {
    const raw = readRawConfig();
    const existing = raw.autoMemory && typeof raw.autoMemory === 'object'
        ? raw.autoMemory
        : {};
    if (updates.enableStop !== undefined)
        existing.enableStop = updates.enableStop;
    if (updates.enableSessionEnd !== undefined)
        existing.enableSessionEnd = updates.enableSessionEnd;
    raw.autoMemory = existing;
    writeRawConfig(raw);
}
const DEFAULT_TOOL_RESPONSE_SCAN_CONFIG = {
    scanToolResponses: true,
    toolResponseMode: 'advisory',
};
/**
 * Returns tool response scanning config with safe defaults.
 */
export function getToolResponseScanConfig() {
    const raw = readRawConfig();
    return {
        scanToolResponses: raw.scanToolResponses !== false,
        toolResponseMode: raw.toolResponseMode === 'enforce' ? 'enforce' : DEFAULT_TOOL_RESPONSE_SCAN_CONFIG.toolResponseMode,
    };
}
/**
 * Persists tool response scanning config.
 */
export function setToolResponseScanConfig(updates) {
    const raw = readRawConfig();
    if (updates.scanToolResponses !== undefined)
        raw.scanToolResponses = updates.scanToolResponses;
    if (updates.toolResponseMode !== undefined)
        raw.toolResponseMode = updates.toolResponseMode;
    writeRawConfig(raw);
}
// ── Device Identity ────────────────────────────────────
/**
 * Returns a stable UUID for this machine.
 * Generates and persists on first call; reads from config thereafter.
 */
export function getDeviceId() {
    const raw = readRawConfig();
    if (typeof raw.deviceId === 'string' && raw.deviceId) {
        return raw.deviceId;
    }
    const id = randomUUID();
    raw.deviceId = id;
    writeRawConfig(raw);
    return id;
}
/**
 * Returns the OS hostname for this machine.
 * Stores in config on first call; reads from config thereafter.
 */
export function getDeviceName() {
    const raw = readRawConfig();
    if (typeof raw.deviceName === 'string' && raw.deviceName) {
        return raw.deviceName;
    }
    const name = hostname();
    raw.deviceName = name;
    writeRawConfig(raw);
    return name;
}
