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

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.
@@ -14,11 +14,13 @@ export type RunningBridgeProbe = {
14
14
  identity?: {
15
15
  extensionId: string;
16
16
  extensionInstanceId: string;
17
+ moduleVersion: string;
17
18
  };
18
19
  };
19
20
  export declare function classifyBrowserLiveSetup(input: {
20
21
  baseSetupReady: boolean;
21
22
  evidenceInstanceId?: string;
23
+ expectedModuleVersion: string;
22
24
  bridgeProbe: RunningBridgeProbe;
23
25
  }): {
24
26
  readonly setupReady: boolean;
@@ -26,6 +28,9 @@ export declare function classifyBrowserLiveSetup(input: {
26
28
  } | {
27
29
  setupReady: boolean;
28
30
  issueCode: "EXTENSION_SESSION_OFFLINE";
31
+ } | {
32
+ setupReady: boolean;
33
+ issueCode: "EXTENSION_VERSION_MISMATCH";
29
34
  } | {
30
35
  setupReady: boolean;
31
36
  issueCode: "EXTENSION_SESSION_REVALIDATION_REQUIRED";
@@ -39,6 +44,7 @@ export declare function pairBrowserExtensionSetup(context: ModuleCommandContext,
39
44
  }): Promise<{
40
45
  extensionId: string;
41
46
  extensionInstanceId: string;
47
+ moduleVersion: string;
42
48
  }>;
43
49
  export declare const behaviorAdapter: {
44
50
  readonly install: (context: ModuleCommandContext) => Promise<{
@@ -47,7 +53,7 @@ export declare const behaviorAdapter: {
47
53
  ok: true;
48
54
  status: "SUCCEEDED";
49
55
  moduleRef: "execution-browser-extension";
50
- moduleVersion: "0.1.47";
56
+ moduleVersion: "0.1.48";
51
57
  data: {
52
58
  loadDir: string;
53
59
  };
@@ -60,7 +66,7 @@ export declare const behaviorAdapter: {
60
66
  readonly ok: true;
61
67
  readonly status: "SUCCEEDED";
62
68
  readonly moduleRef: "execution-browser-extension";
63
- readonly moduleVersion: "0.1.47";
69
+ readonly moduleVersion: "0.1.48";
64
70
  };
65
71
  observedEffects: never[];
66
72
  }>;
@@ -70,7 +76,7 @@ export declare const behaviorAdapter: {
70
76
  ok: true;
71
77
  status: "SUCCEEDED";
72
78
  moduleRef: "execution-browser-extension";
73
- moduleVersion: "0.1.47";
79
+ moduleVersion: "0.1.48";
74
80
  data: {
75
81
  setupStatus: "ACTION_REQUIRED" | "READY";
76
82
  runtimeStatus: "NOT_APPLICABLE";
@@ -82,7 +88,7 @@ export declare const behaviorAdapter: {
82
88
  nextCommand: string;
83
89
  } | {
84
90
  scope: "SETUP";
85
- code: "EXTENSION_SESSION_OFFLINE" | "EXTENSION_SESSION_REVALIDATION_REQUIRED" | undefined;
91
+ code: "EXTENSION_SESSION_OFFLINE" | "EXTENSION_SESSION_REVALIDATION_REQUIRED" | "EXTENSION_VERSION_MISMATCH" | undefined;
86
92
  message: string;
87
93
  relatedModuleRefs: string[];
88
94
  nextCommand: string;
@@ -95,7 +101,7 @@ export declare const behaviorAdapter: {
95
101
  result: {
96
102
  contract: "deployment.result.v1";
97
103
  moduleRef: "execution-browser-extension";
98
- moduleVersion: "0.1.47";
104
+ moduleVersion: "0.1.48";
99
105
  ok: false;
100
106
  status: "ACTION_REQUIRED";
101
107
  data: {
@@ -127,14 +133,14 @@ export declare const behaviorAdapter: {
127
133
  readonly ok: true;
128
134
  readonly status: "SUCCEEDED";
129
135
  readonly moduleRef: "execution-browser-extension";
130
- readonly moduleVersion: "0.1.47";
136
+ readonly moduleVersion: "0.1.48";
131
137
  };
132
138
  observedEffects: string[];
133
139
  } | {
134
140
  result: {
135
141
  contract: "deployment.result.v1";
136
142
  moduleRef: "execution-browser-extension";
137
- moduleVersion: "0.1.47";
143
+ moduleVersion: "0.1.48";
138
144
  ok: false;
139
145
  status: "FAILED";
140
146
  error: {
@@ -167,7 +173,7 @@ export declare const behaviorAdapter: {
167
173
  ok: true;
168
174
  status: "SUCCEEDED";
169
175
  moduleRef: "execution-browser-extension";
170
- moduleVersion: "0.1.47";
176
+ moduleVersion: "0.1.48";
171
177
  data: {
172
178
  docs: string;
173
179
  };
@@ -180,11 +186,11 @@ export declare const behaviorAdapter: {
180
186
  readonly ok: true;
181
187
  readonly status: "SUCCEEDED";
182
188
  readonly moduleRef: "execution-browser-extension";
183
- readonly moduleVersion: "0.1.47";
189
+ readonly moduleVersion: "0.1.48";
184
190
  } | {
185
191
  contract: "deployment.result.v1";
186
192
  moduleRef: "execution-browser-extension";
187
- moduleVersion: "0.1.47";
193
+ moduleVersion: "0.1.48";
188
194
  ok: false;
189
195
  status: "FAILED";
190
196
  error: {
@@ -201,7 +207,7 @@ export declare const behaviorAdapter: {
201
207
  readonly ok: true;
202
208
  readonly status: "SUCCEEDED";
203
209
  readonly moduleRef: "execution-browser-extension";
204
- readonly moduleVersion: "0.1.47";
210
+ readonly moduleVersion: "0.1.48";
205
211
  };
206
212
  observedEffects: never[];
207
213
  }>;
@@ -263,6 +263,8 @@ async function materializeExecutorConfig(context, setup, prepared) {
263
263
  });
264
264
  }
265
265
  async function persistPairedBrowserExtension(context, prepared, identity) {
266
+ if (identity.moduleVersion !== descriptor.moduleVersion)
267
+ throw new Error("EXTENSION_VERSION_MISMATCH");
266
268
  const setup = { extensionId: identity.extensionId };
267
269
  await writeFile(setupFile(context), `${JSON.stringify(setup, null, 2)}\n`, {
268
270
  mode: 0o600,
@@ -270,7 +272,7 @@ async function persistPairedBrowserExtension(context, prepared, identity) {
270
272
  await materializeExecutorConfig(context, setup, prepared);
271
273
  const evidence = {
272
274
  contract: "proflow.browser-extension-verification.v1",
273
- moduleVersion: descriptor.moduleVersion,
275
+ moduleVersion: identity.moduleVersion,
274
276
  loadDir: prepared.loadDir,
275
277
  extensionId: identity.extensionId,
276
278
  extensionInstanceId: identity.extensionInstanceId,
@@ -289,6 +291,11 @@ export function classifyBrowserLiveSetup(input) {
289
291
  setupReady: false,
290
292
  issueCode: "EXTENSION_SESSION_OFFLINE",
291
293
  };
294
+ if (input.bridgeProbe.identity.moduleVersion !== input.expectedModuleVersion)
295
+ return {
296
+ setupReady: false,
297
+ issueCode: "EXTENSION_VERSION_MISMATCH",
298
+ };
292
299
  if (input.bridgeProbe.identity.extensionInstanceId !== input.evidenceInstanceId)
293
300
  return {
294
301
  setupReady: false,
@@ -321,12 +328,15 @@ async function probeRunningBridgeSession(prepared, extensionId, timeoutMs) {
321
328
  if (Reflect.get(body, "online") !== true)
322
329
  return { kind: "PRESENT" };
323
330
  const extensionInstanceId = Reflect.get(body, "extensionInstanceId");
331
+ const moduleVersion = Reflect.get(body, "moduleVersion");
324
332
  if (typeof extensionInstanceId !== "string" ||
325
- extensionInstanceId.length === 0)
333
+ extensionInstanceId.length === 0 ||
334
+ typeof moduleVersion !== "string" ||
335
+ moduleVersion.length === 0)
326
336
  throw new Error("RUNNING_BRIDGE_STATUS_INVALID");
327
337
  return {
328
338
  kind: "PRESENT",
329
- identity: { extensionId, extensionInstanceId },
339
+ identity: { extensionId, extensionInstanceId, moduleVersion },
330
340
  };
331
341
  }
332
342
  catch (error) {
@@ -454,6 +464,7 @@ export const behaviorAdapter = {
454
464
  const live = classifyBrowserLiveSetup({
455
465
  baseSetupReady,
456
466
  ...(evidence ? { evidenceInstanceId: evidence.extensionInstanceId } : {}),
467
+ expectedModuleVersion: descriptor.moduleVersion,
457
468
  bridgeProbe,
458
469
  });
459
470
  const issue = !baseSetupReady
@@ -471,7 +482,9 @@ export const behaviorAdapter = {
471
482
  code: live.issueCode,
472
483
  message: live.issueCode === "EXTENSION_SESSION_OFFLINE"
473
484
  ? "Chrome 扩展已加载,但当前运行会话未在线"
474
- : "Chrome 扩展已重新启动,需要自动刷新当前运行会话证据",
485
+ : live.issueCode === "EXTENSION_VERSION_MISMATCH"
486
+ ? "Chrome 当前运行的扩展版本与 Workspace 物化版本不一致"
487
+ : "Chrome 扩展已重新启动,需要自动刷新当前运行会话证据",
475
488
  relatedModuleRefs: ["execution-runtime"],
476
489
  nextCommand: "platform setup",
477
490
  };
@@ -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.47";
6
+ readonly moduleVersion: "0.1.48";
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.47",
6
+ moduleVersion: "0.1.48",
7
7
  kind: "browser-extension",
8
8
  templateVersion: "1.0.0",
9
9
  platformCompatibility: ">=1.0.0 <2.0.0",
@@ -14206,6 +14206,7 @@ function createTaskObserver(options) {
14206
14206
 
14207
14207
  // packages/execution-browser-extension/extension/background.ts
14208
14208
  var extensionInstanceId = `extension:${crypto.randomUUID()}`;
14209
+ var extensionModuleVersion = chrome.runtime.getManifest().version;
14209
14210
  var sessions = /* @__PURE__ */ new Map();
14210
14211
  var browserOpenObservationGate = createBrowserOpenObservationGate();
14211
14212
  var permissionHandling = /* @__PURE__ */ new Map();
@@ -15288,7 +15289,8 @@ async function runBridgeLoop() {
15288
15289
  method: "POST",
15289
15290
  body: JSON.stringify({
15290
15291
  extensionId: chrome.runtime.id,
15291
- extensionInstanceId
15292
+ extensionInstanceId,
15293
+ moduleVersion: extensionModuleVersion
15292
15294
  })
15293
15295
  });
15294
15296
  if (!hello.ok) throw new Error("BRIDGE_HELLO_REJECTED");
@@ -217,6 +217,7 @@ export async function createBrowserRealityBridgeServer(options) {
217
217
  sessionOnline: sessionOnline(),
218
218
  commandConsumerReady: commandConsumerReady(),
219
219
  extensionInstanceId: session?.extensionInstanceId ?? null,
220
+ moduleVersion: session?.moduleVersion ?? null,
220
221
  queuedCommands: queue.length,
221
222
  pendingCommands: pending.size,
222
223
  lastCommandPollAt,
@@ -317,7 +318,9 @@ export async function createBrowserRealityBridgeServer(options) {
317
318
  stringField(body, "extensionId") !== options.extensionId)
318
319
  throw new BrowserRealityBridgeError("BRIDGE_AUTH_INVALID", "extension identity mismatch");
319
320
  const extensionInstanceId = stringField(body, "extensionInstanceId");
320
- if (session?.extensionInstanceId !== extensionInstanceId) {
321
+ const moduleVersion = stringField(body, "moduleVersion");
322
+ if (session?.extensionInstanceId !== extensionInstanceId ||
323
+ session?.moduleVersion !== moduleVersion) {
321
324
  lastCommandPollAt = null;
322
325
  lastCommandDeliveredAt = null;
323
326
  lastCommandResultAt = null;
@@ -325,6 +328,7 @@ export async function createBrowserRealityBridgeServer(options) {
325
328
  }
326
329
  session = {
327
330
  extensionInstanceId,
331
+ moduleVersion,
328
332
  lastHeartbeatAt: now().getTime(),
329
333
  };
330
334
  send(response, 200, { accepted: true });
@@ -336,6 +340,7 @@ export async function createBrowserRealityBridgeServer(options) {
336
340
  sessionOnline: sessionOnline(),
337
341
  commandConsumerReady: commandConsumerReady(),
338
342
  extensionInstanceId: session?.extensionInstanceId ?? null,
343
+ moduleVersion: session?.moduleVersion ?? null,
339
344
  });
340
345
  return;
341
346
  }
@@ -14,6 +14,7 @@ export type BrowserExtensionPair = (context: {
14
14
  }) => Promise<{
15
15
  extensionId: string;
16
16
  extensionInstanceId: string;
17
+ moduleVersion: string;
17
18
  }>;
18
19
  export declare function browserExtensionInstallInstruction(loadDir: string): string;
19
20
  export declare function browserExtensionSetupSuccessMessage(): string;
@@ -27,4 +28,5 @@ export declare function runInteractiveBrowserExtensionSetup(input: {
27
28
  }): Promise<{
28
29
  extensionId: string;
29
30
  extensionInstanceId: string;
31
+ moduleVersion: string;
30
32
  }>;
@@ -7,6 +7,7 @@ export interface BrowserExtensionPairingOptions {
7
7
  export type BrowserExtensionPairingResult = {
8
8
  extensionId: string;
9
9
  extensionInstanceId: string;
10
+ moduleVersion: string;
10
11
  };
11
12
  export declare function createBrowserExtensionPairingServer(options: BrowserExtensionPairingOptions): Promise<Readonly<{
12
13
  endpoint: string;
@@ -14,6 +15,7 @@ export declare function createBrowserExtensionPairingServer(options: BrowserExte
14
15
  paired: boolean;
15
16
  extensionId: string | null;
16
17
  extensionInstanceId: string | null;
18
+ moduleVersion: string | null;
17
19
  };
18
20
  waitForPairing(): Promise<BrowserExtensionPairingResult>;
19
21
  close(): Promise<void>;
@@ -93,12 +93,13 @@ export async function createBrowserExtensionPairingServer(options) {
93
93
  const body = await readJson(request);
94
94
  const extensionId = text(body.extensionId);
95
95
  const extensionInstanceId = text(body.extensionInstanceId);
96
+ const moduleVersion = text(body.moduleVersion);
96
97
  if (!originId || extensionId !== originId)
97
98
  throw new Error("PAIRING_AUTH_INVALID");
98
99
  if (identity && identity.extensionId !== extensionId) {
99
100
  throw new Error("PAIRING_AUTH_INVALID");
100
101
  }
101
- identity = { extensionId, extensionInstanceId };
102
+ identity = { extensionId, extensionInstanceId, moduleVersion };
102
103
  send(response, 200, { accepted: true });
103
104
  return;
104
105
  }
@@ -160,6 +161,7 @@ export async function createBrowserExtensionPairingServer(options) {
160
161
  paired: paired !== undefined,
161
162
  extensionId: identity?.extensionId ?? null,
162
163
  extensionInstanceId: identity?.extensionInstanceId ?? null,
164
+ moduleVersion: identity?.moduleVersion ?? null,
163
165
  };
164
166
  },
165
167
  waitForPairing() {
@@ -132,6 +132,7 @@ type ChromeTab = {
132
132
  type ChromeRuntime = {
133
133
  runtime: {
134
134
  id: string;
135
+ getManifest(): { version: string };
135
136
  getURL(path: string): string;
136
137
  onMessage: {
137
138
  addListener(
@@ -186,6 +187,7 @@ type ChromeRuntime = {
186
187
  declare const chrome: ChromeRuntime;
187
188
 
188
189
  const extensionInstanceId = `extension:${crypto.randomUUID()}`;
190
+ const extensionModuleVersion = chrome.runtime.getManifest().version;
189
191
  const sessions = new Map<number, ContentObservation>();
190
192
  const browserOpenObservationGate = createBrowserOpenObservationGate();
191
193
  const permissionHandling = new Map<number, string>();
@@ -1637,6 +1639,7 @@ async function runBridgeLoop() {
1637
1639
  body: JSON.stringify({
1638
1640
  extensionId: chrome.runtime.id,
1639
1641
  extensionInstanceId,
1642
+ moduleVersion: extensionModuleVersion,
1640
1643
  }),
1641
1644
  });
1642
1645
  if (!hello.ok) throw new Error("BRIDGE_HELLO_REJECTED");
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.47",
4
+ "version": "0.1.48",
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.47",
3
+ "version": "0.1.48",
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.47",
6
+ "moduleVersion": "0.1.48",
7
7
  "kind": "browser-extension",
8
8
  "templateVersion": "1.0.0",
9
9
  "platformCompatibility": ">=1.0.0 <2.0.0",
package/CHANGELOG.md DELETED
@@ -1,49 +0,0 @@
1
- # @tomflow/proflow-execution-browser-extension
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
-
9
- ## 0.1.46
10
-
11
- ### Patch Changes
12
-
13
- - Allow the durable TASK_RESUMED observer signal to use the bounded worker.wake trigger contract while preserving arbitrary-trigger rejection and browser delivery verification.
14
-
15
- ## 0.1.45
16
-
17
- ### Patch Changes
18
-
19
- - Release the verified Real-3 B1 task recovery, exact execution identity, durable observer resume, bounded gateway error, and matching Agent Action contract fixes.
20
-
21
- ## 0.1.44
22
-
23
- ### Patch Changes
24
-
25
- - Prefer the canonical ChatGPT prompt editor over earlier fallback textareas so worker wake messages are submitted through the real composer.
26
-
27
- ## 0.1.43
28
-
29
- ### Patch Changes
30
-
31
- - Enrich Browser OBSERVE responses with Chrome-owned tab and window identity before returning the page observation.
32
-
33
- ## 0.1.42
34
-
35
- ### Patch Changes
36
-
37
- - Close Real-3 node generation identity fencing across Platform Host admission, durable Execution idempotency, and Observer/Approval resume provenance.
38
-
39
- ## 0.1.41
40
-
41
- ### Patch Changes
42
-
43
- - Resume the existing Task Observer after successful Tasks web mutations so READY nodes receive their normal NODE_READY or REOPEN wake without manual recovery.
44
-
45
- ## 0.1.40
46
-
47
- ### Patch Changes
48
-
49
- - Make the authenticated ProFlow Tasks web app self-contained so its published browser module no longer escapes the `/tasks` session surface through a runtime relative import.