@tomflow/proflow-execution-browser-extension 0.1.46 → 0.1.47

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @tomflow/proflow-execution-browser-extension
2
2
 
3
+ ## 0.1.47
4
+
5
+ ### Patch Changes
6
+
7
+ - Bound startup Carrier snapshot reconstruction so a hung ChatGPT tab cannot block durable Observer recovery, while preserving restored human-denial suppression and no-blind-replay semantics.
8
+
3
9
  ## 0.1.46
4
10
 
5
11
  ### Patch Changes
@@ -47,7 +47,7 @@ export declare const behaviorAdapter: {
47
47
  ok: true;
48
48
  status: "SUCCEEDED";
49
49
  moduleRef: "execution-browser-extension";
50
- moduleVersion: "0.1.46";
50
+ moduleVersion: "0.1.47";
51
51
  data: {
52
52
  loadDir: string;
53
53
  };
@@ -60,7 +60,7 @@ export declare const behaviorAdapter: {
60
60
  readonly ok: true;
61
61
  readonly status: "SUCCEEDED";
62
62
  readonly moduleRef: "execution-browser-extension";
63
- readonly moduleVersion: "0.1.46";
63
+ readonly moduleVersion: "0.1.47";
64
64
  };
65
65
  observedEffects: never[];
66
66
  }>;
