@tomflow/proflow-execution-browser-extension 0.1.26 → 0.1.28

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/DOCS.md CHANGED
@@ -6,7 +6,7 @@ Execution 领域拥有的 Chrome MV3 Extension,负责 Task UI、审批提醒
6
6
 
7
7
  ## 主要能力
8
8
 
9
- - 运行期提供 New Task 与 Side Panel UI、Task Observer、System Observer 和 Browser Effect
9
+ - 运行期提供独立 ProFlow Tasks 扩展页面、Task Observer、System Observer 和 Browser Effect;任务 UI 不再以内嵌 Side Panel 形式占用当前网页。
10
10
  - 运行期创建、恢复和唤醒 Custom GPT Conversation,稳定观察 workerRef/c-id。
11
11
  - 部署期通过独立 `/gpts/editor` / `/gpts/editor/*` Provisioning Surface 物化 Custom GPT;该分支不进入 Task/Worker 状态机。
12
12
  - 正常创建路径在单一 GPT Editor 会话中完成字段、Action Schema、API Key/Bearer、Knowledge ZIP、模型与 Capabilities 配置,再创建 Private GPT;不在 Create 后重新打开同一 GPT 做 Auth。
@@ -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.26";
50
+ moduleVersion: "0.1.28";
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.26";
63
+ readonly moduleVersion: "0.1.28";
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.26";
73
+ moduleVersion: "0.1.28";
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.26";
98
+ moduleVersion: "0.1.28";
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.26";
130
+ readonly moduleVersion: "0.1.28";
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.26";
137
+ moduleVersion: "0.1.28";
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.26";
170
+ moduleVersion: "0.1.28";
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.26";
183
+ readonly moduleVersion: "0.1.28";
184
184
  } | {
185
185
  contract: "deployment.result.v1";
186
186
  moduleRef: "execution-browser-extension";
187
- moduleVersion: "0.1.26";
187
+ moduleVersion: "0.1.28";
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.26";
204
+ readonly moduleVersion: "0.1.28";
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.26";
6
+ readonly moduleVersion: "0.1.28";
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.26",
6
+ moduleVersion: "0.1.28",
7
7
  kind: "browser-extension",
8
8
  templateVersion: "1.0.0",
9
9
  platformCompatibility: ">=1.0.0 <2.0.0",
@@ -13866,6 +13866,13 @@ function createTaskObserver(options) {
13866
13866
  return Object.freeze({ advance, drive });
13867
13867
  }
13868
13868
 
13869
+ // packages/execution-browser-extension/src/recovery-trigger.ts
13870
+ function shouldTriggerObserverRecovery(previous, current) {
13871
+ if (current.pageState !== "IDLE") return false;
13872
+ if (!previous) return true;
13873
+ return previous.pageState !== "IDLE" || previous.url !== current.url || previous.contentInstanceId !== current.contentInstanceId || previous.activityKind !== current.activityKind;
13874
+ }
13875
+
13869
13876
  // packages/execution-browser-extension/extension/background.ts
13870
13877
  var extensionInstanceId = `extension:${crypto.randomUUID()}`;
13871
13878
  var sessions = /* @__PURE__ */ new Map();
@@ -14693,6 +14700,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
14693
14700
  return true;
14694
14701
  }
14695
14702
  if (message.type === "PROFLOW_CONTENT_OBSERVATION" && message.observation && sender.tab?.id !== void 0 && sender.tab.windowId !== void 0) {
14703
+ const previous = sessions.get(sender.tab.id);
14696
14704
  const observed = {
14697
14705
  ...message.observation,
14698
14706
  tabId: sender.tab.id,
@@ -14700,7 +14708,8 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
14700
14708
  };
14701
14709
  sessions.set(sender.tab.id, observed);
14702
14710
  void persistSnapshot();
14703
- if (observed.pageState === "IDLE") void runObserverRecovery();
14711
+ if (shouldTriggerObserverRecovery(previous, observed))
14712
+ void runObserverRecovery();
14704
14713
  sendResponse({ accepted: true, extensionInstanceId });
14705
14714
  return;
14706
14715
  }
@@ -14770,6 +14779,18 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
14770
14779
  return true;
14771
14780
  }
14772
14781
  });
