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.
- package/bin/chromeflow.mjs +23 -3
- package/package.json +1 -1
package/bin/chromeflow.mjs
CHANGED
|
@@ -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
|
|
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}` :
|
|
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.
|
|
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
|
+
"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",
|