"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 _chunkD4EVQM6Icjs = require('./chunk-D4EVQM6I.cjs');







var _chunk4LFBCGLOcjs = require('./chunk-4LFBCGLO.cjs');






var _chunkJZ6L75WTcjs = require('./chunk-JZ6L75WT.cjs');
require('./chunk-464Y2O3H.cjs');

// ../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: _nullishCoalesce(options.mode, () => ( "ask")),
    alwaysAllow: [..._nullishCoalesce(options.alwaysAllow, () => ( []))],
    approvals: [..._nullishCoalesce(options.approvals, () => ( []))],
    layers: [..._nullishCoalesce(options.layers, () => ( []))]
  };
}
function createSourcePolicyLayer(options) {
  return {
    id: _nullishCoalesce(options.id, () => ( `source:${options.sourceSlug}`)),
    rules: {
      ...options.rules,
      allowedMcpPatterns: _optionalChain([options, 'access', _ => _.rules, 'access', _2 => _2.allowedMcpPatterns, 'optionalAccess', _3 => _3.map, 'call', _4 => _4(
        (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: (_nullishCoalesce(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 = _nullishCoalesce(options.now, () => ( Date.now));
  return {
    remember(approval) {
      approvals.set(approval.id, {
        ...approval,
        createdAt: _nullishCoalesce(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: _optionalChain([hint, 'optionalAccess', _5 => _5.reason]),
        matchedRule: _optionalChain([hint, 'optionalAccess', _6 => _6.match]),
        ..._optionalChain([hint, 'optionalAccess', _7 => _7.tryInstead, 'optionalAccess', _8 => _8.length]) ? { tryInstead: hint.tryInstead } : {},
        ..._optionalChain([hint, 'optionalAccess', _9 => _9.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(_nullishCoalesce(_optionalChain([request, 'access', _10 => _10.input, 'optionalAccess', _11 => _11.command]), () => ( "")));
    const baseCommand = _nullishCoalesce(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(_nullishCoalesce(_nullishCoalesce(_optionalChain([request, 'access', _12 => _12.input, 'optionalAccess', _13 => _13.file_path]), () => ( _optionalChain([request, 'access', _14 => _14.input, 'optionalAccess', _15 => _15.path]))), () => ( "")))
    };
  }
  if (request.toolName === "MCP") {
    return {
      kind: "mcp",
      name: String(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([request, 'access', _16 => _16.input, 'optionalAccess', _17 => _17.name]), () => ( _optionalChain([request, 'access', _18 => _18.input, 'optionalAccess', _19 => _19.toolName]))), () => ( _optionalChain([request, 'access', _20 => _20.input, 'optionalAccess', _21 => _21.tool]))), () => ( "")))
    };
  }
  if (request.toolName === "API") {
    const url = _optionalChain([request, 'access', _22 => _22.input, 'optionalAccess', _23 => _23.url]) ? String(request.input.url) : void 0;
    return {
      kind: "api",
      method: String(_nullishCoalesce(_optionalChain([request, 'access', _24 => _24.input, 'optionalAccess', _25 => _25.method]), () => ( "GET"))).toUpperCase(),
      path: pathFromUrl(_nullishCoalesce(url, () => ( String(_nullishCoalesce(_optionalChain([request, 'access', _26 => _26.input, 'optionalAccess', _27 => _27.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 = _optionalChain([layer, 'access', _28 => _28.rules, 'access', _29 => _29.allowedWritePaths, 'optionalAccess', _30 => _30.find, 'call', _31 => _31((rule) => globMatches(rule, intent.path))]);
    return pattern ? { layerId: layer.id, ruleType: "write-path", pattern } : void 0;
  }
  if (intent.kind === "mcp") {
    const pattern = _optionalChain([layer, 'access', _32 => _32.rules, 'access', _33 => _33.allowedMcpPatterns, 'optionalAccess', _34 => _34.find, 'call', _35 => _35((rule) => regexMatches(rule, intent.name))]);
    return pattern ? { layerId: layer.id, ruleType: "mcp-pattern", pattern } : void 0;
  }
  if (intent.kind === "api") {
    const rule = _optionalChain([layer, 'access', _36 => _36.rules, 'access', _37 => _37.allowedApiEndpoints, 'optionalAccess', _38 => _38.find, 'call', _39 => _39((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 = _optionalChain([layer, 'access', _40 => _40.rules, 'access', _41 => _41.allowedBashPatterns, 'optionalAccess', _42 => _42.find, 'call', _43 => _43((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 = _optionalChain([layer, 'access', _44 => _44.rules, 'access', _45 => _45.blockedCommandHints, 'optionalAccess', _46 => _46.find, 'call', _47 => _47((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
        },
        ..._optionalChain([hint, 'access', _48 => _48.tryInstead, 'optionalAccess', _49 => _49.length]) ? { tryInstead: hint.tryInstead } : {},
        ...hint.context ? { context: hint.context } : {}
      };
    }
  }
  return void 0;
}
function pathFromUrl(value) {
  try {
    return new URL(value).pathname;
  } catch (e) {
    return value.startsWith("/") ? value : `/${value}`;
  }
}
function regexMatches(pattern, value) {
  try {
    return new RegExp(pattern).test(value);
  } catch (e2) {
    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 (e3) {
    return false;
  }
}
function asRecord(value) {
  return value && typeof value === "object" ? value : {};
}










































exports.RPC_CHANNELS = _chunkD4EVQM6Icjs.RPC_CHANNELS; exports.THINKING_LEVELS = _chunkD4EVQM6Icjs.THINKING_LEVELS; exports.THINKING_LEVEL_IDS = _chunkD4EVQM6Icjs.THINKING_LEVEL_IDS; exports.THINKING_TO_EFFORT = _chunkD4EVQM6Icjs.THINKING_TO_EFFORT; exports.appendTimelineItem = _chunkJZ6L75WTcjs.appendTimelineItem; exports.createInMemoryApprovalStore = createInMemoryApprovalStore; exports.createPermissionPolicy = createPermissionPolicy; exports.createPermissionPolicyFromConfig = createPermissionPolicyFromConfig; exports.createPolicyDecisionReceipt = createPolicyDecisionReceipt; exports.createRuntimeCapabilityReport = _chunk4LFBCGLOcjs.createRuntimeCapabilityReport; exports.createRuntimeExtensionContext = _chunk4LFBCGLOcjs.createRuntimeExtensionContext; exports.createSourcePolicyLayer = createSourcePolicyLayer; exports.createTimelineCursor = _chunkJZ6L75WTcjs.createTimelineCursor; exports.createTimelineSequencer = _chunkJZ6L75WTcjs.createTimelineSequencer; exports.debug = _chunkD4EVQM6Icjs.debug; exports.evaluateToolPolicy = evaluateToolPolicy; exports.explainToolPolicy = explainToolPolicy; exports.fetchTimeline = _chunkJZ6L75WTcjs.fetchTimeline; exports.findMentionMatches = _chunkD4EVQM6Icjs.findMentionMatches; exports.generateMessageId = _chunkD4EVQM6Icjs.generateMessageId; exports.getThinkingLevelNameKey = _chunkD4EVQM6Icjs.getThinkingLevelNameKey; exports.getThinkingTokens = _chunkD4EVQM6Icjs.getThinkingTokens; exports.invokeSessionTool = _chunk4LFBCGLOcjs.invokeSessionTool; exports.isValidThinkingLevel = _chunkD4EVQM6Icjs.isValidThinkingLevel; exports.mergeTimeline = _chunkJZ6L75WTcjs.mergeTimeline; exports.messageToStored = _chunkD4EVQM6Icjs.messageToStored; exports.normalizePath = _chunkD4EVQM6Icjs.normalizePath; exports.normalizeThinkingLevel = _chunkD4EVQM6Icjs.normalizeThinkingLevel; exports.parseMentions = _chunkD4EVQM6Icjs.parseMentions; exports.pathStartsWith = _chunkD4EVQM6Icjs.pathStartsWith; exports.reduceRuntimeState = _chunk4LFBCGLOcjs.reduceRuntimeState; exports.resolveFileMentions = _chunkD4EVQM6Icjs.resolveFileMentions; exports.resolvePathMentions = _chunkD4EVQM6Icjs.resolvePathMentions; exports.resolveSkillMentions = _chunkD4EVQM6Icjs.resolveSkillMentions; exports.resolveSourceMentions = _chunkD4EVQM6Icjs.resolveSourceMentions; exports.sanitizeProviderSourceTools = _chunk4LFBCGLOcjs.sanitizeProviderSourceTools; exports.selectRuntimeCandidate = _chunk4LFBCGLOcjs.selectRuntimeCandidate; exports.storedToMessage = _chunkD4EVQM6Icjs.storedToMessage; exports.stripAllMentions = _chunkD4EVQM6Icjs.stripAllMentions; exports.stripPathPrefix = _chunkD4EVQM6Icjs.stripPathPrefix; exports.validatePolicyConfig = validatePolicyConfig;
