binary-collections 2.0.10 → 2.0.11
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/.puppeterrc.cjs +25 -0
- package/binaries/binary-executor.cjs +138 -3
- package/binaries/clean-nodemodule.cjs +138 -3
- package/binaries/clean-nodemodules.cjs +138 -3
- package/binaries/dev.cjs +138 -3
- package/binaries/empty.cjs +138 -3
- package/binaries/git-reduce-size.cjs +138 -3
- package/binaries/javakill.cjs +138 -3
- package/binaries/kill-night-crows.bat +7 -0
- package/binaries/kill-night-crows.ps1 +172 -0
- package/binaries/kill-process.cjs +138 -3
- package/binaries/nodekill.cjs +138 -3
- package/binaries/prod.cjs +138 -3
- package/binaries/py +111 -0
- package/binaries/py.cjs +178 -0
- package/binaries/py.cmd +49 -0
- package/binaries/rmfind.cjs +138 -3
- package/binaries/rmx.cjs +138 -3
- package/binaries/submodule-token.cjs +138 -3
- package/binaries/test-cjs +10 -0
- package/binaries/test-cjs.cjs +178 -0
- package/binaries/test-cjs.cmd +11 -0
- package/binaries/yarn-clean +32 -0
- package/binaries/yarn-clean.cjs +178 -0
- package/binaries/yarn-clean.cmd +30 -0
- package/binaries/yarn-clean.py +148 -0
- package/lib/binary-collections-config.cjs +1 -1
- package/lib/binary-collections-config.mjs +1 -1
- package/lib/binary-collections.cjs +167 -106
- package/lib/binary-collections.mjs +108 -94
- package/lib/changelog.cjs +61 -13
- package/lib/changelog.mjs +1 -1
- package/lib/{chunk-AI4CVPJ7.mjs → chunk-2CBJCW7E.mjs} +4 -4
- package/lib/chunk-34IQDTLZ.mjs +27 -0
- package/lib/chunk-3HFFECCI.mjs +27 -0
- package/lib/{chunk-SBNDSKG5.mjs → chunk-4UHL4WVN.mjs} +1 -1
- package/lib/chunk-7XTEJHOE.mjs +193 -0
- package/lib/chunk-AJDD5DZM.mjs +109 -0
- package/lib/chunk-BZWVHODJ.mjs +62 -0
- package/lib/{chunk-BEZKJ25G.mjs → chunk-FCDQGYBF.mjs} +5 -9
- package/lib/chunk-GEYA2USY.mjs +207 -0
- package/lib/chunk-ID2WBTE2.mjs +80 -0
- package/lib/chunk-JXFOHKDM.mjs +239 -0
- package/lib/{chunk-DI5MDPSN.mjs → chunk-N436BNBK.mjs} +192 -64
- package/lib/chunk-NCXAP7AA.mjs +31 -0
- package/lib/chunk-PDN26I7O.mjs +188 -0
- package/lib/{chunk-E6FDDAOO.mjs → chunk-RWLXRTYP.mjs} +1 -1
- package/lib/{chunk-BDCHCWHD.mjs → chunk-TOIVAQF7.mjs} +4 -4
- package/lib/chunk-V5SKYJUB.mjs +136 -0
- package/lib/{chunk-HMRMTYZM.mjs → chunk-WSRETQCA.mjs} +21 -2
- package/lib/chunk-XA3SNBPA.mjs +184 -0
- package/lib/chunk-YYLIQQKF.mjs +31 -0
- package/lib/{chunk-V3N3JEUF.mjs → chunk-Z6JLYU2J.mjs} +60 -13
- package/lib/{chunk-O6SWBEOQ.mjs → chunk-ZDMWBSYF.mjs} +2 -2
- package/lib/clean-github-actions-caches.cjs +63 -15
- package/lib/clean-github-actions-caches.mjs +3 -3
- package/lib/del-gradle.cjs +61 -13
- package/lib/del-gradle.js +1 -0
- package/lib/del-gradle.mjs +1 -1
- package/lib/del-node-modules.cjs +143 -148
- package/lib/del-node-modules.js +210 -14
- package/lib/del-node-modules.mjs +148 -17
- package/lib/del-ps.cjs +61 -13
- package/lib/del-ps.js +1 -0
- package/lib/del-ps.mjs +1 -1
- package/lib/del-yarn-caches.cjs +61 -13
- package/lib/del-yarn-caches.mjs +1 -1
- package/lib/find-node-modules-cli.js +1 -0
- package/lib/free-chatgpt.cjs +253 -47
- package/lib/free-chatgpt.mjs +2 -2
- package/lib/git/gitattributes.cjs +1 -0
- package/lib/git/gitattributes.d.cts +7 -2
- package/lib/git/gitattributes.mjs +1 -1
- package/lib/git/line-endings.cjs +2 -1
- package/lib/git/line-endings.mjs +2 -2
- package/lib/git/undo-commit-cli.cjs +110 -0
- package/lib/git/undo-commit-cli.d.ts +1 -0
- package/lib/git/undo-commit-cli.js +4 -0
- package/lib/git/undo-commit-cli.mjs +14 -0
- package/lib/git/undo-commit.cjs +81 -0
- package/lib/git/undo-commit.d.cts +1 -0
- package/lib/git/undo-commit.mjs +7 -0
- package/lib/git/undo-staged-cli.cjs +110 -0
- package/lib/git/undo-staged-cli.d.ts +1 -0
- package/lib/git/undo-staged-cli.js +4 -0
- package/lib/git/undo-staged-cli.mjs +14 -0
- package/lib/git/undo-staged.cjs +81 -0
- package/lib/git/undo-staged.d.cts +1 -0
- package/lib/git/undo-staged.mjs +7 -0
- package/lib/git/user-config.cjs +61 -14
- package/lib/git/user-config.mjs +2 -2
- package/lib/git-diff-cli.cjs +255 -49
- package/lib/git-diff-cli.d.ts +1 -0
- package/lib/git-diff-cli.js +1 -0
- package/lib/git-diff-cli.mjs +5 -4
- package/lib/git-diff.cjs +254 -49
- package/lib/git-diff.mjs +4 -4
- package/lib/git-fix.cjs +64 -16
- package/lib/git-fix.mjs +10 -10
- package/lib/git-purge.cjs +61 -13
- package/lib/git-purge.mjs +1 -1
- package/lib/kill-night-crows.cjs +87 -0
- package/lib/kill-night-crows.d.mts +1 -0
- package/lib/kill-night-crows.mjs +65 -0
- package/lib/npm-run-series.cjs +60 -13
- package/lib/npm-run-series.mjs +1 -1
- package/lib/package-resolutions-updater-cli.cjs +560 -0
- package/lib/package-resolutions-updater-cli.d.mts +1 -0
- package/lib/package-resolutions-updater-cli.mjs +124 -0
- package/lib/package-resolutions-updater.cjs +174 -154
- package/lib/package-resolutions-updater.d.mts +32 -1
- package/lib/package-resolutions-updater.mjs +16 -294
- package/lib/php-cs-fixer-staged.cjs +105 -0
- package/lib/php-cs-fixer-staged.d.cts +2 -0
- package/lib/php-cs-fixer-staged.mjs +117 -0
- package/lib/print-directory-tree.cjs +62 -14
- package/lib/print-directory-tree.mjs +2 -2
- package/lib/ps/connected-domain.d.ts +1 -1
- package/lib/ps/index.js +1 -0
- package/lib/remove-module.cjs +61 -13
- package/lib/remove-module.mjs +1 -1
- package/lib/rmpath.cjs +63 -15
- package/lib/rmpath.mjs +2 -2
- package/lib/submodule-install.cjs +62 -15
- package/lib/submodule-install.mjs +3 -3
- package/lib/submodule-remove-cli.cjs +5 -1
- package/lib/submodule-remove-cli.mjs +1 -1
- package/lib/submodule-remove.cjs +4 -1
- package/lib/submodule-remove.mjs +1 -1
- package/lib/utils/chatgpt.cjs +192 -34
- package/lib/utils/chatgpt.js +210 -43
- package/lib/utils/chatgpt.mjs +1 -1
- package/lib/utils/findEnvFiles.cjs +107 -0
- package/lib/utils/findEnvFiles.d.ts +8 -0
- package/lib/utils/findEnvFiles.js +121 -0
- package/lib/utils/findEnvFiles.mjs +8 -0
- package/lib/utils/findWorkspaceRoot.cjs +70 -0
- package/lib/utils/findWorkspaceRoot.d.ts +9 -0
- package/lib/utils/findWorkspaceRoot.js +57 -0
- package/lib/utils/findWorkspaceRoot.mjs +40 -0
- package/lib/utils/index.cjs +60 -13
- package/lib/utils/index.mjs +1 -1
- package/lib/utils/isGithubTokenValid.cjs +64 -0
- package/lib/utils/isGithubTokenValid.d.ts +7 -0
- package/lib/utils/isGithubTokenValid.js +48 -0
- package/lib/utils/isGithubTokenValid.mjs +36 -0
- package/lib/yarn-reinstall.cjs +61 -13
- package/lib/yarn-reinstall.mjs +1 -1
- package/package.json +107 -93
- package/readme.md +33 -34
- package/releases/readme.md +1 -1
- package/requirements.txt +1 -0
- package/lib/chunk-4EWQC6GZ.mjs +0 -382
- package/lib/chunk-4ZI7BQKQ.mjs +0 -381
- package/lib/chunk-5J2BEPY5.mjs +0 -83
- package/lib/chunk-AGZYRDC2.mjs +0 -323
- package/lib/chunk-HN52G2YL.mjs +0 -305
- package/lib/chunk-HO6GHCOB.mjs +0 -385
- package/lib/chunk-LEM5OMRP.mjs +0 -384
- package/lib/chunk-RCP7DHVY.mjs +0 -190
- package/lib/chunk-U6SO4QEV.mjs +0 -320
- package/lib/chunk-XD6BJK6Q.mjs +0 -351
- package/lib/chunk-YXSFGA2D.mjs +0 -383
- package/lib/git/gitattributes.d.ts +0 -33
- package/lib/git/gitattributes.js +0 -223
package/lib/utils/chatgpt.js
CHANGED
|
@@ -19,7 +19,29 @@ const puppeteer_extra_plugin_stealth_1 = __importDefault(require("puppeteer-extr
|
|
|
19
19
|
const upath_1 = __importDefault(require("upath"));
|
|
20
20
|
const COOKIE_DIR = upath_1.default.join(process.cwd(), "tmp", "cookies");
|
|
21
21
|
const DEFAULT_COOKIE_PATH = upath_1.default.join(COOKIE_DIR, "cookies.json");
|
|
22
|
+
const NAVIGATION_TIMEOUT_MS = 90000;
|
|
23
|
+
const NETWORK_IDLE_TIMEOUT_MS = 15000;
|
|
24
|
+
const MAX_INLINE_QUESTION_FILE_BYTES = 2 * 1024;
|
|
22
25
|
fs_extra_1.default.ensureDirSync(COOKIE_DIR);
|
|
26
|
+
/**
|
|
27
|
+
* Navigates to a page with a resilient strategy for apps that keep long-lived network connections.
|
|
28
|
+
*
|
|
29
|
+
* @param {import('puppeteer').Page} page - Puppeteer page instance.
|
|
30
|
+
* @param {string} url - URL to navigate to.
|
|
31
|
+
* @returns {Promise<void>} Resolves when the page is at least DOM-ready.
|
|
32
|
+
*/
|
|
33
|
+
function gotoWithFallback(page, url) {
|
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
yield page.goto(url, { waitUntil: "domcontentloaded", timeout: NAVIGATION_TIMEOUT_MS });
|
|
36
|
+
// Best effort: settle initial bursty requests without hard-failing on persistent streams.
|
|
37
|
+
try {
|
|
38
|
+
yield page.waitForNetworkIdle({ idleTime: 1000, timeout: NETWORK_IDLE_TIMEOUT_MS });
|
|
39
|
+
}
|
|
40
|
+
catch (_a) {
|
|
41
|
+
// Ignore network-idle timeouts because ChatGPT keeps active connections open.
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
23
45
|
/**
|
|
24
46
|
* Saves cookies from a Puppeteer page to a specified file path.
|
|
25
47
|
*
|
|
@@ -63,8 +85,8 @@ function navigatePage(page, url) {
|
|
|
63
85
|
if (cookies) {
|
|
64
86
|
yield page.setCookie(...cookies);
|
|
65
87
|
}
|
|
66
|
-
// Navigate
|
|
67
|
-
yield page
|
|
88
|
+
// Navigate with fallback for pages that keep persistent network connections.
|
|
89
|
+
yield gotoWithFallback(page, url);
|
|
68
90
|
// Inject DOM mutation observer to handle dynamic content
|
|
69
91
|
yield page.evaluate(() => {
|
|
70
92
|
window.__domStillUpdating = true;
|
|
@@ -144,31 +166,41 @@ function _restoreCookies(page_1) {
|
|
|
144
166
|
*/
|
|
145
167
|
function writeQuestion(page, question) {
|
|
146
168
|
return __awaiter(this, void 0, void 0, function* () {
|
|
147
|
-
const questions = question.split("\n");
|
|
148
169
|
const promptTextarea = yield page.waitForSelector("#prompt-textarea", { timeout: 30000 });
|
|
149
170
|
if (!promptTextarea) {
|
|
150
171
|
console.log("Cannot find the prompt input on the webpage. Please check whether you have access to chat.openai.com without logging in via your browser.");
|
|
151
|
-
}
|
|
152
|
-
// Clear the prompt textarea
|
|
153
|
-
yield page.evaluate(() => {
|
|
154
|
-
document.querySelector("#prompt-textarea").innerHTML = `<p></p>`;
|
|
155
|
-
});
|
|
156
|
-
// Check if the question has newlines
|
|
157
|
-
if (questions.length === 1) {
|
|
158
|
-
// If there's only one line, type it directly
|
|
159
|
-
yield page.type("#prompt-textarea", questions[0], { delay: 100 });
|
|
160
172
|
return;
|
|
161
173
|
}
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
174
|
+
// Inject the full prompt instantly and emit input-like events so the UI reacts.
|
|
175
|
+
yield page.evaluate((text) => {
|
|
176
|
+
const promptEl = document.querySelector("#prompt-textarea");
|
|
177
|
+
if (!promptEl) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
promptEl.focus();
|
|
181
|
+
promptEl.innerHTML = "";
|
|
182
|
+
const lines = String(text).split("\n");
|
|
183
|
+
for (const line of lines) {
|
|
184
|
+
const p = document.createElement("p");
|
|
185
|
+
p.textContent = line;
|
|
186
|
+
promptEl.appendChild(p);
|
|
171
187
|
}
|
|
188
|
+
promptEl.dispatchEvent(new InputEvent("beforeinput", { bubbles: true, inputType: "insertFromPaste", data: text }));
|
|
189
|
+
promptEl.dispatchEvent(new InputEvent("input", { bubbles: true, inputType: "insertFromPaste", data: text }));
|
|
190
|
+
promptEl.dispatchEvent(new Event("change", { bubbles: true }));
|
|
191
|
+
}, question);
|
|
192
|
+
// If the app state did not pick up the DOM injection, use keyboard insertion as a reliable fallback.
|
|
193
|
+
const hasPromptText = yield page.evaluate(() => {
|
|
194
|
+
const promptEl = document.querySelector("#prompt-textarea");
|
|
195
|
+
return Boolean(promptEl && promptEl.textContent && promptEl.textContent.trim().length > 0);
|
|
196
|
+
});
|
|
197
|
+
if (!hasPromptText) {
|
|
198
|
+
console.log("Prompt state not updated by DOM injection. Falling back to keyboard insertText.");
|
|
199
|
+
yield promptTextarea.click({ clickCount: 1 });
|
|
200
|
+
yield page.keyboard.down("Control");
|
|
201
|
+
yield page.keyboard.press("KeyA");
|
|
202
|
+
yield page.keyboard.up("Control");
|
|
203
|
+
yield page.keyboard.insertText(question);
|
|
172
204
|
}
|
|
173
205
|
});
|
|
174
206
|
}
|
|
@@ -176,29 +208,121 @@ function writeQuestion(page, question) {
|
|
|
176
208
|
* Clicks the submit button in ChatGPT interface, trying different button variants.
|
|
177
209
|
*
|
|
178
210
|
* @param {import('puppeteer').Page} page - Puppeteer page instance.
|
|
179
|
-
* @returns {Promise<
|
|
211
|
+
* @returns {Promise<boolean>} Resolves to true when submission is detected, otherwise false.
|
|
180
212
|
*/
|
|
181
213
|
function clickSubmitButton(page) {
|
|
182
214
|
return __awaiter(this, void 0, void 0, function* () {
|
|
215
|
+
console.log("Attempting to click the submit button...");
|
|
183
216
|
try {
|
|
184
|
-
const
|
|
185
|
-
|
|
217
|
+
const userMessageCountBefore = yield page.$$eval('[data-message-author-role="user"]', (elements) => elements.length);
|
|
218
|
+
const waitForSubmit = (...args_1) => __awaiter(this, [...args_1], void 0, function* (timeout = 5000) {
|
|
219
|
+
try {
|
|
220
|
+
yield page.waitForFunction((previousCount) => {
|
|
221
|
+
const currentCount = document.querySelectorAll('[data-message-author-role="user"]').length;
|
|
222
|
+
return currentCount > previousCount;
|
|
223
|
+
}, { timeout }, userMessageCountBefore);
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
catch (_a) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
186
229
|
});
|
|
187
|
-
|
|
188
|
-
|
|
230
|
+
yield page.waitForFunction(() => {
|
|
231
|
+
const candidates = [
|
|
232
|
+
document.querySelector('[data-testid="fruitjuice-send-button"]'),
|
|
233
|
+
document.querySelector('#composer-submit-button'),
|
|
234
|
+
document.querySelector('[data-testid="send-button"]')
|
|
235
|
+
].filter(Boolean);
|
|
236
|
+
return candidates.some((button) => {
|
|
237
|
+
const isDisabled = button.disabled || button.getAttribute("aria-disabled") === "true";
|
|
238
|
+
const isVisible = button.offsetParent !== null;
|
|
239
|
+
return !isDisabled && isVisible;
|
|
240
|
+
});
|
|
241
|
+
}, { timeout: 5000 }).catch(() => {
|
|
242
|
+
// Continue to diagnostics below even if no enabled button was found within timeout.
|
|
243
|
+
});
|
|
244
|
+
const buttonDetails = yield page.evaluate(() => {
|
|
245
|
+
const selectors = [
|
|
246
|
+
'[data-testid="fruitjuice-send-button"]',
|
|
247
|
+
"#composer-submit-button",
|
|
248
|
+
'[data-testid="send-button"]'
|
|
249
|
+
];
|
|
250
|
+
const details = selectors.map((selector) => {
|
|
251
|
+
const el = document.querySelector(selector);
|
|
252
|
+
const exists = Boolean(el);
|
|
253
|
+
const disabled = exists
|
|
254
|
+
? Boolean(el.disabled || el.getAttribute("aria-disabled") === "true")
|
|
255
|
+
: null;
|
|
256
|
+
const visible = exists ? el.offsetParent !== null : null;
|
|
257
|
+
return { selector, exists, disabled, visible };
|
|
258
|
+
});
|
|
259
|
+
return details;
|
|
189
260
|
});
|
|
190
|
-
|
|
191
|
-
|
|
261
|
+
console.log(`Submit button details: ${JSON.stringify(buttonDetails)}`);
|
|
262
|
+
const clickable = buttonDetails.find((item) => item.exists && item.visible && item.disabled === false);
|
|
263
|
+
const selectedSelector = clickable ? clickable.selector : null;
|
|
264
|
+
if (selectedSelector) {
|
|
265
|
+
yield page.click(selectedSelector);
|
|
266
|
+
console.log(`Clicked submit button selector: ${selectedSelector}`);
|
|
267
|
+
if (yield waitForSubmit(5000)) {
|
|
268
|
+
console.log("Submission detected after selector click.");
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
// Fallback: force a DOM click in case pointer-interception blocked page.click.
|
|
272
|
+
const forcedClickWorked = yield page.evaluate((selector) => {
|
|
273
|
+
const el = document.querySelector(selector);
|
|
274
|
+
if (!el) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
el.click();
|
|
278
|
+
return true;
|
|
279
|
+
}, selectedSelector);
|
|
280
|
+
if (forcedClickWorked) {
|
|
281
|
+
console.log(`Forced DOM click on selector: ${selectedSelector}`);
|
|
282
|
+
if (yield waitForSubmit(5000)) {
|
|
283
|
+
console.log("Submission detected after forced DOM click.");
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
192
287
|
}
|
|
193
|
-
|
|
194
|
-
|
|
288
|
+
console.log("Submit button path did not submit. Trying Enter key fallback on prompt.");
|
|
289
|
+
yield page.focus("#prompt-textarea");
|
|
290
|
+
yield page.keyboard.press("Enter");
|
|
291
|
+
if (yield waitForSubmit(5000)) {
|
|
292
|
+
console.log("Submission detected after Enter key fallback.");
|
|
293
|
+
return true;
|
|
195
294
|
}
|
|
196
|
-
|
|
197
|
-
|
|
295
|
+
// Final fallback: submit the nearest composer form.
|
|
296
|
+
const didRequestSubmit = yield page.evaluate(() => {
|
|
297
|
+
const prompt = document.querySelector("#prompt-textarea");
|
|
298
|
+
if (!prompt) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
const form = prompt.closest("form");
|
|
302
|
+
if (!form) {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
if (typeof form.requestSubmit === "function") {
|
|
306
|
+
form.requestSubmit();
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
form.submit();
|
|
310
|
+
}
|
|
311
|
+
return true;
|
|
312
|
+
});
|
|
313
|
+
if (didRequestSubmit) {
|
|
314
|
+
console.log("Triggered form submit fallback.");
|
|
315
|
+
if (yield waitForSubmit(5000)) {
|
|
316
|
+
console.log("Submission detected after form submit fallback.");
|
|
317
|
+
return true;
|
|
318
|
+
}
|
|
198
319
|
}
|
|
320
|
+
console.log("Failed to submit prompt after all strategies.");
|
|
321
|
+
return false;
|
|
199
322
|
}
|
|
200
323
|
catch (e) {
|
|
201
324
|
console.log(`Failed to click the send button: ${e}`);
|
|
325
|
+
return false;
|
|
202
326
|
}
|
|
203
327
|
});
|
|
204
328
|
}
|
|
@@ -315,12 +439,15 @@ function isLoggedIn(page) {
|
|
|
315
439
|
*/
|
|
316
440
|
function createBrowser() {
|
|
317
441
|
return __awaiter(this, arguments, void 0, function* (browserOptions = {}) {
|
|
442
|
+
const windowsChromeExecutable = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";
|
|
443
|
+
const hasWindowsChrome = process.platform === "win32" && fs_extra_1.default.existsSync(windowsChromeExecutable);
|
|
318
444
|
/**
|
|
319
445
|
* @type {Parameters<import("puppeteer-extra").VanillaPuppeteer["launch"]>[0]}
|
|
320
446
|
*/
|
|
321
|
-
const defaultOptions = Object.assign({ headless: false, userDataDir: upath_1.default.join(process.cwd(), "tmp/puppeteer-profile"),
|
|
447
|
+
const defaultOptions = Object.assign({ headless: false, defaultViewport: null, userDataDir: upath_1.default.join(process.cwd(), "tmp/puppeteer-profile"),
|
|
322
448
|
// Windows-specific options to handle browser launch issues
|
|
323
449
|
args: [
|
|
450
|
+
"--start-maximized",
|
|
324
451
|
"--no-sandbox",
|
|
325
452
|
"--disable-setuid-sandbox",
|
|
326
453
|
"--disable-dev-shm-usage",
|
|
@@ -331,9 +458,9 @@ function createBrowser() {
|
|
|
331
458
|
"--disable-background-timer-throttling",
|
|
332
459
|
"--disable-backgrounding-occluded-windows",
|
|
333
460
|
"--disable-renderer-backgrounding"
|
|
334
|
-
], ignoreDefaultArgs: ["--disable-extensions"] }, (
|
|
335
|
-
//
|
|
336
|
-
executablePath:
|
|
461
|
+
], ignoreDefaultArgs: ["--disable-extensions"] }, (hasWindowsChrome && {
|
|
462
|
+
// Prefer local Chrome installation when present on Windows.
|
|
463
|
+
executablePath: windowsChromeExecutable
|
|
337
464
|
}));
|
|
338
465
|
try {
|
|
339
466
|
return yield puppeteer_extra_1.default.use((0, puppeteer_extra_plugin_stealth_1.default)()).launch(Object.assign(Object.assign({}, defaultOptions), browserOptions));
|
|
@@ -342,7 +469,9 @@ function createBrowser() {
|
|
|
342
469
|
console.error("Failed to launch browser with default options. Trying fallback options...");
|
|
343
470
|
// Fallback: Try with minimal options
|
|
344
471
|
try {
|
|
345
|
-
return yield puppeteer_extra_1.default.use((0, puppeteer_extra_plugin_stealth_1.default)()).launch(Object.assign({ headless: browserOptions.headless || false, args: ["--no-sandbox", "--disable-setuid-sandbox"], ignoreDefaultArgs: false },
|
|
472
|
+
return yield puppeteer_extra_1.default.use((0, puppeteer_extra_plugin_stealth_1.default)()).launch(Object.assign(Object.assign({ headless: browserOptions.headless || false, defaultViewport: null, args: ["--start-maximized", "--no-sandbox", "--disable-setuid-sandbox"], ignoreDefaultArgs: false }, (hasWindowsChrome && {
|
|
473
|
+
executablePath: windowsChromeExecutable
|
|
474
|
+
})), browserOptions));
|
|
346
475
|
}
|
|
347
476
|
catch (fallbackError) {
|
|
348
477
|
console.error("Browser launch failed completely. Common solutions:");
|
|
@@ -375,8 +504,14 @@ function loginToChatGpt() {
|
|
|
375
504
|
if (loginButtonExists) {
|
|
376
505
|
console.log("Login button found, clicking to log in...");
|
|
377
506
|
yield page.click('[data-testid="login-button"]');
|
|
378
|
-
// Wait for the login process to complete
|
|
379
|
-
yield page.waitForNavigation({ waitUntil: "
|
|
507
|
+
// Wait for the login process to complete without requiring full network idleness.
|
|
508
|
+
yield page.waitForNavigation({ waitUntil: "domcontentloaded", timeout: NAVIGATION_TIMEOUT_MS });
|
|
509
|
+
try {
|
|
510
|
+
yield page.waitForNetworkIdle({ idleTime: 1000, timeout: NETWORK_IDLE_TIMEOUT_MS });
|
|
511
|
+
}
|
|
512
|
+
catch (_a) {
|
|
513
|
+
// Ignore: authentication pages can keep background connections active.
|
|
514
|
+
}
|
|
380
515
|
console.log("Login process completed.");
|
|
381
516
|
}
|
|
382
517
|
else {
|
|
@@ -414,6 +549,7 @@ function runChatGpt() {
|
|
|
414
549
|
const headless = chatgptOptions.headless !== undefined ? chatgptOptions.headless : true;
|
|
415
550
|
const questionFile = chatgptOptions.questionFile;
|
|
416
551
|
let question = chatgptOptions.question;
|
|
552
|
+
let shouldUploadQuestionFile = Boolean(questionFile);
|
|
417
553
|
const responseFile = chatgptOptions.responseFile || upath_1.default.join(process.cwd(), "tmp", "response.txt");
|
|
418
554
|
// Validate input parameters
|
|
419
555
|
const noInputProvided = !question && !questionFile;
|
|
@@ -422,6 +558,21 @@ function runChatGpt() {
|
|
|
422
558
|
if (noInputProvided || questionIsEmpty || questionFileIsEmpty) {
|
|
423
559
|
throw new Error("You must provide a question or a question file.");
|
|
424
560
|
}
|
|
561
|
+
// For small files, send content as plain text to avoid file-upload login requirements.
|
|
562
|
+
if (!question && questionFile) {
|
|
563
|
+
if (!fs_extra_1.default.existsSync(questionFile)) {
|
|
564
|
+
throw new Error(`Question file does not exist: ${questionFile}`);
|
|
565
|
+
}
|
|
566
|
+
const questionFileStats = fs_extra_1.default.statSync(questionFile);
|
|
567
|
+
if (questionFileStats.size <= MAX_INLINE_QUESTION_FILE_BYTES) {
|
|
568
|
+
question = fs_extra_1.default.readFileSync(questionFile, "utf8").trim();
|
|
569
|
+
if (!question) {
|
|
570
|
+
throw new Error("Question file is empty.");
|
|
571
|
+
}
|
|
572
|
+
shouldUploadQuestionFile = false;
|
|
573
|
+
console.log(`Question file is ${questionFileStats.size} bytes (<= ${MAX_INLINE_QUESTION_FILE_BYTES}). Sending as text prompt.`);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
425
576
|
let browser;
|
|
426
577
|
try {
|
|
427
578
|
browser = yield createBrowser({ headless });
|
|
@@ -435,8 +586,18 @@ function runChatGpt() {
|
|
|
435
586
|
console.error("4. Close any running Chrome instances and try again");
|
|
436
587
|
throw error;
|
|
437
588
|
}
|
|
589
|
+
const allPages = yield browser.pages();
|
|
438
590
|
/** @type {import('puppeteer').Page} */
|
|
439
|
-
const page =
|
|
591
|
+
const page = allPages.length > 0 ? allPages[0] : yield browser.newPage();
|
|
592
|
+
yield page.bringToFront();
|
|
593
|
+
// Close other pages if more than one page is open.
|
|
594
|
+
if (allPages.length > 1) {
|
|
595
|
+
for (const p of allPages) {
|
|
596
|
+
if (p !== page) {
|
|
597
|
+
yield p.close();
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
440
601
|
try {
|
|
441
602
|
const url = "https://chat.openai.com";
|
|
442
603
|
const navigate = yield navigatePage(page, url);
|
|
@@ -459,7 +620,10 @@ function runChatGpt() {
|
|
|
459
620
|
if (question) {
|
|
460
621
|
yield writeQuestion(page, question);
|
|
461
622
|
// Submit the question
|
|
462
|
-
yield clickSubmitButton(page);
|
|
623
|
+
const didSubmit = yield clickSubmitButton(page);
|
|
624
|
+
if (!didSubmit) {
|
|
625
|
+
throw new Error("Prompt was not submitted. The composer button may be disabled or blocked.");
|
|
626
|
+
}
|
|
463
627
|
yield navigate.waitForDomIdle(1000, 30000); // Wait for DOM to stabilize
|
|
464
628
|
// Wait for the initial response
|
|
465
629
|
yield waitForInitialResponse(page);
|
|
@@ -468,7 +632,7 @@ function runChatGpt() {
|
|
|
468
632
|
// Save cookies for this host at the end
|
|
469
633
|
yield saveCookies(page, getCookiePathForUrl(url));
|
|
470
634
|
}
|
|
471
|
-
else if (questionFile) {
|
|
635
|
+
else if (shouldUploadQuestionFile && questionFile) {
|
|
472
636
|
// Wait for page to fully load before checking login status
|
|
473
637
|
yield navigate.waitForDomIdle(2000, 10000);
|
|
474
638
|
// Check if logged in
|
|
@@ -512,7 +676,10 @@ function runChatGpt() {
|
|
|
512
676
|
yield navigate.waitForDomIdle(2000, 15000);
|
|
513
677
|
console.log("File uploaded successfully");
|
|
514
678
|
// Optionally submit after file upload
|
|
515
|
-
yield clickSubmitButton(page);
|
|
679
|
+
const didSubmit = yield clickSubmitButton(page);
|
|
680
|
+
if (!didSubmit) {
|
|
681
|
+
throw new Error("Prompt was not submitted after file upload.");
|
|
682
|
+
}
|
|
516
683
|
yield navigate.waitForDomIdle(1000, 30000);
|
|
517
684
|
// Wait for and handle response
|
|
518
685
|
yield waitForInitialResponse(page);
|
package/lib/utils/chatgpt.mjs
CHANGED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/utils/findEnvFiles.js
|
|
30
|
+
var findEnvFiles_exports = {};
|
|
31
|
+
__export(findEnvFiles_exports, {
|
|
32
|
+
findEnvFiles: () => findEnvFiles
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(findEnvFiles_exports);
|
|
35
|
+
var import_node_fs = __toESM(require("fs"), 1);
|
|
36
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
37
|
+
var glob = __toESM(require("glob"), 1);
|
|
38
|
+
var DEFAULT_IGNORES = [
|
|
39
|
+
"**/node_modules/**",
|
|
40
|
+
"**/.git/**",
|
|
41
|
+
"**/.yarn/**",
|
|
42
|
+
"**/.pnpm/**",
|
|
43
|
+
"**/dist/**",
|
|
44
|
+
"**/build/**",
|
|
45
|
+
"**/coverage/**",
|
|
46
|
+
"**/vendor/**",
|
|
47
|
+
"**/tmp/**",
|
|
48
|
+
"**/.cache/**",
|
|
49
|
+
"**/assets/**",
|
|
50
|
+
"**/logs/**",
|
|
51
|
+
"**/output/**",
|
|
52
|
+
"**/public/**",
|
|
53
|
+
"**/static/**",
|
|
54
|
+
"**/temp/**",
|
|
55
|
+
"**/backup/**",
|
|
56
|
+
"**/backups/**",
|
|
57
|
+
"**/examples/**",
|
|
58
|
+
"**/docs/**",
|
|
59
|
+
"**/tests/**",
|
|
60
|
+
"**/__tests__/**",
|
|
61
|
+
"**/spec/**",
|
|
62
|
+
"**/__specs__/**",
|
|
63
|
+
"**/scripts/**",
|
|
64
|
+
"**/bin/**",
|
|
65
|
+
"**/hooks/**",
|
|
66
|
+
"**/config/**",
|
|
67
|
+
"**/configs/**",
|
|
68
|
+
"**/settings/**",
|
|
69
|
+
"**/.vscode/**",
|
|
70
|
+
"**/.idea/**"
|
|
71
|
+
];
|
|
72
|
+
function findEnvFiles(startDir = process.cwd(), filter) {
|
|
73
|
+
const found = /* @__PURE__ */ new Set();
|
|
74
|
+
function addFile(file) {
|
|
75
|
+
const normalized = import_node_path.default.normalize(file);
|
|
76
|
+
if (typeof filter === "function" && !filter(normalized)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
found.add(normalized);
|
|
80
|
+
}
|
|
81
|
+
let current = import_node_path.default.resolve(startDir);
|
|
82
|
+
while (true) {
|
|
83
|
+
const envPath = import_node_path.default.join(current, ".env");
|
|
84
|
+
if (import_node_fs.default.existsSync(envPath)) {
|
|
85
|
+
addFile(envPath);
|
|
86
|
+
}
|
|
87
|
+
const parent = import_node_path.default.dirname(current);
|
|
88
|
+
if (parent === current) {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
current = parent;
|
|
92
|
+
}
|
|
93
|
+
const files = glob.globSync("**/.env*", {
|
|
94
|
+
cwd: startDir,
|
|
95
|
+
absolute: true,
|
|
96
|
+
nodir: true,
|
|
97
|
+
ignore: DEFAULT_IGNORES
|
|
98
|
+
});
|
|
99
|
+
for (const file of files) {
|
|
100
|
+
addFile(file);
|
|
101
|
+
}
|
|
102
|
+
return [...found];
|
|
103
|
+
}
|
|
104
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
105
|
+
0 && (module.exports = {
|
|
106
|
+
findEnvFiles
|
|
107
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.findEnvFiles = findEnvFiles;
|
|
40
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
41
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
42
|
+
const glob = __importStar(require("glob"));
|
|
43
|
+
const DEFAULT_IGNORES = [
|
|
44
|
+
"**/node_modules/**",
|
|
45
|
+
"**/.git/**",
|
|
46
|
+
"**/.yarn/**",
|
|
47
|
+
"**/.pnpm/**",
|
|
48
|
+
"**/dist/**",
|
|
49
|
+
"**/build/**",
|
|
50
|
+
"**/coverage/**",
|
|
51
|
+
"**/vendor/**",
|
|
52
|
+
"**/tmp/**",
|
|
53
|
+
"**/.cache/**",
|
|
54
|
+
"**/assets/**",
|
|
55
|
+
"**/logs/**",
|
|
56
|
+
"**/output/**",
|
|
57
|
+
"**/public/**",
|
|
58
|
+
"**/static/**",
|
|
59
|
+
"**/temp/**",
|
|
60
|
+
"**/backup/**",
|
|
61
|
+
"**/backups/**",
|
|
62
|
+
"**/examples/**",
|
|
63
|
+
"**/docs/**",
|
|
64
|
+
"**/tests/**",
|
|
65
|
+
"**/__tests__/**",
|
|
66
|
+
"**/spec/**",
|
|
67
|
+
"**/__specs__/**",
|
|
68
|
+
"**/scripts/**",
|
|
69
|
+
"**/bin/**",
|
|
70
|
+
"**/hooks/**",
|
|
71
|
+
"**/config/**",
|
|
72
|
+
"**/configs/**",
|
|
73
|
+
"**/settings/**",
|
|
74
|
+
"**/.vscode/**",
|
|
75
|
+
"**/.idea/**"
|
|
76
|
+
];
|
|
77
|
+
/**
|
|
78
|
+
* Find .env files.
|
|
79
|
+
*
|
|
80
|
+
* @param {string} startDir
|
|
81
|
+
* @param {(file:string)=>boolean} [filter]
|
|
82
|
+
* @returns {string[]}
|
|
83
|
+
*/
|
|
84
|
+
function findEnvFiles(startDir = process.cwd(), filter) {
|
|
85
|
+
const found = new Set();
|
|
86
|
+
function addFile(file) {
|
|
87
|
+
const normalized = node_path_1.default.normalize(file);
|
|
88
|
+
if (typeof filter === "function" && !filter(normalized)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
found.add(normalized);
|
|
92
|
+
}
|
|
93
|
+
/* --------------------------------
|
|
94
|
+
* Parent directories
|
|
95
|
+
* -------------------------------- */
|
|
96
|
+
let current = node_path_1.default.resolve(startDir);
|
|
97
|
+
while (true) {
|
|
98
|
+
const envPath = node_path_1.default.join(current, ".env");
|
|
99
|
+
if (node_fs_1.default.existsSync(envPath)) {
|
|
100
|
+
addFile(envPath);
|
|
101
|
+
}
|
|
102
|
+
const parent = node_path_1.default.dirname(current);
|
|
103
|
+
if (parent === current) {
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
current = parent;
|
|
107
|
+
}
|
|
108
|
+
/* --------------------------------
|
|
109
|
+
* Subdirectories via glob
|
|
110
|
+
* -------------------------------- */
|
|
111
|
+
const files = glob.globSync("**/.env*", {
|
|
112
|
+
cwd: startDir,
|
|
113
|
+
absolute: true,
|
|
114
|
+
nodir: true,
|
|
115
|
+
ignore: DEFAULT_IGNORES
|
|
116
|
+
});
|
|
117
|
+
for (const file of files) {
|
|
118
|
+
addFile(file);
|
|
119
|
+
}
|
|
120
|
+
return [...found];
|
|
121
|
+
}
|