14782
+ async function openTaskPage() {
14783
+ const taskPageUrl = chrome.runtime.getURL("extension/tasks.html");
14784
+ const [existing] = await chrome.tabs.query({
14785
+ url: taskPageUrl,
14786
+ currentWindow: true
14787
+ });
14788
+ if (existing?.id !== void 0) {
14789
+ await chrome.tabs.update(existing.id, { active: true });
14790
+ return;
14791
+ }
14792
+ await chrome.tabs.create({ url: taskPageUrl, active: true });
14793
+ }
14773
14794
  async function startBackgroundRuntime() {
14774
14795
  await bootstrapManagedRuntimeConfig();
14775
14796
  await persistSnapshot();
@@ -14777,8 +14798,10 @@ async function startBackgroundRuntime() {
14777
14798
  void runProvisioningBridgeLoop();
14778
14799
  void runObserverRecovery();
14779
14800
  }
14801
+ chrome.action.onClicked.addListener(() => {
14802
+ void openTaskPage();
14803
+ });
14780
14804
  chrome.runtime.onInstalled.addListener(() => {
14781
- void chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true });
14782
14805
  void bootstrapManagedRuntimeConfig().then(async () => {
14783
14806
  await persistSnapshot();
14784
14807
  void runBridgeLoop();
@@ -2,7 +2,7 @@ export {};
2
2
  function element(selector) {
3
3
  const value = document.querySelector(selector);
4
4
  if (!value)
5
- throw new Error(`SIDE_PANEL_TARGET_MISSING:${selector}`);
5
+ throw new Error(`TASK_PAGE_TARGET_MISSING:${selector}`);
6
6
  return value;
7
7
  }
8
8
  const connection = element("#connection");
@@ -81,7 +81,7 @@ async function refreshApprovals() {
81
81
  await approvalApplication("approval.deny", {
82
82
  approvalRef: approval.approvalRef,
83
83
  expectedVersion: approval.version,
84
- reason: "Denied from Extension Side Panel",
84
+ reason: "Denied from Extension Task Page",
85
85
  });
86
86
  await refreshApprovals();
87
87
  }));
@@ -116,7 +116,7 @@ async function loadTask(taskId) {
116
116
  await taskApplication("node.reopen", {
117
117
  taskId: selected.taskId,
118
118
  nodeId: node.nodeId,
119
- reason: "Human reopen from Extension Side Panel",
119
+ reason: "Human reopen from Extension Task Page",
120
120
  expectedTaskVersion: selected.version,
121
121
  idempotencyKey: requestId("extension-reopen"),
122
122
  });
@@ -0,0 +1,8 @@
1
+ type RecoveryObservation = {
2
+ url: string;
3
+ contentInstanceId: string;
4
+ pageState: "IDLE" | "BUSY" | "BLOCKED" | "UNKNOWN";
5
+ activityKind: string | null;
6
+ };
7
+ export declare function shouldTriggerObserverRecovery(previous: RecoveryObservation | undefined, current: RecoveryObservation): boolean;
8
+ export {};
@@ -0,0 +1,10 @@
1
+ export function shouldTriggerObserverRecovery(previous, current) {
2
+ if (current.pageState !== "IDLE")
3
+ return false;
4
+ if (!previous)
5
+ return true;
6
+ return (previous.pageState !== "IDLE" ||
7
+ previous.url !== current.url ||
8
+ previous.contentInstanceId !== current.contentInstanceId ||
9
+ previous.activityKind !== current.activityKind);
10
+ }
@@ -12,6 +12,7 @@ import {
12
12
  type TaskObserverDiagnosticAssessment,
13
13
  type TaskObserverDiagnosticFailure,
14
14
  } from "../src/task-observer.js";
15
+ import { shouldTriggerObserverRecovery } from "../src/recovery-trigger.js";
15
16
 
16
17
  type PageState = "IDLE" | "BUSY" | "BLOCKED" | "UNKNOWN";
17
18
  type ActivityKind =
@@ -111,13 +112,11 @@ type ChromeRuntime = {
111
112
  set(value: Record<string, unknown>): Promise<void>;
112
113
  };
113
114
  };
114
- sidePanel: {
115
- setPanelBehavior(options: {
116
- openPanelOnActionClick: boolean;
117
- }): Promise<void>;
115
+ action: {
116
+ onClicked: { addListener(listener: () => void): void };
118
117
  };
119
118
  tabs: {
120
- query(query: { url?: string }): Promise<ChromeTab[]>;
119
+ query(query: { url?: string; currentWindow?: boolean }): Promise<ChromeTab[]>;
121
120
  get(tabId: number): Promise<ChromeTab>;
122
121
  create(create: { url: string; active: boolean }): Promise<ChromeTab>;
123
122
  reload(tabId: number): Promise<void>;
@@ -1218,6 +1217,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
1218
1217
  sender.tab?.id !== undefined &&
1219
1218
  sender.tab.windowId !== undefined
1220
1219
  ) {
1220
+ const previous = sessions.get(sender.tab.id);
1221
1221
  const observed: ContentObservation = {
1222
1222
  ...message.observation,
1223
1223
  tabId: sender.tab.id,
@@ -1225,7 +1225,8 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
1225
1225
  };
1226
1226
  sessions.set(sender.tab.id, observed);
1227
1227
  void persistSnapshot();
1228
- if (observed.pageState === "IDLE") void runObserverRecovery();
1228
+ if (shouldTriggerObserverRecovery(previous, observed))
1229
+ void runObserverRecovery();
1229
1230
  sendResponse({ accepted: true, extensionInstanceId });
1230
1231
  return;
1231
1232
  }
@@ -1316,6 +1317,19 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
1316
1317
  }
1317
1318
  });
