@youdie006/prodex 0.37.0 → 0.37.1

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 CHANGED
@@ -424,6 +424,47 @@ During local development, you can run the TypeScript source directly:
424
424
  npm run dev -- tasks list
425
425
  ```
426
426
 
427
+ ## When a send breaks
428
+
429
+ prodex drives a web UI that changes underneath it, so the interesting question is what you have when that happens.
430
+
431
+ **Report it from the receipt, not from memory.** A blocked consult already records the blocker, the version and the platform, so `prodex pro report-issue` builds the report out of that:
432
+
433
+ ```bash
434
+ prodex pro report-issue # prints it, files nothing
435
+ prodex pro report-issue --confirm # opens it as a GitHub issue, through `gh`
436
+ ```
437
+
438
+ The prompt, the answer and the summary never travel - a public issue is not where a private consult should leak - and filing is deduplicated by blocker code, so something that stays broken adds to one issue instead of opening a new one every time.
439
+
440
+ **Capture what the page looked like.** With diagnostics on, a failing send leaves a screenshot and a snapshot of the picker and composer next to each other:
441
+
442
+ ```bash
443
+ PRODEX_BROWSER_DIAGNOSTICS=1 prodex ask "..."
444
+ # .bridge/diagnostics/<when>/{screen.png,page-shape.json}
445
+ ```
446
+
447
+ The snapshot carries roles, testids, rects, `aria-value*` and `pointer-events`. Those last two are what identified a model row that no coordinate could click and a slider step prodex could not read. Captures stay on your machine and are never attached to a report; a screenshot of ChatGPT shows the conversation.
448
+
449
+ **Notice before a person does.** `scripts/ui-watchdog.mjs` sends a token and checks the reply - a real round trip rather than a guess from the page's shape - and can file what it finds:
450
+
451
+ ```bash
452
+ node scripts/ui-watchdog.mjs # says ok or broken
453
+ node scripts/ui-watchdog.mjs --file-issue # and reports it
454
+ ```
455
+
456
+ It needs the logged-in browser, so it belongs on a machine that has one rather than in CI. A daily cron entry is enough.
457
+
458
+ ## Sending without leaving a trace
459
+
460
+ `--temporary` sends into a ChatGPT Temporary Chat, which leaves your chat list untouched:
461
+
462
+ ```bash
463
+ prodex ask --new-chat --temporary "..."
464
+ ```
465
+
466
+ It costs something, and prodex says so on every such send: an unsaved chat is not in the transcript API, so the answer is read off the page, where tables and citation links can be lost - and neither `pro browser recover` nor `--target-url` can reach it afterwards. It requires `--new-chat`, because a throwaway chat cannot be continued.
467
+
427
468
  ## FAQ
428
469
 
429
470
  **A send failed with `send_ui_changed` / "the ChatGPT web UI may have changed".** prodex drives the visible ChatGPT web UI, so an OpenAI redesign of the composer or send control can break sends. When a send times out without the prompt ever posting (the composer still holds the text, or no send button was found), prodex reports this as a likely UI change instead of a misleading "slow model" timeout. Fix: update prodex (`npm i -g @youdie006/prodex@latest`); if it persists, open an issue at https://github.com/youdie006/prodex/issues, and paste the prompt manually in the visible browser in the meantime.
@@ -15,7 +15,12 @@ export class ChatGptBrowserBlockerError extends Error {
15
15
  this.blocker = blocker;
16
16
  }
17
17
  }
18
- const REASONING_EFFORTS = ["즉시", "중간", "높음", "매우 높음"];
18
+ // Five steps, not four. Measured at both ends of the live slider: position 0 of
19
+ // 4 reads "Instant, 1 of 5" and position 4 reads "Pro, 5 of 5", so Pro is a step
20
+ // of this control rather than a model. Leaving it out meant --effort could not
21
+ // reach the top of the slider at all, and the only route there - --model Pro -
22
+ // answered with advice to "say --effort Pro", which then failed.
23
+ const REASONING_EFFORTS = ["즉시", "중간", "높음", "매우 높음", "Pro"];
19
24
  const PRO_MODES = ["기본", "확장"];
20
25
  // Aliases map friendly CLI input onto the exact Korean menu labels the picker
21
26
  // clicks by text. Keys are lowercased and space-stripped before lookup.
@@ -25,7 +30,9 @@ const REASONING_EFFORT_ALIASES = {
25
30
  medium: "중간",
26
31
  high: "높음",
27
32
  max: "매우 높음",
28
- extrahigh: "매우 높음"
33
+ extrahigh: "매우 높음",
34
+ pro: "Pro",
35
+ "프로": "Pro"
29
36
  };
30
37
  // Menu labels per canonical value, verified live in both the Korean and the
31
38
  // English (US) ChatGPT UI. Matching tries every candidate so either UI works.
@@ -33,7 +40,8 @@ const EFFORT_MENU_LABELS = {
33
40
  "즉시": ["즉시", "Instant"],
34
41
  "중간": ["중간", "Medium"],
35
42
  "높음": ["높음", "High"],
36
- "매우 높음": ["매우 높음", "Extra High"]
43
+ "매우 높음": ["매우 높음", "Extra High"],
44
+ Pro: ["Pro", "프로"]
37
45
  };
38
46
  const PRO_MODE_SUBMENU_LABELS = {
39
47
  "기본": ["Pro 기본", "Pro Standard", "Standard", "기본"],
@@ -1637,7 +1645,21 @@ export function pinnedSelectionWarning(pinned, offered) {
1637
1645
  if (offered.length === 0)
1638
1646
  return undefined;
1639
1647
  const has = (wanted) => offered.some((label) => label.trim().toLowerCase() === wanted.trim().toLowerCase());
1640
- const missing = [pinned.model, pinned.effort].find((wanted) => wanted !== undefined && !has(wanted));
1648
+ // A value prodex already knows to be a slider step needs no listing to
1649
+ // vouch for it: the slider shows one step at a time, so a listing that
1650
+ // happens to read "Extra High" says nothing about Pro. Warning there was a
1651
+ // false alarm about a setting the very next send used successfully, and an
1652
+ // alarm that cries about known-good settings is one people learn to skip.
1653
+ const knownStep = (wanted) => {
1654
+ try {
1655
+ parseReasoningEffort(wanted);
1656
+ return true;
1657
+ }
1658
+ catch {
1659
+ return false;
1660
+ }
1661
+ };
1662
+ const missing = [pinned.model, pinned.effort].find((wanted) => wanted !== undefined && !has(wanted) && !knownStep(wanted));
1641
1663
  if (missing === undefined)
1642
1664
  return undefined;
1643
1665
  // Say only what was seen. The picker lists its models, but the effort slider
package/dist/cli-help.js CHANGED
@@ -26,10 +26,11 @@ 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 300000] [--busy-wait-ms 600000] [--target-url url --confirm-target] [--new-chat] [--temporary] [--stdin] [--json] [--auto-login|--no-auto-login] [--file path] [--attach path] [--tool deep-research|web-search|create-image] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name" | --project-new "name"] "prompt" # explicit visible-browser send
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] [--temporary] [--stdin] [--json] [--auto-login|--no-auto-login] [--file path] [--attach path] [--tool deep-research|web-search|create-image] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"|Pro] [--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] [--json]
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] [--json]
33
+ prodex pro report-issue [--cwd /absolute/path/to/repo] [--task <task-id>] [--repo owner/name] [--confirm] # bug report from a failed consult's receipt; previews unless --confirm, never carries the prompt or the answer
33
34
 
34
35
  Bridge ledger (durable tasks/results/receipts/sessions under .bridge/):
35
36
  prodex init [--cwd /absolute/path/to/repo]
@@ -51,7 +52,7 @@ Bridge ledger (durable tasks/results/receipts/sessions under .bridge/):
51
52
 
52
53
  Agent / MCP integration:
53
54
  prodex mcp [--cwd /absolute/path/to/repo]
54
- prodex setup [--cwd /absolute/path/to/repo] [--host 127.0.0.1] [--port 8787] [--token-ttl-hours <hours>] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name"] [--clear-model|--clear-pro-mode|--clear-effort|--clear-project] [--interactive]
55
+ prodex setup [--cwd /absolute/path/to/repo] [--host 127.0.0.1] [--port 8787] [--token-ttl-hours <hours>] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"|Pro] [--project "name"] [--clear-model|--clear-pro-mode|--clear-effort|--clear-project] [--interactive]
55
56
  prodex start [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js]
56
57
  prodex status [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js] [--show-token] [--url-only] [--unsafe-show-non-expiring-token]
57
58
  prodex tunnel url [--cwd /absolute/path/to/repo] [--source-cli /absolute/path/to/dist/cli.js] --public-url https://... [--show-token] [--url-only]
@@ -79,7 +80,7 @@ export function printSetupHelp(stdout) {
79
80
  stdout(`prodex setup
