// src/utils/storage/memory.ts
function memoryAdapter() {
  const store = /* @__PURE__ */ new Map();
  return {
    async open() {
    },
    async get(key) {
      return store.get(key);
    },
    async set(key, value) {
      store.set(key, value);
    },
    async delete(key) {
      store.delete(key);
    },
    async *iterate(prefix) {
      for (const [k, v] of store) if (k.startsWith(prefix)) yield [k, v];
    },
    async close() {
      store.clear();
    }
  };
}

// src/utils/storage/local-storage.ts
function localStorageAdapter(prefix = "dddk:") {
  const fullKey = (k) => prefix + k;
  return {
    async open() {
      if (typeof localStorage === "undefined") {
        throw new Error("localStorageAdapter: localStorage is unavailable in this runtime");
      }
    },
    async get(key) {
      const raw = localStorage.getItem(fullKey(key));
      if (raw === null) return void 0;
      try {
        return JSON.parse(raw);
      } catch {
        return raw;
      }
    },
    async set(key, value) {
      localStorage.setItem(fullKey(key), JSON.stringify(value));
    },
    async delete(key) {
      localStorage.removeItem(fullKey(key));
    },
    async *iterate(p) {
      const full = prefix + p;
      for (let i = 0; i < localStorage.length; i++) {
        const k = localStorage.key(i);
        if (!k || !k.startsWith(full)) continue;
        const raw = localStorage.getItem(k);
        if (raw === null) continue;
        let val;
        try {
          val = JSON.parse(raw);
        } catch {
          val = raw;
        }
        yield [k.slice(prefix.length), val];
      }
    },
    async close() {
    }
  };
}

// src/utils/storage/indexeddb.ts
var STORE = "kv";
function promisify(req) {
  return new Promise((resolve, reject) => {
    req.onsuccess = () => resolve(req.result);
    req.onerror = () => reject(req.error);
  });
}
function indexedDBAdapter(dbName = "dddk-toolbox") {
  let db;
  return {
    async open() {
      if (typeof indexedDB === "undefined") {
        throw new Error("indexedDBAdapter: IndexedDB unavailable; falling back recommended for SSR / Node");
      }
      db = await new Promise((resolve, reject) => {
        const req = indexedDB.open(dbName, 1);
        req.onupgradeneeded = () => {
          const d = req.result;
          if (!d.objectStoreNames.contains(STORE)) d.createObjectStore(STORE);
        };
        req.onsuccess = () => resolve(req.result);
        req.onerror = () => reject(req.error);
      });
    },
    async get(key) {
      if (!db) throw new Error("indexedDBAdapter: not opened");
      const tx = db.transaction(STORE, "readonly");
      return await promisify(tx.objectStore(STORE).get(key));
    },
    async set(key, value) {
      if (!db) throw new Error("indexedDBAdapter: not opened");
      const tx = db.transaction(STORE, "readwrite");
      await promisify(tx.objectStore(STORE).put(value, key));
    },
    async delete(key) {
      if (!db) throw new Error("indexedDBAdapter: not opened");
      const tx = db.transaction(STORE, "readwrite");
      await promisify(tx.objectStore(STORE).delete(key));
    },
    async *iterate(prefix) {
      if (!db) throw new Error("indexedDBAdapter: not opened");
      const tx = db.transaction(STORE, "readonly");
      const store = tx.objectStore(STORE);
      const range = IDBKeyRange.bound(prefix, prefix + "\uFFFF");
      const cursorReq = store.openCursor(range);
      while (true) {
        const cur = await new Promise((resolve, reject) => {
          cursorReq.onsuccess = () => resolve(cursorReq.result);
          cursorReq.onerror = () => reject(cursorReq.error);
        });
        if (!cur) break;
        yield [String(cur.key), cur.value];
        cur.continue();
      }
    },
    async close() {
      db?.close();
      db = void 0;
    }
  };
}

// src/utils/storage/index.ts
function resolveStorage(kind) {
  if (!kind || kind === "memory") return memoryAdapter();
  if (kind === "localstorage") return localStorageAdapter();
  if (kind === "indexeddb") {
    if (typeof indexedDB === "undefined") return memoryAdapter();
    return indexedDBAdapter();
  }
  return kind;
}

