@youdie006/prodex 0.36.0 → 0.36.2
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/README.md +2 -0
- package/dist/chatgpt-browser.js +77 -5
- package/dist/cli-help.js +1 -1
- package/dist/cli-pro.js +3 -5
- package/dist/cli.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -440,6 +440,8 @@ npm run dev -- tasks list
|
|
|
440
440
|
|
|
441
441
|
**Sends started failing after many consults in one chat.** Long accumulated threads eventually confuse prompt-acceptance detection (measured live around ten-plus messages). Send repeated consults into fresh chats with `--new-chat` (`new_chat: true` on the MCP tool) — the answer still lands in your account and in `.bridge/` receipts either way.
|
|
442
442
|
|
|
443
|
+
**Every send says "still generating" but nothing is being written.** ChatGPT sometimes parks a thread on "You're giving feedback on a new version of ChatGPT - which response do you prefer?", and while it waits the composer keeps its stop control. prodex reports that as a `response_choice_pending` blocker naming the two "I prefer this response" buttons, because waiting will never clear it. Sends that navigate away (`--new-chat`, or any send into a project) are unaffected. A stop control can also linger for a few seconds after an ordinary answer finishes; prodex checks the conversation transcript before believing it, so a finished thread is not mistaken for a busy one.
|
|
444
|
+
|
|
443
445
|
**"menu item not found" on `--effort`/`--pro-mode`/`--project`.** Selection matches the visible menu labels, verified in the Korean and English (US) ChatGPT UI. On another display language, run `prodex pro browser models` to see your labels and pass `--model "<exact label>"`, which clicks any picker radio by exact text.
|
|
444
446
|
|
|
445
447
|
**Does this risk my ChatGPT account?** `prodex` is deliberately not a stealth bot: it uses a real visible browser, you log in manually, and it stops on captcha/verification instead of solving it. It does drive chatgpt.com, though, so keep usage at the human, occasional-consult volume the auto-pacing enforces — do not build tight recurring loops on top of it. Automating a paid account is your responsibility under OpenAI's terms.
|
package/dist/chatgpt-browser.js
CHANGED
|
@@ -632,6 +632,46 @@ export function responseChoiceBlocksThisSend(input) {
|
|
|
632
632
|
return false;
|
|
633
633
|
return !input.newChat && input.project === undefined && input.projectNew === undefined;
|
|
634
634
|
}
|
|
635
|
+
/**
|
|
636
|
+
* Why a requested Pro sub-mode did not make it onto a power-slider picker.
|
|
637
|
+
*
|
|
638
|
+
* The current picker is one five-step slider whose top step IS Pro, and it has
|
|
639
|
+
* no 기본/확장 anywhere - measured: `{ok:true, position:4, max:4, model:"GPT-5.6
|
|
640
|
+
* Sol", effort:"Pro"}`. The send takes that branch and returns, reading
|
|
641
|
+
* `effort ?? model`, so a sub-mode request was dropped on the way past. A run
|
|
642
|
+
* with `--model Pro --pro-mode 확장` finished clean and recorded no warning at
|
|
643
|
+
* all, having never applied 확장. The older picker refuses the same request
|
|
644
|
+
* out loud; silence on one machine and an error on another, for one command,
|
|
645
|
+
* is the half worth fixing. The send is still a correct Pro send, so this is a
|
|
646
|
+
* warning and not a refusal.
|
|
647
|
+
*/
|
|
648
|
+
export function proModeNotAppliedWarning(proMode, sliderEffort) {
|
|
649
|
+
if (!proMode)
|
|
650
|
+
return undefined;
|
|
651
|
+
const step = sliderEffort ? `the slider's "${sliderEffort}" step` : "the slider's current step";
|
|
652
|
+
return (`pro_mode_not_applied: this ChatGPT picker is a power slider with no "Pro ${proMode}" step, ` +
|
|
653
|
+
`so --pro-mode ${proMode} was not applied and the send used ${step}. ` +
|
|
654
|
+
"Drop --pro-mode here, or clear a saved default with `prodex setup --clear-pro-mode`.");
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Which of two flags the slider actually obeyed.
|
|
658
|
+
*
|
|
659
|
+
* On this picker one control carries both: "Pro" is the top EFFORT step, not a
|
|
660
|
+
* model. Naming a model AND an effort therefore asks for two positions of the
|
|
661
|
+
* same slider, and the send takes `effort ?? model` - so the model is dropped.
|
|
662
|
+
* Measured: `--model Pro --effort 중간` answered from gpt-5-6-thinking with an
|
|
663
|
+
* empty warnings list. Asking for Pro and quietly getting a cheaper model is
|
|
664
|
+
* the kind of thing a receipt exists to catch.
|
|
665
|
+
*/
|
|
666
|
+
export function modelIgnoredForEffortWarning(model, effort) {
|
|
667
|
+
if (!model || !effort)
|
|
668
|
+
return undefined;
|
|
669
|
+
if (model.trim().toLowerCase() === effort.trim().toLowerCase())
|
|
670
|
+
return undefined;
|
|
671
|
+
return (`model_ignored: this ChatGPT picker sets the model and the effort with one slider, ` +
|
|
672
|
+
`so --model ${model} and --effort ${effort} name two positions of it. The send used ${effort}. ` +
|
|
673
|
+
`Pass only one of them to say which you meant.`);
|
|
674
|
+
}
|
|
635
675
|
export function chatGptBusyBlocker(state) {
|
|
636
676
|
// Waiting for a choice is not generating. Conflating them turned a click
|
|
637
677
|
// away from ready into a full send budget spent on "still generating".
|
|
@@ -1614,6 +1654,14 @@ async function selectModelReasoning(cdp, options, selectionWarnings = []) {
|
|
|
1614
1654
|
if (wanted) {
|
|
1615
1655
|
await selectPowerStep(cdp, wanted);
|
|
1616
1656
|
}
|
|
1657
|
+
// This branch cannot honour a sub-mode, and used to return without
|
|
1658
|
+
// saying so - the caller got a clean receipt for a 확장 it never got.
|
|
1659
|
+
const proModeWarning = proModeNotAppliedWarning(options.proMode, sliderState.effort ?? undefined);
|
|
1660
|
+
if (proModeWarning)
|
|
1661
|
+
selectionWarnings.push(proModeWarning);
|
|
1662
|
+
const modelWarning = modelIgnoredForEffortWarning(options.model, options.effort);
|
|
1663
|
+
if (modelWarning)
|
|
1664
|
+
selectionWarnings.push(modelWarning);
|
|
1617
1665
|
await dispatchEscapeKey(cdp);
|
|
1618
1666
|
return;
|
|
1619
1667
|
}
|
|
@@ -2543,16 +2591,40 @@ export async function sendChatGptPrompt(options) {
|
|
|
2543
2591
|
throw Object.assign(new Error(`Timed out after ${formatDurationMs(timeoutMs)} (${timeoutMs}ms) waiting for ChatGPT to respond. ` +
|
|
2544
2592
|
"Pro reasoning can run many minutes. Raise --timeout-ms and retry."), completed?.url ? { thread: completed.url } : {});
|
|
2545
2593
|
}
|
|
2594
|
+
/**
|
|
2595
|
+
* One line of `pro browser models`.
|
|
2596
|
+
*
|
|
2597
|
+
* The listing used to append "not selectable via --model yet" to every submenu
|
|
2598
|
+
* row, which is now every row that matters - and it is not true: measured
|
|
2599
|
+
* against this same picker, --model Pro, --effort 즉시 and --pro-mode 확장 all
|
|
2600
|
+
* selected, because selection walks into the submenu. Saying what the row is
|
|
2601
|
+
* set to is the useful half; the false warning was the harmful half.
|
|
2602
|
+
*/
|
|
2603
|
+
export function formatModelMenuOption(option) {
|
|
2604
|
+
const marker = option.checked ? "*" : " ";
|
|
2605
|
+
const value = option.kind === "submenu" && option.value ? ` -> ${option.value}` : "";
|
|
2606
|
+
return `${marker} ${option.label}${value}`;
|
|
2607
|
+
}
|
|
2546
2608
|
export function modelMenuOptionsExpression() {
|
|
2547
2609
|
return `(() => {
|
|
2548
2610
|
const m = document.querySelector('[data-testid="composer-intelligence-picker-content"]');
|
|
2549
2611
|
if (!m) return [];
|
|
2550
2612
|
return [...m.querySelectorAll('[role="menuitemradio"],[role="menuitem"]')]
|
|
2551
|
-
.map((it) =>
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2613
|
+
.map((it) => {
|
|
2614
|
+
// A submenu row renders as label over value ("Model" / "GPT-5.6 Sol"),
|
|
2615
|
+
// and the value is the part a person actually wants to read.
|
|
2616
|
+
const lines = (it.innerText || it.textContent || "")
|
|
2617
|
+
.split(String.fromCharCode(10))
|
|
2618
|
+
.map((line) => line.trim())
|
|
2619
|
+
.filter((line) => line.length > 0);
|
|
2620
|
+
const value = lines[1] || "";
|
|
2621
|
+
return {
|
|
2622
|
+
label: lines[0] || "",
|
|
2623
|
+
kind: it.getAttribute("aria-haspopup") === "menu" ? "submenu" : "radio",
|
|
2624
|
+
checked: it.getAttribute("aria-checked") === "true",
|
|
2625
|
+
...(value ? { value } : {})
|
|
2626
|
+
};
|
|
2627
|
+
})
|
|
2556
2628
|
.filter((o) => o.label.length > 0);
|
|
2557
2629
|
})()`;
|
|
2558
2630
|
}
|
package/dist/cli-help.js
CHANGED
|
@@ -295,7 +295,7 @@ Commands:
|
|
|
295
295
|
${askUsage}
|
|
296
296
|
${recoverUsage}
|
|
297
297
|
|
|
298
|
-
Visible-browser sends require a manual browser session and stop on login, captcha, Cloudflare, permission, rate-limit, or usage-limit blockers.
|
|
298
|
+
Visible-browser sends require a manual browser session and stop on login, captcha, Cloudflare, permission, rate-limit, or usage-limit blockers, plus response_choice_pending when ChatGPT is waiting for you to pick which of two answers you prefer.
|
|
299
299
|
Model/project selection (ask):
|
|
300
300
|
--model Composer model to pick by its exact menu label (verified: Pro). Models whose menu entry opens a submenu of variants are rejected with a clear error for now.
|
|
301
301
|
--pro-mode Pro sub-mode: 기본 (standard) or 확장 (extended), used when the model is Pro. A Pro selection raises the default --timeout-ms to 1200000.
|
package/dist/cli-pro.js
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, statSync } from "node:fs";
|
|
|
2
2
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { buildDryRunBundle } from "./bundle.js";
|
|
5
|
-
import { DEFAULT_CDP_PORT, resolveCdpPort, resolveConversationToDelete, resolveProjectToDelete, chatGptVisibilityBlocker, defaultChatGptProfileDir, formatDurationMs, getChatGptBrowserStatus, listChatGptModelOptions, deleteChatGptConversation, endWedgedBrowser, browserRecoveryPlan, findWedgedBrowser, wedgedBrowserBlocker, deleteChatGptProject, listChatGptProjectsWithIds, listRecentChatGptConversations, listChatGptSidebarProjects, normalizeChatGptTargetUrl, openChatGptBrowser, openChatGptTab, parseProMode, parseReasoningEffort, defaultTimeoutForTools, ensureVirtualDisplay, minimizeChatGptWindow, readLastBrowserLoginLaunch, resolveVirtualDisplayPreference, resolveBrowserWindowMode, resolveHeadlessPreference, recordBrowserLoginLaunch, recoverChatGptAnswerFromThread, sendChatGptPrompt } from "./chatgpt-browser.js";
|
|
5
|
+
import { DEFAULT_CDP_PORT, resolveCdpPort, resolveConversationToDelete, resolveProjectToDelete, chatGptVisibilityBlocker, defaultChatGptProfileDir, formatDurationMs, getChatGptBrowserStatus, formatModelMenuOption, listChatGptModelOptions, deleteChatGptConversation, endWedgedBrowser, browserRecoveryPlan, findWedgedBrowser, wedgedBrowserBlocker, deleteChatGptProject, listChatGptProjectsWithIds, listRecentChatGptConversations, listChatGptSidebarProjects, normalizeChatGptTargetUrl, openChatGptBrowser, openChatGptTab, parseProMode, parseReasoningEffort, defaultTimeoutForTools, ensureVirtualDisplay, minimizeChatGptWindow, readLastBrowserLoginLaunch, resolveVirtualDisplayPreference, resolveBrowserWindowMode, resolveHeadlessPreference, recordBrowserLoginLaunch, recoverChatGptAnswerFromThread, sendChatGptPrompt } from "./chatgpt-browser.js";
|
|
6
6
|
import { ASK_PRO_BOOLEAN_FLAGS, ASK_PRO_PREVIEW_VALUE_FLAGS, ASK_PRO_VALUE_FLAGS, assertHelpRequestArgs, assertNoExtraArgs, assertOnlyOptions, findHelpFlagIndexBeforePromptDelimiter, formatCliCommand, hasAskProDryRunMode, hasAskProMode, hasAskProSendMode, isHelpSubcommand, parseAskProArgs, printHelpIfRequested, readFlag, readPortFlag, readPositionalsWithOptions, readNonNegativeIntegerFlag, readPositiveIntegerFlag, readRepeatedFlag, resolveCwdFlag, resolveOptionalFileFlag, unknownSubcommandError } from "./cli-args.js";
|
|
7
7
|
import { printProBrowserHelp, printProHelp } from "./cli-help.js";
|
|
8
8
|
import { listRawResultsForInspection, listTasksForInspection } from "./cli-ledger.js";
|
|
@@ -442,11 +442,9 @@ export async function runProCommand(rest, io, runCliFn) {
|
|
|
442
442
|
}
|
|
443
443
|
io.stdout("Model menu options in the visible ChatGPT tab (read-only; nothing was selected):");
|
|
444
444
|
for (const option of listed.options) {
|
|
445
|
-
|
|
446
|
-
const suffix = option.kind === "submenu" ? " (has sub-variants; not selectable via --model yet)" : "";
|
|
447
|
-
io.stdout(`${marker} ${option.label}${suffix}`);
|
|
445
|
+
io.stdout(formatModelMenuOption(option));
|
|
448
446
|
}
|
|
449
|
-
io.stdout("
|
|
447
|
+
io.stdout("An arrow shows what that row is set to now; --model / --effort reach into those submenus (e.g. --model Pro).");
|
|
450
448
|
return 0;
|
|
451
449
|
}
|
|
452
450
|
if (browserSubcommand === "projects") {
|
package/dist/cli.js
CHANGED
|
@@ -436,7 +436,7 @@ repo: ${cwd}
|
|
|
436
436
|
|
|
437
437
|
Safety notes:
|
|
438
438
|
- This command only prints commands; it does not start servers, open browsers, or write files.
|
|
439
|
-
- Visible-browser sends require a manual, visible browser session and stop on login, captcha, Cloudflare, permission, rate-limit, or usage-limit blockers.`;
|
|
439
|
+
- Visible-browser sends require a manual, visible browser session and stop on login, captcha, Cloudflare, permission, rate-limit, or usage-limit blockers, plus response_choice_pending when ChatGPT is waiting for you to pick which of two answers you prefer.`;
|
|
440
440
|
}
|
|
441
441
|
async function hasOnboardingReadme(cwd) {
|
|
442
442
|
try {
|