@youdie006/prodex 0.16.8 → 0.16.10
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/chatgpt-browser.js +30 -4
- package/package.json +1 -1
package/dist/chatgpt-browser.js
CHANGED
|
@@ -867,16 +867,28 @@ export function proSubmenuExpanderRectExpression() {
|
|
|
867
867
|
export function projectItemRectExpression(name) {
|
|
868
868
|
return `(() => {${CLICK_POINT_SNIPPET}
|
|
869
869
|
// Korean: "<name> 프로젝트 옵션 열기"; English: "Open project options for <name>".
|
|
870
|
-
const
|
|
870
|
+
const wanted = ${JSON.stringify(name)};
|
|
871
|
+
const optionButtons = [...document.querySelectorAll('[aria-label*="프로젝트 옵션"],[aria-label*="project options" i]')];
|
|
872
|
+
let opt = optionButtons.find((b) => (b.getAttribute("aria-label") || "").includes(wanted));
|
|
873
|
+
if (!opt) {
|
|
874
|
+
// Case-insensitive fallback: sidebar names are user-typed ("Codex") and
|
|
875
|
+
// an agent asking for "codex" should still resolve when unambiguous.
|
|
876
|
+
// Ambiguity fails loudly rather than guessing.
|
|
877
|
+
const ci = optionButtons.filter((b) => (b.getAttribute("aria-label") || "").toLowerCase().includes(wanted.toLowerCase()));
|
|
878
|
+
if (ci.length === 1) opt = ci[0];
|
|
879
|
+
else if (ci.length > 1) return { ok: false, reason: "project name matches multiple sidebar projects case-insensitively; use the exact name" };
|
|
880
|
+
}
|
|
871
881
|
let target = opt ? (opt.closest('a,[role="link"],li') || opt.parentElement) : null;
|
|
872
882
|
if (!target) {
|
|
873
883
|
const icons = [...document.querySelectorAll('[data-testid="project-folder-icon"]')];
|
|
874
884
|
for (const ic of icons) {
|
|
875
885
|
const row = ic.closest('a,li,[role="link"]') || ic.parentElement?.parentElement;
|
|
876
|
-
if (row && (row.textContent || "").includes(
|
|
886
|
+
if (row && (row.textContent || "").includes(wanted)) { target = row; break; }
|
|
877
887
|
}
|
|
878
888
|
}
|
|
879
|
-
if (!target)
|
|
889
|
+
if (!target) {
|
|
890
|
+
return { ok: false, reason: "project not found in sidebar (" + optionButtons.length + " projects visible; names are matched exactly first, then case-insensitively - check the exact sidebar spelling)" };
|
|
891
|
+
}
|
|
880
892
|
// 2026-07 ChatGPT update: the project row (li) is no longer a link - the
|
|
881
893
|
// navigation affordance is a dedicated "Open project home" button inside
|
|
882
894
|
// the row (verified live: clicking the row does nothing, clicking the home
|
|
@@ -1091,7 +1103,21 @@ async function selectProject(cdp, options) {
|
|
|
1091
1103
|
if (!options.project)
|
|
1092
1104
|
return;
|
|
1093
1105
|
const hrefBefore = await cdp.evaluate("location.href");
|
|
1094
|
-
|
|
1106
|
+
// Poll for the project row instead of a single check: right after a
|
|
1107
|
+
// --new-chat navigation the sidebar's Projects section has not hydrated yet
|
|
1108
|
+
// (measured live: "0 projects visible" on the first read, rows appear
|
|
1109
|
+
// moments later) - the same class of race as the model-selector button
|
|
1110
|
+
// after new-chat (0.15.7).
|
|
1111
|
+
let hit = { ok: false };
|
|
1112
|
+
const projectDeadline = Date.now() + 6_000;
|
|
1113
|
+
for (;;) {
|
|
1114
|
+
hit = await cdp.evaluate(projectItemRectExpression(options.project));
|
|
1115
|
+
if (hit.ok && hit.x !== undefined && hit.y !== undefined)
|
|
1116
|
+
break;
|
|
1117
|
+
if (Date.now() >= projectDeadline)
|
|
1118
|
+
break;
|
|
1119
|
+
await sleep(300);
|
|
1120
|
+
}
|
|
1095
1121
|
if (!hit.ok || hit.x === undefined || hit.y === undefined) {
|
|
1096
1122
|
const detail = hit.reason && hit.reason !== "project not found in sidebar" ? ` (${hit.reason})` : "";
|
|
1097
1123
|
throw new Error(`ChatGPT project not found in sidebar: ${options.project}${detail}`);
|