@youdie006/prodex 0.40.22 → 0.40.24
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 +45 -3
- package/docs/releasing.md +46 -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.",
|
|
@@ -5080,6 +5105,18 @@ export function insertComposerTextInPageExpression(text) {
|
|
|
5080
5105
|
export function composerFileInputSelector() {
|
|
5081
5106
|
return 'input[type="file"]:not([accept*="image"])';
|
|
5082
5107
|
}
|
|
5108
|
+
/**
|
|
5109
|
+
* Lookup order for the attachment input. A conversation page also renders a
|
|
5110
|
+
* second form without the prompt editor, earlier in the document and with its
|
|
5111
|
+
* own file inputs (measured 2026-10-02); files set there never reach the
|
|
5112
|
+
* composer. The editor's own form is tried first, the bare selector last.
|
|
5113
|
+
*/
|
|
5114
|
+
export function composerFileInputSelectors() {
|
|
5115
|
+
return [
|
|
5116
|
+
`form:has(#prompt-textarea,[contenteditable="true"]) ${composerFileInputSelector()}`,
|
|
5117
|
+
composerFileInputSelector()
|
|
5118
|
+
];
|
|
5119
|
+
}
|
|
5083
5120
|
/**
|
|
5084
5121
|
* Which of the expected attachments the composer shows, and whether one is
|
|
5085
5122
|
* still uploading.
|
|
@@ -5172,8 +5209,13 @@ export async function attachFilesToComposer(cdp, absolutePaths, options = {}) {
|
|
|
5172
5209
|
const rootNodeId = document.result?.root?.nodeId;
|
|
5173
5210
|
if (rootNodeId === undefined)
|
|
5174
5211
|
throw new Error("Could not read the ChatGPT page DOM to attach files.");
|
|
5175
|
-
|
|
5176
|
-
const
|
|
5212
|
+
let inputNodeId;
|
|
5213
|
+
for (const selector of composerFileInputSelectors()) {
|
|
5214
|
+
const input = await cdp.send("DOM.querySelector", { nodeId: rootNodeId, selector });
|
|
5215
|
+
inputNodeId = input.result?.nodeId || undefined;
|
|
5216
|
+
if (inputNodeId)
|
|
5217
|
+
break;
|
|
5218
|
+
}
|
|
5177
5219
|
if (!inputNodeId) {
|
|
5178
5220
|
throw new Error("The ChatGPT composer has no file input to attach to. Open a normal chat (not a shared or read-only view) and retry.");
|
|
5179
5221
|
}
|
package/docs/releasing.md
CHANGED
|
@@ -16,6 +16,52 @@ 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.23 Release Record
|
|
20
|
+
|
|
21
|
+
Release commit `1c905e3` on `main` (cut after PR #13, merge `92c26ce`); tag `v0.40.23`.
|
|
22
|
+
|
|
23
|
+
**Publishing**
|
|
24
|
+
- `publish.yml` run 36824322576 passed all six platforms on the first attempt, then npm publish with SLSA v1 provenance and the GitHub Release (2026-10-01 06:43 UTC).
|
|
25
|
+
- PR #13's own CI had needed one rerun on Windows for an unrelated 30 s timeout in `tests/cli.test.ts` ("uses an explicit --cwd target for local HTTP MCP start").
|
|
26
|
+
- `npm run release:verify` passed on the release commit after a build.
|
|
27
|
+
|
|
28
|
+
**What it fixes**
|
|
29
|
+
- `--new-chat` sends from a tab already on a new chat now wait for the new page, so attachments no longer fail with "composer has no file input".
|
|
30
|
+
|
|
31
|
+
**Installation on 2026-10-01**
|
|
32
|
+
- Global npm, each verified with `prodex --version` = 0.40.23.
|
|
33
|
+
- WSL, M3, Mac mini: installed. Running services were not restarted: 9 stdio MCP servers on WSL and 7 on M3 keep older code until their clients reconnect. The Mac mini had none running.
|
|
34
|
+
- M4: not reachable (hostname does not resolve); not updated.
|
|
35
|
+
- The browser container is unchanged by this release. It runs its own branch build with its own new-chat wait.
|
|
36
|
+
|
|
37
|
+
**Live check after install**
|
|
38
|
+
- Run from WSL through the installed 0.40.23 against the shared browser.
|
|
39
|
+
- The same file attached twice with `--new-chat`: both answered. The installed 0.40.22 had failed this three times.
|
|
40
|
+
- A plain new chat answered.
|
|
41
|
+
|
|
42
|
+
## 0.40.22 Release Record
|
|
43
|
+
|
|
44
|
+
Release commit `a5f9596` on `main` (cut after PR #12, merge `563f381`); tag `v0.40.22`.
|
|
45
|
+
|
|
46
|
+
**Publishing**
|
|
47
|
+
- `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.
|
|
48
|
+
- Nothing was published by that attempt.
|
|
49
|
+
- 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).
|
|
50
|
+
- Before tagging, `npm run release:verify` passed on the release commit after a build.
|
|
51
|
+
|
|
52
|
+
**What it fixes**
|
|
53
|
+
- Repeat attachments: ChatGPT shows a re-uploaded name as `name(3).txt`.
|
|
54
|
+
|
|
55
|
+
**Installation on 2026-10-01**
|
|
56
|
+
- Global npm, each verified with `prodex --version` = 0.40.22.
|
|
57
|
+
- 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.
|
|
58
|
+
- M4: not reachable (hostname does not resolve); not updated.
|
|
59
|
+
- 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.
|
|
60
|
+
|
|
61
|
+
**Live check after install**
|
|
62
|
+
- 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.
|
|
63
|
+
- 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.
|
|
64
|
+
|
|
19
65
|
## Browser Container Rebuild 2026-10-01
|
|
20
66
|
|
|
21
67
|
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`.
|