// src/utils/text/sampling.ts
function gammaSample(shape) {
  if (shape < 1) return gammaSample(shape + 1) * Math.pow(Math.random(), 1 / shape);
  const d = shape - 1 / 3;
  const c = 1 / Math.sqrt(9 * d);
  while (true) {
    let x;
    let v;
    do {
      const u1 = Math.random() || 1e-12;
      const u2 = Math.random() || 1e-12;
      x = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
      v = 1 + c * x;
    } while (v <= 0);
    v = v * v * v;
    const u = Math.random();
    if (u < 1 - 0.0331 * x * x * x * x) return d * v;
    if (Math.log(u) < 0.5 * x * x + d * (1 - v + Math.log(v))) return d * v;
  }
}
function betaSample(alpha, beta) {
  const x = gammaSample(alpha);
  const y = gammaSample(beta);
  return x / (x + y);
}

// src/utils/sdk-i18n.ts
var STRINGS = {
  en: {
    "agent.thinking": "Thinking\u2026",
    "agent.running": "Agent running\u2026",
    "agent.processing": "Working\u2026",
    "agent.loading": "Loading the page\u2026",
    "agent.done": "\u2713 Done",
    "agent.press_space_close": "press space to close",
    "agent.press_space_continue": "space \u2192 next \xB7 double space \u2192 exit",
    "agent.tap_to_continue": "tap \u2192 next \xB7 double-tap \u2192 exit",
    "agent.space_continue_reject": "space \u2192 next \xB7 double space \u2192 exit",
    "agent.tap_to_dismiss": "tap to dismiss",
    "agent.stop_close": "Agent stopped \u2014 say something new when you're ready",
    "agent.stop_esc": "Esc received \u2014 agent stopped",
    "agent.stop_reject": "Double-tap reject received \u2014 agent stopped",
    // Confirmation copy for destructive / requireConfirmation tool calls.
    // `{target}` / `{path}` / `{action}` placeholders interpolated at call time.
    "agent.confirm.suffix": "\u2014 press space to confirm",
    "agent.confirm.navigate.with_path": "Take you to {path}",
    "agent.confirm.navigate.no_path": "Switch page",
    "agent.confirm.click.with_target": "Click {target}",
    "agent.confirm.click.no_target": "Click",
    "agent.confirm.fill_input.with_target": "Fill {target}",
    "agent.confirm.fill_input.no_target": "Fill field",
    "agent.confirm.delete.with_target": "Delete {target}",
    "agent.confirm.delete.no_target": "Delete",
    "agent.confirm.generic.with_target": "Run {action} \u2192 {target}",
    "agent.confirm.generic.no_target": "Run {action}",
    "palette.theme.light": "Theme: light",
    "palette.theme.dark": "Theme: dark",
    "palette.theme.system": "Theme: follow system",
    "palette.language.current": "\u2713 Active",
    "palette.onboarding.replay": "Replay tour",
    "form.required": "This field is required",
    "form.submit": "Submit",
    "form.assist.fill": "\u2726 AI fill",
    "proactive.yes": "Yes",
    "proactive.no": "No",
    "fallback.empty": "No data",
    "fallback.error": "Error",
    "palette.placeholder": "Search commands or page\u2026",
    "palette.footer.navigate": "to navigate",
    "palette.footer.select": "to select",
    "palette.footer.close": "to close",
    "palette.footer.back": "to go back",
    "palette.section.settings": "Settings",
    "palette.section.go_to": "Go to",
    "palette.section.ai": "AI",
    "palette.section.commands": "Commands",
    "palette.section.docs": "Docs"
  },
  "zh-TW": {
    "agent.thinking": "\u601D\u8003\u4E2D\u2026",
    "agent.running": "Agent \u57F7\u884C\u4E2D\u2026",
    "agent.processing": "\u8655\u7406\u4E2D\u2026",
    "agent.loading": "\u9801\u9762\u8F09\u5165\u4E2D\u2026",
    "agent.done": "\u2713 \u57F7\u884C\u5B8C\u7562",
    "agent.press_space_close": "\u6309 space \u95DC\u9589",
    "agent.press_space_continue": "space \u4E0B\u4E00\u6B65 \uFF5C \u5169\u4E0B space \u76F4\u63A5\u7D50\u675F",
    "agent.tap_to_continue": "\u9EDE\u4E00\u4E0B\u4E0B\u4E00\u6B65 \uFF5C \u5169\u4E0B\u76F4\u63A5\u7D50\u675F",
    "agent.space_continue_reject": "space \u4E0B\u4E00\u6B65 \uFF5C \u5169\u4E0B space \u76F4\u63A5\u7D50\u675F",
    "agent.tap_to_dismiss": "\u9EDE\u4E00\u4E0B\u95DC\u9589",
    "agent.stop_close": "Agent \u5DF2\u505C\u4E0B\uFF0C\u60F3\u5230\u65B0\u7684\u5C31\u76F4\u63A5\u6253\u6216\u6309\u4F4F space",
    "agent.stop_esc": "\u6536\u5230 esc\uFF0Cagent \u5DF2\u505C\u4E0B",
    "agent.stop_reject": "\u6536\u5230\u96D9\u64CA space \u62D2\u7D55\uFF0Cagent \u5DF2\u505C\u4E0B",
    "agent.confirm.suffix": "\u2014 \u6309 space \u78BA\u8A8D",
    "agent.confirm.navigate.with_path": "\u5E36\u4F60\u5230 {path}",
    "agent.confirm.navigate.no_path": "\u5207\u63DB\u9801\u9762",
    "agent.confirm.click.with_target": "\u9EDE\u64CA {target}",
    "agent.confirm.click.no_target": "\u9EDE\u64CA",
    "agent.confirm.fill_input.with_target": "\u586B\u5BEB {target}",
    "agent.confirm.fill_input.no_target": "\u586B\u5BEB\u6B04\u4F4D",
    "agent.confirm.delete.with_target": "\u522A\u9664 {target}",
    "agent.confirm.delete.no_target": "\u522A\u9664",
    "agent.confirm.generic.with_target": "\u57F7\u884C {action} \u2192 {target}",
    "agent.confirm.generic.no_target": "\u57F7\u884C {action}",
    "palette.theme.light": "\u4E3B\u984C:\u4EAE\u8272",
    "palette.theme.dark": "\u4E3B\u984C:\u6697\u8272",
    "palette.theme.system": "\u4E3B\u984C:\u8DDF\u96A8\u7CFB\u7D71",
    "palette.language.current": "\u2713 \u76EE\u524D",
    "palette.onboarding.replay": "\u91CD\u770B\u5C0E\u89BD",
    "form.required": "\u6B64\u6B04\u4F4D\u5FC5\u586B",
    "form.submit": "\u5132\u5B58",
    "form.assist.fill": "\u2726 AI \u586B\u5BEB",
    "proactive.yes": "\u662F",
    "proactive.no": "\u5426",
    "fallback.empty": "\u7121\u8CC7\u6599",
    "fallback.error": "\u932F\u8AA4",
    "palette.placeholder": "\u641C\u5C0B\u6307\u4EE4\u6216\u9801\u9762\u2026",
    "palette.footer.navigate": "\u4E0A\u4E0B\u79FB\u52D5",
    "palette.footer.select": "\u9078\u53D6",
    "palette.footer.close": "\u95DC\u9589",
    "palette.footer.back": "\u4E0A\u4E00\u9801",
    "palette.section.settings": "\u8A2D\u5B9A",
    "palette.section.go_to": "\u524D\u5F80",
    "palette.section.ai": "AI",
    "palette.section.commands": "\u6307\u4EE4",
    "palette.section.docs": "\u6587\u4EF6"
  }
};
function sdkString(locale, key, vars) {
  const dict = STRINGS[locale ?? "en"];
  let s = dict?.[key] ?? STRINGS.en[key];
  if (vars) {
    for (const [k, v] of Object.entries(vars)) {
      s = s.replaceAll(`{${k}}`, String(v));
    }
  }
  return s;
}

