@youdie006/prodex 0.40.21 → 0.40.23
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 +43 -2
- package/docs/releasing.md +75 -0
- package/package.json +1 -1
package/dist/chatgpt-browser.js
CHANGED
|
@@ -805,6 +805,23 @@ async function navigateIdleChatGptPage(page, url) {
|
|
|
805
805
|
* navigation cannot leave the old thread's state in place. A false result
|
|
806
806
|
* must not be used as permission to send into stale content.
|
|
807
807
|
*/
|
|
808
|
+
// Measured 5.2-8.5 s for the new-chat page to settle (2026-09-30).
|
|
809
|
+
const FRESH_CHAT_TIMEOUT_MS = 15_000;
|
|
810
|
+
/** Poll until the document marked before a navigation has been replaced and the new one has a composer. */
|
|
811
|
+
async function waitForReloadedDocument(page, deadline) {
|
|
812
|
+
while (Date.now() < deadline) {
|
|
813
|
+
try {
|
|
814
|
+
if (await evaluateOnPage(page, reloadedDocumentReadyExpression()) === true)
|
|
815
|
+
return true;
|
|
816
|
+
}
|
|
817
|
+
catch (error) {
|
|
818
|
+
if (!/execution context|cannot find context|Runtime\.evaluate failed/i.test(String(error)))
|
|
819
|
+
throw error;
|
|
820
|
+
}
|
|
821
|
+
await sleep(300);
|
|
822
|
+
}
|
|
823
|
+
return false;
|
|
824
|
+
}
|
|
808
825
|
async function waitForFreshChatGptPage(page, timeoutMs) {
|
|
809
826
|
const deadline = Date.now() + timeoutMs;
|
|
810
827
|
while (Date.now() < deadline) {
|
|
@@ -3682,8 +3699,16 @@ export async function sendChatGptPrompt(options) {
|
|
|
3682
3699
|
// caller timed out and released the process lock. Project homes supply
|
|
3683
3700
|
// their own fresh composer and must not pass through the root first.
|
|
3684
3701
|
const freshUrl = options.temporary ? "https://chatgpt.com/?temporary-chat=true" : "https://chatgpt.com/";
|
|
3702
|
+
// A tab already on the root is an empty chat before the navigation
|
|
3703
|
+
// commits, so the fresh-chat check passed on the page being left and the
|
|
3704
|
+
// send then typed or attached into a document that was replaced under it
|
|
3705
|
+
// (measured: "composer has no file input" on every attach from the root).
|
|
3706
|
+
// The mark proves the page in hand is the one the navigation produced.
|
|
3707
|
+
await evaluateOnPage(page, markDocumentForReloadExpression());
|
|
3685
3708
|
await navigateIdleChatGptPage(page, freshUrl);
|
|
3686
|
-
|
|
3709
|
+
const freshDeadline = Date.now() + FRESH_CHAT_TIMEOUT_MS;
|
|
3710
|
+
if (!await waitForReloadedDocument(page, freshDeadline) ||
|
|
3711
|
+
!await waitForFreshChatGptPage(page, Math.max(0, freshDeadline - Date.now()))) {
|
|
3687
3712
|
throw new ChatGptBrowserBlockerError({
|
|
3688
3713
|
code: "fresh_chat_not_ready",
|
|
3689
3714
|
message: "The new-chat page did not become an empty conversation. Nothing was sent.",
|
|
@@ -5098,7 +5123,23 @@ export function attachmentStateExpression(fileNames) {
|
|
|
5098
5123
|
.map((el) => (el.getAttribute("aria-label") || el.getAttribute("title") || el.getAttribute("alt") || ""))
|
|
5099
5124
|
.join(String.fromCharCode(10));
|
|
5100
5125
|
const haystack = text + String.fromCharCode(10) + labels;
|
|
5101
|
-
|
|
5126
|
+
// Uploading a name that was used before makes ChatGPT show it as
|
|
5127
|
+
// "stem(3).ext", so that spelling counts as the same file.
|
|
5128
|
+
const shownAsRenamed = (name) => {
|
|
5129
|
+
const dot = name.lastIndexOf(".");
|
|
5130
|
+
const stem = dot > 0 ? name.slice(0, dot) : name;
|
|
5131
|
+
const ext = dot > 0 ? name.slice(dot) : "";
|
|
5132
|
+
let from = 0;
|
|
5133
|
+
while ((from = haystack.indexOf(stem + "(", from)) !== -1) {
|
|
5134
|
+
let i = from + stem.length + 1;
|
|
5135
|
+
const digitsStart = i;
|
|
5136
|
+
while (i < haystack.length && haystack[i] >= "0" && haystack[i] <= "9") i += 1;
|
|
5137
|
+
if (i > digitsStart && haystack.startsWith(")" + ext, i)) return true;
|
|
5138
|
+
from += 1;
|
|
5139
|
+
}
|
|
5140
|
+
return false;
|
|
5141
|
+
};
|
|
5142
|
+
const present = names.filter((name) => haystack.includes(name) || shownAsRenamed(name));
|
|
5102
5143
|
const attachedFiles = [...document.querySelectorAll('input[type="file"]')]
|
|
5103
5144
|
.reduce((total, el) => total + (el.files ? el.files.length : 0), 0);
|
|
5104
5145
|
// A visible progressbar means a file is still going up; sending now would
|
package/docs/releasing.md
CHANGED
|
@@ -16,6 +16,81 @@ 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.22 Release Record
|
|
20
|
+
|
|
21
|
+
Release commit `a5f9596` on `main` (cut after PR #12, merge `563f381`); tag `v0.40.22`.
|
|
22
|
+
|
|
23
|
+
**Publishing**
|
|
24
|
+
- `publish.yml` run 36817391329 failed on its first attempt on macOS 15 Intel and Windows Server 2025. The failures were 30 s test timeouts in `tests/store.test.ts` (both runners) and `tests/followup-budget.test.ts` (Windows). Neither test touches the change, and PR #12 had passed all six platforms.
|
|
25
|
+
- Nothing was published by that attempt.
|
|
26
|
+
- Re-running the failed jobs passed all six platforms. npm publish with SLSA v1 provenance and the GitHub Release followed (2026-10-01 05:31 UTC).
|
|
27
|
+
- Before tagging, `npm run release:verify` passed on the release commit after a build.
|
|
28
|
+
|
|
29
|
+
**What it fixes**
|
|
30
|
+
- Repeat attachments: ChatGPT shows a re-uploaded name as `name(3).txt`.
|
|
31
|
+
|
|
32
|
+
**Installation on 2026-10-01**
|
|
33
|
+
- Global npm, each verified with `prodex --version` = 0.40.22.
|
|
34
|
+
- WSL, M3, Mac mini: installed. Running services were not restarted: 6 stdio MCP servers on WSL and 7 on M3 keep older code until their clients reconnect. The Mac mini had none running.
|
|
35
|
+
- M4: not reachable (hostname does not resolve); not updated.
|
|
36
|
+
- The browser container builds from its own branch. It received the same fix in its 2026-10-01 rebuild; an npm install does not update it.
|
|
37
|
+
|
|
38
|
+
**Live check after install**
|
|
39
|
+
- A `--new-chat --attach` send from WSL through the installed 0.40.22 failed three times with "composer has no file input". This is a separate defect in the new-chat wait, fixed in the next change.
|
|
40
|
+
- With that fix built from source, the same file attached twice answered both times. That also exercises the 0.40.22 renamed-upload fix on the host browser.
|
|
41
|
+
|
|
42
|
+
## Browser Container Rebuild 2026-10-01
|
|
43
|
+
|
|
44
|
+
The container image was rebuilt again from `feat/headless-browser-compatibility` `b5eac7d` with uncommitted patches. None of them is pushed to that branch; they still have to be reconciled when that branch merges with `main`.
|
|
45
|
+
|
|
46
|
+
**Patches**
|
|
47
|
+
- The streaming selector from 2026-09-30.
|
|
48
|
+
- The new-chat wait raised from 8 s to 15 s.
|
|
49
|
+
- The non-text (image) answer detection from 0.40.21, adapted to the branch's message reader.
|
|
50
|
+
- The renamed-upload attachment fix from this change.
|
|
51
|
+
|
|
52
|
+
**Image and checks**
|
|
53
|
+
- Image `sha256:d2880fda5ab9`.
|
|
54
|
+
- Full suite 1989 passed on the patched tree.
|
|
55
|
+
- Each container swap was gated on the send lock being free (lock file absent, or its holder pid dead). The 2026-09-30 check only looked at process names.
|
|
56
|
+
|
|
57
|
+
**Verified live in the container after the swap**
|
|
58
|
+
- Three fresh-chat sends in a row answered, 35-36 s each; this flow failed about one send in three before the patch.
|
|
59
|
+
- A create-image send returned the non-text note in 49 s, where it had timed out after 6 min 40 s.
|
|
60
|
+
- The same file attached twice in a row answered `plum-7` both times. Before the fix, the second upload, shown by ChatGPT as `attach-probe(3).txt`, waited out the upload budget.
|
|
61
|
+
- An MCP `initialize` through `scripts/container-client.mjs` answered (server reports 0.40.18, the branch's version).
|
|
62
|
+
|
|
63
|
+
**Impact on clients**
|
|
64
|
+
- Clients connected to the container's MCP have to reconnect after each swap.
|
|
65
|
+
|
|
66
|
+
## Browser Container Rebuild 2026-09-30
|
|
67
|
+
|
|
68
|
+
Not an npm release; the container `prodex-browser-browser-1` builds from `feat/headless-browser-compatibility`, so this section records its state.
|
|
69
|
+
|
|
70
|
+
A live check of the container build of `b5eac7d` (2026-09-30) found: web search and temporary chats answered; fresh-chat sends failed intermittently with `fresh_chat_not_ready`; `--attach` failed on the upload budget; a create-image send timed out after 6 min 40 s; and streaming was never detected (15 of 15 samples reported idle while ChatGPT showed its Stop button), because the branch's `CHATGPT_STREAMING_SELECTOR` does not match the redesigned composer's plain `aria-label="Stop"` button.
|
|
71
|
+
|
|
72
|
+
**Rebuild.** Image `sha256:45951848a88b`, built from `b5eac7d` plus one uncommitted line: `CHATGPT_STREAMING_SELECTOR` gained `form button[aria-label="Stop"]` and `form button[aria-label="중지"]`, the same selectors `main` shipped in 0.40.21. Nothing was pushed to that branch; the change lives only in the image. Verified: the selector is present in `/app/dist/chatgpt-browser.js`; container healthy with the profile volume kept; `pro browser login --wait` found the session READY; a fresh-chat send answered in 20 s while a 1 s sampler read the page as generating on all 9 samples during which the Stop button was visible (task `task_20260930_014256`).
|
|
73
|
+
|
|
74
|
+
**Interrupted consult.** The swap at about 01:37 UTC interrupted a consult that another session had started over MCP at 01:34:31 (`task_20260930_013431`, left `claimed` with no thread), and dropped every client's MCP connection to the container; clients have to reconnect with `/mcp`. The pre-swap check only looked for `pro browser ask` processes and missed MCP consults. Before swapping the container again, check whether the send lock's holder process is alive, not the process names. Whether ChatGPT accepted that prompt was never recorded, so it must not be resent blindly.
|
|
75
|
+
|
|
76
|
+
**Still open on the branch, not fixed in this image.**
|
|
77
|
+
|
|
78
|
+
- Fresh-chat flake: the new-chat page took 5.2, 5.2, 5.6 and 8.5 s to become ready in four timed runs inside the container, while `waitForFreshChatGptPage` allows 8 s. The fix is a longer budget.
|
|
79
|
+
- `--attach` and create-image failures: `main` 0.40.21 has fixes for both.
|
|
80
|
+
- These belong to the branch owner and have to be reconciled when the branch merges with `main`.
|
|
81
|
+
|
|
82
|
+
## 0.40.21 Release Record
|
|
83
|
+
|
|
84
|
+
Release commit `936b009` on `main` (cut after PR #10, merge `5e74ba2`); tag `v0.40.21`. `publish.yml` run 36538816944 passed all six platforms on the first attempt, then npm publish with SLSA v1 provenance and the GitHub Release (2026-09-29 08:08 UTC).
|
|
85
|
+
|
|
86
|
+
What it fixes: what 0.40.20 left broken after the ChatGPT redesign - sends starting on a fresh chat, composer tools, `--project-new`, image answers that timed out, and response streaming that was never detected. Found by a live feature matrix against the published 0.40.20; each fix re-run live before release. `--project-new` created a probe project in the user's account, which was deleted afterwards through the project's own actions menu after checking the menu belonged to that project; the other nine projects were compared by id and left intact.
|
|
87
|
+
|
|
88
|
+
Installation on 2026-09-29, global npm, each verified with `prodex --version` = 0.40.21:
|
|
89
|
+
|
|
90
|
+
- WSL, M3, Mac mini: installed. On WSL a fresh-chat consult through the installed binary answered (`v21-ok`). Running services were not restarted: 3 stdio MCP servers on WSL and 4 on M3 keep older code until their clients reconnect; the Mac mini had none.
|
|
91
|
+
- M4: not reachable (hostname does not resolve); not updated.
|
|
92
|
+
- The browser container still runs its own build of `feat/headless-browser-compatibility` `b5eac7d` (see 0.40.20); it was not rebuilt for this release.
|
|
93
|
+
|
|
19
94
|
## 0.40.20 Release Record
|
|
20
95
|
|
|
21
96
|
Release commit `b8f8004` on `main` (cut after PR #9, merge `b134eae`); tag `v0.40.20`. `publish.yml` run 36522237267: the first attempt failed on macOS 15 Intel, where `tests/cli.test.ts` "uses an explicit --cwd target for doctor checks" exceeded its 30 s timeout on the slowest runner (full suite 9.5 min there; the same code had passed that runner in PR #9's CI, and no earlier failed CI run showed this test). Nothing was published by that attempt. Re-running the failed job passed all six platforms, then npm publish with SLSA v1 provenance and the GitHub Release (2026-09-29 05:18 UTC).
|