@youdie006/prodex 0.16.28 → 0.16.30
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 +28 -9
- package/dist/cli-pro.js +20 -5
- package/dist/cli.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -254,6 +254,8 @@ prodex setup --clear-project
|
|
|
254
254
|
prodex setup --interactive # asks model / Pro sub-mode or effort / project
|
|
255
255
|
```
|
|
256
256
|
|
|
257
|
+
The saved default above lives in the repo's `.bridge/config.local.json`, so it only applies when `prodex` runs from that repo. A coding agent often starts the MCP as `prodex mcp` with no `--cwd` (it reads whatever directory the agent launched in), so a per-repo default is missed and consults land in the general chat. For a default that applies from **any** directory, set environment variables instead — `PRODEX_DEFAULT_PROJECT` and `PRODEX_DEFAULT_MODEL` (also `PRODEX_DEFAULT_PRO_MODE`, `PRODEX_DEFAULT_EFFORT`) — in the agent's MCP `env` block or your shell. Use your own project name (list them with `prodex pro browser projects`); with no project set, consults simply go to the general chat. A per-repo config still wins field-by-field over the env fallback.
|
|
258
|
+
|
|
257
259
|
Whatever selection is applied is recorded on the consult receipt (`metadata.selection`); receipt display output redacts the project name, keeping only the model axes visible. `prodex` only clicks the picker you can see; it never selects a model, effort, or project silently outside the visible browser.
|
|
258
260
|
|
|
259
261
|
For a source checkout, keep the explicit send and inspection commands source-aware too:
|
package/dist/chatgpt-browser.js
CHANGED
|
@@ -1246,13 +1246,15 @@ async function selectProject(cdp, options) {
|
|
|
1246
1246
|
// project - which would silently send the prompt into the wrong project.
|
|
1247
1247
|
const alreadyInRequestedProject = await cdp.evaluate(`(() => {
|
|
1248
1248
|
if (!/^https:\\/\\/chatgpt\\.com\\/g\\/g-p-/.test(location.href)) return false;
|
|
1249
|
-
const name = ${JSON.stringify(options.project)};
|
|
1250
|
-
//
|
|
1251
|
-
//
|
|
1252
|
-
//
|
|
1253
|
-
//
|
|
1254
|
-
|
|
1255
|
-
|
|
1249
|
+
const name = ${JSON.stringify(options.project)}.toLowerCase();
|
|
1250
|
+
// Case-insensitive EQUALITY (not substring): matches the case-insensitive
|
|
1251
|
+
// sidebar-row lookup (so "codex" is accepted while sitting on "Codex"),
|
|
1252
|
+
// but a stalled cross-project navigation must NOT be accepted just because
|
|
1253
|
+
// the current project's name CONTAINS the requested one (e.g. "Research
|
|
1254
|
+
// Lab" while "Research" was requested) - that would send into the wrong
|
|
1255
|
+
// project.
|
|
1256
|
+
if ((document.title || "").trim().toLowerCase() === name) return true;
|
|
1257
|
+
return [...document.querySelectorAll('h1,[role="heading"]')].some((h) => (h.innerText || "").trim().toLowerCase() === name);
|
|
1256
1258
|
})()`);
|
|
1257
1259
|
if (!alreadyInRequestedProject) {
|
|
1258
1260
|
throw new Error(`Clicking project "${options.project}" did not navigate the visible tab. If the tab is already inside this project, omit --project and retry.`);
|
|
@@ -1379,11 +1381,27 @@ export async function sendChatGptPrompt(options) {
|
|
|
1379
1381
|
};
|
|
1380
1382
|
let beforeSubmit;
|
|
1381
1383
|
let submitButtonFound = false;
|
|
1384
|
+
const sendWarnings = [];
|
|
1382
1385
|
const cdp = await connectCdp(page.webSocketDebuggerUrl);
|
|
1383
1386
|
try {
|
|
1384
1387
|
await cdp.send("Runtime.enable");
|
|
1385
1388
|
await selectProject(cdp, options);
|
|
1386
|
-
|
|
1389
|
+
try {
|
|
1390
|
+
await selectModelReasoning(cdp, options);
|
|
1391
|
+
}
|
|
1392
|
+
catch (modelError) {
|
|
1393
|
+
// Pro sub-mode isn't exposed in this UI yet (staged rollout). Pro itself is
|
|
1394
|
+
// already selected by this point, so degrade to plain Pro with a warning
|
|
1395
|
+
// instead of failing the whole consult - an agent's --pro-mode 확장 becomes
|
|
1396
|
+
// a successful plain-Pro send rather than a hard block it has to retry past.
|
|
1397
|
+
const modelMsg = modelError instanceof Error ? modelError.message : String(modelError);
|
|
1398
|
+
if (options.proMode && /does not expose Pro sub-modes/.test(modelMsg)) {
|
|
1399
|
+
sendWarnings.push("pro_mode_unavailable: this ChatGPT UI does not expose Pro sub-modes yet, so the consult was sent as plain Pro. Drop --pro-mode (or run `prodex setup --clear-pro-mode`).");
|
|
1400
|
+
}
|
|
1401
|
+
else {
|
|
1402
|
+
throw modelError;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1387
1405
|
// Capture the answer baseline AFTER any project navigation or model switch
|
|
1388
1406
|
// so assistant-message counts compare within the thread we actually send
|
|
1389
1407
|
// into; a --project/--project-new hop lands on a page with its own counts.
|
|
@@ -1520,7 +1538,7 @@ export async function sendChatGptPrompt(options) {
|
|
|
1520
1538
|
title: completed.title,
|
|
1521
1539
|
answer: completed.answer.trim(),
|
|
1522
1540
|
modelHints: completed.modelHints,
|
|
1523
|
-
warnings: []
|
|
1541
|
+
warnings: [...sendWarnings]
|
|
1524
1542
|
};
|
|
1525
1543
|
}
|
|
1526
1544
|
// Timed out while the answer was still streaming: salvage the partial text
|
|
@@ -1534,6 +1552,7 @@ export async function sendChatGptPrompt(options) {
|
|
|
1534
1552
|
answer: completed.answer.trim(),
|
|
1535
1553
|
modelHints: completed.modelHints,
|
|
1536
1554
|
warnings: [
|
|
1555
|
+
...sendWarnings,
|
|
1537
1556
|
`answer_incomplete: ChatGPT was still generating after ${formatDurationMs(timeoutMs)} (${timeoutMs}ms), so the answer below may be truncated. Raise --timeout-ms and retry for the full response.`
|
|
1538
1557
|
]
|
|
1539
1558
|
};
|
package/dist/cli-pro.js
CHANGED
|
@@ -545,7 +545,19 @@ export async function runAskProCommand(rest, io) {
|
|
|
545
545
|
}
|
|
546
546
|
const targetCwd = resolveCwdFlag(io.cwd, parsedAskPro.optionArgs);
|
|
547
547
|
const targetStore = new BridgeStore(targetCwd);
|
|
548
|
-
const files = readRepeatedFlag(parsedAskPro.optionArgs, "--file")
|
|
548
|
+
const files = readRepeatedFlag(parsedAskPro.optionArgs, "--file").map((file) => {
|
|
549
|
+
if (!path.isAbsolute(file))
|
|
550
|
+
return file;
|
|
551
|
+
// Accept an absolute --file that points INSIDE the repo by converting it to
|
|
552
|
+
// the repo-relative path the reader requires (agents naturally pass absolute
|
|
553
|
+
// paths); reject one that escapes the repo so a file outside the project
|
|
554
|
+
// (secrets, ~/.ssh, ...) is not attached to a consult by mistake.
|
|
555
|
+
const rel = path.relative(targetCwd, path.resolve(file));
|
|
556
|
+
if (rel === "" || rel.startsWith("..") || path.isAbsolute(rel)) {
|
|
557
|
+
throw new Error(`--file "${file}" is outside the repo root (${targetCwd}). Pass a path inside the repo (absolute or relative), or point --cwd at that repo.`);
|
|
558
|
+
}
|
|
559
|
+
return rel;
|
|
560
|
+
});
|
|
549
561
|
const targetUrl = readFlag(parsedAskPro.optionArgs, "--target-url");
|
|
550
562
|
const normalizedTargetUrl = targetUrl ? normalizeChatGptTargetUrl(targetUrl) : undefined;
|
|
551
563
|
if (!normalizedTargetUrl && parsedAskPro.optionArgs.includes("--confirm-target")) {
|
|
@@ -559,12 +571,15 @@ export async function runAskProCommand(rest, io) {
|
|
|
559
571
|
throw new Error("--json applies to the visible-browser send output; the dry-run preview does not support it.");
|
|
560
572
|
}
|
|
561
573
|
const prompt = parsedAskPro.promptParts.join(" ").trim();
|
|
562
|
-
|
|
574
|
+
const usingStdin = parsedAskPro.optionArgs.includes("--stdin");
|
|
575
|
+
// A prompt is required UNLESS --stdin supplies one: `git diff | prodex ask
|
|
576
|
+
// --stdin` (piped text is the whole prompt) is as valid as `... --stdin
|
|
577
|
+
// "review this"` (positional instruction + piped data below it).
|
|
578
|
+
if (!prompt && !usingStdin) {
|
|
563
579
|
throw new Error('ask-pro requires a prompt. Example: prodex ask "Explain this stack trace" (or pipe input: git diff | prodex ask --stdin "review this diff").');
|
|
564
580
|
}
|
|
565
581
|
let promptText = prompt;
|
|
566
|
-
if (
|
|
567
|
-
// Unix ergonomics: `git diff | prodex ask --stdin "review this"`.
|
|
582
|
+
if (usingStdin) {
|
|
568
583
|
const piped = ((await io.readStdin?.()) ?? "").trim();
|
|
569
584
|
if (!piped) {
|
|
570
585
|
throw new Error("--stdin was set but no piped input was received on stdin (pipe something in, e.g. `git diff | prodex ask --stdin \"review\"`).");
|
|
@@ -573,7 +588,7 @@ export async function runAskProCommand(rest, io) {
|
|
|
573
588
|
if (piped.length > MAX_STDIN_CHARS) {
|
|
574
589
|
throw new Error(`--stdin input is too large (${piped.length} chars > ${MAX_STDIN_CHARS}); attach a file with --file instead.`);
|
|
575
590
|
}
|
|
576
|
-
promptText = `${prompt}\n\n--- piped input (stdin) ---\n${piped}
|
|
591
|
+
promptText = prompt ? `${prompt}\n\n--- piped input (stdin) ---\n${piped}` : piped;
|
|
577
592
|
}
|
|
578
593
|
const browserDefaults = await loadBrowserDefaults(targetCwd);
|
|
579
594
|
const explicitProject = readFlag(parsedAskPro.optionArgs, "--project");
|
package/dist/cli.js
CHANGED
|
@@ -321,6 +321,7 @@ repo: ${cwd}
|
|
|
321
321
|
${cli} claude prompt --cwd ${quotedCwd}${sourceCliOption}
|
|
322
322
|
Agents get the bridge/ledger tools plus pro_consult (ask ChatGPT Pro directly; see docs/clients.md for Codex timeout and approval notes).
|
|
323
323
|
Saved setup defaults (--model/--project) apply to agent consults too - pin them once per repo so consults stop landing in the general chat list.
|
|
324
|
+
Agents often run the MCP as \`prodex mcp\` with no --cwd, which misses a per-repo default. For a default that applies from ANY directory, set PRODEX_DEFAULT_PROJECT and PRODEX_DEFAULT_MODEL (in the agent's MCP env block, or your shell) to YOUR project/model. No project? Consults just go to the general chat. List your exact project names with \`${cli} pro browser projects\`.
|
|
324
325
|
${cli} pro debate-prompt --topic "your question"${sourceCliOption} # structured GPT Pro debate prompt for your agent
|
|
325
326
|
|
|
326
327
|
3. Local bridge health and records:
|