import {
  createSourceRuntimeProviderOptions
} from "./chunk-6XZO2YDF.js";
import {
  createClaudeProviderRuntime,
  createCodexProviderRuntime,
  createFlitroProviderRuntime
} from "./chunk-C7A3LQG6.js";
import {
  invokeSessionTool
} from "./chunk-5N6QO6NC.js";
import {
  createTimelineSequencer,
  fetchTimeline
} from "./chunk-VK2Y4OK3.js";

// ../packages/host-services/dist/index.js
import { createHash } from "crypto";
import { createHash as createHash2 } from "crypto";
import { createHash as createHash3 } from "crypto";
import { watch, existsSync, readFileSync } from "fs";
import { createHash as createHash4 } from "crypto";
var DEFAULT_APPROVAL_TTL_MS = 12e4;
function createPrivilegedExecutionBroker(options = {}) {
  const pending = /* @__PURE__ */ new Map();
  const now = options.now ?? Date.now;
  const audit = options.audit ?? (() => void 0);
  function auditEvent(event, timestamp = now()) {
    audit({ ...event, timestamp });
  }
  return {
    createRequest(input) {
      const timestamp = now();
      const approvalTtlMs = input.approvalTtlMs ?? options.approvalTtlMs ?? DEFAULT_APPROVAL_TTL_MS;
      const policy = validatePrivilegedCommand(input.command);
      const request = {
        requestId: input.requestId,
        sessionId: input.sessionId,
        command: input.command,
        commandHash: hashCommand(input.command),
        reason: input.reason,
        impact: input.impact,
        approvalTtlMs,
        createdAt: timestamp,
        expiresAt: timestamp + approvalTtlMs,
        policyAllowed: policy.allowed,
        policyReason: policy.reason
      };
      pending.set(input.requestId, request);
      auditEvent({
        event: "privileged_request_created",
        requestId: request.requestId,
        sessionId: request.sessionId,
        commandHash: request.commandHash,
        policyAllowed: request.policyAllowed,
        policyReason: request.policyReason
      }, timestamp);
      return request;
    },
    resolveApproval(requestId, approved, resolveOptions = {}) {
      const timestamp = resolveOptions.now ?? now();
      const request = pending.get(requestId);
      if (!request) return { ok: false, reason: "not_found" };
      pending.delete(requestId);
      if (resolveOptions.expectedCommandHash && resolveOptions.expectedCommandHash !== request.commandHash) {
        auditEvent({
          event: "privileged_request_hash_mismatch",
          requestId: request.requestId,
          sessionId: request.sessionId,
          commandHash: request.commandHash
        }, timestamp);
        return { ok: false, reason: "command_hash_mismatch" };
      }
      if (!request.policyAllowed) {
        auditEvent({
          event: "privileged_request_blocked_by_policy",
          requestId: request.requestId,
          sessionId: request.sessionId,
          commandHash: request.commandHash,
          policyAllowed: false,
          policyReason: request.policyReason
        }, timestamp);
        return { ok: false, reason: "blocked_by_policy" };
      }
      if (timestamp > request.expiresAt) {
        auditEvent({
          event: "privileged_request_expired",
          requestId: request.requestId,
          sessionId: request.sessionId,
          commandHash: request.commandHash
        }, timestamp);
        return { ok: false, reason: "expired" };
      }
      auditEvent({
        event: approved ? "privileged_request_approved" : "privileged_request_denied",
        requestId: request.requestId,
        sessionId: request.sessionId,
        commandHash: request.commandHash
      }, timestamp);
      return approved ? { ok: true, request } : { ok: false, reason: "blocked_by_policy" };
    }
  };
}
function hashCommand(command) {
  return createHash("sha256").update(command, "utf8").digest("hex");
}
function validatePrivilegedCommand(command) {
  const normalized = command.trim().toLowerCase();
  const allowed = /^brew\s+install\s+--cask\s+\S+/.test(normalized) || /^brew\s+upgrade\s+--cask\s+\S+/.test(normalized) || /^installer\s+-pkg\s+\S+.*\s+-target\s+\//.test(normalized);
  return allowed ? { allowed: true } : {
    allowed: false,
    reason: "Privileged execution policy only allows brew cask install/upgrade and installer -pkg -target / commands"
  };
}
function stableHash(value) {
  return createHash2("sha256").update(stableStringify(value), "utf8").digest("hex").slice(0, 16);
}
function stableStringify(value) {
  if (Array.isArray(value)) {
    return `[${value.map(stableStringify).join(",")}]`;
  }
  if (value && typeof value === "object") {
    const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([left], [right]) => left.localeCompare(right));
    return `{${entries.map(([key, entryValue]) => `${JSON.stringify(key)}:${stableStringify(entryValue)}`).join(",")}}`;
  }
  return JSON.stringify(value);
}
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 cloneCommandOrigin(origin) {
  return { ...origin };
}
var DEFAULT_MAX_INLINE_BYTES = 60 * 1024;
function createToolOutputPolicy(options = {}) {
  const maxInlineBytes = options.maxInlineBytes ?? DEFAULT_MAX_INLINE_BYTES;
  return {
    process(input) {
      const redaction = redactSecrets(input.text);
      const byteLength = Buffer.byteLength(redaction.text, "utf8");
      const shouldInline = byteLength <= maxInlineBytes;
      if (shouldInline) {
        return {
          callId: input.callId,
          toolName: input.toolName,
          action: "inline",
          byteLength,
          redacted: redaction.redacted,
          truncated: false,
          inlineText: redaction.text,
          ...input.intent ? { intent: input.intent } : {}
        };
      }
      const truncated = truncateByBytes(redaction.text, maxInlineBytes);
      const source = { ...input, text: redaction.text };
      const summary = options.summarizer ? options.summarizer({ text: truncated, source }) : truncated;
      return {
        callId: input.callId,
        toolName: input.toolName,
        action: "artifact",
        byteLength,
        redacted: redaction.redacted,
        truncated: true,
        summary,
        artifactRef: options.artifactRef?.(input) ?? `tool-output://${input.callId}`,
        ...input.intent ? { intent: input.intent } : {}
      };
    }
  };
}
function truncateByBytes(text, maxBytes) {
  const buffer = Buffer.from(text, "utf8");
  if (buffer.byteLength <= maxBytes) return text;
  return buffer.subarray(0, maxBytes).toString("utf8");
}
function createSourceAuthoringPlan(input) {
  const slug = slugify(input.serviceName);
  const fallbackDecision = decideSourceBrowserFallback(input);
  return {
    recommendedPath: fallbackDecision ? "browser-fallback" : "source",
    workspaceId: input.workspaceId,
    ...input.purpose ? { purpose: input.purpose } : {},
    source: {
      id: `${slug}_planned`,
      slug,
      name: input.serviceName.trim(),
      provider: slug
    },
    validationSteps: [
      "validate_config",
      "test_connection",
      "verify_auth",
      "write_guide",
      "seed_read_only_policy"
    ],
    ...fallbackDecision ? { browserFallbackDecision: fallbackDecision } : {}
  };
}
function decideSourceBrowserFallback(input) {
  if (input.uiOnly || input.repeatable === false) {
    return {
      reason: "one_off_or_ui_only",
      reusableSourceLater: true,
      detail: "Prefer browser fallback for one-off or UI-only work; create a source later when the workflow becomes repeatable."
    };
  }
  if (input.authReliability === "brittle") {
    return {
      reason: "brittle_auth",
      reusableSourceLater: true,
      detail: "Prefer browser fallback until source authentication is reliable enough to reuse."
    };
  }
  if (input.structuredAccess === false) {
    return {
      reason: "not_structured",
      reusableSourceLater: true,
      detail: "Prefer browser fallback because the task does not need reusable structured access."
    };
  }
  return void 0;
}
function slugify(value) {
  const slug = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
  return slug || "source";
}
function expandWebhookTemplate(input) {
  const variables = input.variables ?? {};
  const secrets = input.secrets ?? {};
  const receipts = /* @__PURE__ */ new Map();
  const missing = /* @__PURE__ */ new Set();
  const expanded = input.template.replace(/\$\{([A-Z0-9_]+)\}|\$([A-Z0-9_]+)/g, (match, braced, bare) => {
    const name = braced ?? bare;
    if (!name) return match;
    if (Object.prototype.hasOwnProperty.call(secrets, name) && secrets[name] !== void 0) {
      receipts.set(name, { name, found: true, source: "secret", redacted: true });
      return String(secrets[name]);
    }
    if (Object.prototype.hasOwnProperty.call(variables, name) && variables[name] !== void 0) {
      receipts.set(name, { name, found: true, source: "variable", redacted: false });
      return String(variables[name]);
    }
    missing.add(name);
    receipts.set(name, { name, found: false, redacted: false });
    return match;
  });
  let redactedPreview = expanded;
  for (const [name, value] of Object.entries(secrets)) {
    if (!value) continue;
    redactedPreview = redactedPreview.split(value).join("[REDACTED]");
    if (!receipts.has(name)) {
      receipts.set(name, { name, found: false, source: "secret", redacted: true });
    }
  }
  return {
    expanded,
    redactedPreview,
    missingVariables: [...missing].sort(),
    variables: [...receipts.values()].sort((left, right) => left.name.localeCompare(right.name))
  };
}
function createMessagingAccessPolicy(options = {}) {
  const owners = new Set(options.owners ?? []);
  const allowedSenders = new Set(options.allowedSenders ?? []);
  const pendingSenders = new Set(options.pendingSenders ?? []);
  return {
    authorize(request) {
      const commandOrigin = {
        type: "remote",
        channel: request.channel,
        actorId: request.actorId
      };
      if (owners.has(request.actorId)) {
        return { decision: "allow", reason: "owner", commandOrigin };
      }
      if (allowedSenders.has(request.actorId)) {
        return { decision: "allow", reason: "sender_allowed", commandOrigin };
      }
      if (pendingSenders.has(request.actorId)) {
        return { decision: "ask", reason: "sender_pending_approval", commandOrigin };
      }
      return { decision: "deny", reason: "sender_not_allowed", commandOrigin };
    }
  };
}
function createInMemoryAuditStore(options = {}) {
  const now = options.now ?? Date.now;
  const entries = [];
  return {
    async append(input) {
      const seq = entries.length + 1;
      const entry = {
        ...cloneAuditEntryInput(input),
        auditId: `audit:${seq}`,
        seq,
        timestamp: now()
      };
      entries.push(entry);
      return {
        auditId: entry.auditId,
        seq: entry.seq,
        timestamp: entry.timestamp,
        entry: cloneAuditEntry(entry)
      };
    },
    async list(filter = {}) {
      return filterAuditEntries(entries, filter).map(cloneAuditEntry);
    },
    getSnapshot() {
      return { entries: entries.map(cloneAuditEntry) };
    }
  };
}
function cloneAuditEntryInput(input) {
  return {
    ...input,
    ...input.actor ? { actor: { ...input.actor } } : {},
    ...input.metadata ? { metadata: { ...input.metadata } } : {}
  };
}
function cloneAuditEntry(entry) {
  return {
    ...entry,
    ...entry.actor ? { actor: { ...entry.actor } } : {},
    ...entry.metadata ? { metadata: { ...entry.metadata } } : {}
  };
}
function filterAuditEntries(entries, filter) {
  return entries.filter((entry) => !filter.sessionId || entry.sessionId === filter.sessionId).filter((entry) => !filter.category || entry.category === filter.category).slice(0, filter.limit ?? Number.POSITIVE_INFINITY);
}
function createInMemoryArtifactStore(options = {}) {
  const now = options.now ?? Date.now;
  const artifacts = /* @__PURE__ */ new Map();
  return {
    async write(input) {
      const redaction = redactSecrets(input.text);
      const record = {
        artifactRef: input.artifactRef,
        ...input.sessionId ? { sessionId: input.sessionId } : {},
        toolName: input.toolName,
        contentType: input.contentType,
        text: redaction.text,
        byteLength: Buffer.byteLength(redaction.text, "utf8"),
        redacted: redaction.redacted,
        createdAt: now(),
        ...input.metadata ? { metadata: { ...input.metadata } } : {}
      };
      artifacts.set(record.artifactRef, record);
      return artifactReceipt(record);
    },
    async read(artifactRef) {
      const record = artifacts.get(artifactRef);
      return record ? cloneArtifactRecord(record) : void 0;
    },
    async list(filter = {}) {
      return filterArtifactRecords([...artifacts.values()], filter).map(artifactReceipt);
    },
    getSnapshot() {
      return {
        artifacts: [...artifacts.values()].map(cloneArtifactRecord)
      };
    }
  };
}
function filterArtifactRecords(records, filter) {
  return records.filter((record) => !filter.sessionId || record.sessionId === filter.sessionId).filter((record) => !filter.toolName || record.toolName === filter.toolName).slice(0, filter.limit ?? Number.POSITIVE_INFINITY);
}
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 cloneArtifactRecord(record) {
  return {
    ...record,
    ...record.metadata ? { metadata: { ...record.metadata } } : {}
  };
}
function createInMemoryNotificationHost(options = {}) {
  const now = options.now ?? Date.now;
  const notifications = [];
  let counter = 0;
  return {
    async notify(request) {
      const redaction = redactSecrets(request.body ?? "");
      const receipt = {
        notificationId: `notification:${++counter}`,
        ...request.sessionId ? { sessionId: request.sessionId } : {},
        ...request.topicId ? { topicId: request.topicId } : {},
        deliveredChannels: [...new Set(request.channels)],
        title: request.title,
        ...request.body !== void 0 ? { bodyPreview: redaction.text } : {},
        severity: request.severity ?? "info",
        redacted: redaction.redacted,
        timestamp: now(),
        ...request.origin ? { origin: cloneCommandOrigin(request.origin) } : {}
      };
      notifications.push(receipt);
      return cloneNotificationReceipt(receipt);
    },
    getSnapshot() {
      return { notifications: notifications.map(cloneNotificationReceipt) };
    }
  };
}
function cloneNotificationReceipt(receipt) {
  return {
    ...receipt,
    deliveredChannels: [...receipt.deliveredChannels],
    ...receipt.origin ? { origin: cloneCommandOrigin(receipt.origin) } : {}
  };
}
function createMessagingBindingStore(options = {}) {
  const now = options.now ?? Date.now;
  const bindings = /* @__PURE__ */ new Map();
  return {
    async bindTopic(input) {
      const timestamp = now();
      const existing = bindings.get(input.bindingId);
      const binding = {
        bindingId: input.bindingId,
        sessionId: input.sessionId,
        channel: input.channel,
        topicId: input.topicId,
        ...input.actorId ? { actorId: input.actorId } : existing?.actorId ? { actorId: existing.actorId } : {},
        createdAt: existing?.createdAt ?? timestamp,
        updatedAt: timestamp,
        ...input.metadata ? { metadata: { ...input.metadata } } : existing?.metadata ? { metadata: { ...existing.metadata } } : {}
      };
      bindings.set(binding.bindingId, binding);
      return cloneTopicBinding(binding);
    },
    async resolveTopic(lookup) {
      const binding = [...bindings.values()].find((candidate) => candidate.channel === lookup.channel && candidate.topicId === lookup.topicId);
      return binding ? cloneTopicBinding(binding) : void 0;
    },
    async listBindings(filter = {}) {
      return [...bindings.values()].filter((binding) => !filter.sessionId || binding.sessionId === filter.sessionId).filter((binding) => !filter.channel || binding.channel === filter.channel).map(cloneTopicBinding);
    },
    async unbindTopic(bindingId, unbindOptions = {}) {
      if (!bindings.has(bindingId)) return { ok: false, bindingId, reason: "not_found" };
      bindings.delete(bindingId);
      return {
        ok: true,
        bindingId,
        unboundAt: now(),
        ...unbindOptions.actorId ? { actorId: unbindOptions.actorId } : {}
      };
    },
    getSnapshot() {
      return { bindings: [...bindings.values()].map(cloneTopicBinding) };
    }
  };
}
function cloneTopicBinding(binding) {
  return {
    ...binding,
    ...binding.metadata ? { metadata: { ...binding.metadata } } : {}
  };
}
var DEFAULT_SECRET_ENV_KEY_PATTERN = /(token|api[_-]?key|secret|password|passwd|credential|authorization|auth)$/i;
function scrubLocalMcpEnvironment(env, options = {}) {
  const keepKeys = new Set(options.keepKeys ?? []);
  const removeKeyPattern = options.removeKeyPattern ?? DEFAULT_SECRET_ENV_KEY_PATTERN;
  const scrubbed = {};
  const redactedPreview = {};
  const removedKeys = [];
  for (const [key, value] of Object.entries(env)) {
    if (value === void 0) continue;
    if (!keepKeys.has(key) && removeKeyPattern.test(key)) {
      removedKeys.push(key);
      redactedPreview[key] = "[REDACTED]";
      continue;
    }
    scrubbed[key] = value;
    redactedPreview[key] = value;
  }
  removedKeys.sort();
  return {
    env: scrubbed,
    removedKeys,
    redactedPreview
  };
}
function createConfigRecoveryReceipt(input) {
  const migratedAliases = [...input.migratedAliases ?? []].sort();
  const matcherIdsBackfilled = [...input.matcherIdsBackfilled ?? []].sort();
  const body = {
    configPath: input.configPath,
    configKind: input.configKind,
    problem: input.problem,
    recovery: input.recovery,
    defaultVersion: input.defaultVersion,
    userConfigHash: input.userConfigHash,
    migratedAliases,
    matcherIdsBackfilled,
    timestamp: input.timestamp
  };
  return {
    ...body,
    receiptId: `config-recovery:${stableHash(body)}`,
    overwroteUserConfig: false,
    migratedAliases,
    matcherIdsBackfilled
  };
}
function createResourceBundleSnapshot(input) {
  const resources = [...input.resources].map((resource) => ({ ...resource })).sort((left, right) => left.path.localeCompare(right.path));
  const body = {
    workspaceId: input.workspaceId,
    resources,
    timestamp: input.timestamp
  };
  return {
    snapshotId: `resource-bundle:${stableHash(body)}`,
    workspaceId: input.workspaceId,
    resourceCount: resources.length,
    resources,
    ...input.timestamp !== void 0 ? { timestamp: input.timestamp } : {}
  };
}
function createConfigWatchEvent(input) {
  const body = { ...input };
  return {
    ...body,
    eventId: `config-watch:${stableHash(body)}`
  };
}
var RUNTIME_KIND_ORDER = ["claude", "codex", "mcp", "cli"];
function createToolRegistryVersion(input) {
  const tools = [...input.tools].map((tool) => ({
    ...tool,
    ...tool.featureFlags ? { featureFlags: [...tool.featureFlags].sort() } : {},
    runtimeSupport: { ...tool.runtimeSupport }
  })).sort((left, right) => left.name.localeCompare(right.name));
  const unsupported = collectRuntimeSupportGaps(tools, "unsupported");
  const degraded = collectRuntimeSupportGaps(tools, "degraded");
  const body = {
    registryVersion: input.registryVersion,
    tools
  };
  return {
    registryId: `tool-registry:${stableHash(body)}`,
    registryVersion: input.registryVersion,
    toolCount: tools.length,
    tools,
    degraded,
    unsupported
  };
}
function collectRuntimeSupportGaps(tools, level) {
  const gaps = [];
  for (const tool of tools) {
    const runtimeKinds = [...RUNTIME_KIND_ORDER].sort();
    for (const runtimeKind of runtimeKinds) {
      if (tool.runtimeSupport[runtimeKind] === level) {
        gaps.push({ name: tool.name, runtimeKind });
      }
    }
  }
  return gaps;
}
function validateStatusConfig(config, file = "statuses.json") {
  const errors = [];
  const warnings = [];
  const statusIds = /* @__PURE__ */ new Set();
  config.statuses.forEach((status, index) => {
    if (!status.id) {
      errors.push({
        file,
        path: `statuses[${index}].id`,
        message: "Status id is required",
        severity: "error"
      });
      return;
    }
    if (statusIds.has(status.id)) {
      errors.push({
        file,
        path: `statuses[${index}].id`,
        message: "Status id must be unique",
        severity: "error"
      });
      return;
    }
    statusIds.add(status.id);
  });
  const initial = config.statuses.find((status) => status.id === config.initialStatus);
  if (!initial) {
    errors.push({
      file,
      path: "initialStatus",
      message: "Initial status is not defined",
      severity: "error"
    });
  } else if (initial.terminal) {
    errors.push({
      file,
      path: "initialStatus",
      message: "Initial status cannot be terminal",
      severity: "error"
    });
  }
  for (const [index, transition] of (config.allowedTransitions ?? []).entries()) {
    if (!statusIds.has(transition.from)) {
      errors.push({
        file,
        path: `allowedTransitions[${index}].from`,
        message: "Transition source status is not defined",
        severity: "error"
      });
    }
    if (!statusIds.has(transition.to)) {
      errors.push({
        file,
        path: `allowedTransitions[${index}].to`,
        message: "Transition target status is not defined",
        severity: "error"
      });
    }
  }
  if (!config.statuses.some((status) => status.terminal)) {
    warnings.push({
      file,
      path: "statuses",
      message: "Status config has no terminal status",
      severity: "warning",
      suggestion: "Add at least one terminal status such as done or archived."
    });
  }
  return {
    valid: errors.length === 0,
    errors,
    warnings
  };
}
function createInMemoryHostUtilityToolRegistry(options = {}) {
  const now = options.now ?? Date.now;
  const outputPolicy = options.outputPolicy ?? createToolOutputPolicy();
  const tools = /* @__PURE__ */ new Map();
  return {
    register(input) {
      tools.set(input.descriptor.name, cloneUtilityRegistration(input));
    },
    async execute(input) {
      const startedAt = now();
      const policyDecision = input.policyDecision ?? { decision: "allow" };
      const descriptor = tools.get(input.toolName)?.descriptor;
      if (policyDecision.decision !== "allow") {
        return createUtilityReceipt({
          input,
          descriptor,
          startedAt,
          finishedAt: now(),
          text: policyDecision.reason,
          exitStatus: "denied",
          policyDecision,
          outputPolicy
        });
      }
      const registration = tools.get(input.toolName);
      if (!registration) {
        return createUtilityReceipt({
          input,
          startedAt,
          finishedAt: now(),
          text: "host utility tool is not registered",
          exitStatus: "unsupported",
          policyDecision,
          outputPolicy
        });
      }
      try {
        const result = await registration.handler(input.input, {
          callId: input.callId,
          ...input.commandOrigin ? { commandOrigin: cloneCommandOrigin(input.commandOrigin) } : {}
        });
        return createUtilityReceipt({
          input,
          descriptor: registration.descriptor,
          startedAt,
          finishedAt: now(),
          text: result.text,
          exitStatus: result.exitStatus ?? "success",
          policyDecision,
          outputPolicy,
          metadata: result.metadata
        });
      } catch (error) {
        return createUtilityReceipt({
          input,
          descriptor: registration.descriptor,
          startedAt,
          finishedAt: now(),
          text: error instanceof Error ? error.message : String(error),
          exitStatus: "failed",
          policyDecision,
          outputPolicy
        });
      }
    },
    capabilityReport() {
      return createToolRegistryVersion({
        registryVersion: options.registryVersion ?? "in-memory",
        tools: [...tools.values()].map((tool) => tool.descriptor)
      });
    }
  };
}
function createUtilityReceipt(input) {
  const output = input.outputPolicy.process({
    callId: input.input.callId,
    toolName: input.input.toolName,
    text: input.text,
    intent: input.descriptor?.category
  });
  return {
    toolName: input.input.toolName,
    callId: input.input.callId,
    inputDigest: `sha256:${createHash3("sha256").update(stableStringify(input.input.input), "utf8").digest("hex")}`,
    executionMode: "host-service",
    ...input.descriptor?.sandboxProfile ? { sandboxProfile: cloneSandboxProfile(input.descriptor.sandboxProfile) } : {},
    output,
    durationMs: input.finishedAt - input.startedAt,
    startedAt: input.startedAt,
    finishedAt: input.finishedAt,
    exitStatus: input.exitStatus,
    policyDecision: { ...input.policyDecision },
    ...input.input.commandOrigin ? { commandOrigin: cloneCommandOrigin(input.input.commandOrigin) } : {},
    ...input.metadata ? { metadata: { ...input.metadata } } : {}
  };
}
function cloneUtilityRegistration(input) {
  return {
    descriptor: cloneHostUtilityDescriptor(input.descriptor),
    handler: input.handler
  };
}
function cloneHostUtilityDescriptor(descriptor) {
  return {
    ...descriptor,
    ...descriptor.featureFlags ? { featureFlags: [...descriptor.featureFlags] } : {},
    runtimeSupport: { ...descriptor.runtimeSupport },
    ...descriptor.sandboxProfile ? { sandboxProfile: cloneSandboxProfile(descriptor.sandboxProfile) } : {}
  };
}
function cloneSandboxProfile(profile) {
  return {
    ...profile,
    allowedRuntimes: [...profile.allowedRuntimes],
    envScrubbedKeys: [...profile.envScrubbedKeys]
  };
}
function createSecondaryLlmCallPolicy(options) {
  const allowedModels = new Set(options.allowedModels);
  const allowedAttachmentRoots = options.allowedAttachmentRoots ?? [];
  return {
    authorize(input) {
      if (!allowedModels.has(input.model)) {
        return { decision: "deny", reason: "model_not_allowed", model: input.model };
      }
      const inputBytes = Buffer.byteLength(input.prompt, "utf8");
      if (inputBytes > options.maxInputBytes) {
        return { decision: "deny", reason: "input_too_large", model: input.model };
      }
      const maxOutputBytes = input.maxOutputBytes ?? options.maxOutputBytes;
      if (maxOutputBytes > options.maxOutputBytes) {
        return { decision: "deny", reason: "output_too_large", model: input.model };
      }
      if ((input.attachments ?? []).some((path) => !isAllowedAttachmentPath(path, allowedAttachmentRoots))) {
        return { decision: "deny", reason: "attachment_path_not_allowed", model: input.model };
      }
      return {
        decision: "allow",
        model: input.model,
        inputBytes,
        maxOutputBytes
      };
    }
  };
}
function isAllowedAttachmentPath(path, allowedRoots) {
  if (allowedRoots.length === 0) return false;
  return allowedRoots.some((root) => path === root || path.startsWith(`${root.replace(/\/+$/, "")}/`));
}
function createInMemorySessionToolBridge(options = {}) {
  const now = options.now ?? Date.now;
  const sessions = /* @__PURE__ */ new Map();
  const plans = [];
  const browserActions = [];
  const messages = [];
  const spawnedSessions = [];
  const sourceOperations = [];
  const skillOperations = [];
  const automationConfigOperations = [];
  const scheduleOperations = [];
  let generatedSessionCounter = 0;
  let messageCounter = 0;
  function ensureSession(sessionId) {
    const id = sessionId ?? "default";
    const existing = sessions.get(id);
    if (existing) return existing;
    const created = { sessionId: id };
    sessions.set(id, created);
    return created;
  }
  function nextSessionId() {
    return options.nextSessionId?.() ?? `session-${++generatedSessionCounter}`;
  }
  const bridge = {
    async submitPlan(request) {
      ensureSession(request.sessionId);
      plans.push({
        sessionId: request.sessionId,
        planRef: request.planRef,
        ...request.origin ? { origin: request.origin } : {},
        submittedAt: now()
      });
      return { accepted: true, planRef: request.planRef };
    },
    async runBrowserAction(request) {
      const record = {
        sessionId: request.sessionId,
        action: request.action,
        ...request.input !== void 0 ? { input: request.input } : {},
        recordedAt: now()
      };
      ensureSession(request.sessionId);
      browserActions.push(record);
      return {
        ok: true,
        result: {
          action: record.action,
          ...record.input !== void 0 ? { input: record.input } : {},
          recordedAt: record.recordedAt
        }
      };
    },
    async spawnSession(request) {
      const sessionId = nextSessionId();
      const record = {
        sessionId,
        ...request.parentSessionId ? { parentSessionId: request.parentSessionId } : {},
        prompt: request.prompt,
        ...request.model ? { model: request.model } : {},
        ...request.commandOrigin ? { commandOrigin: request.commandOrigin } : {},
        createdAt: now()
      };
      spawnedSessions.push(record);
      sessions.set(sessionId, {
        sessionId,
        topic: request.prompt,
        status: "created"
      });
      return { sessionId };
    },
    async sendSessionMessage(request) {
      ensureSession(request.sessionId);
      const commandId = `message:${++messageCounter}`;
      messages.push({
        sessionId: request.sessionId,
        message: request.message,
        ...request.attachments ? { attachments: cloneAttachments(request.attachments) } : {},
        ...request.commandOrigin ? { commandOrigin: request.commandOrigin } : {},
        commandId,
        sentAt: now()
      });
      return { ok: true, commandId };
    },
    async updateSessionMetadata(request) {
      const sessionId = request.sessionId ?? "default";
      const current = ensureSession(sessionId);
      const next = {
        ...current,
        sessionId,
        ...request.labels ? { labels: uniqueSorted(request.labels) } : {},
        ...request.status ? { status: request.status } : {},
        ...request.flagged !== void 0 ? { flagged: request.flagged } : {},
        ...request.topic ? { topic: request.topic } : {}
      };
      sessions.set(sessionId, next);
      return cloneSession(next);
    },
    async listSessions(request) {
      const labels = request.labels ?? [];
      const filtered = [...sessions.values()].filter((session) => !request.status || session.status === request.status).filter((session) => labels.every((label) => session.labels?.includes(label))).sort((left, right) => String(left.sessionId ?? "").localeCompare(String(right.sessionId ?? ""))).slice(0, request.limit ?? Number.POSITIVE_INFINITY).map(cloneSession);
      return { sessions: filtered };
    },
    // Sources CRUD (in-memory recording stubs)
    async listSources(request) {
      sourceOperations.push({ op: "listSources", request, ts: now() });
      return { sources: [] };
    },
    async getSource(request) {
      sourceOperations.push({ op: "getSource", request, ts: now() });
      return { source: { slug: request.sourceSlug, name: request.sourceSlug, provider: "stub", type: "api", enabled: true } };
    },
    async createSource(request) {
      sourceOperations.push({ op: "createSource", request, ts: now() });
      return { ok: true, source: { slug: request.name.toLowerCase().replace(/\s+/g, "-"), name: request.name, provider: request.provider, type: request.type, enabled: request.enabled ?? true } };
    },
    async updateSource(request) {
      sourceOperations.push({ op: "updateSource", request, ts: now() });
      return { ok: true, source: { slug: request.sourceSlug, name: request.name ?? request.sourceSlug, provider: "stub", type: "api", enabled: request.enabled ?? true } };
    },
    async deleteSource(request) {
      sourceOperations.push({ op: "deleteSource", request, ts: now() });
      return { ok: true, sourceSlug: request.sourceSlug };
    },
    // Skills CRUD (in-memory recording stubs)
    async listSkills(request) {
      skillOperations.push({ op: "listSkills", request, ts: now() });
      return { skills: [] };
    },
    async getSkill(request) {
      skillOperations.push({ op: "getSkill", request, ts: now() });
      return { skill: { slug: request.skillSlug, name: request.skillSlug, description: "stub", source: "workspace", content: "" } };
    },
    async createSkill(request) {
      skillOperations.push({ op: "createSkill", request, ts: now() });
      return { ok: true, skill: { slug: request.slug, name: request.name, description: request.description, source: "workspace" } };
    },
    async updateSkill(request) {
      skillOperations.push({ op: "updateSkill", request, ts: now() });
      return { ok: true, skill: { slug: request.skillSlug, name: request.name ?? request.skillSlug, description: request.description ?? "stub", source: "workspace" } };
    },
    async deleteSkill(request) {
      skillOperations.push({ op: "deleteSkill", request, ts: now() });
      return { ok: true, skillSlug: request.skillSlug };
    },
    // Automations Config (in-memory recording stubs)
    async getAutomationsConfig(request) {
      automationConfigOperations.push({ op: "getAutomationsConfig", request, ts: now() });
      return { config: null, configPath: "/stub/automations.json" };
    },
    async updateAutomationsConfig(request) {
      automationConfigOperations.push({ op: "updateAutomationsConfig", request, ts: now() });
      return { ok: true, automationCount: 0, errors: [] };
    },
    // Scheduler (in-memory recording stubs)
    async listSchedules(request) {
      scheduleOperations.push({ op: "listSchedules", request, ts: now() });
      return { schedules: [] };
    },
    async startSchedule(request) {
      scheduleOperations.push({ op: "startSchedule", request, ts: now() });
      return { schedulerId: request.schedulerId, state: "started", timestamp: now() };
    },
    async stopSchedule(request) {
      scheduleOperations.push({ op: "stopSchedule", request, ts: now() });
      return { ok: true, schedulerId: request.schedulerId, state: "stopped" };
    },
    ...options.queryLlm ? {
      async queryLlm(request) {
        return options.queryLlm(request);
      }
    } : {}
  };
  return {
    bridge,
    getSnapshot() {
      return {
        sessions: [...sessions.values()].map(cloneSession),
        plans: plans.map((plan) => ({ ...plan })),
        browserActions: browserActions.map((action) => ({ ...action })),
        messages: messages.map((message) => ({
          ...message,
          ...message.attachments ? { attachments: cloneAttachments(message.attachments) } : {}
        })),
        spawnedSessions: spawnedSessions.map((session) => ({ ...session })),
        sourceOperations: sourceOperations.map((op) => ({ ...op })),
        skillOperations: skillOperations.map((op) => ({ ...op })),
        automationConfigOperations: automationConfigOperations.map((op) => ({ ...op })),
        scheduleOperations: scheduleOperations.map((op) => ({ ...op }))
      };
    }
  };
}
function cloneSession(session) {
  return {
    ...session,
    ...session.labels ? { labels: [...session.labels] } : {}
  };
}
function cloneAttachments(attachments) {
  return attachments.map((attachment) => ({ ...attachment }));
}
function uniqueSorted(values) {
  return [...new Set(values)].sort();
}
function createConfigWatcherManager(options) {
  const watchers = [];
  const hashes = /* @__PURE__ */ new Map();
  const debounceMs = options.debounceMs ?? 300;
  const now = options.now ?? Date.now;
  const debounceTimers = /* @__PURE__ */ new Map();
  let active = false;
  function hashFile(path) {
    try {
      if (!existsSync(path)) return void 0;
      const content = readFileSync(path, "utf-8");
      return createHash4("sha256").update(content).digest("hex").slice(0, 16);
    } catch {
      return void 0;
    }
  }
  function handleChange(file) {
    const existing = debounceTimers.get(file.path);
    if (existing) clearTimeout(existing);
    debounceTimers.set(file.path, setTimeout(() => {
      debounceTimers.delete(file.path);
      if (!active) return;
      const previousHash = hashes.get(file.path);
      const nextHash = hashFile(file.path);
      if (previousHash === nextHash) return;
      let action;
      if (!previousHash && nextHash) action = "created";
      else if (previousHash && !nextHash) action = "deleted";
      else action = "updated";
      if (nextHash) {
        hashes.set(file.path, nextHash);
      } else {
        hashes.delete(file.path);
      }
      options.callbacks.onConfigChange({
        workspaceId: options.workspaceId,
        configPath: file.path,
        configKind: file.kind,
        action,
        source: "file_watcher",
        timestamp: now(),
        previousHash,
        nextHash
      });
    }, debounceMs));
  }
  return {
    get watching() {
      return active;
    },
    start() {
      if (active) return;
      active = true;
      for (const file of options.files) {
        const initialHash = hashFile(file.path);
        if (initialHash) hashes.set(file.path, initialHash);
        try {
          const watcher = watch(file.path, { persistent: false }, () => {
            handleChange(file);
          });
          watcher.on("error", (err) => {
            options.callbacks.onError?.(err);
          });
          watchers.push(watcher);
        } catch {
        }
      }
    },
    stop() {
      active = false;
      for (const watcher of watchers) {
        watcher.close();
      }
      watchers.length = 0;
      for (const timer of debounceTimers.values()) {
        clearTimeout(timer);
      }
      debounceTimers.clear();
    }
  };
}

