@tomflow/proflow-execution-browser-extension 0.1.1 → 0.1.3

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,17 @@
1
1
  # @tomflow/proflow-execution-browser-extension
2
2
 
3
+ ## 0.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Real-1 final remediation and black-box release closure
8
+
9
+ ## 0.1.2
10
+
11
+ ### Patch Changes
12
+
13
+ - Close the Real-1 global Platform control-plane contract across every published ProFlow package. Platform CLI now owns one durable global Workspace binding with canonical identity, cross-process operation locking, cwd/`--workspace` install targeting, cross-directory instance commands, whole-instance uninstall/rebind, and deterministic npm/yarn/pnpm Workspace package-manager selection. Every package-owned install entry, including newly generated Module Template packages, delegates to the Shell-global `platform` command and fails closed when that global CLI is unavailable; Deployment Conformance and the formal test plans mechanically enforce the same rule across all 24 packages.
14
+
3
15
  ## 0.1.1
4
16
 
5
17
  ### Patch Changes
@@ -3,7 +3,7 @@ export declare const behaviorAdapter: {
3
3
  result: {
4
4
  contract: "deployment.result.v1";
5
5
  moduleRef: "execution-browser-extension";
6
- moduleVersion: "0.1.1";
6
+ moduleVersion: "0.1.3";
7
7
  ok: boolean;
8
8
  status: string;
9
9
  };
@@ -13,7 +13,7 @@ export declare const behaviorAdapter: {
13
13
  result: {
14
14
  contract: "deployment.result.v1";
15
15
  moduleRef: "execution-browser-extension";
16
- moduleVersion: "0.1.1";
16
+ moduleVersion: "0.1.3";
17
17
  ok: boolean;
18
18
  status: string;
19
19
  };
@@ -23,7 +23,7 @@ export declare const behaviorAdapter: {
23
23
  result: {
24
24
  contract: "deployment.result.v1";
25
25
  moduleRef: "execution-browser-extension";
26
- moduleVersion: "0.1.1";
26
+ moduleVersion: "0.1.3";
27
27
  ok: boolean;
28
28
  status: string;
29
29
  actionRequired: {
@@ -37,7 +37,7 @@ export declare const behaviorAdapter: {
37
37
  result: {
38
38
  contract: "deployment.result.v1";
39
39
  moduleRef: "execution-browser-extension";
40
- moduleVersion: "0.1.1";
40
+ moduleVersion: "0.1.3";
41
41
  ok: boolean;
42
42
  status: string;
43
43
  checks: {
@@ -52,10 +52,25 @@ export declare const behaviorAdapter: {
52
52
  result: {
53
53
  contract: "deployment.result.v1";
54
54
  moduleRef: "execution-browser-extension";
55
- moduleVersion: "0.1.1";
55
+ moduleVersion: "0.1.3";
56
56
  ok: boolean;
57
57
  status: string;
58
58
  };
59
59
  observedEffects: never[];
60
60
  };
61
61
  };
62
+ export declare function browserExtensionLoadDir(workspaceRoot: string): string;
63
+ export declare function materializeProductionConfig(input: {
64
+ moduleRef: string;
65
+ config: Record<string, string>;
66
+ workspaceRoot: string;
67
+ }): Promise<{
68
+ loadDir: string;
69
+ }>;
70
+ export declare function createProductionBinding(input: {
71
+ moduleRef: string;
72
+ config: Record<string, string>;
73
+ workspaceRoot: string;
74
+ }): {
75
+ behaviorAdapter: Record<string, unknown>;
76
+ };
@@ -1,3 +1,6 @@
1
+ import { cp, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { basename, dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
1
4
  import { descriptor } from "./descriptor.js";
2
5
  const base = {
3
6
  contract: "deployment.result.v1",
@@ -45,3 +48,177 @@ export const behaviorAdapter = {
45
48
  observedEffects: [],
46
49
  }),
47
50
  };
51
+ function loopbackEndpoint(value, key) {
52
+ const url = new URL(value);
53
+ if (url.protocol !== "http:" ||
54
+ url.hostname !== "127.0.0.1" ||
55
+ url.pathname !== "/" ||
56
+ url.search !== "" ||
57
+ url.hash !== "") {
58
+ throw new Error(`${key} must be a loopback HTTP origin`);
59
+ }
60
+ return value.replace(/\/$/, "");
61
+ }
62
+ async function credential(file, key) {
63
+ const token = (await readFile(file, "utf8")).trim();
64
+ if (token.length < 32)
65
+ throw new Error(`${key} must contain at least 32 characters`);
66
+ return token;
67
+ }
68
+ function packageRoot() {
69
+ const candidate = dirname(dirname(fileURLToPath(import.meta.url)));
70
+ return basename(candidate) === "dist" ? dirname(candidate) : candidate;
71
+ }
72
+ export function browserExtensionLoadDir(workspaceRoot) {
73
+ return join(workspaceRoot, ".proflow", "deployment", "browser-extension", "execution-browser-extension");
74
+ }
75
+ export async function materializeProductionConfig(input) {
76
+ const required = [
77
+ "bridge.endpoint",
78
+ "bridge.token",
79
+ "taskApplication.endpoint",
80
+ "taskApplication.token",
81
+ "approvalApplication.endpoint",
82
+ "approvalApplication.token",
83
+ ];
84
+ for (const key of required) {
85
+ if (!input.config[key])
86
+ throw new Error(`missing required browser config ${key}`);
87
+ }
88
+ const runtimeConfig = {
89
+ proflowRuntimeBridge: {
90
+ endpoint: loopbackEndpoint(input.config["bridge.endpoint"] ?? "", "bridge.endpoint"),
91
+ token: await credential(input.config["bridge.token"] ?? "", "bridge.token"),
92
+ },
93
+ proflowTaskApplication: {
94
+ endpoint: loopbackEndpoint(input.config["taskApplication.endpoint"] ?? "", "taskApplication.endpoint"),
95
+ token: await credential(input.config["taskApplication.token"] ?? "", "taskApplication.token"),
96
+ },
97
+ proflowApprovalApplication: {
98
+ endpoint: loopbackEndpoint(input.config["approvalApplication.endpoint"] ?? "", "approvalApplication.endpoint"),
99
+ token: await credential(input.config["approvalApplication.token"] ?? "", "approvalApplication.token"),
100
+ },
101
+ };
102
+ const sourceRoot = packageRoot();
103
+ const loadDir = browserExtensionLoadDir(input.workspaceRoot);
104
+ await mkdir(join(loadDir, "dist"), { recursive: true });
105
+ await cp(join(sourceRoot, "dist", "extension"), join(loadDir, "dist", "extension"), {
106
+ recursive: true,
107
+ force: true,
108
+ });
109
+ await cp(join(sourceRoot, "extension"), join(loadDir, "extension"), {
110
+ recursive: true,
111
+ force: true,
112
+ });
113
+ await cp(join(sourceRoot, "manifest.json"), join(loadDir, "manifest.json"), {
114
+ force: true,
115
+ });
116
+ await writeFile(join(loadDir, "runtime-config.json"), `${JSON.stringify(runtimeConfig, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
117
+ return { loadDir };
118
+ }
119
+ async function readBrowserVerificationEvidence(file, expectedLoadDir) {
120
+ if (!file)
121
+ return undefined;
122
+ try {
123
+ const raw = JSON.parse(await readFile(file, "utf8"));
124
+ if (raw.contract !== "proflow.browser-extension-verification.v1" ||
125
+ raw.moduleVersion !== descriptor.moduleVersion ||
126
+ raw.loadDir !== expectedLoadDir ||
127
+ typeof raw.extensionId !== "string" ||
128
+ raw.extensionId.length < 16 ||
129
+ raw.serviceWorker !== "RUNNING" ||
130
+ typeof raw.observedAt !== "string" ||
131
+ Number.isNaN(Date.parse(raw.observedAt)))
132
+ return undefined;
133
+ return raw;
134
+ }
135
+ catch {
136
+ return undefined;
137
+ }
138
+ }
139
+ export function createProductionBinding(input) {
140
+ const loadDir = browserExtensionLoadDir(input.workspaceRoot);
141
+ const verificationEvidenceFile = input.config.verificationEvidenceFile;
142
+ const boundBase = {
143
+ contract: "deployment.result.v1",
144
+ moduleRef: descriptor.moduleRef,
145
+ moduleVersion: descriptor.moduleVersion,
146
+ };
147
+ const configured = async () => {
148
+ try {
149
+ const raw = JSON.parse(await readFile(join(loadDir, "runtime-config.json"), "utf8"));
150
+ return typeof raw === "object" && raw !== null;
151
+ }
152
+ catch {
153
+ return false;
154
+ }
155
+ };
156
+ return {
157
+ behaviorAdapter: {
158
+ ...behaviorAdapter,
159
+ preflight: async () => ({
160
+ result: (await configured())
161
+ ? { ...boundBase, ok: true, status: "SUCCEEDED" }
162
+ : {
163
+ ...boundBase,
164
+ ok: false,
165
+ status: "ACTION_REQUIRED",
166
+ actionRequired: {
167
+ action: "configure-browser-extension",
168
+ description: `Materialize Browser Extension runtime config before loading ${loadDir}`,
169
+ },
170
+ },
171
+ observedEffects: [],
172
+ }),
173
+ status: async () => ({
174
+ result: (await configured())
175
+ ? {
176
+ ...boundBase,
177
+ ok: true,
178
+ status: "SUCCEEDED",
179
+ data: { loadDir, configMaterialized: true },
180
+ }
181
+ : {
182
+ ...boundBase,
183
+ ok: false,
184
+ status: "ACTION_REQUIRED",
185
+ actionRequired: {
186
+ action: "configure-browser-extension",
187
+ description: "Browser Extension runtime config is not materialized",
188
+ },
189
+ },
190
+ observedEffects: [],
191
+ }),
192
+ verify: async () => {
193
+ const evidence = await readBrowserVerificationEvidence(verificationEvidenceFile, loadDir);
194
+ return {
195
+ result: (await configured()) && evidence
196
+ ? {
197
+ ...boundBase,
198
+ ok: true,
199
+ status: "SUCCEEDED",
200
+ checks: [
201
+ {
202
+ id: "real-carrier-e3-e4",
203
+ status: "PASS",
204
+ message: `Real Chrome loaded extension ${evidence.extensionId} from ${loadDir} and its MV3 Service Worker was observed running`,
205
+ },
206
+ ],
207
+ }
208
+ : {
209
+ ...boundBase,
210
+ ok: false,
211
+ status: "ACTION_REQUIRED",
212
+ actionRequired: {
213
+ action: "verify-real-chrome-extension",
214
+ description: `Load ${loadDir} in real Chrome and write verified evidence to ${verificationEvidenceFile ?? "the configured verificationEvidenceFile"}`,
215
+ },
216
+ },
217
+ observedEffects: evidence
218
+ ? ["Observes real Chrome MV3 load evidence"]
219
+ : [],
220
+ };
221
+ },
222
+ },
223
+ };
224
+ }
@@ -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.1";
6
+ readonly moduleVersion: "0.1.3";
7
7
  readonly kind: "browser-extension";
8
8
  readonly templateVersion: "1.0.0";
9
9
  readonly platformCompatibility: ">=1.0.0 <2.0.0";
@@ -41,10 +41,10 @@ export declare const descriptor: {
41
41
  readonly description: "Loopback Browser Reality Bridge endpoint";
42
42
  }, {
43
43
  readonly key: "bridge.token";
44
- readonly type: "secretRef";
44
+ readonly type: "path";
45
45
  readonly required: true;
46
46
  readonly sensitive: true;
47
- readonly description: "Browser Reality Bridge extension token reference";
47
+ readonly description: "File containing the Browser Reality Bridge extension token";
48
48
  }, {
49
49
  readonly key: "taskApplication.endpoint";
50
50
  readonly type: "url";
@@ -52,10 +52,10 @@ export declare const descriptor: {
52
52
  readonly description: "Loopback Platform Host Task application endpoint";
53
53
  }, {
54
54
  readonly key: "taskApplication.token";
55
- readonly type: "secretRef";
55
+ readonly type: "path";
56
56
  readonly required: true;
57
57
  readonly sensitive: true;
58
- readonly description: "Platform Host Task application token reference";
58
+ readonly description: "File containing the Platform Host Task application token";
59
59
  }, {
60
60
  readonly key: "approvalApplication.endpoint";
61
61
  readonly type: "url";
@@ -63,10 +63,15 @@ export declare const descriptor: {
63
63
  readonly description: "Loopback Platform Host Approval application endpoint";
64
64
  }, {
65
65
  readonly key: "approvalApplication.token";
66
- readonly type: "secretRef";
66
+ readonly type: "path";
67
67
  readonly required: true;
68
68
  readonly sensitive: true;
69
- readonly description: "Platform Host Approval application token reference";
69
+ readonly description: "File containing the Platform Host Approval application token";
70
+ }, {
71
+ readonly key: "verificationEvidenceFile";
72
+ readonly type: "path";
73
+ readonly required: true;
74
+ readonly description: "JSON evidence file written after real Chrome loads the Deployment-managed MV3 extension and its Service Worker runs";
70
75
  }, {
71
76
  readonly key: "chromeRuntimeModuleRef";
72
77
  readonly type: "moduleRef";
@@ -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.1",
6
+ moduleVersion: "0.1.3",
7
7
  kind: "browser-extension",
8
8
  templateVersion: "1.0.0",
9
9
  platformCompatibility: ">=1.0.0 <2.0.0",
@@ -34,10 +34,10 @@ export const descriptor = {
34
34
  },
35
35
  {
36
36
  key: "bridge.token",
37
- type: "secretRef",
37
+ type: "path",
38
38
  required: true,
39
39
  sensitive: true,
40
- description: "Browser Reality Bridge extension token reference",
40
+ description: "File containing the Browser Reality Bridge extension token",
41
41
  },
42
42
  {
43
43
  key: "taskApplication.endpoint",
@@ -47,10 +47,10 @@ export const descriptor = {
47
47
  },
48
48
  {
49
49
  key: "taskApplication.token",
50
- type: "secretRef",
50
+ type: "path",
51
51
  required: true,
52
52
  sensitive: true,
53
- description: "Platform Host Task application token reference",
53
+ description: "File containing the Platform Host Task application token",
54
54
  },
55
55
  {
56
56
  key: "approvalApplication.endpoint",
@@ -60,10 +60,16 @@ export const descriptor = {
60
60
  },
61
61
  {
62
62
  key: "approvalApplication.token",
63
- type: "secretRef",
63
+ type: "path",
64
64
  required: true,
65
65
  sensitive: true,
66
- description: "Platform Host Approval application token reference",
66
+ description: "File containing the Platform Host Approval application token",
67
+ },
68
+ {
69
+ key: "verificationEvidenceFile",
70
+ type: "path",
71
+ required: true,
72
+ description: "JSON evidence file written after real Chrome loads the Deployment-managed MV3 extension and its Service Worker runs",
67
73
  },
68
74
  {
69
75
  key: "chromeRuntimeModuleRef",