// src/modules/proactive/render-piece.ts
function createPieceRender(opts) {
  const keys = { yes: "Space", no: "Space:double", dismiss: "Escape", ...opts.keys ?? {} };
  return async (_prompt, surface, ctx) => {
    let piece;
    if (surface.pieces) {
      piece = surface.pieces;
    } else {
      const text = typeof surface.text === "function" ? surface.text(ctx ?? { now: Date.now() }) : surface.text;
      piece = {
        root: {
          kind: "Card",
          children: [
            { kind: "Text", text },
            {
              kind: "Stack",
              direction: "horizontal",
              gap: 8,
              children: [
                { kind: "Button", text: surface.yesLabel ?? "Yes", action: "yes", shortcut: keys.yes },
                { kind: "Button", text: surface.noLabel ?? "No", action: "no", shortcut: keys.no, variant: "secondary" },
                ...surface.dismissable !== false ? [{ kind: "Button", text: "\xD7", action: "dismiss", shortcut: keys.dismiss, variant: "secondary" }] : []
              ]
            }
          ]
        }
      };
    }
    try {
      const result = await opts.mount(piece, {
        placement: surface.placement ?? "inline",
        timeoutMs: surface.autoTimeoutMs
      });
      if (result.action === "yes" || result.action === "no" || result.action === "dismiss") return result.action;
      return "yes";
    } catch {
      return "dismiss";
    }
  };
}

