@youdie006/prodex 0.40.27 → 0.40.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.
@@ -844,8 +844,10 @@ async function navigateIdleChatGptPage(page, url) {
844
844
  * navigation cannot leave the old thread's state in place. A false result
845
845
  * must not be used as permission to send into stale content.
846
846
  */
847
- // Measured 5.2-8.5 s for the new-chat page to settle (2026-09-30).
848
- const FRESH_CHAT_TIMEOUT_MS = 15_000;
847
+ // Measured 5.2-8.5 s for the new-chat page to settle (2026-09-30), and over
848
+ // 15 s for back-to-back sends with the host at load average 28-32 on 8 cores
849
+ // (2026-10-06). It is only a ceiling: a ready page returns at once.
850
+ const FRESH_CHAT_TIMEOUT_MS = 30_000;
849
851
  /** Poll until the document marked before a navigation has been replaced and the new one has a composer. */
850
852
  async function waitForReloadedDocument(page, deadline) {
851
853
  while (Date.now() < deadline) {
@@ -1750,6 +1752,13 @@ async function waitForExpressionTrue(cdp, expression, timeoutMs, intervalMs = 15
1750
1752
  const MENU_OPEN_TIMEOUT_MS = 5_000;
1751
1753
  const MENU_SETTLE_TIMEOUT_MS = 5_000;
1752
1754
  const PROJECT_NAVIGATION_TIMEOUT_MS = 8_000;
1755
+ /**
1756
+ * How long the composer's own controls (model selector, tools button, file
1757
+ * input) may take to appear after the editor. Measured over 8 s for the model
1758
+ * selector on back-to-back sends with the host at load average 24-44
1759
+ * (2026-10-06). It is only a ceiling: a rendered control returns at once.
1760
+ */
1761
+ const COMPOSER_RENDER_TIMEOUT_MS = 30_000;
1753
1762
  export function menuOpenExpression() {
1754
1763
  return `Boolean(document.querySelector('[data-testid="composer-intelligence-picker-content"],[role="menu"]:has([role="slider"])'))`;
1755
1764
  }
@@ -2846,7 +2855,7 @@ async function selectModelReasoning(cdp, options, selectionWarnings = []) {
2846
2855
  // the same pattern succeeded either side of it. The neighbouring waits for
2847
2856
  // the same kind of render already allow six to eight.
2848
2857
  let button = { ok: false };
2849
- const buttonDeadline = Date.now() + PROJECT_NAVIGATION_TIMEOUT_MS;
2858
+ const buttonDeadline = Date.now() + COMPOSER_RENDER_TIMEOUT_MS;
2850
2859
  for (;;) {
2851
2860
  button = await cdp.evaluate(modelButtonRectExpression());
2852
2861
  if (button.ok && button.x !== undefined && button.y !== undefined)
@@ -5156,7 +5165,6 @@ export function insertComposerTextInPageExpression(text) {
5156
5165
  export function composerFileInputSelector() {
5157
5166
  return 'input[type="file"]:not([accept*="image"])';
5158
5167
  }
5159
- const COMPOSER_FILE_INPUT_TIMEOUT_MS = 15_000;
5160
5168
  const COMPOSER_TOOLS_MENU_ATTEMPTS = 3;
5161
5169
  export const PRODEX_ATTACH_INPUT_ATTRIBUTE = "data-prodex-attach-input";
5162
5170
  /**
@@ -5279,7 +5287,7 @@ export async function attachFilesToComposer(cdp, absolutePaths, options = {}) {
5279
5287
  // this point in that window sometimes. Wait for the input itself, before
5280
5288
  // the chip check (chips render with it) and before reading the DOM tree.
5281
5289
  const waitForComposerFileInput = async () => {
5282
- const inputDeadline = Date.now() + COMPOSER_FILE_INPUT_TIMEOUT_MS;
5290
+ const inputDeadline = Date.now() + COMPOSER_RENDER_TIMEOUT_MS;
5283
5291
  for (;;) {
5284
5292
  try {
5285
5293
  if (await cdp.evaluate(markComposerFileInputExpression()) === true)
@@ -5504,7 +5512,7 @@ export async function enableComposerTools(cdp, labels) {
5504
5512
  // The server-rendered editor shows before the app attaches the composer's
5505
5513
  // controls (measured 2026-10-06), so a first miss is usually just early.
5506
5514
  let button = await cdp.evaluate(composerToolsButtonRectExpression());
5507
- const buttonDeadline = Date.now() + COMPOSER_FILE_INPUT_TIMEOUT_MS;
5515
+ const buttonDeadline = Date.now() + COMPOSER_RENDER_TIMEOUT_MS;
5508
5516
  while ((!button.ok || button.x === undefined || button.y === undefined) && Date.now() < buttonDeadline) {
5509
5517
  await sleep(500);
5510
5518
  button = await cdp.evaluate(composerToolsButtonRectExpression());
package/docs/releasing.md CHANGED
@@ -16,6 +16,58 @@ 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
+ ## Browser Container Rebuild 2026-10-06 (afternoon)
20
+
21
+ **Patches now committed**
22
+ - The patches the container runs on top of `feat/headless-browser-compatibility` `b5eac7d` are now committed on their own branch, `container/redesign-patches`:
23
+ - `0c3a9cc`: every patch from 2026-09-30 to 2026-10-06.
24
+ - `1233603`: the 30 s composer-render ceiling from this change.
25
+ - They had lived only in a scratch worktree.
26
+ - `feat/headless-browser-compatibility` itself is unchanged.
27
+
28
+ **Image**
29
+ - `sha256:ce0240c0e8a4` was built from `1233603`, and the branch suite passed (2002).
30
+ - The swap was gated on the send lock being free.
31
+
32
+ **Verified**
33
+ - Three back-to-back `--model Pro --pro-mode` new-chat sends answered (42-50 s each).
34
+ - Before this, a real consult from another session had been refused as `composer_not_ready` (`task_20261006_050125`) under host load average 24-44.
35
+
36
+ **Host load**
37
+ - The load came from an unrelated container, `apo-neo4j`, which had restarted 57,058 times because it could not resolve its own hostname. The user is handling it.
38
+
39
+ ## 0.40.27 Release Record
40
+
41
+ Release commit `f84ce2b` on `main` (cut after PR #17, merge `9dad219`); tag `v0.40.27`.
42
+
43
+ **Publishing**
44
+ - `publish.yml` run 37419470087 passed all six platforms on the first attempt, then npm publish with SLSA v1 provenance and the GitHub Release (2026-10-06 05:57 UTC).
45
+ - `npm run release:verify` on the release commit passed on its second run. The first failed in package smoke, where the fake DevTools endpoint did not answer within 500 ms while the host load average was about 30 (8 cores).
46
+
47
+ **What it fixes**
48
+ - Source pills in page-read answers are spelled out as markdown links or `[label]`.
49
+ - Recovery waits for the thread's turns instead of refusing its own request right after navigating.
50
+
51
+ **Installation on 2026-10-06**
52
+ - Global npm, each verified with `prodex --version` = 0.40.27.
53
+ - WSL, M3, Mac mini: installed. Running services were not restarted: 5 stdio MCP servers on WSL and 4 on M3 keep older code until their clients reconnect. The Mac mini had none running.
54
+ - M4: not reachable (hostname does not resolve); not updated.
55
+
56
+ **Live check after install (installed 0.40.27, shared WSL browser)**
57
+ - All answered:
58
+ - a new-chat attachment
59
+ - a web-search answer, ending in a markdown source link
60
+ - a project send
61
+ - `pro browser recover` with the tab on another conversation, which returned the answer
62
+
63
+ **Browser container, same day**
64
+ - The pill and recovery fixes were adapted to the branch code.
65
+ - A consult from another session (task `task_20261006_050125`, 05:01 UTC) had been refused with `composer_not_ready`. Back-to-back `--model Pro` new-chat sends reproduced a related failure, `fresh_chat_not_ready`: the new-chat page took more than 15 s to settle with the host load average at 28-32. The branch's new-chat ceiling was raised to 30 s. It is only a ceiling.
66
+ - Image `sha256:2b76266ad524`. The earlier interrupted-looking consult `task_20261006_050200` had finished at 05:07, before the swap.
67
+ - The swap was gated on the send lock being free.
68
+ - Two branch tests failed in the pre-build run, and the build script did not stop on test failures, so the image was built and swapped anyway. One test advanced a fake clock 25 s against the new 30 s ceiling; it was fixed. The other was a load-sensitive project-sidebar test, which passed on rerun. After that, the full branch suite passed (2002). The image's runtime code is the code that passed.
69
+ - Verified: three back-to-back `--model Pro --pro-mode` new-chat sends answered (44-50 s each).
70
+
19
71
  ## 0.40.26 Release Record
20
72
 
21
73
  Release commit `b413c24` on `main` (cut after PR #16, merge `af5cf20`); tag `v0.40.26`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@youdie006/prodex",
3
- "version": "0.40.27",
3
+ "version": "0.40.28",
4
4
  "description": "Local receipt bus for coordinating Codex execution with ChatGPT Pro/Projects consultation.",
5
5
  "author": "youdie006",
6
6
  "license": "MIT",