chromeflow 0.12.3 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/chromeflow.mjs +23 -3
  2. package/package.json +1 -1
@@ -24764,6 +24764,7 @@ var PROMOTE_AT_SUCCESS = 2;
24764
24764
  var DEMOTE_AT_FAILS = 1;
24765
24765
  var PRUNE_AT_FAILS = 2;
24766
24766
  var PROVISIONAL_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
24767
+ var MAX_PROVISIONAL_PER_ORIGIN = 20;
24767
24768
  var ATOM_KEYS = ["tool", "target", "selector", "recovered_via", "signal", "verification", "clear_first", "fragile", "reason"];
24768
24769
  function originKey(url) {
24769
24770
  if (!url) return void 0;
@@ -24972,9 +24973,28 @@ var FlowStore = class {
24972
24973
  for (const atom of buf) this.upsert(k, [atom], null);
24973
24974
  }
24974
24975
  this.lastAutosaved = { key: k, sig: signatureOf(buf) };
24976
+ this.capProvisional(k);
24975
24977
  this.pruneExpired();
24976
24978
  this.persist();
24977
24979
  }
24980
+ /**
24981
+ * Backstop against unbounded growth on high-cardinality pages. A search-results
24982
+ * or feed page produces a fresh per-instance selector on every action (a person's
24983
+ * name, a post id), so each autosave is a distinct signature that can never dedup,
24984
+ * never recur, and never promote — it just piles up one dead provisional per action.
24985
+ * The notability gate already screens most of these out; this caps whatever slips
24986
+ * through. Trusted flows are never evicted; only the oldest provisional overflow is.
24987
+ */
24988
+ capProvisional(k) {
24989
+ const flows = this.data.origins[k];
24990
+ if (!flows) return;
24991
+ const provisional = flows.filter((f) => f.tier === "provisional");
24992
+ if (provisional.length <= MAX_PROVISIONAL_PER_ORIGIN) return;
24993
+ const doomed = new Set(
24994
+ [...provisional].sort((a, b) => Date.parse(a.last_verified) - Date.parse(b.last_verified)).slice(0, provisional.length - MAX_PROVISIONAL_PER_ORIGIN)
24995
+ );
24996
+ this.data.origins[k] = flows.filter((f) => !doomed.has(f));
24997
+ }
24978
24998
  /** Flush every buffered origin. Call on shutdown and for single-origin sessions. */
24979
24999
  flushAll() {
24980
25000
  for (const k of [...this.buffer.keys()]) this.autoCommit(k);
@@ -26250,7 +26270,7 @@ Current URL: ${activeTab.url}`;
26250
26270
  const nowUrl = r.after_url ?? r.before_url;
26251
26271
  const usedUntil = !!(until_selector || until_url_contains || until_text_contains || until_url_changes);
26252
26272
  const verification = until_url_changes ? "until_url_changes=true" : until_selector ? `until_selector=${JSON.stringify(until_selector)}` : until_url_contains ? `until_url_contains=${JSON.stringify(until_url_contains)}` : until_text_contains ? `until_text_contains=${JSON.stringify(until_text_contains)}` : expect_submit ? "expect_submit=true" : void 0;
26253
- if (r.success && (r.recovered_via || r.navigated || usedUntil)) {
26273
+ if (r.success && (r.recovered_via || r.navigated)) {
26254
26274
  flowStore.observe({
26255
26275
  tool: "click_element",
26256
26276
  target: textHint ?? `selector=${selector}`,
@@ -26259,7 +26279,7 @@ Current URL: ${activeTab.url}`;
26259
26279
  signal: r.navigated ? "navigated" : until_url_changes ? "until_url_change" : usedUntil ? "until_*" : r.recovered_via,
26260
26280
  verification,
26261
26281
  fragile: isFragileSelector(selector),
26262
- reason: r.recovered_via ? `click recovered via ${r.recovered_via}` : r.navigated ? "navigating submit/link" : "verified terminal click"
26282
+ reason: r.recovered_via ? `click recovered via ${r.recovered_via}` : "navigating submit/link"
26263
26283
  }, actionUrl);
26264
26284
  }
26265
26285
  flowStore.noteUrl(nowUrl);
@@ -26632,7 +26652,7 @@ function registerFlowTools(server, bridge, flowStore) {
26632
26652
  }
26633
26653
 
26634
26654
  // packages/mcp-server/src/index.ts
26635
- var PACKAGE_VERSION = true ? "0.12.3" : "dev";
26655
+ var PACKAGE_VERSION = true ? "0.12.4" : "dev";
26636
26656
  main().catch((err) => {
26637
26657
  console.error("[chromeflow] Fatal error:", err);
26638
26658
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chromeflow",
3
- "version": "0.12.3",
3
+ "version": "0.12.4",
4
4
  "description": "MCP server for chromeflow \u2014 lets Claude Code or Codex CLI drive your real Chrome browser with sessions intact. Plugin install recommended; npx chromeflow for manual MCP wiring.",
5
5
  "type": "module",
6
6
  "main": "./bin/chromeflow.mjs",