// src/modules/proactive/index.ts
var Proactive = class {
  prompts = /* @__PURE__ */ new Map();
  state = /* @__PURE__ */ new Map();
  storage;
  analytics;
  memory;
  opts;
  opened = false;
  sessionShown = 0;
  sessionDismisses = 0;
  lastShownAt = 0;
  paused = false;
  constructor(opts = {}) {
    this.storage = resolveStorage(opts.storage ?? "indexeddb");
    this.analytics = opts.analytics;
    this.memory = opts.memory;
    this.opts = opts;
  }
  async init() {
    await this.storage.open("dddk-proactive");
    this.opened = true;
    const snap = await this.storage.get("proactive:state");
    if (snap) for (const [id, st] of Object.entries(snap)) this.state.set(id, st);
  }
  register(p) {
    this.prompts.set(p.id, p);
    if (!this.state.has(p.id)) {
      this.state.set(p.id, {
        category: p.category,
        lastShownAt: 0,
        dismissedInSession: false,
        variantStats: {}
      });
    }
  }
  unregister(id) {
    this.prompts.delete(id);
  }
  pause() {
    this.paused = true;
  }
  resume() {
    this.paused = false;
  }
  /** Evaluate all prompts; fire the highest-priority eligible one. Returns the prompt id if fired. */
  async tick(ctx = {}) {
    if (this.paused) return;
    const fatigue = this.opts.fatigue ?? {};
    if (this.sessionShown >= (fatigue.maxPerSession ?? 3)) return;
    if (Date.now() - this.lastShownAt < (fatigue.cooldownMs ?? 6e4)) return;
    if (this.sessionDismisses >= (fatigue.consecutiveDismissCap ?? 3)) return;
    const paletteOpen = this.opts.isPaletteOpen?.() ?? false;
    const mode = this.opts.whenPaletteOpen ?? "suppress";
    if (paletteOpen && mode === "suppress") return;
    const full = { now: Date.now(), memory: this.memory, ...ctx };
    const eligible = [];
    for (const p2 of this.prompts.values()) {
      const st = this.state.get(p2.id);
      if (!st) continue;
      if (st.dismissedInSession && fatigue.dismissPenalty?.sameId === "session") continue;
      if (fatigue.dismissPenalty?.sameCategory && p2.category) {
        const recentSame = [...this.state.values()].some(
          (s) => s.category === p2.category && Date.now() - s.lastShownAt < (fatigue.dismissPenalty.sameCategory ?? 0)
        );
        if (recentSame) continue;
      }
      const results = await Promise.all(p2.triggers.map((t) => t.condition(full)));
      const ok = (p2.triggerLogic ?? "AND") === "OR" ? results.some(Boolean) : results.every(Boolean);
      if (ok) eligible.push(p2);
    }
    if (eligible.length === 0) return;
    eligible.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
    const p = eligible[0];
    await this.fire(p, full);
    return p.id;
  }
  async ask(opts) {
    if (!this.opts.render) return "dismiss";
    const oneOff = {
      id: `_oneoff_${Math.random().toString(36).slice(2, 8)}`,
      triggers: [],
      surface: {
        text: opts.text,
        yesLabel: opts.yesLabel ?? sdkString(this.opts.locale, "proactive.yes"),
        noLabel: opts.noLabel ?? sdkString(this.opts.locale, "proactive.no"),
        dismissable: true
      }
    };
    return await this.opts.render(oneOff, oneOff.surface);
  }
  explain(id) {
    const p = this.prompts.get(id);
    const st = this.state.get(id);
    if (!p || !st) return void 0;
    return {
      promptId: id,
      lastShownAt: st.lastShownAt,
      dismissedInSession: st.dismissedInSession,
      variantStats: st.variantStats,
      fatigue: {
        sessionShown: this.sessionShown,
        sessionDismisses: this.sessionDismisses,
        timeSinceLastShown: Date.now() - this.lastShownAt
      }
    };
  }
  selectVariant(p) {
    if (!p.variants || p.variants.length === 0) {
      return { variantId: "_default", surface: p.surface };
    }
    const st = this.state.get(p.id);
    const method = p.variantSelector ?? "thompson_sampling";
    if (method === "random") {
      const v = p.variants[Math.floor(Math.random() * p.variants.length)];
      return { variantId: v.id, surface: v.surface };
    }
    if (method === "epsilon_greedy") {
      if (Math.random() < 0.1) {
        const v = p.variants[Math.floor(Math.random() * p.variants.length)];
        return { variantId: v.id, surface: v.surface };
      }
      let best2 = p.variants[0];
      let bestRate = -1;
      for (const v of p.variants) {
        const s = st.variantStats[v.id];
        const total = s ? s.yes + s.no : 0;
        const rate = total > 0 && s ? s.yes / total : 0;
        if (rate > bestRate) {
          bestRate = rate;
          best2 = v;
        }
      }
      return { variantId: best2.id, surface: best2.surface };
    }
    let best = p.variants[0];
    let bestSample = -Infinity;
    for (const v of p.variants) {
      const s = st.variantStats[v.id] ?? { yes: 0, no: 0, dismiss: 0 };
      const sample = betaSample(s.yes + 1, s.no + 1);
      if (sample > bestSample) {
        bestSample = sample;
        best = v;
      }
    }
    return { variantId: best.id, surface: best.surface };
  }
  async fire(p, ctx) {
    if (!this.opts.render) return;
    const { variantId, surface } = this.selectVariant(p);
    const st = this.state.get(p.id);
    st.lastShownAt = Date.now();
    this.lastShownAt = st.lastShownAt;
    this.sessionShown++;
    this.analytics?.track("proactive.shown", { promptId: p.id, variantId });
    const response = await this.opts.render(p, surface);
    if (response === "dismiss") {
      st.dismissedInSession = true;
      this.sessionDismisses++;
    } else {
      this.sessionDismisses = 0;
    }
    if (!st.variantStats[variantId]) st.variantStats[variantId] = { yes: 0, no: 0, dismiss: 0 };
    st.variantStats[variantId][response]++;
    this.analytics?.track("proactive.response", { promptId: p.id, variantId, response });
    if (this.opened) {
      const dump = {};
      for (const [id, s] of this.state) dump[id] = s;
      await this.storage.set("proactive:state", dump);
    }
    if (p.onResponse) await p.onResponse(response, ctx);
  }
  async dispose() {
    if (this.opened) await this.storage.close();
    this.opened = false;
  }
};
var triggers = {
  dwell(opts) {
    return {
      id: "dwell",
      condition: (ctx) => (ctx.dwellMs ?? 0) >= opts.ms
    };
  },
  idleTime(opts) {
    return {
      id: "idle",
      condition: (ctx) => (ctx.dwellMs ?? 0) >= opts.ms
    };
  },
  scrollDepth(opts) {
    return {
      id: "scroll_depth",
      condition: (ctx) => (ctx.scrollDepth ?? 0) >= opts.percent
    };
  },
  pageMatch(opts) {
    return {
      id: "page_match",
      condition: (ctx) => {
        if (!ctx.page) return false;
        return typeof opts.path === "string" ? ctx.page.includes(opts.path) : opts.path.test(ctx.page);
      }
    };
  },
  exitIntent() {
    return {
      id: "exit_intent",
      condition: (ctx) => Boolean(ctx.customMeta?.exitIntent)
    };
  },
  schedule(opts) {
    let n = 0;
    return {
      id: "schedule",
      condition: () => ++n % opts.everyN === 0
    };
  }
};
var builtin = { triggers };
function createProactive(opts = {}) {
  return new Proactive(opts);
}
export {
  Proactive,
  builtin,
  createPieceRender,
  createProactive,
  triggers
};
