@youdie006/prodex 0.40.35 → 0.40.37
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/dist/chatgpt-browser.js +24 -8
- package/docs/releasing.md +39 -0
- package/package.json +1 -1
package/dist/chatgpt-browser.js
CHANGED
|
@@ -311,12 +311,19 @@ export const CHATGPT_RENDERED_MESSAGE_TEXT_JS = `
|
|
|
311
311
|
}
|
|
312
312
|
const lines = findAll(node, (n) => hasClass(n, "cm-line")).map((line) => line.textContent || "");
|
|
313
313
|
const pre = tagOf(node) === "pre" ? node : findAll(node, (n) => tagOf(n) === "pre")[0];
|
|
314
|
-
|
|
314
|
+
// Some blocks keep their text in a source element with no <pre>
|
|
315
|
+
// (measured 2026-10-19), and the whole block's text carries the toolbar.
|
|
316
|
+
const source = pre || findAll(node, (n) => attr(n, "data-code-block-source") !== null)[0];
|
|
317
|
+
const code = fullCode !== null ? trimEnd(fullCode) : lines.length > 0 ? lines.join(NL) : trimEnd(source ? source.textContent || "" : node.textContent || "");
|
|
315
318
|
const editor = findAll(node, (n) => attr(n, "data-language") !== null)[0];
|
|
316
319
|
const toolbar = findAll(node, (n) => attr(n, "data-markdown-copy") === "exclude")[0];
|
|
317
320
|
const label = toolbar ? collapse(findAll(toolbar, (n) => n.nodeType === 1 && tagOf(n) === "div" && children(n).every((c) => c.nodeType === 3)).map((n) => n.textContent || "")[0] || "").trim() : "";
|
|
318
321
|
const language = ((editor && attr(editor, "data-language")) || label).trim().toLowerCase();
|
|
319
|
-
|
|
322
|
+
// A fence must be longer than any backtick run inside, or a block that
|
|
323
|
+
// shows a fenced example is closed early by it.
|
|
324
|
+
const longestRun = (code.match(new RegExp(BT + "+", "g")) || []).reduce((most, run) => Math.max(most, run.length), 0);
|
|
325
|
+
const fence = BT.repeat(Math.max(3, longestRun + 1));
|
|
326
|
+
return fence + language + NL + code + NL + fence;
|
|
320
327
|
};
|
|
321
328
|
const table = (node) => {
|
|
322
329
|
const cell = (value) => collapse(value).trim().split("|").join(String.fromCharCode(92) + "|");
|
|
@@ -492,6 +499,17 @@ const CHATGPT_GENERATING_CONTROL_PATTERN = /\bstop\s+(?:generating|responding|re
|
|
|
492
499
|
// is matched only inside the composer's form, where the send control lives,
|
|
493
500
|
// so a "Stop" elsewhere on the page cannot answer for it.
|
|
494
501
|
export const CHATGPT_STREAMING_SELECTOR = '[data-testid="stop-button"],form button[aria-label="Stop"],form button[aria-label="중지"],[data-message-author-role="assistant"][aria-busy="true"],[data-message-author-role="assistant"] [aria-busy="true"]';
|
|
502
|
+
/**
|
|
503
|
+
* Whether a streaming signal is actually on screen. Measured 2026-10-20: after
|
|
504
|
+
* a Pro answer finished, the composer kept a zero-size, undisplayed "Stop"
|
|
505
|
+
* button, and its mere presence held a finished answer as "generating" for
|
|
506
|
+
* the whole budget. A message drawn through display: contents has no box of
|
|
507
|
+
* its own, so its children decide.
|
|
508
|
+
*/
|
|
509
|
+
export const CHATGPT_STREAMING_SIGNAL_JS = `
|
|
510
|
+
const streamingSignalVisible = () =>
|
|
511
|
+
[...document.querySelectorAll(${JSON.stringify(CHATGPT_STREAMING_SELECTOR)})].some((node) =>
|
|
512
|
+
node.getClientRects().length > 0 || [...(node.children || [])].some((child) => child.getClientRects().length > 0));`;
|
|
495
513
|
export function defaultChatGptProfileDir() {
|
|
496
514
|
return path.join(os.homedir(), ".local", "share", "prodex", "chrome-chatgpt-pro");
|
|
497
515
|
}
|
|
@@ -5325,11 +5343,10 @@ export const CHATGPT_THINKING_PLACEHOLDER_JS = `ansLines.length <= 1 && (/^(생
|
|
|
5325
5343
|
export function statusExpression() {
|
|
5326
5344
|
const excludedTextSelector = JSON.stringify(CHATGPT_RUNTIME_BLOCKER_TEXT_EXCLUDED_ANCESTORS);
|
|
5327
5345
|
const blockerScanExcludedSelector = JSON.stringify(CHATGPT_BLOCKER_SCAN_EXCLUDED_ANCESTORS);
|
|
5328
|
-
const streamingSelector = JSON.stringify(CHATGPT_STREAMING_SELECTOR);
|
|
5329
5346
|
const responseChoiceSelector = JSON.stringify(CHATGPT_RESPONSE_CHOICE_SELECTOR);
|
|
5330
5347
|
const generatingControlPattern = JSON.stringify(CHATGPT_GENERATING_CONTROL_PATTERN.source);
|
|
5331
5348
|
const generatingControlFlags = JSON.stringify(CHATGPT_GENERATING_CONTROL_PATTERN.flags);
|
|
5332
|
-
return `(() => {${CHATGPT_MODEL_HINTS_JS}
|
|
5349
|
+
return `(() => {${CHATGPT_MODEL_HINTS_JS}${CHATGPT_STREAMING_SIGNAL_JS}
|
|
5333
5350
|
${composerExpressionHelpers()}
|
|
5334
5351
|
const text = document.body?.innerText || "";
|
|
5335
5352
|
const runtimeExcludedTextSelector = ${excludedTextSelector};
|
|
@@ -5380,7 +5397,7 @@ export function statusExpression() {
|
|
|
5380
5397
|
blockerScanTextSample: blockerScanText.slice(0, 12000),
|
|
5381
5398
|
visibleButtonLabels,
|
|
5382
5399
|
hasComposer,
|
|
5383
|
-
generating: placeholder ||
|
|
5400
|
+
generating: placeholder || streamingSignalVisible() || visibleButtonLabels.some((label) => generatingControlPattern.test(label)),
|
|
5384
5401
|
awaitingResponseChoice: Boolean(document.querySelector(${responseChoiceSelector})),
|
|
5385
5402
|
modelHints: modelHintLines(),
|
|
5386
5403
|
openDialogText: (([...document.querySelectorAll('[role="dialog"]')].find((d) => d.offsetWidth || d.offsetHeight || d.getClientRects().length)?.innerText) || "").trim().slice(0, 200)
|
|
@@ -6426,11 +6443,10 @@ function composerExpressionHelpers() {
|
|
|
6426
6443
|
export function answerExpression() {
|
|
6427
6444
|
const excludedTextSelector = JSON.stringify(CHATGPT_RUNTIME_BLOCKER_TEXT_EXCLUDED_ANCESTORS);
|
|
6428
6445
|
const blockerScanExcludedSelector = JSON.stringify(CHATGPT_BLOCKER_SCAN_EXCLUDED_ANCESTORS);
|
|
6429
|
-
const streamingSelector = JSON.stringify(CHATGPT_STREAMING_SELECTOR);
|
|
6430
6446
|
const responseChoiceSelector = JSON.stringify(CHATGPT_RESPONSE_CHOICE_SELECTOR);
|
|
6431
6447
|
const generatingControlPattern = JSON.stringify(CHATGPT_GENERATING_CONTROL_PATTERN.source);
|
|
6432
6448
|
const generatingControlFlags = JSON.stringify(CHATGPT_GENERATING_CONTROL_PATTERN.flags);
|
|
6433
|
-
return `(() => {${CHATGPT_MODEL_HINTS_JS}
|
|
6449
|
+
return `(() => {${CHATGPT_MODEL_HINTS_JS}${CHATGPT_STREAMING_SIGNAL_JS}
|
|
6434
6450
|
const text = document.body?.innerText || "";
|
|
6435
6451
|
const excludedTextSelector = ${excludedTextSelector};
|
|
6436
6452
|
const blockerScanExcludedSelector = ${blockerScanExcludedSelector};
|
|
@@ -6497,7 +6513,7 @@ export function answerExpression() {
|
|
|
6497
6513
|
blockerTextSample: visibleTextOutsideMessages(excludedTextSelector).slice(0, 12000),
|
|
6498
6514
|
blockerScanTextSample: visibleTextOutsideMessages(blockerScanExcludedSelector).slice(0, 12000),
|
|
6499
6515
|
visibleButtonLabels: buttons,
|
|
6500
|
-
generating: placeholder ||
|
|
6516
|
+
generating: placeholder || streamingSignalVisible() || buttons.some((label) => generatingControlPattern.test(label)),
|
|
6501
6517
|
awaitingResponseChoice: Boolean(document.querySelector(${responseChoiceSelector})),
|
|
6502
6518
|
assistantMessageCount: assistantMessages.length,
|
|
6503
6519
|
userMessageCount: userMessages.length,
|
package/docs/releasing.md
CHANGED
|
@@ -16,6 +16,45 @@ Release target: `v0.40.13` on `main`. The GitHub Release records the resolved co
|
|
|
16
16
|
|
|
17
17
|
The release adds a guarded, opt-in transition and more accurate blocker reporting. It does not claim that headless Pro consultation is verified on either deployment target or that authentication can be retained indefinitely.
|
|
18
18
|
|
|
19
|
+
## 0.40.36 Release Record
|
|
20
|
+
|
|
21
|
+
Release commit `eee7a7c` on `main` (cut after PR #30, merge `1e53f4e`); tag `v0.40.36`.
|
|
22
|
+
|
|
23
|
+
**Publishing**
|
|
24
|
+
- `publish.yml` run 39220885039 passed all six platforms on the first attempt, then npm publish with SLSA v1 provenance and the GitHub Release (2026-10-19 08:10 UTC).
|
|
25
|
+
- `npm run release:verify` passed on the release commit after a build.
|
|
26
|
+
|
|
27
|
+
**Installed**
|
|
28
|
+
- WSL, M3, Mac mini: `prodex --version` reports 0.40.36. Running services were not restarted: 9 stdio MCP servers on WSL and 2 on M3 keep older code until their clients reconnect. The Mac mini had none running.
|
|
29
|
+
- The maintainer watchdog checkout was pulled to `eee7a7c` and rebuilt.
|
|
30
|
+
|
|
31
|
+
**Verified live**
|
|
32
|
+
- Host, installed 0.40.36: an answer with a markdown code block showing a fenced `js` example was saved with a four-backtick fence and no toolbar label line. Code blocks with HTML entities and backslashes, a table with an escaped pipe, and inline and display math were saved intact.
|
|
33
|
+
|
|
34
|
+
**Browser container**
|
|
35
|
+
- `container/redesign-patches` `3233bdc` ports PR #30 by hand. Image `3945d3d38af0`; branch suite 2042 passed, 3 skipped. Swapped under the send lock check. Live: the same nested block was saved intact.
|
|
36
|
+
|
|
37
|
+
**Known and left as is**
|
|
38
|
+
- An answer's text `<tag>` is saved as `<tag>`, as displayed; rendering the saved markdown again may treat it as an HTML tag.
|
|
39
|
+
|
|
40
|
+
## 0.40.35 Release Record
|
|
41
|
+
|
|
42
|
+
Release commit `4c711c7` on `main` (cut after PR #29, merge `fdf7501`); tag `v0.40.35`.
|
|
43
|
+
|
|
44
|
+
**Publishing**
|
|
45
|
+
- `publish.yml` run 39211269776 passed all six platforms on the first attempt, then npm publish with SLSA v1 provenance and the GitHub Release (2026-10-19 06:40 UTC).
|
|
46
|
+
- `npm run release:verify` passed on the release commit after a build.
|
|
47
|
+
|
|
48
|
+
**Installed**
|
|
49
|
+
- WSL, M3, Mac mini: `prodex --version` reports 0.40.35. Running services were not restarted: 10 stdio MCP servers on WSL and 2 on M3 keep older code until their clients reconnect. The Mac mini had none running.
|
|
50
|
+
- The maintainer watchdog checkout was pulled to `4c711c7` and rebuilt.
|
|
51
|
+
|
|
52
|
+
**Verified live**
|
|
53
|
+
- Host, installed 0.40.35: the special-character stdin prompt (paths, HTML tags and entities, markdown, a link, `$`, tabs, a table, Korean) answered `SPECIAL_OK`; 0.40.34 had refused it as `request_mismatch`.
|
|
54
|
+
|
|
55
|
+
**Browser container**
|
|
56
|
+
- `container/redesign-patches` `62b713e` ports PR #29. Image `9b46b724ea31`; branch suite 2041 passed, 3 skipped. Swapped under the send lock check. Live: the same prompt answered `SPECIAL_OK` (the previous image refused it); smoke `PRODEX_PRO_SMOKE_OK`.
|
|
57
|
+
|
|
19
58
|
## 0.40.34 Release Record
|
|
20
59
|
|
|
21
60
|
Release commit `574e5f0` on `main` (cut after PR #28, merge `1d93de4`); tag `v0.40.34`.
|