1318
1319
 
1320
+ async function openTaskPage(): Promise<void> {
1321
+ const taskPageUrl = chrome.runtime.getURL("extension/tasks.html");
1322
+ const [existing] = await chrome.tabs.query({
1323
+ url: taskPageUrl,
1324
+ currentWindow: true,
1325
+ });
1326
+ if (existing?.id !== undefined) {
1327
+ await chrome.tabs.update(existing.id, { active: true });
1328
+ return;
1329
+ }
1330
+ await chrome.tabs.create({ url: taskPageUrl, active: true });
1331
+ }
1332
+
1319
1333
  async function startBackgroundRuntime(): Promise<void> {
1320
1334
  await bootstrapManagedRuntimeConfig();
1321
1335
  await persistSnapshot();
@@ -1324,8 +1338,10 @@ async function startBackgroundRuntime(): Promise<void> {
1324
1338
  void runObserverRecovery();
1325
1339
  }
1326
1340
 
1341
+ chrome.action.onClicked.addListener(() => {
1342
+ void openTaskPage();
1343
+ });
1327
1344
  chrome.runtime.onInstalled.addListener(() => {
1328
- void chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true });
1329
1345
  void bootstrapManagedRuntimeConfig().then(async () => {
1330
1346
  await persistSnapshot();
1331
1347
  void runBridgeLoop();
@@ -29,7 +29,7 @@
29
29
 
30
30
  <section>
31
31
  <h2>Task Application</h2>
32
- <p>Connects the Side Panel to the loopback platform-host application surface. This credential is separate from Role and Browser-bridge credentials.</p>
32
+ <p>Connects the independent ProFlow Tasks page to the loopback platform-host application surface. This credential is separate from Role and Browser-bridge credentials.</p>
33
33
  <form id="task-application-form">
34
34
  <label>Platform-host endpoint <input id="task-application-endpoint" required placeholder="http://127.0.0.1:47830" /></label>
35
35
  <label>Task application token <input id="task-application-token" type="password" required autocomplete="off" /></label>
@@ -3,25 +3,28 @@
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width" />
6
- <title>ProFlow</title>
6
+ <title>ProFlow Tasks</title>
7
7
  <style>
8
- body { font: 13px system-ui; margin: 12px; }
9
- section { border-top: 1px solid #ddd; margin-top: 14px; padding-top: 10px; }
8
+ body { background: #f7f7f8; color: #18181b; font: 14px system-ui; margin: 0; }
9
+ main { box-sizing: border-box; margin: 0 auto; max-width: 1180px; padding: 28px; }
10
+ header { margin-bottom: 20px; }
11
+ section { background: #fff; border: 1px solid #e4e4e7; border-radius: 10px; margin-top: 14px; padding: 16px; }
10
12
  label { display: block; margin: 8px 0; }
11
- input, textarea { box-sizing: border-box; display: block; margin-top: 4px; width: 100%; }
12
- textarea { min-height: 72px; }
13
- button { margin: 4px 4px 4px 0; padding: 5px 9px; }
13
+ input, textarea { box-sizing: border-box; display: block; margin-top: 4px; padding: 8px; width: 100%; }
14
+ textarea { min-height: 84px; }
15
+ button { margin: 4px 4px 4px 0; padding: 7px 11px; }
14
16
  button[disabled] { opacity: .55; }
15
- .task { border: 1px solid #ddd; margin: 6px 0; padding: 7px; }
16
- .meta { color: #555; font-size: 12px; }
17
+ .task { border: 1px solid #e4e4e7; border-radius: 8px; margin: 8px 0; padding: 10px; }
18
+ .meta { color: #52525b; font-size: 12px; }
17
19
  #error { color: #a00; white-space: pre-wrap; }
18
20
  #result { white-space: pre-wrap; }
19
- #browser-status { max-height: 180px; overflow: auto; }
21
+ #browser-status { max-height: 220px; overflow: auto; }
20
22
  </style>
21
23
  </head>
22
24
  <body>
25
+ <main>
23
26
  <header>
24
- <h1>ProFlow</h1>
27
+ <h1>ProFlow Tasks</h1>
25
28
  <div id="connection" class="meta">Connecting…</div>
26
29
  </header>
27
30
 
@@ -54,7 +57,7 @@
54
57
 
55
58
  <section>
56
59
  <h2>Execution Approval</h2>
57
- <p class="meta">Approval is an Execution-owned durable fact. This panel only sends authenticated human decisions to the Execution Owner.</p>
60
+ <p class="meta">Approval is an Execution-owned durable fact. This page only sends authenticated human decisions to the Execution Owner.</p>
58
61
  <button id="refresh-approvals" type="button">Refresh approvals</button>
59
62
  <div id="approvals"></div>
60
63
  </section>
@@ -72,6 +75,7 @@
72
75
 
73
76
  <p id="error" role="alert"></p>
74
77
  <pre id="result" role="status"></pre>
75
- <script type="module" src="../dist/extension/side-panel.js"></script>
78
+ <script type="module" src="../dist/extension/tasks.js"></script>
79
+ </main>
76
80
  </body>
77
81
  </html>
@@ -47,7 +47,7 @@ type TaskView = TaskSummary & {
47
47
 
48
48
  function element<T extends HTMLElement>(selector: string): T {
49
49
  const value = document.querySelector<T>(selector);
50
- if (!value) throw new Error(`SIDE_PANEL_TARGET_MISSING:${selector}`);
50
+ if (!value) throw new Error(`TASK_PAGE_TARGET_MISSING:${selector}`);
51
51
  return value;
52
52
  }
53
53
 
@@ -152,7 +152,7 @@ async function refreshApprovals() {
152
152
  await approvalApplication("approval.deny", {
153
153
  approvalRef: approval.approvalRef,
154
154
  expectedVersion: approval.version,
155
- reason: "Denied from Extension Side Panel",
155
+ reason: "Denied from Extension Task Page",
156
156
  });
157
157
  await refreshApprovals();
158
158
  }),
@@ -189,7 +189,7 @@ async function loadTask(taskId: string) {
189
189
  await taskApplication("node.reopen", {
190
190
  taskId: selected.taskId,
191
191
  nodeId: node.nodeId,
192
- reason: "Human reopen from Extension Side Panel",
192
+ reason: "Human reopen from Extension Task Page",
193
193
  expectedTaskVersion: selected.version,
194
194
  idempotencyKey: requestId("extension-reopen"),
195
195
  });
package/manifest.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "ProFlow Execution Browser",
4
- "version": "0.1.26",
4
+ "version": "0.1.28",
5
5
  "permissions": [
6
6
  "tabs",
7
- "storage",
8
- "sidePanel"
7
+ "storage"
9
8
  ],
10
9
  "host_permissions": [
11
10
  "https://chatgpt.com/*",
@@ -36,8 +35,8 @@
36
35
  "run_at": "document_idle"
37
36
  }
38
37
  ],
39
- "side_panel": {
40
- "default_path": "extension/side-panel.html"
38
+ "action": {
39
+ "default_title": "Open ProFlow Tasks"
41
40
  },
42
41
  "options_page": "extension/options.html"
43
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomflow/proflow-execution-browser-extension",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "Execution-owned MV3 Browser executor, evidence provider and browser application surface.",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -27,8 +27,8 @@
27
27
  "SETUP.md"
28
28
  ],
29
29
  "dependencies": {
30
- "@tomflow/proflow-execution-contracts": "^0.1.10",
31
- "@tomflow/proflow-module-contract": "^0.1.13"
30
+ "@tomflow/proflow-module-contract": "^0.1.13",
31
+ "@tomflow/proflow-execution-contracts": "^0.1.10"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@tomflow/proflow-execution-runtime": "^0.1.15",
@@ -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.26",
6
+ "moduleVersion": "0.1.28",
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,31 +0,0 @@
1
- # @tomflow/proflow-execution-browser-extension
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
-
15
- ## 0.1.24
16
-
17
- ### Patch Changes
18
-
19
- - Cover Chrome's observed delayed Secure Preferences flush while waiting for unpacked-extension registration to become enabled after pairing.
20
-
21
- ## 0.1.23
22
-
23
- ### Patch Changes
24
-
25
- - Wait for Chrome unpacked-extension registration to become observably enabled after heartbeat pairing before Browser setup reports success.
26
-
27
- ## 0.1.22
28
-
29
- ### Patch Changes
30
-
31
- - Make Browser Extension static materialization version-idempotent, freeze real-user install/remove acceptance paths, and remove unsupported Reload/Disable-Enable test scenarios.
File without changes