@@ -70,7 +70,7 @@ export declare const behaviorAdapter: {
70
70
  ok: true;
71
71
  status: "SUCCEEDED";
72
72
  moduleRef: "execution-browser-extension";
73
- moduleVersion: "0.1.46";
73
+ moduleVersion: "0.1.47";
74
74
  data: {
75
75
  setupStatus: "ACTION_REQUIRED" | "READY";
76
76
  runtimeStatus: "NOT_APPLICABLE";
@@ -95,7 +95,7 @@ export declare const behaviorAdapter: {
95
95
  result: {
96
96
  contract: "deployment.result.v1";
97
97
  moduleRef: "execution-browser-extension";
98
- moduleVersion: "0.1.46";
98
+ moduleVersion: "0.1.47";
99
99
  ok: false;
100
100
  status: "ACTION_REQUIRED";
101
101
  data: {
@@ -127,14 +127,14 @@ export declare const behaviorAdapter: {
127
127
  readonly ok: true;
128
128
  readonly status: "SUCCEEDED";
129
129
  readonly moduleRef: "execution-browser-extension";
130
- readonly moduleVersion: "0.1.46";
130
+ readonly moduleVersion: "0.1.47";
131
131
  };
132
132
  observedEffects: string[];
133
133
  } | {
134
134
  result: {
135
135
  contract: "deployment.result.v1";
136
136
  moduleRef: "execution-browser-extension";
137
- moduleVersion: "0.1.46";
137
+ moduleVersion: "0.1.47";
138
138
  ok: false;
139
139
  status: "FAILED";
140
140
  error: {
@@ -167,7 +167,7 @@ export declare const behaviorAdapter: {
167
167
  ok: true;
168
168
  status: "SUCCEEDED";
169
169
  moduleRef: "execution-browser-extension";
170
- moduleVersion: "0.1.46";
170
+ moduleVersion: "0.1.47";
171
171
  data: {
172
172
  docs: string;
173
173
  };
@@ -180,11 +180,11 @@ export declare const behaviorAdapter: {
180
180
  readonly ok: true;
181
181
  readonly status: "SUCCEEDED";
182
182
  readonly moduleRef: "execution-browser-extension";
183
- readonly moduleVersion: "0.1.46";
183
+ readonly moduleVersion: "0.1.47";
184
184
  } | {
185
185
  contract: "deployment.result.v1";
186
186
  moduleRef: "execution-browser-extension";
187
- moduleVersion: "0.1.46";
187
+ moduleVersion: "0.1.47";
188
188
  ok: false;
189
189
  status: "FAILED";
190
190
  error: {
@@ -201,7 +201,7 @@ export declare const behaviorAdapter: {
201
201
  readonly ok: true;
202
202
  readonly status: "SUCCEEDED";
203
203
  readonly moduleRef: "execution-browser-extension";
204
- readonly moduleVersion: "0.1.46";
204
+ readonly moduleVersion: "0.1.47";
205
205
  };
206
206
  observedEffects: never[];
207
207
  }>;
@@ -3,7 +3,7 @@ export declare const descriptor: {
3
3
  readonly contractVersion: "1.0.0";
4
4
  readonly moduleRef: "execution-browser-extension";
5
5
  readonly packageName: "@tomflow/proflow-execution-browser-extension";
6
- readonly moduleVersion: "0.1.46";
6
+ readonly moduleVersion: "0.1.47";
7
7
  readonly kind: "browser-extension";
8
8
  readonly templateVersion: "1.0.0";
9
9
  readonly platformCompatibility: ">=1.0.0 <2.0.0";
@@ -3,7 +3,7 @@ export const descriptor = {
3
3
  contractVersion: "1.0.0",
4
4
  moduleRef: "execution-browser-extension",
5
5
  packageName: "@tomflow/proflow-execution-browser-extension",
6
- moduleVersion: "0.1.46",
6
+ moduleVersion: "0.1.47",
7
7
  kind: "browser-extension",
8
8
  templateVersion: "1.0.0",
9
9
  platformCompatibility: ">=1.0.0 <2.0.0",
@@ -13844,6 +13844,19 @@ function createCollaborationCarrierApplication(options) {
13844
13844
  }
13845
13845
 
13846
13846
  // packages/execution-browser-extension/src/recovery-trigger.ts
13847
+ async function boundedRecoveryObservation(observe, timeoutMs) {
13848
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
13849
+ throw new TypeError("RECOVERY_OBSERVATION_TIMEOUT_INVALID");
13850
+ let timer;
13851
+ const timeout = new Promise((resolve) => {
13852
+ timer = setTimeout(() => resolve(null), timeoutMs);
13853
+ });
13854
+ try {
13855
+ return await Promise.race([observe().catch(() => null), timeout]);
13856
+ } finally {
13857
+ if (timer !== void 0) clearTimeout(timer);
13858
+ }
13859
+ }
13847
13860
  function shouldTriggerObserverRecovery(previous, current) {
13848
13861
  if (current.pageState !== "IDLE") return false;
13849
13862
  if (!previous) return true;
@@ -14202,6 +14215,7 @@ var carrierContinuationControl = createCarrierContinuationControl();
14202
14215
  var BROWSER_CARRIER_KEEPALIVE_KEY = "proflowBrowserSnapshot";
14203
14216
  var BROWSER_CARRIER_KEEPALIVE_MS = 2e4;
14204
14217
  var BROWSER_BRIDGE_FETCH_TIMEOUT_MS = 5e3;
14218
+ var BROWSER_RECOVERY_SNAPSHOT_TIMEOUT_MS = 1e3;
14205
14219
  var snapshotPersistence = Promise.resolve();
14206
14220
  var transientPermissionAttemptsRestore = null;
14207
14221
  var sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
@@ -14946,23 +14960,31 @@ function processContentObservation(observed, triggerRecovery) {
14946
14960
  async function rebuildCarrierAttentionsFromTabs() {
14947
14961
  const consumedDenials = [];
14948
14962
  const tabs = await chrome.tabs.query({ url: "https://chatgpt.com/g/*" });
14949
- for (const tab of tabs) {
14950
- if (tab.id === void 0 || tab.windowId === void 0) continue;
14951
- try {
14952
- const response = await chrome.tabs.sendMessage(tab.id, {
14953
- type: "PROFLOW_PAGE_SNAPSHOT_REQUEST"
14954
- });
14955
- if (!isRecord(response) || response.ok !== true) continue;
14956
- const observed = parseSnapshotObservation(response.value, tab);
14957
- if (observed) {
14958
- processContentObservation(observed, false);
14959
- const consumed = carrierContinuationControl.consumeRecovery(
14960
- void 0,
14961
- observed
14962
- );
14963
- if (consumed) consumedDenials.push(consumed);
14964
- }
14965
- } catch {
14963
+ const snapshots = await Promise.all(
14964
+ tabs.map(async (tab) => {
14965
+ const tabId = tab.id;
14966
+ if (tabId === void 0 || tab.windowId === void 0) return null;
14967
+ const response = await boundedRecoveryObservation(
14968
+ () => chrome.tabs.sendMessage(tabId, {
14969
+ type: "PROFLOW_PAGE_SNAPSHOT_REQUEST"
14970
+ }),
14971
+ BROWSER_RECOVERY_SNAPSHOT_TIMEOUT_MS
14972
+ );
14973
+ return { tab, response };
14974
+ })
14975
+ );
14976
+ for (const snapshot of snapshots) {
14977
+ if (!snapshot) continue;
14978
+ const { tab, response } = snapshot;
14979
+ if (!isRecord(response) || response.ok !== true) continue;
14980
+ const observed = parseSnapshotObservation(response.value, tab);
14981
+ if (observed) {
14982
+ processContentObservation(observed, false);
14983
+ const consumed = carrierContinuationControl.consumeRecovery(
14984
+ void 0,
14985
+ observed
14986
+ );
14987
+ if (consumed) consumedDenials.push(consumed);
14966
14988
  }
14967
14989
  }
14968
14990
  await persistSnapshot();
@@ -4,5 +4,6 @@ type RecoveryObservation = {
4
4
  pageState: "IDLE" | "BUSY" | "BLOCKED" | "UNKNOWN";
5
5
  activityKind: string | null;
6
6
  };
7
+ export declare function boundedRecoveryObservation<Value>(observe: () => Promise<Value>, timeoutMs: number): Promise<Value | null>;
7
8
  export declare function shouldTriggerObserverRecovery(previous: RecoveryObservation | undefined, current: RecoveryObservation): boolean;
8
9
  export {};
@@ -1,3 +1,18 @@
1
+ export async function boundedRecoveryObservation(observe, timeoutMs) {
2
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
3
+ throw new TypeError("RECOVERY_OBSERVATION_TIMEOUT_INVALID");
4
+ let timer;
5
+ const timeout = new Promise((resolve) => {
6
+ timer = setTimeout(() => resolve(null), timeoutMs);
7
+ });
8
+ try {
9
+ return await Promise.race([observe().catch(() => null), timeout]);
10
+ }
11
+ finally {
12
+ if (timer !== undefined)
13
+ clearTimeout(timer);
14
+ }
15
+ }
1
16
  export function shouldTriggerObserverRecovery(previous, current) {
2
17
  if (current.pageState !== "IDLE")
3
18
  return false;
@@ -18,7 +18,10 @@ import {
18
18
  resolveRoutineCarrierPermission,
19
19
  } from "../src/carrier-permission-lifecycle.js";
20
20
  import { createCollaborationCarrierApplication } from "../src/collaboration-carrier.js";
21
- import { shouldTriggerObserverRecovery } from "../src/recovery-trigger.js";
21
+ import {
22
+ boundedRecoveryObservation,
23
+ shouldTriggerObserverRecovery,
24
+ } from "../src/recovery-trigger.js";
22
25
  import {
23
26
  createSystemObserver,
24
27
  type SystemObserverReasonFailure,
@@ -192,6 +195,7 @@ const carrierContinuationControl = createCarrierContinuationControl();
192
195
  const BROWSER_CARRIER_KEEPALIVE_KEY = "proflowBrowserSnapshot";
193
196
  const BROWSER_CARRIER_KEEPALIVE_MS = 20_000;
194
197
  const BROWSER_BRIDGE_FETCH_TIMEOUT_MS = 5_000;
198
+ const BROWSER_RECOVERY_SNAPSHOT_TIMEOUT_MS = 1_000;
195
199
  let snapshotPersistence = Promise.resolve();
196
200
  let transientPermissionAttemptsRestore: Promise<boolean> | null = null;
197
201
 
@@ -1235,24 +1239,32 @@ async function rebuildCarrierAttentionsFromTabs(): Promise<
1235
1239
  > {
1236
1240
  const consumedDenials: CarrierContinuationDenial[] = [];
1237
1241
  const tabs = await chrome.tabs.query({ url: "https://chatgpt.com/g/*" });
1238
- for (const tab of tabs) {
1239
- if (tab.id === undefined || tab.windowId === undefined) continue;
1240
- try {
1241
- const response = await chrome.tabs.sendMessage(tab.id, {
1242
- type: "PROFLOW_PAGE_SNAPSHOT_REQUEST",
1243
- });
1244
- if (!isRecord(response) || response.ok !== true) continue;
1245
- const observed = parseSnapshotObservation(response.value, tab);
1246
- if (observed) {
1247
- processContentObservation(observed, false);
1248
- const consumed = carrierContinuationControl.consumeRecovery(
1249
- undefined,
1250
- observed,
1251
- );
1252
- if (consumed) consumedDenials.push(consumed);
1253
- }
1254
- } catch {
1255
- // A tab without a live content receiver is not reconstructed from guesses.
1242
+ const snapshots = await Promise.all(
1243
+ tabs.map(async (tab) => {
1244
+ const tabId = tab.id;
1245
+ if (tabId === undefined || tab.windowId === undefined) return null;
1246
+ const response = await boundedRecoveryObservation(
1247
+ () =>
1248
+ chrome.tabs.sendMessage(tabId, {
1249
+ type: "PROFLOW_PAGE_SNAPSHOT_REQUEST",
1250
+ }),
1251
+ BROWSER_RECOVERY_SNAPSHOT_TIMEOUT_MS,
1252
+ );
1253
+ return { tab, response };
1254
+ }),
1255
+ );
1256
+ for (const snapshot of snapshots) {
1257
+ if (!snapshot) continue;
1258
+ const { tab, response } = snapshot;
1259
+ if (!isRecord(response) || response.ok !== true) continue;
1260
+ const observed = parseSnapshotObservation(response.value, tab);
1261
+ if (observed) {
1262
+ processContentObservation(observed, false);
1263
+ const consumed = carrierContinuationControl.consumeRecovery(
1264
+ undefined,
1265
+ observed,
1266
+ );
1267
+ if (consumed) consumedDenials.push(consumed);
1256
1268
  }
1257
1269
  }
1258
1270
  await persistSnapshot();
package/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "ProFlow Execution Browser",
4
- "version": "0.1.46",
4
+ "version": "0.1.47",
5
5
  "permissions": [
6
6
  "tabs",
7
7
  "storage"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomflow/proflow-execution-browser-extension",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "description": "Execution-owned MV3 Browser executor, evidence provider and browser application surface.",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -3,7 +3,7 @@
3
3
  "contractVersion": "1.0.0",
4
4
  "moduleRef": "execution-browser-extension",
5
5
  "packageName": "@tomflow/proflow-execution-browser-extension",
6
- "moduleVersion": "0.1.46",
6
+ "moduleVersion": "0.1.47",
7
7
  "kind": "browser-extension",
8
8
  "templateVersion": "1.0.0",
9
9
  "platformCompatibility": ">=1.0.0 <2.0.0",