import {
  RPC_CHANNELS,
  THINKING_LEVELS,
  THINKING_LEVEL_IDS,
  THINKING_TO_EFFORT,
  debug,
  findMentionMatches,
  generateMessageId,
  getThinkingLevelNameKey,
  getThinkingTokens,
  isValidThinkingLevel,
  messageToStored,
  normalizePath,
  normalizeThinkingLevel,
  parseMentions,
  pathStartsWith,
  resolveFileMentions,
  resolvePathMentions,
  resolveSkillMentions,
  resolveSourceMentions,
  storedToMessage,
  stripAllMentions,
  stripPathPrefix
} from "./chunk-C2HDOLKS.js";
import {
  createRuntimeCapabilityReport,
  createRuntimeExtensionContext,
  invokeSessionTool,
  reduceRuntimeState,
  sanitizeProviderSourceTools,
  selectRuntimeCandidate
} from "./chunk-5N6QO6NC.js";
import {
  appendTimelineItem,
  createTimelineCursor,
  createTimelineSequencer,
  fetchTimeline,
  mergeTimeline
} from "./chunk-VK2Y4OK3.js";
import "./chunk-R5U7XKVJ.js";

// ../packages/policy/dist/index.js
var FILE_WRITE_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "MultiEdit", "NotebookEdit"]);
var DANGEROUS_BASH_COMMANDS = /* @__PURE__ */ new Set([
  "rm",
  "rmdir",
  "sudo",
  "su",
  "chmod",
  "chown",
  "chgrp",
  "mv",
  "cp",
  "dd",
  "mkfs",
  "fdisk",
  "parted",
  "kill",
  "killall",
  "pkill",
  "reboot",
  "shutdown",
  "halt",
  "poweroff",
  "curl",
  "wget",
  "ssh",
  "scp",
  "rsync"
]);
var READ_ONLY_BASH_PATTERNS = [
  /^git\s+status(\s|$)/,
  /^git\s+diff(\s|$)/,
  /^git\s+log(\s|$)/,
  /^ls(\s|$)/,
  /^pwd(\s|$)/,
  /^cat\s+/,
  /^sed\s+-n\s+/,
  /^rg(\s|$)/,
  /^find\s+/
];
function createPermissionPolicy(options = {}) {
  return {
    mode: options.mode ?? "ask",
    alwaysAllow: [...options.alwaysAllow ?? []],
    approvals: [...options.approvals ?? []],
    layers: [...options.layers ?? []]
  };
}
function createSourcePolicyLayer(options) {
  return {
    id: options.id ?? `source:${options.sourceSlug}`,
    rules: {
      ...options.rules,
      allowedMcpPatterns: options.rules.allowedMcpPatterns?.map(
        (pattern) => scopeMcpPatternToSource(options.sourceSlug, pattern)
      )
    }
  };
}
function validatePolicyConfig(input) {
  const errors = [];
  const warnings = [];
  const config = asRecord(input);
  const mode = config.mode;
  if (mode !== void 0 && !isPermissionMode(mode)) {
    errors.push({
      path: "mode",
      message: `Invalid permission mode: ${String(mode)}`,
      suggestion: "Use one of: safe, ask, allow-all"
    });
  }
  if (config.layers !== void 0 && !Array.isArray(config.layers)) {
    errors.push({
      path: "layers",
      message: "Expected layers to be an array"
    });
  }
  if (Array.isArray(config.layers)) {
    config.layers.forEach((layerValue, layerIndex) => {
      const layer = asRecord(layerValue);
      const basePath = `layers[${layerIndex}]`;
      if (typeof layer.id !== "string" || layer.id.length === 0) {
        errors.push({
          path: `${basePath}.id`,
          message: "Layer id is required"
        });
      }
      validateRuleSet(layer.rules, `${basePath}.rules`, errors);
    });
  }
  return {
    valid: errors.length === 0,
    errors,
    warnings
  };
}
function createPermissionPolicyFromConfig(input) {
  const validation = validatePolicyConfig(input);
  if (!validation.valid) return { validation };
  const config = asRecord(input);
  return {
    validation,
    policy: createPermissionPolicy({
      mode: config.mode,
      alwaysAllow: config.alwaysAllow,
      approvals: config.approvals,
      layers: (config.layers ?? []).map(
        (layer) => layer.sourceSlug ? createSourcePolicyLayer({
          id: layer.id,
          sourceSlug: layer.sourceSlug,
          rules: layer.rules
        }) : {
          id: layer.id,
          rules: layer.rules,
          scope: layer.scope
        }
      )
    })
  };
}
function evaluateToolPolicy(policy, request) {
  const explanation = explainToolPolicy(policy, request);
  if (explanation.decision === "allow") return { decision: "allow" };
  return {
    decision: explanation.decision,
    reason: explanation.reason
  };
}
function createPolicyDecisionReceipt(options) {
  const explanation = explainToolPolicy(options.policy, options.request);
  const decision = explanation.decision === "allow" ? { decision: "allow" } : { decision: explanation.decision, reason: explanation.reason };
  return {
    requestId: options.requestId,
    decision,
    explain: explanation,
    intent: explanation.intent,
    ...explanation.matchedRule ? { matchedRule: explanation.matchedRule } : {},
    ...options.request.scope ? { scope: options.request.scope } : {},
    ...options.origin ? { origin: options.origin } : {},
    ...options.ttl !== void 0 ? { ttl: options.ttl } : {},
    ...explanation.hint ? { hint: explanation.hint } : {},
    ...options.timelineRefs ? { timelineRefs: options.timelineRefs } : {}
  };
}
function explainToolPolicy(policy, request) {
  const intent = normalizeToolIntent(request);
  if (matchesApproval(policy, request)) {
    return { decision: "allow", intent };
  }
  if (matchesAlwaysAllow(policy, request)) {
    return { decision: "allow", intent };
  }
  if (policy.mode === "allow-all") {
    return { decision: "allow", intent };
  }
  const layeredAllow = findLayeredAllow(policy, intent, request.scope);
  if (layeredAllow) {
    return {
      decision: "allow",
      intent,
      matchedRule: layeredAllow
    };
  }
  if (intent.kind === "file_write") {
    if (policy.mode === "ask") {
      return {
        decision: "ask",
        reason: `${intent.toolName} requires approval in ask mode`,
        intent
      };
    }
    return {
      decision: "deny",
      reason: `${intent.toolName} is blocked in safe mode`,
      intent
    };
  }
  if (intent.kind === "bash") {
    return evaluateBashPolicy(policy, intent);
  }
  if (intent.kind === "mcp" && policy.mode === "safe") {
    return {
      decision: "deny",
      reason: `MCP tool is blocked in safe mode: ${intent.name}`,
      intent
    };
  }
  if (intent.kind === "api" && policy.mode === "safe") {
    return {
      decision: "deny",
      reason: `API endpoint is blocked in safe mode: ${intent.method} ${intent.path}`,
      intent
    };
  }
  return { decision: "allow", intent };
}
function createInMemoryApprovalStore(options = {}) {
  const approvals = /* @__PURE__ */ new Map();
  const now = options.now ?? Date.now;
  return {
    remember(approval) {
      approvals.set(approval.id, {
        ...approval,
        createdAt: approval.createdAt ?? now()
      });
    },
    revoke(id) {
      approvals.delete(id);
    },
    snapshot() {
      const currentTime = now();
      return [...approvals.values()].filter((approval) => !approval.expiresAt || approval.expiresAt > currentTime);
    }
  };
}
function matchesApproval(policy, request) {
  const requestScope = scopeKey(request.scope);
  return policy.approvals.some((approval) => approval.toolName === request.toolName && scopeKey(approval.scope) === requestScope);
}
function matchesAlwaysAllow(policy, request) {
  const requestScope = scopeKey(request.scope);
  return policy.alwaysAllow.some((rule) => {
    if (rule.toolName !== request.toolName) return false;
    if (!rule.scope) return true;
    return scopeKey(rule.scope) === requestScope;
  });
}
function scopeKey(scope) {
  if (!scope) return "global";
  if (typeof scope === "string") return scope;
  switch (scope.type) {
    case "session":
      return `session:${scope.sessionId}`;
    case "workspace":
      return `workspace:${scope.workspaceId}`;
    case "source":
      return `source:${scope.sourceSlug}`;
    case "skill":
      return `skill:${scope.skillSlug}`;
    case "automation":
      return `automation:${scope.automationId}`;
    case "tool-call":
      return `tool-call:${scope.callId}`;
  }
}
function evaluateBashPolicy(policy, intent) {
  if (intent.kind !== "bash") {
    return { decision: "allow", intent };
  }
  if (policy.mode === "ask" && DANGEROUS_BASH_COMMANDS.has(intent.baseCommand)) {
    return {
      decision: "ask",
      reason: `${intent.baseCommand} requires approval in ask mode`,
      intent
    };
  }
  if (policy.mode === "safe") {
    const layeredAllow = findLayeredAllow(policy, intent);
    const readOnly = READ_ONLY_BASH_PATTERNS.some((pattern) => pattern.test(intent.command.trim()));
    if (!readOnly) {
      const hint = findBlockedCommandHint(policy, intent);
      return {
        decision: "deny",
        reason: `Bash command is blocked in safe mode: ${intent.baseCommand || "unknown command"}`,
        intent,
        hint: hint?.reason,
        matchedRule: hint?.match,
        ...hint?.tryInstead?.length ? { tryInstead: hint.tryInstead } : {},
        ...hint?.context ? { hintContext: hint.context } : {}
      };
    }
    if (layeredAllow) {
      return { decision: "allow", intent, matchedRule: layeredAllow };
    }
  }
  return { decision: "allow", intent };
}
function normalizeToolIntent(request) {
  if (request.toolIntent) return request.toolIntent;
  if (request.toolName === "Bash") {
    const command = String(request.input?.command ?? "");
    const baseCommand = command.trim().split(/\s+/)[0] ?? "";
    return { kind: "bash", command, baseCommand };
  }
  if (FILE_WRITE_TOOLS.has(request.toolName)) {
    return {
      kind: "file_write",
      toolName: request.toolName,
      path: String(request.input?.file_path ?? request.input?.path ?? "")
    };
  }
  if (request.toolName === "MCP") {
    return {
      kind: "mcp",
      name: String(request.input?.name ?? request.input?.toolName ?? request.input?.tool ?? "")
    };
  }
  if (request.toolName === "API") {
    const url = request.input?.url ? String(request.input.url) : void 0;
    return {
      kind: "api",
      method: String(request.input?.method ?? "GET").toUpperCase(),
      path: pathFromUrl(url ?? String(request.input?.path ?? "/")),
      url
    };
  }
  return { kind: "unknown", toolName: request.toolName };
}
function findLayeredAllow(policy, intent, scope) {
  for (const layer of policy.layers) {
    if (layer.scope && scopeKey(layer.scope) !== scopeKey(scope)) continue;
    const match = matchLayerRules(layer, intent);
    if (match) return match;
  }
  return void 0;
}
function matchLayerRules(layer, intent) {
  if (intent.kind === "file_write") {
    const pattern = layer.rules.allowedWritePaths?.find((rule) => globMatches(rule, intent.path));
    return pattern ? { layerId: layer.id, ruleType: "write-path", pattern } : void 0;
  }
  if (intent.kind === "mcp") {
    const pattern = layer.rules.allowedMcpPatterns?.find((rule) => regexMatches(rule, intent.name));
    return pattern ? { layerId: layer.id, ruleType: "mcp-pattern", pattern } : void 0;
  }
  if (intent.kind === "api") {
    const rule = layer.rules.allowedApiEndpoints?.find((candidate) => candidate.method.toUpperCase() === intent.method && globMatches(candidate.pattern, intent.path));
    return rule ? { layerId: layer.id, ruleType: "api-endpoint", pattern: `${rule.method.toUpperCase()} ${rule.pattern}` } : void 0;
  }
  if (intent.kind === "bash") {
    const pattern = layer.rules.allowedBashPatterns?.find((rule) => regexMatches(rule, intent.command));
    return pattern ? { layerId: layer.id, ruleType: "bash-pattern", pattern } : void 0;
  }
  return void 0;
}
function findBlockedCommandHint(policy, intent) {
  for (const layer of policy.layers) {
    const hint = layer.rules.blockedCommandHints?.find((rule) => {
      if (rule.command !== intent.baseCommand) return false;
      if (!rule.whenNotMatching) return true;
      return !regexMatches(rule.whenNotMatching, intent.command);
    });
    if (hint) {
      return {
        reason: hint.reason,
        match: {
          layerId: layer.id,
          ruleType: "blocked-command-hint",
          pattern: hint.command
        },
        ...hint.tryInstead?.length ? { tryInstead: hint.tryInstead } : {},
        ...hint.context ? { context: hint.context } : {}
      };
    }
  }
  return void 0;
}
function pathFromUrl(value) {
  try {
    return new URL(value).pathname;
  } catch {
    return value.startsWith("/") ? value : `/${value}`;
  }
}
function regexMatches(pattern, value) {
  try {
    return new RegExp(pattern).test(value);
  } catch {
    return pattern === value;
  }
}
function globMatches(pattern, value) {
  const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "__DOUBLE_STAR__").replace(/\*/g, "[^/]*").replace(/__DOUBLE_STAR__/g, ".*");
  return new RegExp(`^${escaped}$`).test(value);
}
function scopeMcpPatternToSource(sourceSlug, pattern) {
  if (pattern.includes("mcp__")) return pattern;
  return `^mcp__${escapeRegex(sourceSlug)}__.*${pattern}`;
}
function escapeRegex(value) {
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function validateRuleSet(rulesValue, path, errors) {
  if (rulesValue === void 0) {
    errors.push({
      path,
      message: "Layer rules are required"
    });
    return;
  }
  const rules = asRecord(rulesValue);
  validateRegexList(rules.allowedBashPatterns, `${path}.allowedBashPatterns`, errors);
  validateRegexList(rules.allowedMcpPatterns, `${path}.allowedMcpPatterns`, errors);
  validateApiEndpointRules(rules.allowedApiEndpoints, `${path}.allowedApiEndpoints`, errors);
}
function validateRegexList(value, path, errors) {
  if (value === void 0) return;
  if (!Array.isArray(value)) {
    errors.push({ path, message: "Expected an array of regular expression strings" });
    return;
  }
  value.forEach((pattern, index) => {
    if (typeof pattern !== "string") {
      errors.push({ path: `${path}[${index}]`, message: "Expected a regular expression string" });
      return;
    }
    if (!isValidRegex(pattern)) {
      errors.push({
        path: `${path}[${index}]`,
        message: `Invalid regular expression: ${pattern}`
      });
    }
  });
}
function validateApiEndpointRules(value, path, errors) {
  if (value === void 0) return;
  if (!Array.isArray(value)) {
    errors.push({ path, message: "Expected an array of API endpoint rules" });
    return;
  }
  value.forEach((ruleValue, index) => {
    const rule = asRecord(ruleValue);
    const method = rule.method;
    if (typeof method !== "string" || !HTTP_METHODS.has(method.toUpperCase())) {
      errors.push({
        path: `${path}[${index}].method`,
        message: `Invalid HTTP method: ${String(method)}`,
        suggestion: "Use one of: GET, POST, PUT, PATCH, DELETE"
      });
    }
    if (typeof rule.pattern !== "string") {
      errors.push({
        path: `${path}[${index}].pattern`,
        message: "API endpoint pattern is required"
      });
    }
  });
}
function isPermissionMode(value) {
  return value === "safe" || value === "ask" || value === "allow-all";
}
var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE"]);
function isValidRegex(pattern) {
  try {
    new RegExp(pattern);
    return true;
  } catch {
    return false;
  }
}
function asRecord(value) {
  return value && typeof value === "object" ? value : {};
}
export {
  RPC_CHANNELS,
  THINKING_LEVELS,
  THINKING_LEVEL_IDS,
  THINKING_TO_EFFORT,
  appendTimelineItem,
  createInMemoryApprovalStore,
  createPermissionPolicy,
  createPermissionPolicyFromConfig,
  createPolicyDecisionReceipt,
  createRuntimeCapabilityReport,
  createRuntimeExtensionContext,
  createSourcePolicyLayer,
  createTimelineCursor,
  createTimelineSequencer,
  debug,
  evaluateToolPolicy,
  explainToolPolicy,
  fetchTimeline,
  findMentionMatches,
  generateMessageId,
  getThinkingLevelNameKey,
  getThinkingTokens,
  invokeSessionTool,
  isValidThinkingLevel,
  mergeTimeline,
  messageToStored,
  normalizePath,
  normalizeThinkingLevel,
  parseMentions,
  pathStartsWith,
  reduceRuntimeState,
  resolveFileMentions,
  resolvePathMentions,
  resolveSkillMentions,
  resolveSourceMentions,
  sanitizeProviderSourceTools,
  selectRuntimeCandidate,
  storedToMessage,
  stripAllMentions,
  stripPathPrefix,
  validatePolicyConfig
};
