@tomflow/proflow-execution-browser-extension 0.1.24 → 0.1.26
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 +12 -0
- package/dist/deployment/adapter.d.ts +10 -10
- package/dist/deployment/descriptor.d.ts +1 -1
- package/dist/deployment/descriptor.js +1 -1
- package/dist/extension/background.js +33 -10
- package/dist/extension/content.js +5 -1
- package/dist/src/custom-gpt-role.js +3 -13
- package/dist/src/index.js +3 -1
- package/dist/src/submitted-message.d.ts +5 -0
- package/dist/src/submitted-message.js +10 -0
- package/extension/background.ts +41 -10
- package/extension/content.ts +11 -1
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/proflow.module.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @tomflow/proflow-execution-browser-extension
|
|
2
2
|
|
|
3
|
+
## 0.1.26
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Close the Real-3 source candidate and real-workspace loop: fail-closed Browser submit verification, worker-bound Task mutation and WAKE confirmation, detached platform start ownership with shell return, discoverable docs, and targeted single-package Workspace update.
|
|
8
|
+
|
|
9
|
+
## 0.1.25
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Preserve irreversible Custom GPT role authority and revalidate existing roles without duplicate creation
|
|
14
|
+
|
|
3
15
|
## 0.1.24
|
|
4
16
|
|
|
5
17
|
### 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.
|
|
50
|
+
moduleVersion: "0.1.26";
|
|
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.
|
|
63
|
+
readonly moduleVersion: "0.1.26";
|
|
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.
|
|
73
|
+
moduleVersion: "0.1.26";
|
|
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.
|
|
98
|
+
moduleVersion: "0.1.26";
|
|
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.
|
|
130
|
+
readonly moduleVersion: "0.1.26";
|
|
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.
|
|
137
|
+
moduleVersion: "0.1.26";
|
|
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.
|
|
170
|
+
moduleVersion: "0.1.26";
|
|
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.
|
|
183
|
+
readonly moduleVersion: "0.1.26";
|
|
184
184
|
} | {
|
|
185
185
|
contract: "deployment.result.v1";
|
|
186
186
|
moduleRef: "execution-browser-extension";
|
|
187
|
-
moduleVersion: "0.1.
|
|
187
|
+
moduleVersion: "0.1.26";
|
|
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.
|
|
204
|
+
readonly moduleVersion: "0.1.26";
|
|
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.
|
|
6
|
+
readonly moduleVersion: "0.1.26";
|
|
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.
|
|
6
|
+
moduleVersion: "0.1.26",
|
|
7
7
|
kind: "browser-extension",
|
|
8
8
|
templateVersion: "1.0.0",
|
|
9
9
|
platformCompatibility: ">=1.0.0 <2.0.0",
|
|
@@ -14190,6 +14190,7 @@ var observerRecoveryRetryCount = 0;
|
|
|
14190
14190
|
function runObserverRecovery() {
|
|
14191
14191
|
if (observerRecoveryInFlight) return observerRecoveryInFlight;
|
|
14192
14192
|
observerRecoveryInFlight = (async () => {
|
|
14193
|
+
let recoveryNeedsRetry = false;
|
|
14193
14194
|
await collaborationCarrier.recoverPending(50).catch(() => void 0);
|
|
14194
14195
|
const signalBatch = await invokeObserverApplication(
|
|
14195
14196
|
"execution.listSignals",
|
|
@@ -14219,18 +14220,14 @@ function runObserverRecovery() {
|
|
|
14219
14220
|
signalRef: candidate.signalRef
|
|
14220
14221
|
});
|
|
14221
14222
|
} catch {
|
|
14223
|
+
recoveryNeedsRetry = true;
|
|
14222
14224
|
}
|
|
14223
14225
|
}
|
|
14224
14226
|
}
|
|
14225
14227
|
const listed = await invokeTaskApplication("task.list", {}).catch(
|
|
14226
14228
|
() => null
|
|
14227
14229
|
);
|
|
14228
|
-
if (listed === null
|
|
14229
|
-
observerRecoveryRetryCount += 1;
|
|
14230
|
-
setTimeout(() => void runObserverRecovery(), 2e3);
|
|
14231
|
-
} else if (listed !== null) {
|
|
14232
|
-
observerRecoveryRetryCount = 0;
|
|
14233
|
-
}
|
|
14230
|
+
if (listed === null) recoveryNeedsRetry = true;
|
|
14234
14231
|
if (isRecord(listed) && Array.isArray(listed.tasks)) {
|
|
14235
14232
|
for (const candidate of listed.tasks.slice(0, 100)) {
|
|
14236
14233
|
if (!isRecord(candidate) || typeof candidate.taskId !== "string")
|
|
@@ -14239,10 +14236,20 @@ function runObserverRecovery() {
|
|
|
14239
14236
|
continue;
|
|
14240
14237
|
await invokeTaskApplication("task.ensureWorkers", {
|
|
14241
14238
|
taskId: candidate.taskId
|
|
14242
|
-
}).catch(() =>
|
|
14243
|
-
|
|
14239
|
+
}).catch(() => {
|
|
14240
|
+
recoveryNeedsRetry = true;
|
|
14241
|
+
});
|
|
14242
|
+
await taskObserver.drive(candidate.taskId).catch(() => {
|
|
14243
|
+
recoveryNeedsRetry = true;
|
|
14244
|
+
});
|
|
14244
14245
|
}
|
|
14245
14246
|
}
|
|
14247
|
+
if (recoveryNeedsRetry && observerRecoveryRetryCount < 6) {
|
|
14248
|
+
observerRecoveryRetryCount += 1;
|
|
14249
|
+
setTimeout(() => void runObserverRecovery(), 2e3);
|
|
14250
|
+
} else if (!recoveryNeedsRetry) {
|
|
14251
|
+
observerRecoveryRetryCount = 0;
|
|
14252
|
+
}
|
|
14246
14253
|
const previousSystemState = await loadSystemObserverState().catch(
|
|
14247
14254
|
() => null
|
|
14248
14255
|
);
|
|
@@ -14285,6 +14292,21 @@ async function contentCommand(tabId, command) {
|
|
|
14285
14292
|
}
|
|
14286
14293
|
return response.value;
|
|
14287
14294
|
}
|
|
14295
|
+
async function waitForSubmittedMessage(tabId, fingerprint) {
|
|
14296
|
+
for (let attempt = 0; attempt < 60; attempt += 1) {
|
|
14297
|
+
try {
|
|
14298
|
+
const value = await contentCommand(tabId, {
|
|
14299
|
+
operation: "verify",
|
|
14300
|
+
fingerprint
|
|
14301
|
+
});
|
|
14302
|
+
if (isRecord(value) && value.verified === true)
|
|
14303
|
+
return observationFor(tabId);
|
|
14304
|
+
} catch {
|
|
14305
|
+
}
|
|
14306
|
+
await sleep(250);
|
|
14307
|
+
}
|
|
14308
|
+
throw new Error("MESSAGE_SUBMIT_REALITY_UNCONFIRMED");
|
|
14309
|
+
}
|
|
14288
14310
|
function numeric(value, name) {
|
|
14289
14311
|
if (!Number.isInteger(value)) throw new Error(`${name}_INVALID`);
|
|
14290
14312
|
return value;
|
|
@@ -14312,11 +14334,12 @@ async function executeCommand(command) {
|
|
|
14312
14334
|
return contentCommand(tabId, { operation: "observe" });
|
|
14313
14335
|
if (command.type === "SUBMIT") {
|
|
14314
14336
|
const before = observationFor(tabId);
|
|
14337
|
+
const fingerprint = text(command.fingerprint, "FINGERPRINT");
|
|
14315
14338
|
try {
|
|
14316
14339
|
await contentCommand(tabId, {
|
|
14317
14340
|
operation: "submit",
|
|
14318
14341
|
value: text(command.text, "TEXT"),
|
|
14319
|
-
fingerprint
|
|
14342
|
+
fingerprint
|
|
14320
14343
|
});
|
|
14321
14344
|
} catch (error46) {
|
|
14322
14345
|
const replacement = await waitForObservation(
|
|
@@ -14325,7 +14348,7 @@ async function executeCommand(command) {
|
|
|
14325
14348
|
).catch(() => null);
|
|
14326
14349
|
if (!replacement) throw error46;
|
|
14327
14350
|
}
|
|
14328
|
-
return
|
|
14351
|
+
return waitForSubmittedMessage(tabId, fingerprint);
|
|
14329
14352
|
}
|
|
14330
14353
|
if (command.type === "VERIFY")
|
|
14331
14354
|
return contentCommand(tabId, {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { containsSubmittedFingerprint } from "../src/submitted-message.js";
|
|
1
2
|
const contentInstanceId = `content:${crypto.randomUUID()}`;
|
|
2
3
|
function pageState() {
|
|
3
4
|
if (document.querySelector('[role="dialog"]'))
|
|
@@ -25,7 +26,10 @@ function safeElement(selector) {
|
|
|
25
26
|
return element;
|
|
26
27
|
}
|
|
27
28
|
function hasFingerprint(fingerprint) {
|
|
28
|
-
return
|
|
29
|
+
return containsSubmittedFingerprint([...document.querySelectorAll('[data-message-author-role="user"]')].map((element) => ({
|
|
30
|
+
authorRole: element.getAttribute("data-message-author-role"),
|
|
31
|
+
textContent: element.textContent,
|
|
32
|
+
})), fingerprint);
|
|
29
33
|
}
|
|
30
34
|
chrome.runtime.onMessage.addListener((command, _sender, sendResponse) => {
|
|
31
35
|
void (async () => {
|
|
@@ -33,7 +33,6 @@ export async function createCustomGptRole(input, ports) {
|
|
|
33
33
|
: { onlineTimeoutMs: input.onlineTimeoutMs }),
|
|
34
34
|
});
|
|
35
35
|
let result;
|
|
36
|
-
let rollbackSavedRole;
|
|
37
36
|
let credential = "";
|
|
38
37
|
try {
|
|
39
38
|
const prepared = await ports.roleRegistry.prepareCredential();
|
|
@@ -55,7 +54,6 @@ export async function createCustomGptRole(input, ports) {
|
|
|
55
54
|
roleRef: result.gptId,
|
|
56
55
|
carrierUrl: result.carrierUrl,
|
|
57
56
|
}, credential);
|
|
58
|
-
rollbackSavedRole = saved.rollback;
|
|
59
57
|
if (typeof saved.credential !== "string" || saved.credential.length < 32)
|
|
60
58
|
throw new Error("WORKSPACE_ROLE_CREDENTIAL_INVALID");
|
|
61
59
|
if (saved.credential !== credential)
|
|
@@ -79,18 +77,10 @@ export async function createCustomGptRole(input, ports) {
|
|
|
79
77
|
});
|
|
80
78
|
return result;
|
|
81
79
|
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
if (rollbackSavedRole) {
|
|
84
|
-
try {
|
|
85
|
-
await rollbackSavedRole();
|
|
86
|
-
}
|
|
87
|
-
catch {
|
|
88
|
-
throw new Error("WORKSPACE_ROLE_ROLLBACK_FAILED");
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
throw error;
|
|
92
|
-
}
|
|
93
80
|
finally {
|
|
81
|
+
// Remote GPT creation is irreversible from this host. Do not roll the durable
|
|
82
|
+
// Role back after post-create validation failure; the caller can safely revalidate
|
|
83
|
+
// that same Role on the next setup instead of creating a duplicate GPT.
|
|
94
84
|
credential = "";
|
|
95
85
|
await host.close();
|
|
96
86
|
}
|
package/dist/src/index.js
CHANGED
|
@@ -240,7 +240,9 @@ export function createExecutionBrowserExtension(options) {
|
|
|
240
240
|
throw new ExecutionBrowserError("PRECONDITION_FAILED", "ROLE_URL_MISMATCH");
|
|
241
241
|
const precondition = await effectStarted(raw);
|
|
242
242
|
const opened = await options.browser.open(request.input.roleUrl);
|
|
243
|
-
await options.browser.submit(opened.tabId, `WORKER_BIND ${request.input.bootstrapFingerprint}`, request.input.bootstrapFingerprint);
|
|
243
|
+
const submitted = await options.browser.submit(opened.tabId, `WORKER_BIND ${request.input.bootstrapFingerprint}`, request.input.bootstrapFingerprint);
|
|
244
|
+
if (!(await options.browser.hasMessage(submitted.tabId, request.input.bootstrapFingerprint)))
|
|
245
|
+
throw new ExecutionBrowserError("UNKNOWN_SIDE_EFFECT", "CREATE_MESSAGE_REALITY_UNCONFIRMED");
|
|
244
246
|
const observed = await options.browser.observe(opened.tabId);
|
|
245
247
|
const identity = parseCarrierIdentity(observed.url);
|
|
246
248
|
if (identity.roleRef !== request.input.roleRef || !identity.workerRef)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function containsSubmittedFingerprint(candidates, fingerprint) {
|
|
2
|
+
if (!fingerprint)
|
|
3
|
+
return false;
|
|
4
|
+
for (const candidate of candidates) {
|
|
5
|
+
if (candidate.authorRole === "user" &&
|
|
6
|
+
candidate.textContent?.includes(fingerprint))
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
return false;
|
|
10
|
+
}
|
package/extension/background.ts
CHANGED
|
@@ -587,6 +587,7 @@ let observerRecoveryRetryCount = 0;
|
|
|
587
587
|
function runObserverRecovery() {
|
|
588
588
|
if (observerRecoveryInFlight) return observerRecoveryInFlight;
|
|
589
589
|
observerRecoveryInFlight = (async () => {
|
|
590
|
+
let recoveryNeedsRetry = false;
|
|
590
591
|
await collaborationCarrier.recoverPending(50).catch(() => undefined);
|
|
591
592
|
const signalBatch = await invokeObserverApplication(
|
|
592
593
|
"execution.listSignals",
|
|
@@ -634,18 +635,14 @@ function runObserverRecovery() {
|
|
|
634
635
|
});
|
|
635
636
|
} catch {
|
|
636
637
|
// Leave the durable signal unacknowledged for the next bounded recovery pass.
|
|
638
|
+
recoveryNeedsRetry = true;
|
|
637
639
|
}
|
|
638
640
|
}
|
|
639
641
|
}
|
|
640
642
|
const listed = await invokeTaskApplication("task.list", {}).catch(
|
|
641
643
|
() => null,
|
|
642
644
|
);
|
|
643
|
-
if (listed === null
|
|
644
|
-
observerRecoveryRetryCount += 1;
|
|
645
|
-
setTimeout(() => void runObserverRecovery(), 2_000);
|
|
646
|
-
} else if (listed !== null) {
|
|
647
|
-
observerRecoveryRetryCount = 0;
|
|
648
|
-
}
|
|
645
|
+
if (listed === null) recoveryNeedsRetry = true;
|
|
649
646
|
if (isRecord(listed) && Array.isArray(listed.tasks)) {
|
|
650
647
|
for (const candidate of listed.tasks.slice(0, 100)) {
|
|
651
648
|
if (!isRecord(candidate) || typeof candidate.taskId !== "string")
|
|
@@ -663,10 +660,22 @@ function runObserverRecovery() {
|
|
|
663
660
|
// missing roles are re-provisioned by the Host/Execution path.
|
|
664
661
|
await invokeTaskApplication("task.ensureWorkers", {
|
|
665
662
|
taskId: candidate.taskId,
|
|
666
|
-
}).catch(() =>
|
|
667
|
-
|
|
663
|
+
}).catch(() => {
|
|
664
|
+
recoveryNeedsRetry = true;
|
|
665
|
+
});
|
|
666
|
+
await taskObserver.drive(candidate.taskId).catch(() => {
|
|
667
|
+
recoveryNeedsRetry = true;
|
|
668
|
+
});
|
|
668
669
|
}
|
|
669
670
|
}
|
|
671
|
+
// A bounded retry continues the same stable Execution identities. Execution
|
|
672
|
+
// remains the no-blind-replay authority for APPLIED/NOT_APPLIED/UNKNOWN.
|
|
673
|
+
if (recoveryNeedsRetry && observerRecoveryRetryCount < 6) {
|
|
674
|
+
observerRecoveryRetryCount += 1;
|
|
675
|
+
setTimeout(() => void runObserverRecovery(), 2_000);
|
|
676
|
+
} else if (!recoveryNeedsRetry) {
|
|
677
|
+
observerRecoveryRetryCount = 0;
|
|
678
|
+
}
|
|
670
679
|
const previousSystemState = await loadSystemObserverState().catch(
|
|
671
680
|
() => null,
|
|
672
681
|
);
|
|
@@ -724,6 +733,27 @@ async function contentCommand(
|
|
|
724
733
|
return response.value;
|
|
725
734
|
}
|
|
726
735
|
|
|
736
|
+
async function waitForSubmittedMessage(
|
|
737
|
+
tabId: number,
|
|
738
|
+
fingerprint: string,
|
|
739
|
+
): Promise<ContentObservation> {
|
|
740
|
+
for (let attempt = 0; attempt < 60; attempt += 1) {
|
|
741
|
+
try {
|
|
742
|
+
const value = await contentCommand(tabId, {
|
|
743
|
+
operation: "verify",
|
|
744
|
+
fingerprint,
|
|
745
|
+
});
|
|
746
|
+
if (isRecord(value) && value.verified === true)
|
|
747
|
+
return observationFor(tabId);
|
|
748
|
+
} catch {
|
|
749
|
+
// Navigation can replace the content instance after submit. The next
|
|
750
|
+
// bounded observation/verification pass uses the newly published session.
|
|
751
|
+
}
|
|
752
|
+
await sleep(250);
|
|
753
|
+
}
|
|
754
|
+
throw new Error("MESSAGE_SUBMIT_REALITY_UNCONFIRMED");
|
|
755
|
+
}
|
|
756
|
+
|
|
727
757
|
function numeric(value: unknown, name: string): number {
|
|
728
758
|
if (!Number.isInteger(value)) throw new Error(`${name}_INVALID`);
|
|
729
759
|
return value as number;
|
|
@@ -757,11 +787,12 @@ async function executeCommand(command: BridgeCommand): Promise<unknown> {
|
|
|
757
787
|
return contentCommand(tabId, { operation: "observe" });
|
|
758
788
|
if (command.type === "SUBMIT") {
|
|
759
789
|
const before = observationFor(tabId);
|
|
790
|
+
const fingerprint = text(command.fingerprint, "FINGERPRINT");
|
|
760
791
|
try {
|
|
761
792
|
await contentCommand(tabId, {
|
|
762
793
|
operation: "submit",
|
|
763
794
|
value: text(command.text, "TEXT"),
|
|
764
|
-
fingerprint
|
|
795
|
+
fingerprint,
|
|
765
796
|
});
|
|
766
797
|
} catch (error) {
|
|
767
798
|
const replacement = await waitForObservation(
|
|
@@ -770,7 +801,7 @@ async function executeCommand(command: BridgeCommand): Promise<unknown> {
|
|
|
770
801
|
).catch(() => null);
|
|
771
802
|
if (!replacement) throw error;
|
|
772
803
|
}
|
|
773
|
-
return
|
|
804
|
+
return waitForSubmittedMessage(tabId, fingerprint);
|
|
774
805
|
}
|
|
775
806
|
if (command.type === "VERIFY")
|
|
776
807
|
return contentCommand(tabId, {
|
package/extension/content.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { containsSubmittedFingerprint } from "../src/submitted-message.js";
|
|
2
|
+
|
|
1
3
|
type PageState = "IDLE" | "BUSY" | "BLOCKED" | "UNKNOWN";
|
|
2
4
|
type ContentCommand = {
|
|
3
5
|
type: "PROFLOW_PAGE_COMMAND";
|
|
@@ -61,7 +63,15 @@ function safeElement(selector: string | undefined): HTMLElement {
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
function hasFingerprint(fingerprint: string | undefined): boolean {
|
|
64
|
-
return
|
|
66
|
+
return containsSubmittedFingerprint(
|
|
67
|
+
[...document.querySelectorAll('[data-message-author-role="user"]')].map(
|
|
68
|
+
(element) => ({
|
|
69
|
+
authorRole: element.getAttribute("data-message-author-role"),
|
|
70
|
+
textContent: element.textContent,
|
|
71
|
+
}),
|
|
72
|
+
),
|
|
73
|
+
fingerprint,
|
|
74
|
+
);
|
|
65
75
|
}
|
|
66
76
|
|
|
67
77
|
chrome.runtime.onMessage.addListener((command, _sender, sendResponse) => {
|
package/manifest.json
CHANGED
package/package.json
CHANGED
package/proflow.module.json
CHANGED
|
@@ -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.
|
|
6
|
+
"moduleVersion": "0.1.26",
|
|
7
7
|
"kind": "browser-extension",
|
|
8
8
|
"templateVersion": "1.0.0",
|
|
9
9
|
"platformCompatibility": ">=1.0.0 <2.0.0",
|