"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;




var _chunkQX5YU4WLcjs = require('./chunk-QX5YU4WL.cjs');








var _chunkKQCATETEcjs = require('./chunk-KQCATETE.cjs');






var _chunkKKF4ZNPPcjs = require('./chunk-KKF4ZNPP.cjs');
require('./chunk-NBBXBOGV.cjs');
require('./chunk-HYTJ22QN.cjs');
require('./chunk-D4EVQM6I.cjs');
require('./chunk-YO2IWAUP.cjs');
require('./chunk-IBP5WYJY.cjs');
require('./chunk-C6YLU4BJ.cjs');
require('./chunk-4LFBCGLO.cjs');
require('./chunk-JZ6L75WT.cjs');
require('./chunk-3V2PGOS7.cjs');
require('./chunk-XFJLW472.cjs');






var _chunkQAZIYEHIcjs = require('./chunk-QAZIYEHI.cjs');



var _chunkROUGOHCWcjs = require('./chunk-ROUGOHCW.cjs');
require('./chunk-464Y2O3H.cjs');

// ../packages/server/dist/index.js
var _os = require('os');
var _promises = require('fs/promises');
var _path = require('path');

var _fs = require('fs');

var _http = require('http');
var _ws = require('ws');
var _child_process = require('child_process');



var PersistenceQueue = (_class = class {
  __init() {this.pending = /* @__PURE__ */ new Map()}
  __init2() {this.writeInProgress = /* @__PURE__ */ new Map()}
  
  constructor(options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
    this.debounceMs = _nullishCoalesce(options.debounceMs, () => ( 500));
  }
  enqueue(filePath, data) {
    const existing = this.pending.get(filePath);
    if (existing) clearTimeout(existing.timer);
    const timer = setTimeout(() => {
      this.pending.delete(filePath);
      void this.flush(filePath, data);
    }, this.debounceMs);
    this.pending.set(filePath, { data, timer });
  }
  async flush(filePath, data) {
    const pendingEntry = this.pending.get(filePath);
    if (pendingEntry) {
      clearTimeout(pendingEntry.timer);
      this.pending.delete(filePath);
    }
    const serialize = _nullishCoalesce(data, () => ( _optionalChain([pendingEntry, 'optionalAccess', _ => _.data])));
    if (!serialize) return;
    const inFlight = this.writeInProgress.get(filePath);
    if (inFlight) await inFlight;
    const writePromise = this.atomicWrite(filePath, serialize());
    this.writeInProgress.set(filePath, writePromise);
    try {
      await writePromise;
    } finally {
      this.writeInProgress.delete(filePath);
    }
  }
  async flushAll() {
    const paths = [...this.pending.keys()];
    await Promise.all(paths.map((path) => this.flush(path)));
    const inFlight = [...this.writeInProgress.values()];
    if (inFlight.length) await Promise.all(inFlight);
  }
  get pendingCount() {
    return this.pending.size;
  }
  async atomicWrite(filePath, content) {
    const dir = _path.dirname.call(void 0, filePath);
    if (!_fs.existsSync.call(void 0, dir)) await _promises.mkdir.call(void 0, dir, { recursive: true });
    const tmpPath = `${filePath}.tmp`;
    await _promises.writeFile.call(void 0, tmpPath, content, "utf-8");
    try {
      await _promises.rename.call(void 0, tmpPath, filePath);
    } catch (e) {
      try {
        await _promises.unlink.call(void 0, tmpPath);
      } catch (e2) {
      }
      throw new Error(`Failed to atomically write ${filePath}`);
    }
  }
}, _class);
function mapPermissionModeToApprovalPolicy(mode) {
  switch (mode) {
    case "safe":
      return "never";
    case "ask":
      return "on-request";
    case "allow-all":
      return "auto";
    default:
      return "on-request";
  }
}
function mapPermissionModeToCodexParams(mode) {
  switch (mode) {
    case "safe":
      return { approvalPolicy: "untrusted", approvalsReviewer: "user", sandbox: "read-only" };
    case "allow-all":
      return { approvalPolicy: "never", approvalsReviewer: "user", sandbox: "danger-full-access" };
    case "ask":
    default:
      return { approvalPolicy: "on-request", approvalsReviewer: "user", sandbox: "workspace-write" };
  }
}
function resolvePermissionModeForProvider(provider, permissionMode, request) {
  if (!permissionMode) return {};
  if (provider === "claude") {
    return {
      claude: {
        ...request.claude,
        permissionMode
      }
    };
  }
  if (provider === "codex") {
    return {
      codex: {
        ...request.codex,
        permissionMode,
        ...mapPermissionModeToCodexParams(permissionMode)
      }
    };
  }
  if (provider === "flitro" && request.flitro) {
    return {
      flitro: {
        ...request.flitro,
        approvalPolicy: mapPermissionModeToApprovalPolicy(permissionMode)
      }
    };
  }
  return {};
}
function createDefaultLocalHostController(options) {
  assertDefaultRuntimeRequest(options.request);
  const providerPermissionPatch = resolvePermissionModeForProvider(
    options.request.provider,
    options.request.permissionMode,
    options.request
  );
  const req = options.request;
  const result = _chunkKQCATETEcjs.createHostAgentRuntime.call(void 0, {
    ...options.request,
    ...providerPermissionPatch,
    candidates: req.candidates,
    auth: req.auth,
    provider: options.request.provider,
    cwd: options.request.cwd,
    now: options.now,
    extensions: {
      ..._nullishCoalesce(req.extensions, () => ( {})),
      hostServices: {
        ..._nullishCoalesce(_optionalChain([req, 'access', _2 => _2.extensions, 'optionalAccess', _3 => _3.hostServices]), () => ( {})),
        ...options.sessionTools ? { sessionTools: options.sessionTools } : {}
      }
    }
  });
  return _chunkKQCATETEcjs.createHostRuntimeController.call(void 0, {
    runtime: result.runtime,
    sourceRuntime: result.sourceRuntime,
    sessionTools: options.sessionTools,
    now: options.now
  });
}
function assertDefaultRuntimeRequest(request) {
  const req = request;
  if (!req.candidates || !Array.isArray(req.candidates)) {
    throw new HttpError(400, "default_controller_requires_candidates");
  }
  if (!req.auth) {
    throw new HttpError(400, "default_controller_requires_auth");
  }
}
var HttpError = class extends Error {
  constructor(status, message) {
    super(message);
    this.status = status;
  }
  
};
var DEFAULT_CLAUDE_MODELS = ["claude-sonnet-4.5", "claude-opus-4.1", "claude-haiku-4.5"];
var DEFAULT_CODEX_MODELS = ["gpt-5.5", "gpt-5.4", "gpt-5.4-mini"];
var CACHE_TTL_MS = 5 * 60 * 1e3;
var FETCH_TIMEOUT_MS = 5e3;
var cached;
async function discoverModels() {
  if (cached && Date.now() < cached.expiry) return cached.result;
  const [claude, codex] = await Promise.all([discoverClaudeModels(), discoverCodexModels()]);
  const result = { claude, codex };
  cached = { result, expiry: Date.now() + CACHE_TTL_MS };
  return result;
}
async function discoverClaudeModels() {
  const discovered = [];
  try {
    const cachePath = _path.join.call(void 0, _os.homedir.call(void 0, ), ".claude", "cache", "gateway-models.json");
    const raw = await _promises.readFile.call(void 0, cachePath, "utf8");
    const parsed = JSON.parse(raw);
    if (Array.isArray(parsed.models)) {
      for (const entry of parsed.models) {
        const id = typeof entry === "string" ? entry : _optionalChain([entry, 'optionalAccess', _4 => _4.id]);
        if (typeof id === "string" && id.trim()) discovered.push(id.trim());
      }
    }
  } catch (e3) {
  }
  if (discovered.length === 0) {
    const baseUrl = process.env.ANTHROPIC_BASE_URL;
    if (baseUrl) {
      try {
        const headers = { "anthropic-version": "2023-06-01" };
        const authToken = process.env.ANTHROPIC_AUTH_TOKEN;
        const apiKey = process.env.ANTHROPIC_API_KEY;
        if (authToken) headers["Authorization"] = `Bearer ${authToken}`;
        else if (apiKey) headers["x-api-key"] = apiKey;
        const url = `${baseUrl.replace(/\/$/, "")}/v1/models`;
        const response = await fetch(url, {
          headers,
          signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
        });
        if (response.ok) {
          const body = await response.json();
          if (Array.isArray(body.data)) {
            for (const entry of body.data) {
              if (typeof entry.id === "string" && entry.id.trim()) {
                discovered.push(entry.id.trim());
              }
            }
          }
        }
      } catch (e4) {
      }
    }
  }
  const extra = process.env.WEFT_EXTRA_MODELS_CLAUDE;
  if (extra) {
    for (const id of extra.split(",")) {
      if (id.trim()) discovered.push(id.trim());
    }
  }
  return deduplicateModels(DEFAULT_CLAUDE_MODELS, discovered);
}
async function discoverCodexModels() {
  const discovered = [];
  try {
    const configPath = _path.join.call(void 0, _nullishCoalesce(process.env.CODEX_HOME, () => ( _path.join.call(void 0, _os.homedir.call(void 0, ), ".codex"))), "config.toml");
    const raw = await _promises.readFile.call(void 0, configPath, "utf8");
    for (const match of raw.matchAll(/^\s*model\s*=\s*"([^"]+)"/gm)) {
      if (match[1].trim()) discovered.push(match[1].trim());
    }
  } catch (e5) {
  }
  if (discovered.length === 0) {
    const baseUrl = process.env.OPENAI_BASE_URL;
    if (baseUrl) {
      try {
        const headers = {};
        const apiKey = process.env.OPENAI_API_KEY;
        if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
        const url = `${baseUrl.replace(/\/$/, "")}/v1/models`;
        const response = await fetch(url, {
          headers,
          signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
        });
        if (response.ok) {
          const body = await response.json();
          if (Array.isArray(body.data)) {
            for (const entry of body.data) {
              if (typeof entry.id === "string" && entry.id.trim()) {
                discovered.push(entry.id.trim());
              }
            }
          }
        }
      } catch (e6) {
      }
    }
  }
  const extra = process.env.WEFT_EXTRA_MODELS_CODEX;
  if (extra) {
    for (const id of extra.split(",")) {
      if (id.trim()) discovered.push(id.trim());
    }
  }
  return deduplicateModels(DEFAULT_CODEX_MODELS, discovered);
}
function deduplicateModels(defaults, discovered) {
  const seen = new Set(defaults);
  const result = [...defaults];
  for (const model of discovered) {
    if (!seen.has(model)) {
      result.push(model);
      seen.add(model);
    }
  }
  return result;
}
function toSourceSummary(config) {
  return {
    slug: config.slug,
    name: config.name,
    provider: config.provider,
    type: config.type,
    enabled: config.enabled,
    isAuthenticated: config.isAuthenticated,
    connectionStatus: config.connectionStatus,
    tagline: config.tagline
  };
}
function toSkillSummary(skill) {
  return {
    slug: skill.slug,
    name: skill.metadata.name,
    description: skill.metadata.description,
    source: skill.source,
    icon: skill.metadata.icon,
    globs: skill.metadata.globs,
    requiredSources: skill.metadata.requiredSources
  };
}
function createWorkspaceSessionToolBridge(options) {
  const { workspaceRootPath, baseBridge = {}, scheduler } = options;
  return {
    ...baseBridge,
    // ── Sources CRUD ─────────────────────────────────────
    async listSources(request) {
      const sources = _chunkKKF4ZNPPcjs.loadAllSources.call(void 0, workspaceRootPath);
      return {
        sources: sources.filter((s) => !request.enabledOnly || s.config.enabled).map((s) => toSourceSummary(s.config))
      };
    },
    async getSource(request) {
      const config = _chunkKKF4ZNPPcjs.loadSourceConfig.call(void 0, workspaceRootPath, request.sourceSlug);
      if (!config) throw new Error(`Source not found: ${request.sourceSlug}`);
      return {
        source: {
          ...toSourceSummary(config),
          createdAt: config.createdAt,
          updatedAt: config.updatedAt,
          mcp: config.mcp,
          api: config.api,
          local: config.local
        }
      };
    },
    async createSource(request) {
      try {
        const config = await _chunkKKF4ZNPPcjs.createSource.call(void 0, workspaceRootPath, {
          name: request.name,
          provider: request.provider,
          type: request.type,
          mcp: request.mcp,
          api: request.api,
          local: request.local,
          icon: request.icon,
          enabled: request.enabled
        });
        return {
          ok: true,
          source: toSourceSummary(config)
        };
      } catch (error) {
        return { ok: false, reason: error instanceof Error ? error.message : String(error) };
      }
    },
    async updateSource(request) {
      try {
        const config = _chunkKKF4ZNPPcjs.loadSourceConfig.call(void 0, workspaceRootPath, request.sourceSlug);
        if (!config) return { ok: false, reason: `Source not found: ${request.sourceSlug}` };
        const updated = {
          ...config,
          ...request.name !== void 0 ? { name: request.name } : {},
          ...request.enabled !== void 0 ? { enabled: request.enabled } : {},
          ...request.icon !== void 0 ? { icon: request.icon } : {},
          ...request.tagline !== void 0 ? { tagline: request.tagline } : {},
          updatedAt: Date.now()
        };
        _chunkKKF4ZNPPcjs.saveSourceConfig.call(void 0, workspaceRootPath, updated);
        return {
          ok: true,
          source: toSourceSummary(updated)
        };
      } catch (error) {
        return { ok: false, reason: error instanceof Error ? error.message : String(error) };
      }
    },
    async deleteSource(request) {
      try {
        const config = _chunkKKF4ZNPPcjs.loadSourceConfig.call(void 0, workspaceRootPath, request.sourceSlug);
        if (!config) return { ok: false, sourceSlug: request.sourceSlug, reason: "source_not_found" };
        _chunkKKF4ZNPPcjs.deleteSource.call(void 0, workspaceRootPath, request.sourceSlug);
        return { ok: true, sourceSlug: request.sourceSlug };
      } catch (error) {
        return { ok: false, sourceSlug: request.sourceSlug, reason: error instanceof Error ? error.message : String(error) };
      }
    },
    // ── Skills CRUD ──────────────────────────────────────
    async listSkills(_request) {
      const skills = _chunkQAZIYEHIcjs.loadAllSkills.call(void 0, workspaceRootPath);
      return {
        skills: skills.map((s) => toSkillSummary(s))
      };
    },
    async getSkill(request) {
      const skill = _chunkQAZIYEHIcjs.loadSkillBySlug.call(void 0, workspaceRootPath, request.skillSlug);
      if (!skill) throw new Error(`Skill not found: ${request.skillSlug}`);
      return {
        skill: {
          ...toSkillSummary(skill),
          content: skill.content,
          alwaysAllow: skill.metadata.alwaysAllow
        }
      };
    },
    async createSkill(request) {
      try {
        const skill = _chunkQAZIYEHIcjs.createSkill.call(void 0, workspaceRootPath, {
          slug: request.slug,
          name: request.name,
          description: request.description,
          content: request.content,
          globs: request.globs,
          alwaysAllow: request.alwaysAllow,
          icon: request.icon,
          requiredSources: request.requiredSources
        });
        return {
          ok: true,
          skill: toSkillSummary(skill)
        };
      } catch (error) {
        return { ok: false, reason: error instanceof Error ? error.message : String(error) };
      }
    },
    async updateSkill(request) {
      try {
        const skill = _chunkQAZIYEHIcjs.updateSkill.call(void 0, workspaceRootPath, request.skillSlug, {
          name: request.name,
          description: request.description,
          content: request.content,
          globs: request.globs,
          alwaysAllow: request.alwaysAllow,
          icon: request.icon,
          requiredSources: request.requiredSources
        });
        return {
          ok: true,
          skill: toSkillSummary(skill)
        };
      } catch (error) {
        return { ok: false, reason: error instanceof Error ? error.message : String(error) };
      }
    },
    async deleteSkill(request) {
      const ok = _chunkQAZIYEHIcjs.deleteSkill.call(void 0, workspaceRootPath, request.skillSlug);
      if (!ok) return { ok: false, skillSlug: request.skillSlug, reason: "skill_not_found" };
      return { ok: true, skillSlug: request.skillSlug };
    },
    // ── Automations Config ───────────────────────────────
    async getAutomationsConfig(_request) {
      return _chunkQX5YU4WLcjs.loadAutomationsConfig.call(void 0, workspaceRootPath);
    },
    async updateAutomationsConfig(request) {
      const result = _chunkQX5YU4WLcjs.saveAutomationsConfig.call(void 0, workspaceRootPath, request.config);
      return result;
    },
    // ── Scheduler ────────────────────────────────────────
    async listSchedules(_request) {
      if (!scheduler) return { schedules: [] };
      const snapshot = scheduler.getSnapshot();
      return {
        schedules: snapshot.schedules.map((s) => ({
          schedulerId: s.schedulerId,
          workspaceId: s.workspaceId,
          cron: s.cron,
          timezone: s.timezone
        }))
      };
    },
    async startSchedule(request) {
      if (!scheduler) throw new Error("Scheduler not configured");
      const receipt = scheduler.start({
        schedulerId: request.schedulerId,
        workspaceId: request.workspaceId,
        cron: request.cron,
        timezone: request.timezone
      });
      return {
        schedulerId: receipt.schedulerId,
        state: receipt.state,
        timestamp: receipt.timestamp
      };
    },
    async stopSchedule(request) {
      if (!scheduler) return { ok: false, schedulerId: request.schedulerId, reason: "scheduler_not_configured" };
      const receipt = scheduler.stop(request.schedulerId);
      if (!receipt) return { ok: false, schedulerId: request.schedulerId, reason: "scheduler_not_found" };
      return { ok: true, schedulerId: request.schedulerId, state: "stopped" };
    }
  };
}
function createLocalHostServer(options) {
  const controllers = /* @__PURE__ */ new Map();
  const publishedSchedulerEvents = [];
  const products = createLocalHostProductServices({
    storageDir: options.storageDir,
    now: options.now
  });
  const automation = options.automationWorkspace ? createLocalHostAutomationWorkspace({
    ...options.automationWorkspace,
    now: options.now
  }) : void 0;
  let httpServer;
  let wss;
  const authToken = _nullishCoalesce(_nullishCoalesce(options.authToken, () => ( process.env.WEFT_SERVER_TOKEN)), () => ( ""));
  function requestAuthorized(req) {
    if (!authToken) return true;
    if (req.method === "OPTIONS") return true;
    const url = new URL(_nullishCoalesce(req.url, () => ( "/")), "http://localhost");
    if (req.method === "GET" && url.pathname === "/health") return true;
    const header = _nullishCoalesce(req.headers.authorization, () => ( ""));
    if (header === `Bearer ${authToken}`) return true;
    return url.searchParams.get("token") === authToken;
  }
  const scheduler = _chunkQX5YU4WLcjs.createAutomationSchedulerHost.call(void 0, {
    now: options.now,
    publish(event) {
      publishedSchedulerEvents.push(event);
    }
  });
  const resolvedWorkspaceRootPath = _nullishCoalesce(options.workspaceRootPath, () => ( _optionalChain([options, 'access', _5 => _5.automationWorkspace, 'optionalAccess', _6 => _6.workspaceRootPath])));
  const effectiveSessionTools = resolvedWorkspaceRootPath ? createWorkspaceSessionToolBridge({
    workspaceRootPath: resolvedWorkspaceRootPath,
    baseBridge: options.sessionTools,
    scheduler
  }) : options.sessionTools;
  const wsSessions = /* @__PURE__ */ new Map();
  function snapshot() {
    return {
      sessions: [...controllers.keys()].sort(),
      ...options.sessionToolSnapshot ? { sessionTools: options.sessionToolSnapshot() } : {},
      ...automation ? { automation: automation.snapshot() } : {},
      scheduler: {
        schedules: scheduler.getSnapshot().schedules,
        publishedEvents: publishedSchedulerEvents.map((event) => ({ ...event }))
      },
      products: products.snapshot()
    };
  }
  function handleHttpRequest(req, res) {
    if (!requestAuthorized(req)) {
      res.writeHead(401, { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" });
      res.end(JSON.stringify({ error: "unauthorized" }));
      return;
    }
    const chunks = [];
    req.on("data", (chunk) => chunks.push(chunk));
    req.on("end", () => {
      const body = chunks.length > 0 ? Buffer.concat(chunks) : void 0;
      const protocol = "http";
      const host = _nullishCoalesce(req.headers.host, () => ( "localhost"));
      const url = new URL(_nullishCoalesce(req.url, () => ( "/")), `${protocol}://${host}`);
      const requestInit = {
        method: req.method,
        headers: Object.entries(req.headers).reduce((acc, [key, value]) => {
          if (value !== void 0) acc[key] = Array.isArray(value) ? value.join(", ") : value;
          return acc;
        }, {})
      };
      if (body && req.method !== "GET" && req.method !== "HEAD") {
        requestInit.body = body;
      }
      const request = new Request(url.toString(), requestInit);
      const workspaceRootPath = _nullishCoalesce(options.workspaceRootPath, () => ( _optionalChain([options, 'access', _7 => _7.automationWorkspace, 'optionalAccess', _8 => _8.workspaceRootPath])));
      void handleRequest({
        request,
        controllers,
        scheduler,
        products,
        automation,
        workspaceRootPath,
        snapshot,
        createController: _nullishCoalesce(options.createController, () => ( ((req2) => createDefaultLocalHostController({
          request: req2,
          sessionTools: effectiveSessionTools,
          now: options.now
        }))))
      }).then((response) => {
        res.writeHead(response.status, Object.fromEntries(response.headers.entries()));
        if (response.body) {
          const reader = response.body.getReader();
          const pump = () => reader.read().then(({ done, value }) => {
            if (done) {
              res.end();
              return;
            }
            res.write(Buffer.from(value));
            return pump();
          });
          return pump();
        } else {
          res.end();
        }
      });
    });
  }
  function handleWebSocketConnection(ws, req) {
    if (!requestAuthorized(req)) {
      ws.close(4003, "unauthorized");
      return;
    }
    const url = new URL(_nullishCoalesce(req.url, () => ( "/")), "http://localhost");
    const parts = url.pathname.split("/").filter(Boolean);
    const sessionId = parts[1];
    const data = { sessionId, lastPong: Date.now() };
    wsSessions.set(ws, data);
    const controller = controllers.get(sessionId);
    if (!controller) {
      ws.close(4004, `session ${sessionId} not found`);
      return;
    }
    data.unsubscribe = controller.subscribe(
      (envelope) => ws.send(JSON.stringify(envelope)),
      (error) => ws.send(JSON.stringify({ type: "stream_error", message: error.message })),
      () => ws.close(1e3, "stream closed")
    );
    data.heartbeatTimer = setInterval(() => {
      const elapsed = Date.now() - data.lastPong;
      if (elapsed > WS_HEARTBEAT_INTERVAL_MS + WS_PONG_TIMEOUT_MS) {
        ws.close(4001, "heartbeat timeout");
        return;
      }
      ws.send(JSON.stringify({ type: "ping" }));
    }, WS_HEARTBEAT_INTERVAL_MS);
    ws.on("message", (raw) => {
      let msg;
      try {
        msg = JSON.parse(typeof raw === "string" ? raw : raw.toString("utf8"));
      } catch (e7) {
        return;
      }
      if (msg.type === "pong") {
        data.lastPong = Date.now();
        return;
      }
      if (msg.type === "send_message") {
        void controller.sendMessage({ message: msg.text }).catch(
          (err) => ws.send(JSON.stringify({ type: "stream_error", message: err instanceof Error ? err.message : String(err) }))
        );
      } else if (msg.type === "respond_permission") {
        void controller.respondToPermission({
          requestId: msg.requestId,
          allowed: msg.allowed,
          remember: msg.remember
        }).catch(
          (err) => ws.send(JSON.stringify({ type: "stream_error", message: err instanceof Error ? err.message : String(err) }))
        );
      }
    });
    ws.on("close", () => {
      if (data.heartbeatTimer) clearInterval(data.heartbeatTimer);
      _optionalChain([data, 'access', _9 => _9.unsubscribe, 'optionalCall', _10 => _10()]);
      wsSessions.delete(ws);
    });
  }
  return {
    get url() {
      if (!httpServer) return "";
      const addr = httpServer.address();
      if (!addr || typeof addr === "string") return "";
      return `http://${addr.address}:${addr.port}`;
    },
    async start() {
      if (httpServer) return;
      await products.load();
      const port = _nullishCoalesce(options.port, () => ( 0));
      const hostname = _nullishCoalesce(options.hostname, () => ( "127.0.0.1"));
      httpServer = _http.createServer.call(void 0, (req, res) => {
        handleHttpRequest(req, res);
      });
      wss = new (0, _ws.WebSocketServer)({ noServer: true });
      wss.on("connection", (ws, req) => {
        handleWebSocketConnection(ws, req);
      });
      httpServer.on("upgrade", (req, socket, head) => {
        if (!requestAuthorized(req)) {
          socket.write("HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n");
          socket.destroy();
          return;
        }
        _optionalChain([wss, 'optionalAccess', _11 => _11.handleUpgrade, 'call', _12 => _12(req, socket, head, (ws) => {
          _optionalChain([wss, 'optionalAccess', _13 => _13.emit, 'call', _14 => _14("connection", ws, req)]);
        })]);
      });
      await new Promise((resolve2) => httpServer.listen(port, hostname, resolve2));
    },
    async stop() {
      if (!httpServer) return;
      const currentServer = httpServer;
      const currentWss = wss;
      httpServer = void 0;
      wss = void 0;
      if (currentWss) {
        await new Promise((resolve2) => currentWss.close(() => resolve2()));
      }
      await new Promise((resolve2) => currentServer.close(() => resolve2()));
      await _optionalChain([automation, 'optionalAccess', _15 => _15.dispose, 'call', _16 => _16()]);
      await Promise.all([...controllers.values()].map((controller) => controller.dispose().catch(() => void 0)));
      controllers.clear();
      await products.flushPersistence();
    },
    getSnapshot: snapshot
  };
}
var WS_HEARTBEAT_INTERVAL_MS = 3e4;
var WS_PONG_TIMEOUT_MS = 1e4;
async function handleRequest(options) {
  const url = new URL(options.request.url);
  const method = options.request.method.toUpperCase();
  const parts = url.pathname.split("/").filter(Boolean);
  if (method === "OPTIONS") {
    return new Response(null, {
      status: 204,
      headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "GET, POST, PATCH, DELETE, OPTIONS",
        "Access-Control-Allow-Headers": "content-type",
        "Access-Control-Max-Age": "86400"
      }
    });
  }
  try {
    if (method === "GET" && url.pathname === "/health") {
      return json({
        ok: true,
        sessions: options.controllers.size,
        schedulers: options.scheduler.getSnapshot().schedules.length
      });
    }
    if (method === "GET" && url.pathname === "/host/snapshot") {
      return json(options.snapshot());
    }
    if (method === "GET" && url.pathname === "/fs/browse") {
      return json(await browseFileSystem(_nullishCoalesce(url.searchParams.get("path"), () => ( void 0))));
    }
    if (method === "POST" && url.pathname === "/automations/events") {
      if (!options.automation) throw new HttpError(404, "automation_workspace_not_configured");
      const body = await readJson(options.request);
      return json(await options.automation.emitEvent({
        request: body,
        controllers: options.controllers,
        products: options.products
      }));
    }
    const productResponse = await handleProductRoute({
      method,
      url,
      parts,
      request: options.request,
      products: options.products
    });
    if (productResponse) return productResponse;
    if (method === "GET" && url.pathname === "/models") {
      return json(await discoverModels());
    }
    if (method === "GET" && url.pathname === "/sessions") {
      return json({
        sessions: [...options.controllers.keys()].map((sessionId) => {
          const ctrl = options.controllers.get(sessionId);
          return {
            sessionId,
            provider: ctrl.provider,
            runtimeKind: ctrl.runtimeKind
          };
        })
      });
    }
    if (method === "POST" && url.pathname === "/sessions") {
      const body = withDefaultSessionId(await readJson(options.request));
      const controller = await options.createController(body);
      options.controllers.set(controller.sessionId, controller);
      const preflight = await controller.preflight();
      return json({
        sessionId: controller.sessionId,
        provider: controller.provider,
        runtimeKind: controller.runtimeKind,
        preflight
      });
    }
    if (parts[0] === "sessions" && typeof parts[1] === "string") {
      if (!parts[2] && method === "GET") {
        const ctrl = getController(options.controllers, parts[1]);
        return json({
          sessionId: ctrl.sessionId,
          provider: ctrl.provider,
          runtimeKind: ctrl.runtimeKind
        });
      }
      if (!parts[2] && method === "DELETE") {
        const ctrl = options.controllers.get(parts[1]);
        if (!ctrl) throw new HttpError(404, "session_not_found");
        await ctrl.dispose();
        options.controllers.delete(parts[1]);
        return json({ ok: true, sessionId: parts[1] });
      }
      return handleSessionRoute({
        method,
        action: parts[2],
        controller: getController(options.controllers, parts[1]),
        request: options.request,
        workspaceRootPath: options.workspaceRootPath
      });
    }
    if (method === "GET" && url.pathname === "/scheduler") {
      const snapshot = options.scheduler.getSnapshot();
      return json({
        schedules: snapshot.schedules.map((s) => ({
          schedulerId: s.schedulerId,
          workspaceId: s.workspaceId,
          cron: s.cron,
          timezone: s.timezone
        }))
      });
    }
    if (method === "POST" && url.pathname === "/scheduler/start") {
      const body = await readJson(options.request);
      return json(options.scheduler.start(body));
    }
    if (parts[0] === "scheduler" && typeof parts[1] === "string" && method === "POST") {
      if (parts[2] === "tick") {
        const body = await readJson(options.request);
        return json({ ok: options.scheduler.tick(parts[1], body) });
      }
      if (parts[2] === "stop") {
        const receipt = options.scheduler.stop(parts[1]);
        return receipt ? json(receipt) : json({ ok: false, reason: "scheduler_not_found" }, 404);
      }
    }
    if (parts[0] === "sources") {
      if (!options.workspaceRootPath) throw new HttpError(404, "workspace_root_not_configured");
      const wp = options.workspaceRootPath;
      if (!parts[1] && method === "GET") {
        const enabledOnly = url.searchParams.get("enabledOnly") === "true";
        const sources = _chunkKKF4ZNPPcjs.loadAllSources.call(void 0, wp);
        return json({
          sources: sources.filter((s) => !enabledOnly || s.config.enabled).map((s) => toSourceSummary(s.config))
        });
      }
      if (!parts[1] && method === "POST") {
        const body = await readJson(options.request);
        const config = await _chunkKKF4ZNPPcjs.createSource.call(void 0, wp, body);
        return json({ ok: true, source: toSourceSummary(config) });
      }
      if (typeof parts[1] === "string" && method === "GET") {
        const config = _chunkKKF4ZNPPcjs.loadSourceConfig.call(void 0, wp, parts[1]);
        if (!config) throw new HttpError(404, "source_not_found");
        return json({ source: { ...toSourceSummary(config), createdAt: config.createdAt, updatedAt: config.updatedAt, mcp: config.mcp, api: config.api, local: config.local } });
      }
      if (typeof parts[1] === "string" && method === "PATCH") {
        const config = _chunkKKF4ZNPPcjs.loadSourceConfig.call(void 0, wp, parts[1]);
        if (!config) throw new HttpError(404, "source_not_found");
        const patch = await readJson(options.request);
        const updated = {
          ...config,
          ...patch.name !== void 0 ? { name: String(patch.name) } : {},
          ...patch.enabled !== void 0 ? { enabled: Boolean(patch.enabled) } : {},
          ...patch.icon !== void 0 ? { icon: String(patch.icon) } : {},
          ...patch.tagline !== void 0 ? { tagline: String(patch.tagline) } : {},
          updatedAt: Date.now()
        };
        _chunkKKF4ZNPPcjs.saveSourceConfig.call(void 0, wp, updated);
        return json({ ok: true, source: toSourceSummary(updated) });
      }
      if (typeof parts[1] === "string" && method === "DELETE") {
        const config = _chunkKKF4ZNPPcjs.loadSourceConfig.call(void 0, wp, parts[1]);
        if (!config) throw new HttpError(404, "source_not_found");
        _chunkKKF4ZNPPcjs.deleteSource.call(void 0, wp, parts[1]);
        return json({ ok: true, sourceSlug: parts[1] });
      }
    }
    if (parts[0] === "skills") {
      if (!options.workspaceRootPath) throw new HttpError(404, "workspace_root_not_configured");
      const wp = options.workspaceRootPath;
      if (!parts[1] && method === "GET") {
        const skills = _chunkQAZIYEHIcjs.loadAllSkills.call(void 0, wp);
        return json({
          skills: skills.map((s) => toSkillSummary(s))
        });
      }
      if (!parts[1] && method === "POST") {
        const body = await readJson(options.request);
        const skill = _chunkQAZIYEHIcjs.createSkill.call(void 0, wp, body);
        return json({ ok: true, skill: toSkillSummary(skill) });
      }
      if (typeof parts[1] === "string" && method === "GET") {
        const skill = _chunkQAZIYEHIcjs.loadSkillBySlug.call(void 0, wp, parts[1]);
        if (!skill) throw new HttpError(404, "skill_not_found");
        return json({ skill: { ...toSkillSummary(skill), content: skill.content, alwaysAllow: skill.metadata.alwaysAllow } });
      }
      if (typeof parts[1] === "string" && method === "PATCH") {
        const patch = await readJson(options.request);
        const skill = _chunkQAZIYEHIcjs.updateSkill.call(void 0, wp, parts[1], patch);
        return json({ ok: true, skill: toSkillSummary(skill) });
      }
      if (typeof parts[1] === "string" && method === "DELETE") {
        const ok = _chunkQAZIYEHIcjs.deleteSkill.call(void 0, wp, parts[1]);
        if (!ok) throw new HttpError(404, "skill_not_found");
        return json({ ok: true, skillSlug: parts[1] });
      }
    }
    if (parts[0] === "automations" && parts[1] === "config") {
      if (!options.workspaceRootPath) throw new HttpError(404, "workspace_root_not_configured");
      const wp = options.workspaceRootPath;
      if (method === "GET") {
        return json(_chunkQX5YU4WLcjs.loadAutomationsConfig.call(void 0, wp));
      }
      if (method === "PUT") {
        const body = await readJson(options.request);
        const result = _chunkQX5YU4WLcjs.saveAutomationsConfig.call(void 0, wp, body);
        if (!result.ok) return json(result, 400);
        return json(result);
      }
    }
    return json({ ok: false, reason: "not_found" }, 404);
  } catch (error) {
    if (error instanceof HttpError) {
      return json({ ok: false, reason: error.message }, error.status);
    }
    return json({ ok: false, reason: error instanceof Error ? error.message : String(error) }, 500);
  }
}
function withDefaultSessionId(request) {
  if (request.sessionId) return request;
  return {
    ...request,
    sessionId: `local-${request.provider}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
  };
}
async function handleProductRoute(options) {
  if (options.method === "POST" && options.url.pathname === "/notifications") {
    return json(await options.products.sendNotification(await readJson(options.request)));
  }
  if (options.method === "GET" && options.url.pathname === "/notifications") {
    return json(options.products.listNotifications({
      sessionId: _nullishCoalesce(options.url.searchParams.get("sessionId"), () => ( void 0))
    }));
  }
  if (options.method === "POST" && options.url.pathname === "/artifacts") {
    return json(await options.products.writeArtifact(await readJson(options.request)));
  }
  if (options.method === "GET" && options.parts[0] === "artifacts" && options.parts[1]) {
    const artifact = options.products.readArtifact(decodeURIComponent(options.parts[1]));
    return artifact ? json(artifact) : json({ ok: false, reason: "artifact_not_found" }, 404);
  }
  if (options.method === "POST" && options.url.pathname === "/bindings") {
    return json(await options.products.bindTopic(await readJson(options.request)));
  }
  if (options.method === "POST" && options.url.pathname === "/bindings/resolve") {
    const binding = options.products.resolveTopic(await readJson(options.request));
    return binding ? json(binding) : json(void 0);
  }
  if (options.method === "GET" && options.url.pathname === "/metadata/sessions") {
    return json(options.products.listSessionMetadata());
  }
  if (options.parts[0] === "metadata" && options.parts[1] === "sessions" && options.parts[2]) {
    const sessionId = decodeURIComponent(options.parts[2]);
    if (options.method === "GET") {
      const metadata = options.products.getSessionMetadata(sessionId);
      return metadata ? json(metadata) : json({ ok: false, reason: "session_metadata_not_found" }, 404);
    }
    if (options.method === "PATCH") {
      return json(await options.products.updateSessionMetadata(
        sessionId,
        await readJson(options.request)
      ));
    }
  }
  if (options.method === "POST" && options.url.pathname === "/utility/execute") {
    return json(await options.products.executeUtility(await readJson(options.request)));
  }
  if (options.method === "POST" && options.url.pathname === "/admin/config/watch-events") {
    return json(await options.products.recordConfigWatchEvent(await readJson(options.request)));
  }
  if (options.method === "POST" && options.url.pathname === "/admin/config/resource-bundles") {
    return json(await options.products.createResourceBundleSnapshot(await readJson(options.request)));
  }
  if (options.method === "POST" && options.url.pathname === "/admin/config/status/validate") {
    return json(await options.products.validateStatusConfig(await readJson(options.request)));
  }
  if (options.method === "GET" && options.url.pathname === "/admin/tools/registry") {
    return json(options.products.hostToolRegistry());
  }
  if (options.method === "GET" && options.url.pathname === "/audit") {
    return json(options.products.listAudit({
      sessionId: _nullishCoalesce(options.url.searchParams.get("sessionId"), () => ( void 0)),
      category: _nullishCoalesce(options.url.searchParams.get("category"), () => ( void 0))
    }));
  }
  return void 0;
}
async function handleSessionRoute(input) {
  if (input.method === "GET" && input.action === "preflight") {
    return json(await input.controller.preflight());
  }
  if (input.method === "POST" && input.action === "messages") {
    const body = withSkillDirective(
      await readJson(input.request),
      input.workspaceRootPath
    );
    return json(await input.controller.sendMessage(body));
  }
  if (input.method === "POST" && input.action === "timeline") {
    const body = await readJson(input.request);
    return json(await input.controller.fetchTimeline(body));
  }
  if (input.method === "POST" && input.action === "permissions") {
    const body = await readJson(input.request);
    return json(await input.controller.respondToPermission(body));
  }
  if (input.method === "POST" && input.action === "tools") {
    const body = await readJson(input.request);
    return json(await input.controller.invokeSessionTool(body));
  }
  throw new HttpError(404, "not_found");
}
function withSkillDirective(request, workspaceRootPath) {
  if (!workspaceRootPath) return request;
  if (!request.skillSlugs || request.skillSlugs.length === 0) return request;
  const plan = _chunkROUGOHCWcjs.createSkillActivationPlan.call(void 0, {
    skills: _chunkQAZIYEHIcjs.loadAllSkills.call(void 0, workspaceRootPath),
    prompt: request.message,
    selectedSkillSlugs: request.skillSlugs,
    enabledSourceSlugs: request.sourceSlugs,
    filePaths: _optionalChain([request, 'access', _17 => _17.attachments, 'optionalAccess', _18 => _18.map, 'call', _19 => _19((attachment) => attachment.path)])
  });
  if (plan.prerequisiteFiles.length === 0) return request;
  return {
    ...request,
    message: _chunkROUGOHCWcjs.prependSkillDirective.call(void 0, request.message, plan.prerequisiteFiles)
  };
}
function getController(controllers, sessionId) {
  const controller = controllers.get(sessionId);
  if (!controller) throw new HttpError(404, "session_not_found");
  return controller;
}
async function readJson(request) {
  if (!request.body) return {};
  return await request.json();
}
function json(body, status = 200) {
  return new Response(JSON.stringify(body), {
    status,
    headers: {
      "content-type": "application/json",
      "Access-Control-Allow-Origin": "*"
    }
  });
}
async function browseFileSystem(inputPath) {
  const requestedPath = _path.resolve.call(void 0, inputPath && inputPath.trim() ? inputPath : _os.homedir.call(void 0, ));
  const requestedStats = await _promises.lstat.call(void 0, requestedPath).catch((error) => {
    if (isNodeError(error, "ENOENT")) throw new HttpError(404, "path_not_found");
    throw error;
  });
  const currentPath = requestedStats.isDirectory() ? requestedPath : _path.dirname.call(void 0, requestedPath);
  const entries = await Promise.all((await _promises.readdir.call(void 0, currentPath)).map(async (name) => {
    const entryPath = _path.join.call(void 0, currentPath, name);
    try {
      const stats = await _promises.lstat.call(void 0, entryPath);
      const type = stats.isDirectory() ? "directory" : "file";
      return {
        name,
        path: entryPath,
        type,
        size: type === "file" ? stats.size : void 0,
        isSymlink: stats.isSymbolicLink() || void 0
      };
    } catch (e8) {
      return void 0;
    }
  }));
  const parentPath = _path.dirname.call(void 0, currentPath);
  return {
    currentPath,
    parentPath: parentPath === currentPath ? null : parentPath,
    entries: entries.filter((entry) => Boolean(entry)).sort((left, right) => {
      if (left.type !== right.type) return left.type === "directory" ? -1 : 1;
      return left.name.localeCompare(right.name);
    })
  };
}
function isNodeError(error, code) {
  return error instanceof Error && "code" in error && error.code === code;
}
function createLocalHostAutomationWorkspace(options) {
  const promptQueue = [];
  const dispatches = [];
  const system = new (0, _chunkQX5YU4WLcjs.AutomationSystem)({
    workspaceRootPath: options.workspaceRootPath,
    workspaceId: options.workspaceId,
    onPromptsReady(prompts) {
      promptQueue.push(...prompts.map(clonePendingPrompt));
    }
  });
  return {
    async emitEvent(input) {
      await system.emit(
        input.request.event,
        normalizeAutomationPayload(input.request.payload, options.workspaceId, options.now)
      );
      const prompts = promptQueue.splice(0, promptQueue.length);
      const currentDispatches = [];
      for (const prompt of prompts) {
        const dispatch = await dispatchAutomationPrompt({
          prompt,
          sessionId: _nullishCoalesce(_nullishCoalesce(prompt.sessionId, () => ( options.sessionId)), () => ( promptSessionFromPayload(input.request.payload))),
          controllers: input.controllers,
          products: input.products
        });
        dispatches.push(dispatch);
        currentDispatches.push(dispatch);
      }
      return {
        ok: true,
        workspaceId: options.workspaceId,
        event: input.request.event,
        promptCount: prompts.length,
        dispatches: currentDispatches.map(cloneDispatchReceipt)
      };
    },
    snapshot() {
      return {
        workspaceId: options.workspaceId,
        workspaceRootPath: options.workspaceRootPath,
        promptQueue: promptQueue.map(clonePendingPrompt),
        dispatches: dispatches.map(cloneDispatchReceipt)
      };
    },
    async dispose() {
      await system.dispose();
      promptQueue.splice(0, promptQueue.length);
    }
  };
}
async function dispatchAutomationPrompt(input) {
  const matcherId = _nullishCoalesce(_nullishCoalesce(input.prompt.matcherId, () => ( input.prompt.automationName)), () => ( "automation"));
  const promptPreview = redactAutomationPrompt(input.prompt.prompt);
  const baseReceipt = {
    matcherId,
    ...input.prompt.automationName ? { automationName: input.prompt.automationName } : {},
    ...input.sessionId ? { sessionId: input.sessionId } : {},
    promptPreview
  };
  const controller = input.sessionId ? input.controllers.get(input.sessionId) : void 0;
  if (!controller) {
    const receipt = {
      ...baseReceipt,
      status: "failed",
      error: input.sessionId ? "session_not_found" : "session_not_selected"
    };
    input.products.appendAudit({
      category: "automation",
      action: "automation_prompt_dispatch_failed",
      ...input.sessionId ? { sessionId: input.sessionId } : {},
      redactedSummary: promptPreview,
      metadata: {
        matcherId,
        error: receipt.error
      }
    });
    return receipt;
  }
  try {
    await controller.sendMessage({
      message: input.prompt.prompt,
      commandOrigin: { type: "automation", id: matcherId },
      ...input.prompt.permissionMode ? { permissionMode: input.prompt.permissionMode } : {}
    });
    input.products.appendAudit({
      category: "automation",
      action: "automation_prompt_dispatched",
      sessionId: controller.sessionId,
      redactedSummary: promptPreview,
      metadata: {
        matcherId,
        automationName: input.prompt.automationName,
        labels: input.prompt.labels,
        mentions: input.prompt.mentions
      }
    });
    return {
      ...baseReceipt,
      sessionId: controller.sessionId,
      status: "success"
    };
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    input.products.appendAudit({
      category: "automation",
      action: "automation_prompt_dispatch_failed",
      sessionId: controller.sessionId,
      redactedSummary: promptPreview,
      metadata: {
        matcherId,
        error: message
      }
    });
    return {
      ...baseReceipt,
      sessionId: controller.sessionId,
      status: "failed",
      error: message
    };
  }
}
function normalizeAutomationPayload(payload, workspaceId, now) {
  return {
    ...payload,
    workspaceId: _nullishCoalesce(payload.workspaceId, () => ( workspaceId)),
    timestamp: _nullishCoalesce(payload.timestamp, () => ( (_nullishCoalesce(now, () => ( Date.now)))()))
  };
}
function promptSessionFromPayload(payload) {
  return typeof payload.sessionId === "string" ? payload.sessionId : void 0;
}
function clonePendingPrompt(prompt) {
  return {
    ...prompt,
    mentions: [...prompt.mentions],
    ...prompt.labels ? { labels: [...prompt.labels] } : {}
  };
}
function cloneDispatchReceipt(receipt) {
  return { ...receipt };
}
function redactAutomationPrompt(prompt) {
  return prompt.replace(/(authorization\s*[:=]\s*)(bearer\s+)?[^\s,;]+/gi, (_match, prefix, bearer = "") => `${prefix}${bearer}[REDACTED]`).replace(/(token\s*[:=]\s*)[^\s,;]+/gi, (_match, prefix) => `${prefix}[REDACTED]`).replace(/(api[_-]?key\s*[:=]\s*)[^\s,;]+/gi, (_match, prefix) => `${prefix}[REDACTED]`).replace(/(secret\s*[:=]\s*)[^\s,;]+/gi, (_match, prefix) => `${prefix}[REDACTED]`);
}
function createLocalHostProductServices(options) {
  const now = _nullishCoalesce(options.now, () => ( Date.now));
  const statePath = options.storageDir ? _path.join.call(void 0, options.storageDir, "host-state.json") : void 0;
  const notifications = [];
  const artifacts = /* @__PURE__ */ new Map();
  const topicBindings = /* @__PURE__ */ new Map();
  const sessionMetadata = /* @__PURE__ */ new Map();
  const configWatchEvents = [];
  const resourceBundles = /* @__PURE__ */ new Map();
  const audit = [];
  const utilityRegistry = _chunkKQCATETEcjs.createInMemoryHostUtilityToolRegistry.call(void 0, {
    now,
    outputPolicy: _chunkKQCATETEcjs.createToolOutputPolicy.call(void 0, )
  });
  registerBuiltinUtilityTools(utilityRegistry);
  const persistenceQueue = new PersistenceQueue();
  function persist() {
    if (!statePath || !options.storageDir) return;
    persistenceQueue.enqueue(statePath, () => JSON.stringify({
      notifications,
      artifacts: [...artifacts.values()],
      topicBindings: [...topicBindings.values()],
      sessionMetadata: [...sessionMetadata.values()],
      configWatchEvents,
      resourceBundles: [...resourceBundles.values()],
      audit
    }, null, 2));
  }
  async function flushPersistence() {
    await persistenceQueue.flushAll();
  }
  function appendAudit(input) {
    const entry = {
      auditId: `audit:${audit.length + 1}`,
      seq: audit.length + 1,
      timestamp: now(),
      ...input
    };
    audit.push(entry);
    return entry;
  }
  return {
    flushPersistence,
    async load() {
      if (!statePath) return;
      try {
        const loaded = JSON.parse(await _promises.readFile.call(void 0, statePath, "utf8"));
        notifications.splice(0, notifications.length, ...(_nullishCoalesce(loaded.notifications, () => ( []))).map(cloneNotification));
        artifacts.clear();
        for (const artifact of _nullishCoalesce(loaded.artifacts, () => ( []))) {
          artifacts.set(artifact.artifactRef, cloneArtifact(artifact));
        }
        topicBindings.clear();
        for (const binding of _nullishCoalesce(loaded.topicBindings, () => ( []))) {
          topicBindings.set(binding.bindingId, cloneTopicBinding(binding));
        }
        sessionMetadata.clear();
        for (const metadata of _nullishCoalesce(loaded.sessionMetadata, () => ( []))) {
          sessionMetadata.set(metadata.sessionId, cloneSessionMetadata(metadata));
        }
        configWatchEvents.splice(0, configWatchEvents.length, ...(_nullishCoalesce(loaded.configWatchEvents, () => ( []))).map(cloneConfigWatchEvent));
        resourceBundles.clear();
        for (const bundle of _nullishCoalesce(loaded.resourceBundles, () => ( []))) {
          resourceBundles.set(bundle.snapshotId, cloneResourceBundleSnapshot(bundle));
        }
        audit.splice(0, audit.length, ...(_nullishCoalesce(loaded.audit, () => ( []))).map(cloneAudit));
      } catch (error) {
        if (error.code !== "ENOENT") throw error;
      }
    },
    snapshot() {
      return {
        notifications: notifications.map(cloneNotification),
        artifacts: [...artifacts.values()].map(artifactReceipt),
        topicBindings: [...topicBindings.values()].map(cloneTopicBinding),
        sessionMetadata: [...sessionMetadata.values()].map(cloneSessionMetadata),
        configWatchEvents: configWatchEvents.map(cloneConfigWatchEvent),
        resourceBundles: [...resourceBundles.values()].map(cloneResourceBundleSnapshot),
        toolRegistry: utilityRegistry.capabilityReport(),
        audit: audit.map(cloneAudit)
      };
    },
    appendAudit,
    async sendNotification(request) {
      const body = redactSecrets(_nullishCoalesce(request.body, () => ( "")));
      const receipt = {
        notificationId: `notification:${notifications.length + 1}`,
        ...request.sessionId ? { sessionId: request.sessionId } : {},
        ...request.topicId ? { topicId: request.topicId } : {},
        deliveredChannels: uniqueChannels(request.channels),
        title: request.title,
        ...request.body !== void 0 ? { bodyPreview: body.text } : {},
        severity: _nullishCoalesce(request.severity, () => ( "info")),
        redacted: body.redacted,
        timestamp: now(),
        ...request.origin ? { origin: { ...request.origin } } : {}
      };
      notifications.push(receipt);
      appendAudit({
        category: "notification",
        action: "notification_sent",
        sessionId: request.sessionId,
        redactedSummary: receipt.title,
        metadata: {
          notificationId: receipt.notificationId,
          channels: receipt.deliveredChannels
        }
      });
      persist();
      return cloneNotification(receipt);
    },
    listNotifications(filter = {}) {
      return notifications.filter((notification) => !filter.sessionId || notification.sessionId === filter.sessionId).map(cloneNotification);
    },
    async writeArtifact(request) {
      const redaction = redactSecrets(request.text);
      const record = {
        artifactRef: request.artifactRef,
        ...request.sessionId ? { sessionId: request.sessionId } : {},
        toolName: request.toolName,
        contentType: request.contentType,
        text: redaction.text,
        byteLength: Buffer.byteLength(redaction.text, "utf8"),
        redacted: redaction.redacted,
        createdAt: now(),
        ...request.metadata ? { metadata: { ...request.metadata } } : {}
      };
      artifacts.set(record.artifactRef, record);
      appendAudit({
        category: "tool_output",
        action: "artifact_written",
        sessionId: request.sessionId,
        metadata: {
          artifactRef: record.artifactRef,
          toolName: record.toolName
        }
      });
      persist();
      return artifactReceipt(record);
    },
    readArtifact(artifactRef) {
      const artifact = artifacts.get(artifactRef);
      return artifact ? cloneArtifact(artifact) : void 0;
    },
    async bindTopic(request) {
      const timestamp = now();
      const existing = topicBindings.get(request.bindingId);
      const binding = {
        bindingId: request.bindingId,
        sessionId: request.sessionId,
        channel: request.channel,
        topicId: request.topicId,
        ...request.actorId ? { actorId: request.actorId } : {},
        createdAt: _nullishCoalesce(_optionalChain([existing, 'optionalAccess', _20 => _20.createdAt]), () => ( timestamp)),
        updatedAt: timestamp,
        ...request.metadata ? { metadata: { ...request.metadata } } : {}
      };
      topicBindings.set(binding.bindingId, binding);
      appendAudit({
        category: "messaging",
        action: "topic_bound",
        sessionId: request.sessionId,
        metadata: {
          bindingId: binding.bindingId,
          channel: binding.channel,
          topicId: binding.topicId
        }
      });
      persist();
      return cloneTopicBinding(binding);
    },
    resolveTopic(request) {
      const binding = [...topicBindings.values()].find((candidate) => candidate.channel === request.channel && candidate.topicId === request.topicId);
      return binding ? cloneTopicBinding(binding) : void 0;
    },
    async updateSessionMetadata(sessionId, request) {
      const previous = sessionMetadata.get(sessionId);
      const next = {
        sessionId,
        labels: request.labels ? [...request.labels] : _optionalChain([previous, 'optionalAccess', _21 => _21.labels]) ? [...previous.labels] : [],
        ...request.status !== void 0 ? { status: request.status } : _optionalChain([previous, 'optionalAccess', _22 => _22.status]) ? { status: previous.status } : {},
        preferences: {
          ..._nullishCoalesce(_optionalChain([previous, 'optionalAccess', _23 => _23.preferences]), () => ( {})),
          ..._nullishCoalesce(request.preferences, () => ( {}))
        },
        updatedAt: now(),
        ...request.actor ? { actor: { ...request.actor } } : _optionalChain([previous, 'optionalAccess', _24 => _24.actor]) ? { actor: { ...previous.actor } } : {}
      };
      sessionMetadata.set(sessionId, next);
      appendAudit({
        category: "metadata",
        action: "session_metadata_updated",
        sessionId,
        actor: request.actor,
        redactedSummary: `labels=${next.labels.join(",")} status=${_nullishCoalesce(next.status, () => ( ""))}`.trim(),
        metadata: {
          labels: next.labels,
          status: next.status,
          preferenceKeys: Object.keys(next.preferences).sort()
        }
      });
      persist();
      return cloneSessionMetadata(next);
    },
    getSessionMetadata(sessionId) {
      const metadata = sessionMetadata.get(sessionId);
      return metadata ? cloneSessionMetadata(metadata) : void 0;
    },
    listSessionMetadata() {
      return [...sessionMetadata.values()].sort((left, right) => left.sessionId.localeCompare(right.sessionId)).map(cloneSessionMetadata);
    },
    async executeUtility(request) {
      const receipt = await utilityRegistry.execute(request);
      appendAudit({
        category: "session_tool",
        action: "utility_executed",
        sessionId: sessionIdFromUtilityInput(request.input),
        metadata: {
          toolName: receipt.toolName,
          callId: receipt.callId,
          exitStatus: receipt.exitStatus
        }
      });
      persist();
      return receipt;
    },
    async recordConfigWatchEvent(request) {
      const event = _chunkKQCATETEcjs.createConfigWatchEvent.call(void 0, request);
      configWatchEvents.push(event);
      appendAudit({
        category: "config",
        action: "config_watch_event_recorded",
        redactedSummary: `${event.configKind}:${event.action}`,
        metadata: {
          eventId: event.eventId,
          workspaceId: event.workspaceId,
          configPath: event.configPath
        }
      });
      persist();
      return cloneConfigWatchEvent(event);
    },
    async createResourceBundleSnapshot(request) {
      const bundle = _chunkKQCATETEcjs.createResourceBundleSnapshot.call(void 0, request);
      resourceBundles.set(bundle.snapshotId, bundle);
      appendAudit({
        category: "config",
        action: "resource_bundle_snapshot_created",
        redactedSummary: `${bundle.workspaceId}:${bundle.resourceCount}`,
        metadata: {
          snapshotId: bundle.snapshotId,
          workspaceId: bundle.workspaceId,
          resourceCount: bundle.resourceCount
        }
      });
      persist();
      return cloneResourceBundleSnapshot(bundle);
    },
    async validateStatusConfig(request) {
      const result = _chunkKQCATETEcjs.validateStatusConfig.call(void 0, request);
      appendAudit({
        category: "config",
        action: "status_config_validated",
        redactedSummary: result.valid ? "valid" : "invalid",
        metadata: {
          valid: result.valid,
          errorCount: result.errors.length,
          warningCount: result.warnings.length
        }
      });
      persist();
      return cloneStatusConfigValidationResult(result);
    },
    hostToolRegistry() {
      return utilityRegistry.capabilityReport();
    },
    listAudit(filter = {}) {
      return audit.filter((entry) => !filter.sessionId || entry.sessionId === filter.sessionId).filter((entry) => !filter.category || entry.category === filter.category).map(cloneAudit);
    }
  };
}
function sessionIdFromUtilityInput(input) {
  if (!input || typeof input !== "object") return void 0;
  const sessionId = input.sessionId;
  return typeof sessionId === "string" ? sessionId : void 0;
}
function registerBuiltinUtilityTools(registry) {
  registry.register({
    descriptor: {
      name: "render_template",
      category: "rendering",
      schemaVersion: "1",
      featureFlags: ["builtin", "host-utility"],
      safeMode: true,
      readOnly: true,
      runtimeSupport: {
        claude: "supported",
        codex: "supported",
        mcp: "degraded",
        cli: "unsupported"
      },
      sandboxProfile: {
        filesystem: "artifact-write",
        network: "none",
        allowedRuntimes: ["builtin"],
        timeoutMs: 5e3,
        envScrubbedKeys: []
      }
    },
    handler(input) {
      const record = input && typeof input === "object" ? input : {};
      const template = typeof record.template === "string" ? record.template : "";
      const variables = record.variables && typeof record.variables === "object" ? record.variables : {};
      return {
        text: template.replace(/\{\{\s*([A-Za-z0-9_.-]+)\s*\}\}/g, (_match, key) => variables[key] === void 0 ? "" : String(variables[key])),
        exitStatus: "success"
      };
    }
  });
  registry.register({
    descriptor: {
      name: "transform_data",
      category: "sandbox",
      schemaVersion: "1",
      featureFlags: ["builtin", "host-utility"],
      safeMode: true,
      readOnly: true,
      runtimeSupport: {
        claude: "supported",
        codex: "supported",
        mcp: "degraded",
        cli: "unsupported"
      },
      sandboxProfile: {
        filesystem: "none",
        network: "none",
        allowedRuntimes: ["builtin"],
        timeoutMs: 5e3,
        envScrubbedKeys: []
      }
    },
    handler(input) {
      return {
        text: JSON.stringify(input, null, 2),
        exitStatus: "success"
      };
    }
  });
  registry.register({
    descriptor: {
      name: "script_sandbox",
      category: "sandbox",
      schemaVersion: "1",
      featureFlags: ["builtin", "host-utility", "subprocess"],
      safeMode: false,
      readOnly: false,
      runtimeSupport: {
        claude: "supported",
        codex: "supported",
        mcp: "unsupported",
        cli: "unsupported"
      },
      sandboxProfile: {
        filesystem: "artifact-write",
        network: "none",
        allowedRuntimes: ["echo"],
        timeoutMs: 5e3,
        envScrubbedKeys: ["TOKEN", "API_KEY", "SECRET", "PASSWORD"]
      }
    },
    async handler(input) {
      const record = input && typeof input === "object" ? input : {};
      const command = typeof record.command === "string" ? record.command : "";
      const args = Array.isArray(record.args) ? record.args.filter((arg) => typeof arg === "string") : [];
      if (command !== "echo") {
        return {
          text: `script_sandbox command is not allowed: ${command}`,
          exitStatus: "failed"
        };
      }
      const { stdout, stderr } = await new Promise((resolvePromise, rejectPromise) => {
        const child = _child_process.execFile.call(void 0, command, args, { timeout: 5e3, env: {} }, (error, stdout2, stderr2) => {
          if (error && !stdout2 && !stderr2) {
            rejectPromise(error);
          } else {
            resolvePromise({ stdout: stdout2, stderr: stderr2 });
          }
        });
        child.on("error", rejectPromise);
      });
      return {
        text: stdout || stderr,
        exitStatus: "success",
        metadata: { exitCode: 0 }
      };
    }
  });
}
function redactSecrets(text) {
  const patterns = [
    /(authorization\s*[:=]\s*)(bearer\s+)?[^\s,;]+/gi,
    /(token\s*[:=]\s*)[^\s,;]+/gi,
    /(api[_-]?key\s*[:=]\s*)[^\s,;]+/gi,
    /(secret\s*[:=]\s*)[^\s,;]+/gi
  ];
  let redacted = false;
  let output = text;
  for (const pattern of patterns) {
    output = output.replace(pattern, (_match, ...args) => {
      const prefix = typeof args[0] === "string" ? args[0] : "";
      const optionalPrefix = typeof args[1] === "string" ? args[1] : "";
      redacted = true;
      return `${prefix}${optionalPrefix}[REDACTED]`;
    });
  }
  return { text: output, redacted };
}
function artifactReceipt(record) {
  return {
    artifactRef: record.artifactRef,
    ...record.sessionId ? { sessionId: record.sessionId } : {},
    toolName: record.toolName,
    contentType: record.contentType,
    byteLength: record.byteLength,
    redacted: record.redacted,
    createdAt: record.createdAt,
    ...record.metadata ? { metadata: { ...record.metadata } } : {}
  };
}
function uniqueChannels(channels) {
  return [...new Set(channels)];
}
function cloneNotification(receipt) {
  return {
    ...receipt,
    deliveredChannels: [...receipt.deliveredChannels],
    ...receipt.origin ? { origin: { ...receipt.origin } } : {}
  };
}
function cloneArtifact(artifact) {
  return {
    ...artifact,
    ...artifact.metadata ? { metadata: { ...artifact.metadata } } : {}
  };
}
function cloneTopicBinding(binding) {
  return {
    ...binding,
    ...binding.metadata ? { metadata: { ...binding.metadata } } : {}
  };
}
function cloneSessionMetadata(metadata) {
  return {
    ...metadata,
    labels: [...metadata.labels],
    preferences: { ...metadata.preferences },
    ...metadata.actor ? { actor: { ...metadata.actor } } : {}
  };
}
function cloneConfigWatchEvent(event) {
  return { ...event };
}
function cloneResourceBundleSnapshot(bundle) {
  return {
    ...bundle,
    resources: bundle.resources.map((resource) => ({ ...resource }))
  };
}
function cloneStatusConfigValidationResult(result) {
  return {
    valid: result.valid,
    errors: result.errors.map((error) => ({ ...error })),
    warnings: result.warnings.map((warning) => ({ ...warning }))
  };
}
function cloneAudit(entry) {
  return {
    ...entry,
    ...entry.actor ? { actor: { ...entry.actor } } : {},
    ...entry.metadata ? { metadata: { ...entry.metadata } } : {}
  };
}
function createLocalHostClient(options) {
  const baseUrl = options.baseUrl.replace(/\/$/, "");
  const fetchImpl = _nullishCoalesce(options.fetch, () => ( fetch));
  const authToken = options.authToken;
  async function request(method, path, body) {
    const headers = {};
    if (authToken) headers.Authorization = `Bearer ${authToken}`;
    if (body !== void 0) headers["content-type"] = "application/json";
    const response = await fetchImpl(`${baseUrl}${path}`, {
      method,
      ...body === void 0 ? {} : {
        body: JSON.stringify(body)
      },
      ...Object.keys(headers).length > 0 ? { headers } : {}
    });
    const data = await response.json();
    if (!response.ok) {
      throw new Error(_nullishCoalesce(data.reason, () => ( `Local host request failed: ${response.status}`)));
    }
    return data;
  }
  return {
    health() {
      return request("GET", "/health");
    },
    models() {
      return request("GET", "/models");
    },
    browseFileSystem(fsRequest = {}) {
      return request("GET", query("/fs/browse", fsRequest));
    },
    createSession(createRequest) {
      return request("POST", "/sessions", createRequest);
    },
    listSessions() {
      return request("GET", "/sessions");
    },
    getSession(sessionId) {
      return request("GET", `/sessions/${encodeURIComponent(sessionId)}`);
    },
    deleteSession(sessionId) {
      return request("DELETE", `/sessions/${encodeURIComponent(sessionId)}`);
    },
    preflight(sessionId) {
      return request("GET", `/sessions/${encodeURIComponent(sessionId)}/preflight`);
    },
    sendMessage(sessionId, sendRequest) {
      return request("POST", `/sessions/${encodeURIComponent(sessionId)}/messages`, sendRequest);
    },
    fetchTimeline(sessionId, fetchRequest = {}) {
      return request("POST", `/sessions/${encodeURIComponent(sessionId)}/timeline`, fetchRequest);
    },
    invokeSessionTool(sessionId, toolRequest) {
      return request("POST", `/sessions/${encodeURIComponent(sessionId)}/tools`, toolRequest);
    },
    startScheduler(schedule) {
      return request("POST", "/scheduler/start", schedule);
    },
    tickScheduler(schedulerId, tickRequest = {}) {
      return request("POST", `/scheduler/${encodeURIComponent(schedulerId)}/tick`, tickRequest);
    },
    stopScheduler(schedulerId) {
      return request("POST", `/scheduler/${encodeURIComponent(schedulerId)}/stop`, {});
    },
    sendNotification(notification) {
      return request("POST", "/notifications", notification);
    },
    listNotifications(filter = {}) {
      return request("GET", query("/notifications", filter));
    },
    writeArtifact(artifact) {
      return request("POST", "/artifacts", artifact);
    },
    readArtifact(artifactRef) {
      return request("GET", `/artifacts/${encodeURIComponent(artifactRef)}`);
    },
    bindTopic(binding) {
      return request("POST", "/bindings", binding);
    },
    resolveTopic(lookup) {
      return request("POST", "/bindings/resolve", lookup);
    },
    updateSessionMetadata(sessionId, metadata) {
      return request("PATCH", `/metadata/sessions/${encodeURIComponent(sessionId)}`, metadata);
    },
    getSessionMetadata(sessionId) {
      return request("GET", `/metadata/sessions/${encodeURIComponent(sessionId)}`);
    },
    listSessionMetadata() {
      return request("GET", "/metadata/sessions");
    },
    executeUtilityTool(utilityRequest) {
      return request("POST", "/utility/execute", utilityRequest);
    },
    recordConfigWatchEvent(configEvent) {
      return request("POST", "/admin/config/watch-events", configEvent);
    },
    createResourceBundleSnapshot(bundle) {
      return request("POST", "/admin/config/resource-bundles", bundle);
    },
    validateStatusConfig(statusConfig) {
      return request("POST", "/admin/config/status/validate", statusConfig);
    },
    hostToolRegistry() {
      return request("GET", "/admin/tools/registry");
    },
    emitAutomationEvent(automationRequest) {
      return request("POST", "/automations/events", automationRequest);
    },
    listAudit(filter = {}) {
      return request("GET", query("/audit", filter));
    },
    hostSnapshot() {
      return request("GET", "/host/snapshot");
    },
    // Sources CRUD
    listSources(filter = {}) {
      return request("GET", query("/sources", { enabledOnly: filter.enabledOnly ? "true" : void 0 }));
    },
    getSource(sourceSlug) {
      return request("GET", `/sources/${encodeURIComponent(sourceSlug)}`);
    },
    createSource(input) {
      return request("POST", "/sources", input);
    },
    updateSource(sourceSlug, patch) {
      return request("PATCH", `/sources/${encodeURIComponent(sourceSlug)}`, patch);
    },
    deleteSource(sourceSlug) {
      return request("DELETE", `/sources/${encodeURIComponent(sourceSlug)}`);
    },
    // Skills CRUD
    listSkills() {
      return request("GET", "/skills");
    },
    getSkill(skillSlug) {
      return request("GET", `/skills/${encodeURIComponent(skillSlug)}`);
    },
    createSkill(input) {
      return request("POST", "/skills", input);
    },
    updateSkill(skillSlug, patch) {
      return request("PATCH", `/skills/${encodeURIComponent(skillSlug)}`, patch);
    },
    deleteSkill(skillSlug) {
      return request("DELETE", `/skills/${encodeURIComponent(skillSlug)}`);
    },
    // Automations Config
    getAutomationsConfig() {
      return request("GET", "/automations/config");
    },
    updateAutomationsConfig(config) {
      return request("PUT", "/automations/config", config);
    },
    // Scheduler
    listSchedules() {
      return request("GET", "/scheduler");
    },
    streamTimeline(sessionId, onEvent, onError) {
      const wsUrl = authenticatedWsUrl(baseUrl, sessionId, authToken);
      let ws;
      let reconnectTimer;
      const backoffMs = [250, 500, 1e3, 2e3];
      let attempt = 0;
      function connect() {
        ws = new WebSocket(wsUrl);
        ws.onmessage = (event) => {
          const data = JSON.parse(event.data);
          if ("type" in data && data.type === "stream_error") {
            _optionalChain([onError, 'optionalCall', _25 => _25(new Error(data.message))]);
          } else {
            onEvent(data);
          }
        };
        ws.onerror = () => {
          _optionalChain([onError, 'optionalCall', _26 => _26(new Error("WebSocket connection error"))]);
        };
        ws.onclose = (event) => {
          if (event.code !== 1e3) {
            attempt = Math.min(attempt, backoffMs.length - 1);
            reconnectTimer = setTimeout(connect, backoffMs[attempt]);
            attempt++;
          }
        };
        ws.onopen = () => {
          attempt = 0;
        };
      }
      connect();
      return () => {
        if (reconnectTimer) clearTimeout(reconnectTimer);
        _optionalChain([ws, 'optionalAccess', _27 => _27.close, 'call', _28 => _28(1e3, "client disconnect")]);
      };
    }
  };
}
function authenticatedWsUrl(baseUrl, sessionId, authToken) {
  const url = new URL(`${baseUrl.replace(/^http/, "ws")}/sessions/${encodeURIComponent(sessionId)}/stream`);
  if (authToken) url.searchParams.set("token", authToken);
  return url.toString();
}
function query(path, params) {
  const search = new URLSearchParams();
  for (const [key, value] of Object.entries(params)) {
    if (value !== void 0) search.set(key, value);
  }
  const suffix = search.toString();
  return suffix ? `${path}?${suffix}` : path;
}





exports.createDefaultLocalHostController = createDefaultLocalHostController; exports.createLocalHostClient = createLocalHostClient; exports.createLocalHostServer = createLocalHostServer; exports.createWorkspaceSessionToolBridge = createWorkspaceSessionToolBridge;
