@youdie006/prodex 0.16.32 → 0.16.33
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/browser-send-lock.js +1 -1
- package/dist/chatgpt-browser.js +2 -2
- package/dist/cli-help.js +3 -3
- package/dist/cli-pro.js +39 -6
- package/dist/cli.js +4 -1
- package/dist/mcp.js +4 -1
- package/package.json +1 -1
|
@@ -115,7 +115,7 @@ export async function withBrowserSendLock(waitMs, onWait, fn) {
|
|
|
115
115
|
continue;
|
|
116
116
|
}
|
|
117
117
|
if (Date.now() >= deadline) {
|
|
118
|
-
throw new Error(`Another prodex browser send is in progress (pid ${holder.pid}).
|
|
118
|
+
throw new Error(`Another prodex browser send is in progress (pid ${holder.pid}) and did not finish within the wait budget. Retry once it finishes, or raise --timeout-ms (which is also the queue budget).`);
|
|
119
119
|
}
|
|
120
120
|
if (!waited) {
|
|
121
121
|
waited = true;
|
package/dist/chatgpt-browser.js
CHANGED
|
@@ -1308,7 +1308,7 @@ export async function recoverChatGptAnswerFromThread(options) {
|
|
|
1308
1308
|
code: "browser_unreachable",
|
|
1309
1309
|
message: `No Chrome DevTools endpoint is reachable on 127.0.0.1:${port}.`,
|
|
1310
1310
|
retryable: true,
|
|
1311
|
-
next_step: "Run `prodex pro browser login
|
|
1311
|
+
next_step: "Run `prodex pro browser login` to reopen the dedicated window - it reuses the saved session (no manual login unless it expired) and returns immediately when run non-interactively - then retry."
|
|
1312
1312
|
});
|
|
1313
1313
|
}
|
|
1314
1314
|
const cdp = await connectCdp(page.page.webSocketDebuggerUrl);
|
|
@@ -1790,7 +1790,7 @@ async function findChatGptPage(port, timeoutMs, targetUrl) {
|
|
|
1790
1790
|
code: "browser_unreachable",
|
|
1791
1791
|
message: `No Chrome DevTools endpoint is reachable on 127.0.0.1:${port}.`,
|
|
1792
1792
|
retryable: true,
|
|
1793
|
-
next_step: "Run `prodex pro browser login
|
|
1793
|
+
next_step: "Run `prodex pro browser login` to reopen the dedicated window - it reuses the saved session (no manual login unless it expired) and returns immediately when run non-interactively - then retry.",
|
|
1794
1794
|
...(error instanceof Error ? { detail: error.message } : {})
|
|
1795
1795
|
}
|
|
1796
1796
|
};
|
package/dist/cli-help.js
CHANGED
|
@@ -26,7 +26,7 @@ Ask / consult commands:
|
|
|
26
26
|
prodex pro browser models [--source-cli /absolute/path/to/dist/cli.js] [--port 9333] [--timeout-ms 15000] # read-only list of model menu options
|
|
27
27
|
prodex pro browser projects [--source-cli /absolute/path/to/dist/cli.js] [--port 9333] [--timeout-ms 15000] # read-only list of sidebar project names (for --project)
|
|
28
28
|
prodex pro browser recover [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] --target-url <thread-url> [--timeout-ms 60000] # recover a finished answer from a thread whose send timed out
|
|
29
|
-
prodex pro browser ask [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms
|
|
29
|
+
prodex pro browser ask [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 300000] [--busy-wait-ms 600000] [--target-url url --confirm-target] [--new-chat] [--stdin] [--json] [--auto-login|--no-auto-login] [--file path] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name" | --project-new "name"] "prompt" # explicit visible-browser send
|
|
30
30
|
prodex pro latest [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
|
|
31
31
|
prodex pro list [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--json]
|
|
32
32
|
prodex pro show <task-id|latest> [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
|
|
@@ -252,8 +252,8 @@ export function printProBrowserHelp(stdout, sourceCli) {
|
|
|
252
252
|
: "prodex pro browser smoke [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 90000]";
|
|
253
253
|
const selectionUsage = '[--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name" | --project-new "name"]';
|
|
254
254
|
const askUsage = sourceCli
|
|
255
|
-
? `${cli} pro browser ask${sourceCliOption} [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms
|
|
256
|
-
: `prodex pro browser ask [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms
|
|
255
|
+
? `${cli} pro browser ask${sourceCliOption} [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 300000] [--busy-wait-ms 600000] [--target-url url --confirm-target] [--new-chat] [--stdin] [--json] [--auto-login|--no-auto-login] [--file path] ${selectionUsage} "prompt"`
|
|
256
|
+
: `prodex pro browser ask [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 300000] [--busy-wait-ms 600000] [--target-url url --confirm-target] [--new-chat] [--stdin] [--json] [--auto-login|--no-auto-login] [--file path] ${selectionUsage} "prompt"`;
|
|
257
257
|
const modelsUsage = sourceCli
|
|
258
258
|
? `${cli} pro browser models${sourceCliOption} [--port 9333] [--timeout-ms 15000]`
|
|
259
259
|
: "prodex pro browser models [--source-cli /absolute/path/to/dist/cli.js] [--port 9333] [--timeout-ms 15000]";
|
package/dist/cli-pro.js
CHANGED
|
@@ -277,8 +277,7 @@ export async function runProCommand(rest, io, runCliFn) {
|
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
if (browserSubcommand === "open" || browserSubcommand === "status" || browserSubcommand === "doctor") {
|
|
280
|
-
|
|
281
|
-
throw new Error(`Use \`prodex pro browser ${replacement}\` for explicit browser automation.`);
|
|
280
|
+
throw new Error(`Use \`prodex pro browser ${legacyBrowserSubcommandReplacement(browserSubcommand)}\` for explicit browser automation.`);
|
|
282
281
|
}
|
|
283
282
|
if (browserSubcommand === "smoke") {
|
|
284
283
|
if (printProBrowserHelpIfRequested(browserArgs, "pro browser smoke", io, { valueFlags: ["--cwd", "--port", "--timeout-ms", "--source-cli"] }))
|
|
@@ -426,7 +425,10 @@ export async function runProCommand(rest, io, runCliFn) {
|
|
|
426
425
|
throw unknownSubcommandError("pro browser", browserSubcommand, ["login", "ask", "smoke", "check", "models", "projects", "recover"]);
|
|
427
426
|
}
|
|
428
427
|
if (subcommand === "open" || subcommand === "status" || subcommand === "smoke" || subcommand === "check" || subcommand === "doctor") {
|
|
429
|
-
|
|
428
|
+
// Point at a subcommand that EXISTS: `pro status` used to say "use `pro
|
|
429
|
+
// browser status`", which itself errors with "use `pro browser check`" -
|
|
430
|
+
// a two-hop dead end that made an agent abandon the diagnosis.
|
|
431
|
+
throw new Error(`Use \`prodex pro browser ${legacyBrowserSubcommandReplacement(subcommand)}\` for explicit browser automation.`);
|
|
430
432
|
}
|
|
431
433
|
if (subcommand === "list") {
|
|
432
434
|
if (printHelpIfRequested(proArgs, "pro list", io.stdout, printProHelp, { valueFlags: ["--cwd", "--source-cli"] }))
|
|
@@ -531,6 +533,16 @@ export async function runProCommand(rest, io, runCliFn) {
|
|
|
531
533
|
export async function runConsultsCommand(rest, io) {
|
|
532
534
|
throw new Error("The legacy `consults` alias is retired. Use `prodex pro list`, `prodex pro latest`, or `prodex pro show <task-id|latest>`.");
|
|
533
535
|
}
|
|
536
|
+
// Retired browser subcommands map to the one that replaced them. Every value
|
|
537
|
+
// here must be a subcommand that actually exists, so the error is a single hop
|
|
538
|
+
// to a runnable command.
|
|
539
|
+
function legacyBrowserSubcommandReplacement(subcommand) {
|
|
540
|
+
if (subcommand === "open")
|
|
541
|
+
return "login";
|
|
542
|
+
if (subcommand === "smoke")
|
|
543
|
+
return "smoke";
|
|
544
|
+
return "check";
|
|
545
|
+
}
|
|
534
546
|
// File marker + human-pacing gate for visible-browser sends. Reads the previous
|
|
535
547
|
// send's start time from .bridge/last-browser-send, waits out any remaining
|
|
536
548
|
// minimum interval (auto-throttle, not an error), then stamps the new send.
|
|
@@ -702,7 +714,11 @@ export async function runAskProCommand(rest, io) {
|
|
|
702
714
|
const effectiveProSelection = selectionProMode !== undefined || (selectionModel !== undefined && /pro/i.test(selectionModel));
|
|
703
715
|
// Pro reasoning routinely runs 6-20 minutes; 15 min was still cutting long
|
|
704
716
|
// answers off (field report), so a Pro selection defaults to 20 minutes.
|
|
705
|
-
|
|
717
|
+
// With NO model selection at all (no flag, no saved default) the UI's
|
|
718
|
+
// current model is unknown and may be Pro, so the floor is 5 minutes: the
|
|
719
|
+
// old 90s guess made repos without saved defaults time out on ordinary
|
|
720
|
+
// consults (observed in several field sessions).
|
|
721
|
+
const defaultBrowserTimeoutMs = effectiveProSelection ? 1_200_000 : 300_000;
|
|
706
722
|
const browserTimeoutMs = hasSendMode
|
|
707
723
|
? (readPositiveIntegerFlag(parsedAskPro.optionArgs, "--timeout-ms") ?? defaultBrowserTimeoutMs)
|
|
708
724
|
: undefined;
|
|
@@ -759,7 +775,12 @@ export async function runAskProCommand(rest, io) {
|
|
|
759
775
|
}
|
|
760
776
|
throw new Error(formatBlockedConsultRecordedMessage(blocker.message, task.id, sourceCli, { cwd: targetCwd }));
|
|
761
777
|
}
|
|
762
|
-
|
|
778
|
+
// Queue behind another prodex send by default (same budget as the send
|
|
779
|
+
// itself). MCP consults cannot pass --busy-wait-ms at all, so the old
|
|
780
|
+
// fail-fast default made pro_consult die instantly with advice the
|
|
781
|
+
// caller had no way to follow; --busy-wait-ms 0 opts back into failing
|
|
782
|
+
// fast. A dead holder is still reaped immediately.
|
|
783
|
+
const sendOnce = () => withBrowserSendLock(busyWaitMs ?? browserTimeoutMs ?? 0, (detail) => io.stderr(`progress: ${detail}`), () => sendChatGptPrompt({
|
|
763
784
|
port: browserPort,
|
|
764
785
|
prompt: bundle.text,
|
|
765
786
|
targetUrl: normalizedTargetUrl,
|
|
@@ -1366,7 +1387,10 @@ export async function printProductCheck(store, io, args, configCwd = io.cwd) {
|
|
|
1366
1387
|
}
|
|
1367
1388
|
catch (error) {
|
|
1368
1389
|
if (isMissingFileError(error)) {
|
|
1369
|
-
|
|
1390
|
+
// Name it optional: browser consults need no config at all, but agents
|
|
1391
|
+
// reading "config: missing" in an otherwise healthy check concluded
|
|
1392
|
+
// prodex was unconfigured and went chasing `setup` (field sessions).
|
|
1393
|
+
io.stdout(`config: missing - run \`${formatSetupCommand(sourceCli, { cwd: setupHintCwd })}\` (optional - only the HTTP MCP surface needs it; browser consults work without it)`);
|
|
1370
1394
|
}
|
|
1371
1395
|
else {
|
|
1372
1396
|
io.stdout(`config: failed ${sourceAwareSetupMessage(errorMessage(error), sourceCli, { cwd: setupHintCwd })}`);
|
|
@@ -1412,6 +1436,15 @@ export async function printProductCheck(store, io, args, configCwd = io.cwd) {
|
|
|
1412
1436
|
if (nextStep)
|
|
1413
1437
|
io.stdout(`next: ${nextStep}`);
|
|
1414
1438
|
}
|
|
1439
|
+
else if (browserStatus.blocker?.code === "response_in_progress") {
|
|
1440
|
+
// Busy is not broken: the session is healthy and answering, and sends
|
|
1441
|
+
// queue behind it automatically. Reporting it as "blocked" made agents
|
|
1442
|
+
// conclude the browser was down and start relaunching/logging in (field
|
|
1443
|
+
// failure, observed across several repos).
|
|
1444
|
+
io.stdout(`chatgpt: busy ${browserStatus.blocker.code} - ${browserStatus.blocker.message}`);
|
|
1445
|
+
io.stdout("next: No action needed - a send queues behind it automatically (--busy-wait-ms 0 fails fast instead).");
|
|
1446
|
+
chatgptReady = true;
|
|
1447
|
+
}
|
|
1415
1448
|
else if (browserStatus.blocker) {
|
|
1416
1449
|
const visibilityText = browserStatus.blocker.code === "tab_not_visible" ? ` visibility=${browserStatus.visibilityState ?? "unknown"}` : "";
|
|
1417
1450
|
io.stdout(`chatgpt: blocked ${browserStatus.blocker.code}${visibilityText} - ${browserStatus.blocker.message}`);
|
package/dist/cli.js
CHANGED
|
@@ -929,7 +929,10 @@ async function runDoctor(store, io, sourceCli, setupHintCwd) {
|
|
|
929
929
|
}
|
|
930
930
|
catch (error) {
|
|
931
931
|
if (isMissingFileError(error)) {
|
|
932
|
-
|
|
932
|
+
// Name it optional: browser consults need no config at all, but agents
|
|
933
|
+
// reading "config: missing" in an otherwise healthy check concluded
|
|
934
|
+
// prodex was unconfigured and went chasing `setup` (field sessions).
|
|
935
|
+
io.stdout(`config: missing - run \`${formatSetupCommand(sourceCli, { cwd: setupHintCwd })}\` (optional - only the HTTP MCP surface needs it; browser consults work without it)`);
|
|
933
936
|
}
|
|
934
937
|
else {
|
|
935
938
|
ok = false;
|
package/dist/mcp.js
CHANGED
|
@@ -142,7 +142,10 @@ export function createServer(cwd = process.cwd(), options = {}) {
|
|
|
142
142
|
inputSchema: {
|
|
143
143
|
prompt: McpBridgeTextSchema.min(1),
|
|
144
144
|
model: McpShortTextSchema.optional(),
|
|
145
|
-
pro_mode:
|
|
145
|
+
// pro_mode is deliberately NOT advertised: ChatGPT's 2026-07 update
|
|
146
|
+
// removed Pro sub-modes, and agents that saw the field passed
|
|
147
|
+
// nonsense ("true") and got a hard validation error instead of an
|
|
148
|
+
// answer. Unknown keys are stripped, so a stale caller still works.
|
|
146
149
|
effort: McpShortTextSchema.optional(),
|
|
147
150
|
project: McpShortTextSchema.optional(),
|
|
148
151
|
timeout_ms: z.number().int().positive().max(3_600_000).optional(),
|