// ../packages/runtime-factory/dist/index.js
function createHostAgentRuntime(options) {
  const sourceRuntime = options.sourceRuntime ? createSourceRuntimeProviderOptions(options.sourceRuntime) : void 0;
  const extensions = mergeExtensions(options.extensions, options.policy, sourceRuntime);
  if (options.provider === "claude") {
    return {
      runtime: createClaudeProviderRuntime({
        cwd: options.cwd,
        sessionId: options.sessionId,
        epoch: options.epoch,
        now: options.now,
        candidates: options.candidates,
        auth: options.auth,
        allowFallback: options.allowFallback,
        extensions,
        sourceTools: sourceRuntime?.sourceTools,
        model: options.claude?.model ?? options.model,
        reasoningEffort: options.claude?.reasoningEffort ?? options.reasoningEffort,
        env: options.claude?.env,
        permissionMode: options.claude?.permissionMode,
        query: options.claude?.query,
        loadSdk: options.claude?.loadSdk
      }),
      sourceRuntime
    };
  }
  if (options.provider === "flitro") {
    if (!options.flitro?.server) {
      throw new Error('createHostAgentRuntime: flitro.server is required for provider="flitro"');
    }
    return {
      runtime: createFlitroProviderRuntime({
        server: options.flitro.server,
        sessionId: options.sessionId,
        epoch: options.epoch,
        now: options.now,
        candidates: options.candidates,
        auth: options.auth,
        allowFallback: options.allowFallback,
        extensions,
        model: options.flitro.model ?? options.model,
        skillNames: options.flitro.skillNames,
        mcpServerNames: options.flitro.mcpServerNames,
        approvalPolicy: options.flitro.approvalPolicy
      }),
      sourceRuntime
    };
  }
  return {
    runtime: createCodexProviderRuntime({
      cwd: options.cwd,
      sessionId: options.sessionId,
      epoch: options.epoch,
      now: options.now,
      candidates: options.candidates,
      auth: options.auth,
      allowFallback: options.allowFallback,
      extensions,
      sourceTools: sourceRuntime?.sourceTools,
      appServerClient: options.codex?.appServerClient,
      createAppServerClient: options.codex?.createAppServerClient,
      model: options.codex?.model ?? options.model,
      reasoningEffort: options.codex?.reasoningEffort ?? options.reasoningEffort,
      permissionMode: options.codex?.permissionMode,
      approvalPolicy: options.codex?.approvalPolicy,
      approvalsReviewer: options.codex?.approvalsReviewer,
      sandbox: options.codex?.sandbox,
      appServerSubprocess: options.codex?.appServerSubprocess
    }),
    sourceRuntime
  };
}
function createHostRuntimeController(options) {
  const { runtime, sourceRuntime } = options;
  const hostTimeline = [];
  const hostTimelineEpoch = options.hostTimelineEpoch ?? `host:${runtime.sessionId}`;
  const hostTimelineSequencer = createTimelineSequencer({
    sessionId: runtime.sessionId,
    provider: "host",
    epoch: hostTimelineEpoch,
    now: options.now
  });
  let sendCount = 0;
  return {
    sessionId: runtime.sessionId,
    provider: runtime.provider,
    runtimeKind: runtime.runtimeKind,
    async preflight() {
      const capabilityReport = await runtime.preflight();
      return {
        sessionId: runtime.sessionId,
        provider: runtime.provider,
        runtimeKind: runtime.runtimeKind,
        state: runtime.getState(),
        capabilityReport,
        ...sourceRuntime ? { sourceRuntime } : {}
      };
    },
    async sendMessage(request) {
      await runtime.commands.sendMessage(request.message, {
        ...request.turnId ? { turnId: request.turnId } : {},
        ...request.model ? { model: request.model } : {},
        ...request.reasoningEffort ? { reasoningEffort: request.reasoningEffort } : {},
        ...request.permissionMode ? { permissionMode: request.permissionMode } : {},
        ...request.commandOrigin ? { commandOrigin: request.commandOrigin } : {}
      });
      sendCount += 1;
      return { ok: true, commandId: `send:${sendCount}` };
    },
    async abort(reason) {
      await runtime.commands.abort(reason);
      return { ok: true, commandId: "abort" };
    },
    async respondToPermission(request) {
      await runtime.commands.respondToPermission(request.requestId, request.allowed, request.remember);
      return { ok: true, commandId: `permission:${request.requestId}` };
    },
    invokeSessionTool(request) {
      const bridge = options.sessionTools ?? {};
      return invokeSessionTool({
        sessionId: runtime.sessionId,
        toolName: request.toolName,
        request: request.request,
        bridge,
        policy: options.hostToolPolicy,
        commandOrigin: request.commandOrigin,
        appendTimeline(item) {
          const envelope = hostTimelineSequencer.append(item);
          hostTimeline.push(envelope);
          return envelope;
        }
      });
    },
    async fetchTimeline(request = {}) {
      if (request.cursor?.epoch === hostTimelineEpoch) {
        return fetchTimeline(hostTimeline, request);
      }
      return runtime.fetchTimeline(request);
    },
    subscribe(onEvent, onError, onClose) {
      runtime.events.connect(onEvent, onError, onClose);
      return () => runtime.events.disconnect();
    },
    async dispose() {
      await runtime.commands.dispose();
      return { ok: true, commandId: "dispose" };
    }
  };
}
function mergeExtensions(base, policy, sourceRuntime) {
  return {
    ...base,
    ...policy ? { policy } : {},
    sources: sourceRuntime?.extensions.sources ?? base?.sources
  };
}

export {
  createPrivilegedExecutionBroker,
  createToolOutputPolicy,
  createSourceAuthoringPlan,
  expandWebhookTemplate,
  createMessagingAccessPolicy,
  createInMemoryAuditStore,
  createInMemoryArtifactStore,
  createInMemoryNotificationHost,
  createMessagingBindingStore,
  scrubLocalMcpEnvironment,
  createConfigRecoveryReceipt,
  createResourceBundleSnapshot,
  createConfigWatchEvent,
  createToolRegistryVersion,
  validateStatusConfig,
  createInMemoryHostUtilityToolRegistry,
  createSecondaryLlmCallPolicy,
  createInMemorySessionToolBridge,
  createConfigWatcherManager,
  createHostAgentRuntime,
  createHostRuntimeController
};
