@tomflow/chatloop-extension 0.3.36 → 0.3.38

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.
@@ -125,7 +125,15 @@
125
125
  audit.messageEvidence[id] = read?.result || {status: "EMPTY_RESULT"};
126
126
  // Only dedicated tests created by this diagnostic may expose their
127
127
  // harmless assistant text, for verifying strict status parsing.
128
- if (owned.some(item => item.id === id || (item.id === run?.sourceTabId && id === run?.tabId))) {
128
+ const ownedAcceptance = owned.some(item => item.id === id
129
+ || (item.id === run?.sourceTabId && id === run?.tabId));
130
+ // The existing read-only Audit may also inspect the CURRENT, exactly
131
+ // matched Worker-owned Chat. It drives the Observer's existing poll,
132
+ // never types into a conversation or creates an Action. Never persist
133
+ // unapproved user reply text for ordinary project sessions.
134
+ const currentOwner = run?.tabId === id
135
+ && audit.messageEvidence[id]?.url === "https://chatgpt.com" + run.page;
136
+ if (ownedAcceptance || currentOwner) {
129
137
  const proof = await chrome.tabs.sendMessage(id,
130
138
  {type: "CHAT_LOOP_TURN_VERIFY_V1"}).catch(() => null);
131
139
  audit.messageEvidence[id].observerStatus = proof?.status || "UNAVAILABLE";
@@ -135,7 +143,7 @@
135
143
  status: observed.status, reason: observed.reason, page: observed.page,
136
144
  userKey: observed.userKey, eventCount: observed.eventCount,
137
145
  observedAt: observed.observedAt} : null;
138
- audit.messageEvidence[id].observerReplyText =
146
+ if (ownedAcceptance) audit.messageEvidence[id].observerReplyText =
139
147
  typeof proof?.replyText === "string" ? proof.replyText.slice(0, 3000) : null;
140
148
  }
141
149
  } catch {
@@ -8,14 +8,19 @@
8
8
  const match = MARKER.exec(lines.at(-1)?.trim() || "");
9
9
  if (!match) return "UNKNOWN";
10
10
  const markers = text.match(ALL_MARKERS) || [];
11
- // A portable handoff packet may legitimately quote DONE/CONTINUE rules for
12
- // the next Chat. Only its final HANDOFF token must be unique; all other
13
- // statuses still require a single marker in the entire reply.
11
+ // Status is a protocol line, not any occurrence of its token in prose.
12
+ // A reply may describe a previous Turn as, e.g., "it ended with
13
+ // [CHAT_LOOP_STATUS:CONTINUE]" and still legitimately finish with DONE.
14
+ // Require exactly one standalone status line, at the end. Never accept
15
+ // two standalone statuses (even if they have the same value).
16
+ const standalone = lines.filter(line => MARKER.test(line.trim()));
17
+ // Historical HANDOFF packets may embed prior standalone statuses. Keep
18
+ // its compatibility rule while requiring only one HANDOFF token total.
14
19
  if (match[1] === "HANDOFF") {
15
20
  return markers.filter(v => v === "[CHAT_LOOP_STATUS:HANDOFF]").length === 1
16
21
  ? "HANDOFF" : "UNKNOWN";
17
22
  }
18
- if (markers.length !== 1) return "UNKNOWN";
23
+ if (standalone.length !== 1) return "UNKNOWN";
19
24
  return match[1];
20
25
  }
21
26
  function fingerprint(text) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Chat Loop Extension",
4
- "version": "0.3.36",
4
+ "version": "0.3.38",
5
5
  "description": "Chat Loop browser companion: Eye actions, Turn observer, Continue and Handoff Actions",
6
6
  "permissions": [
7
7
  "activeTab",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomflow/chatloop-extension",
3
- "version": "0.3.36",
3
+ "version": "0.3.38",
4
4
  "type": "module",
5
5
  "description": "Chat Loop Extension package: nine formal Action pages and its own native CLI bridge",
6
6
  "bin": {