80
81
 
81
82
  Commands:
82
- prodex setup [--cwd /absolute/path/to/repo] [--host 127.0.0.1] [--port 8787] [--token-ttl-hours <hours>] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name"] [--clear-model|--clear-pro-mode|--clear-effort|--clear-project] [--interactive]
83
+ prodex setup [--cwd /absolute/path/to/repo] [--host 127.0.0.1] [--port 8787] [--token-ttl-hours <hours>] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"|Pro] [--project "name"] [--clear-model|--clear-pro-mode|--clear-effort|--clear-project] [--interactive]
83
84
 
84
85
  Save a loopback-only HTTP MCP profile in .bridge/config.local.json. Use --token-ttl-hours before tunnels or ChatGPT Project use.
85
86
 
@@ -167,10 +168,11 @@ Commands:
167
168
  prodex pro browser check [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
168
169
  prodex pro browser smoke [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo]
169
170
  prodex pro browser models [--source-cli /absolute/path/to/dist/cli.js]
170
- prodex pro browser ask [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--target-url url --confirm-target] [--new-chat] [--temporary] [--stdin] [--json] [--auto-login|--no-auto-login] [--file path] [--attach path] [--tool deep-research|web-search|create-image] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name" | --project-new "name"] "prompt"
171
+ prodex pro browser ask [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--target-url url --confirm-target] [--new-chat] [--temporary] [--stdin] [--json] [--auto-login|--no-auto-login] [--file path] [--attach path] [--tool deep-research|web-search|create-image] [--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"|Pro] [--project "name" | --project-new "name"] "prompt"
171
172
  prodex pro latest [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--json]
172
173
  prodex pro list [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--json]
173
174
  prodex pro show <task-id|latest> [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--json]
175
+ prodex pro report-issue [--cwd /absolute/path/to/repo] [--task <task-id>] [--repo owner/name] [--confirm] # bug report from a failed consult's receipt; previews unless --confirm, never carries the prompt or the answer
174
176
 
175
177
  Use \`prodex pro ask\` for dry-run/manual previews.
176
178
  Use \`prodex pro browser ask\` only when you want an explicit visible-browser send.
@@ -251,7 +253,7 @@ export function printProBrowserHelp(stdout, sourceCli) {
251
253
  const smokeUsage = sourceCli
252
254
  ? `${cli} pro browser smoke${sourceCliOption} [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 90000]`
253
255
  : "prodex pro browser smoke [--source-cli /absolute/path/to/dist/cli.js] [--cwd /absolute/path/to/repo] [--port 9333] [--timeout-ms 90000]";
254
- const selectionUsage = '[--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"] [--project "name" | --project-new "name"]';
256
+ const selectionUsage = '[--model Pro] [--pro-mode 기본|확장] [--effort 즉시|중간|높음|"매우 높음"|Pro] [--project "name" | --project-new "name"]';
255
257
  const askUsage = sourceCli
256
258
  ? `${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] [--temporary] [--stdin] [--json] [--auto-login|--no-auto-login] [--file path] [--attach path] [--tool deep-research|web-search|create-image] ${selectionUsage} "prompt"`
257
259
  : `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] [--temporary] [--stdin] [--json] [--auto-login|--no-auto-login] [--file path] [--attach path] [--tool deep-research|web-search|create-image] ${selectionUsage} "prompt"`;
package/dist/cli.js CHANGED
@@ -436,7 +436,9 @@ 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, plus response_choice_pending when ChatGPT is waiting for you to pick which of two answers you prefer.`;
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
+ - When a send is blocked, \`prodex pro report-issue\` turns that receipt into a bug report (prints it; --confirm files it). It carries the blocker, version and platform, never the prompt or the answer.
441
+ - PRODEX_BROWSER_DIAGNOSTICS=1 makes a failing send leave a screenshot and a page snapshot under .bridge/diagnostics for whoever debugs it. They stay local.`;
440
442
  }
441
443
  async function hasOnboardingReadme(cwd) {
442
444
  try {
package/dist/config.js CHANGED
@@ -10,7 +10,8 @@ const BRIDGE_DIRECTORY_MODE = 0o700;
10
10
  const BrowserDefaultsSchema = z.object({
11
11
  model: z.string().min(1).optional(),
12
12
  pro_mode: z.enum(["기본", "확장"]).optional(),
13
- effort: z.enum(["즉시", "중간", "높음", "매우 높음"]).optional(),
13
+ // Pro is the slider's fifth step, so a saved default may name it.
14
+ effort: z.enum(["즉시", "중간", "높음", "매우 높음", "Pro"]).optional(),
14
15
  project: z.string().min(1).optional()
15
16
  });
16
17
  const LocalConfigSchema = z.object({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@youdie006/prodex",
3
- "version": "0.37.0",
3
+ "version": "0.37.1",
4
4
  "description": "Local receipt bus for coordinating Codex execution with ChatGPT Pro/Projects consultation.",
5
5
  "author": "youdie006",
6
6
  "license": "MIT",