binary-collections 2.0.10 → 2.0.12

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.
Files changed (290) hide show
  1. package/.opencode/package.json +5 -0
  2. package/.puppeterrc.cjs +25 -0
  3. package/binaries/binary-executor.cjs +138 -3
  4. package/binaries/clean-nodemodule.cjs +138 -3
  5. package/binaries/clean-nodemodules.cjs +138 -3
  6. package/binaries/dev.cjs +138 -3
  7. package/binaries/empty.cjs +138 -3
  8. package/binaries/git-reduce-size.cjs +138 -3
  9. package/binaries/javakill.cjs +138 -3
  10. package/binaries/kill-night-crows.bat +7 -0
  11. package/binaries/kill-night-crows.ps1 +172 -0
  12. package/binaries/kill-process.cjs +138 -3
  13. package/binaries/nodekill.cjs +138 -3
  14. package/binaries/prod.cjs +138 -3
  15. package/binaries/py +111 -0
  16. package/binaries/py.cjs +178 -0
  17. package/binaries/py.cmd +49 -0
  18. package/binaries/rmfind.cjs +138 -3
  19. package/binaries/rmx +15 -1
  20. package/binaries/rmx.cjs +138 -3
  21. package/binaries/rmx.cmd +12 -0
  22. package/binaries/submodule-token.cjs +138 -3
  23. package/binaries/test-cjs +18 -0
  24. package/binaries/test-cjs.cjs +178 -0
  25. package/binaries/test-cjs.cmd +26 -0
  26. package/binaries/test-esm +16 -0
  27. package/binaries/test-esm.cjs +178 -0
  28. package/binaries/test-esm.cmd +23 -0
  29. package/binaries/yarn-clean +32 -0
  30. package/binaries/yarn-clean.cjs +178 -0
  31. package/binaries/yarn-clean.cmd +30 -0
  32. package/binaries/yarn-clean.py +166 -0
  33. package/binaries/yc +110 -0
  34. package/binaries/yc.cjs +178 -0
  35. package/lib/binary-collections/config.cjs +126 -0
  36. package/lib/binary-collections/config.mjs +7 -0
  37. package/lib/binary-collections/executeScript.cjs +19 -0
  38. package/lib/binary-collections/executeScript.d.cts +12 -0
  39. package/lib/binary-collections/executeScript.mjs +6 -0
  40. package/lib/binary-collections/findScript.cjs +284 -0
  41. package/lib/binary-collections/findScript.d.cts +12 -0
  42. package/lib/binary-collections/findScript.mjs +7 -0
  43. package/lib/binary-collections/listScript.cjs +266 -0
  44. package/lib/binary-collections/listScript.d.cts +19 -0
  45. package/lib/binary-collections/listScript.mjs +7 -0
  46. package/lib/binary-collections.cjs +342 -194
  47. package/lib/binary-collections.mjs +22 -268
  48. package/lib/changelog.cjs +61 -13
  49. package/lib/changelog.mjs +1 -1
  50. package/lib/{chunk-E6FDDAOO.mjs → chunk-2LSRSEXF.mjs} +2 -2
  51. package/lib/chunk-34IQDTLZ.mjs +27 -0
  52. package/lib/chunk-3HFFECCI.mjs +27 -0
  53. package/lib/{chunk-V3N3JEUF.mjs → chunk-5RTXZVCW.mjs} +60 -13
  54. package/lib/chunk-66KDU4TX.mjs +268 -0
  55. package/lib/chunk-6PU7BAHB.mjs +61 -0
  56. package/lib/{chunk-6HHJRKFB.mjs → chunk-BZWVHODJ.mjs} +4 -1
  57. package/lib/chunk-C6D2TTYU.mjs +32 -0
  58. package/lib/chunk-FB2WKVJD.mjs +158 -0
  59. package/lib/{chunk-66PAU5PS.mjs → chunk-G5UUEWUO.mjs} +9 -5
  60. package/lib/{chunk-HO6GHCOB.mjs → chunk-GAGABICI.mjs} +198 -63
  61. package/lib/chunk-H44UWUFY.mjs +105 -0
  62. package/lib/chunk-NCZPTKDV.mjs +79 -0
  63. package/lib/chunk-NGFK3EYW.mjs +28 -0
  64. package/lib/chunk-NVEG3LEZ.mjs +143 -0
  65. package/lib/chunk-OGXVGBRI.mjs +29 -0
  66. package/lib/chunk-OXV52GD5.mjs +62 -0
  67. package/lib/{chunk-PDSXF5HY.mjs → chunk-PDN26I7O.mjs} +1 -0
  68. package/lib/chunk-PXBMHE7O.mjs +35 -0
  69. package/lib/chunk-R5FJOR63.mjs +47 -0
  70. package/lib/chunk-SPTECFE5.mjs +180 -0
  71. package/lib/chunk-UXCFNAR6.mjs +55 -0
  72. package/lib/chunk-V2IBPCEV.mjs +39 -0
  73. package/lib/chunk-XPJGCDOD.mjs +14 -0
  74. package/lib/{chunk-AI4CVPJ7.mjs → chunk-ZDMWBSYF.mjs} +4 -4
  75. package/lib/chunk-ZOWVMII3.mjs +228 -0
  76. package/lib/clean-github-actions-caches-cli.cjs +465 -0
  77. package/lib/clean-github-actions-caches-cli.d.cts +1 -0
  78. package/lib/clean-github-actions-caches-cli.mjs +56 -0
  79. package/lib/clean-github-actions-caches.cjs +152 -160
  80. package/lib/clean-github-actions-caches.d.cts +15 -1
  81. package/lib/clean-github-actions-caches.mjs +4 -130
  82. package/lib/cross-env/command.cjs +63 -0
  83. package/lib/cross-env/command.d.ts +8 -0
  84. package/lib/cross-env/command.js +45 -0
  85. package/lib/cross-env/command.mjs +9 -0
  86. package/lib/cross-env/index.cjs +178 -0
  87. package/lib/cross-env/index.d.ts +8 -0
  88. package/lib/cross-env/index.js +102 -0
  89. package/lib/cross-env/index.mjs +101 -0
  90. package/lib/cross-env/variable.cjs +60 -0
  91. package/lib/cross-env/variable.d.ts +7 -0
  92. package/lib/cross-env/variable.js +59 -0
  93. package/lib/cross-env/variable.mjs +9 -0
  94. package/lib/del-gradle.cjs +61 -13
  95. package/lib/del-gradle.js +9 -8
  96. package/lib/del-gradle.mjs +1 -1
  97. package/lib/del-node-modules.cjs +143 -148
  98. package/lib/del-node-modules.js +210 -14
  99. package/lib/del-node-modules.mjs +148 -17
  100. package/lib/del-ps.cjs +61 -13
  101. package/lib/del-ps.js +9 -8
  102. package/lib/del-ps.mjs +1 -1
  103. package/lib/del-yarn-caches.cjs +61 -13
  104. package/lib/del-yarn-caches.js +2 -2
  105. package/lib/del-yarn-caches.mjs +1 -1
  106. package/lib/file/copy-cli.cjs +92 -0
  107. package/lib/file/copy-cli.d.mts +1 -0
  108. package/lib/file/copy-cli.mjs +55 -0
  109. package/lib/file/copy.cjs +56 -0
  110. package/lib/file/copy.d.mts +1 -0
  111. package/lib/file/copy.mjs +8 -0
  112. package/lib/file/move-cli.cjs +91 -0
  113. package/lib/file/move-cli.d.mts +1 -0
  114. package/lib/file/move-cli.mjs +55 -0
  115. package/lib/file/move.cjs +55 -0
  116. package/lib/file/move.d.mts +1 -0
  117. package/lib/file/move.mjs +8 -0
  118. package/lib/find-node-modules-cli.js +2 -1
  119. package/lib/free-chatgpt.cjs +259 -47
  120. package/lib/free-chatgpt.js +10 -10
  121. package/lib/free-chatgpt.mjs +2 -2
  122. package/lib/git/gitattributes.cjs +1 -0
  123. package/lib/git/gitattributes.d.cts +7 -2
  124. package/lib/git/gitattributes.mjs +1 -1
  125. package/lib/git/line-endings.cjs +2 -1
  126. package/lib/git/line-endings.mjs +2 -2
  127. package/lib/git/undo-commit-cli.cjs +110 -0
  128. package/lib/git/undo-commit-cli.d.ts +1 -0
  129. package/lib/git/undo-commit-cli.js +4 -0
  130. package/lib/git/undo-commit-cli.mjs +14 -0
  131. package/lib/git/undo-commit.cjs +81 -0
  132. package/lib/git/undo-commit.d.cts +1 -0
  133. package/lib/git/undo-commit.mjs +7 -0
  134. package/lib/git/undo-staged-cli.cjs +110 -0
  135. package/lib/git/undo-staged-cli.d.ts +1 -0
  136. package/lib/git/undo-staged-cli.js +4 -0
  137. package/lib/git/undo-staged-cli.mjs +14 -0
  138. package/lib/git/undo-staged.cjs +81 -0
  139. package/lib/git/undo-staged.d.cts +1 -0
  140. package/lib/git/undo-staged.mjs +7 -0
  141. package/lib/git/user-config.cjs +61 -14
  142. package/lib/git/user-config.mjs +2 -2
  143. package/lib/git-diff-cli.cjs +427 -75
  144. package/lib/git-diff-cli.d.ts +1 -0
  145. package/lib/git-diff-cli.js +1 -0
  146. package/lib/git-diff-cli.mjs +6 -4
  147. package/lib/git-diff.cjs +426 -75
  148. package/lib/git-diff.d.ts +2 -1
  149. package/lib/git-diff.js +91 -34
  150. package/lib/git-diff.mjs +5 -4
  151. package/lib/git-fix.cjs +64 -16
  152. package/lib/git-fix.mjs +10 -10
  153. package/lib/git-purge.cjs +61 -13
  154. package/lib/git-purge.mjs +1 -1
  155. package/lib/index.d.ts +1 -1
  156. package/lib/kill-night-crows.cjs +87 -0
  157. package/lib/kill-night-crows.d.mts +1 -0
  158. package/lib/kill-night-crows.mjs +65 -0
  159. package/lib/node-cache-cleaner/npm.cjs +65 -0
  160. package/lib/node-cache-cleaner/npm.d.ts +2 -0
  161. package/lib/node-cache-cleaner/npm.js +41 -0
  162. package/lib/node-cache-cleaner/npm.mjs +10 -0
  163. package/lib/node-cache-cleaner/npx.cjs +89 -0
  164. package/lib/node-cache-cleaner/npx.d.ts +4 -0
  165. package/lib/node-cache-cleaner/npx.js +82 -0
  166. package/lib/{ps/index.d.mjs → node-cache-cleaner/npx.mjs} +6 -5
  167. package/lib/node-cache-cleaner/yarn.cjs +73 -0
  168. package/lib/node-cache-cleaner/yarn.d.ts +2 -0
  169. package/lib/node-cache-cleaner/yarn.js +62 -0
  170. package/lib/node-cache-cleaner/yarn.mjs +10 -0
  171. package/lib/node-cache-cleaner-cli.cjs +182 -0
  172. package/lib/node-cache-cleaner-cli.d.ts +2 -0
  173. package/lib/node-cache-cleaner-cli.js +60 -0
  174. package/lib/node-cache-cleaner-cli.mjs +56 -0
  175. package/lib/node-executor.cjs +91 -0
  176. package/lib/node-executor.d.cts +2 -0
  177. package/lib/node-executor.mjs +103 -0
  178. package/lib/npm-run-series.cjs +79 -39
  179. package/lib/npm-run-series.mjs +20 -6
  180. package/lib/package-resolutions-updater-cli.cjs +645 -0
  181. package/lib/package-resolutions-updater-cli.d.mts +1 -0
  182. package/lib/package-resolutions-updater-cli.mjs +102 -0
  183. package/lib/package-resolutions-updater.cjs +259 -133
  184. package/lib/package-resolutions-updater.d.mts +51 -1
  185. package/lib/package-resolutions-updater.mjs +18 -294
  186. package/lib/php-cs-fixer-staged.cjs +105 -0
  187. package/lib/php-cs-fixer-staged.d.cts +2 -0
  188. package/lib/php-cs-fixer-staged.mjs +117 -0
  189. package/lib/print-directory-tree.cjs +62 -14
  190. package/lib/print-directory-tree.mjs +2 -2
  191. package/lib/ps/connected-domain.d.ts +1 -1
  192. package/lib/ps/connected-domain.js +10 -10
  193. package/lib/ps/index.cjs +1 -1
  194. package/lib/ps/index.mjs +177 -171
  195. package/lib/ps/isWin.js +1 -1
  196. package/lib/ps/table-parser.js +6 -6
  197. package/lib/remove-module.cjs +61 -13
  198. package/lib/remove-module.mjs +1 -1
  199. package/lib/rm-node-module-cli.cjs +222 -0
  200. package/lib/rm-node-module-cli.d.cts +1 -0
  201. package/lib/rm-node-module-cli.mjs +89 -0
  202. package/lib/rm-node-modules.cjs +127 -0
  203. package/lib/rm-node-modules.d.cts +35 -0
  204. package/lib/{binary-collections-config.mjs → rm-node-modules.mjs} +3 -3
  205. package/lib/rmpath.cjs +63 -15
  206. package/lib/rmpath.mjs +2 -2
  207. package/lib/submodule-install.cjs +107 -47
  208. package/lib/submodule-install.mjs +48 -35
  209. package/lib/submodule-remove-cli.cjs +6 -3
  210. package/lib/submodule-remove-cli.js +3 -3
  211. package/lib/submodule-remove-cli.mjs +2 -3
  212. package/lib/submodule-remove.cjs +4 -1
  213. package/lib/submodule-remove.mjs +1 -1
  214. package/lib/utils/chatgpt.cjs +198 -34
  215. package/lib/utils/chatgpt.js +260 -93
  216. package/lib/utils/chatgpt.mjs +1 -1
  217. package/lib/utils/findEnvFiles.cjs +89 -0
  218. package/lib/utils/findEnvFiles.d.cts +19 -0
  219. package/lib/utils/findEnvFiles.mjs +6 -0
  220. package/lib/utils/findWorkspaceRoot.cjs +70 -0
  221. package/lib/utils/findWorkspaceRoot.d.ts +9 -0
  222. package/lib/utils/findWorkspaceRoot.js +57 -0
  223. package/lib/utils/findWorkspaceRoot.mjs +40 -0
  224. package/lib/utils/index.cjs +60 -13
  225. package/lib/utils/index.mjs +1 -1
  226. package/lib/utils/isGithubTokenValid.cjs +64 -0
  227. package/lib/utils/isGithubTokenValid.d.ts +7 -0
  228. package/lib/utils/isGithubTokenValid.js +48 -0
  229. package/lib/utils/isGithubTokenValid.mjs +36 -0
  230. package/lib/{ps/index.d.cjs → utils/isWindows.cjs} +17 -3
  231. package/lib/utils/isWindows.d.ts +5 -0
  232. package/lib/utils/isWindows.js +10 -0
  233. package/lib/utils/isWindows.mjs +8 -0
  234. package/lib/utils/runBash.cjs +53 -0
  235. package/lib/utils/runBash.d.cts +12 -0
  236. package/lib/utils/runBash.mjs +66 -0
  237. package/lib/yarn-per-branch-lock-installer.cjs +97 -0
  238. package/lib/yarn-per-branch-lock-installer.d.cts +2 -0
  239. package/lib/yarn-per-branch-lock-installer.mjs +109 -0
  240. package/lib/yarn-reinstall.cjs +61 -13
  241. package/lib/yarn-reinstall.mjs +1 -1
  242. package/package.json +133 -110
  243. package/readme.html +784 -0
  244. package/readme.md +116 -229
  245. package/releases/readme.md +1 -1
  246. package/requirements.txt +1 -0
  247. package/test/README.md +2 -2
  248. package/test-project/package.json +8 -2
  249. package/test-project/workspaces/workspace-a/package.json +135 -0
  250. package/test-project/workspaces/workspace-a/readme.md +20 -0
  251. package/test-project/workspaces/workspace-a/release/readme.md +42 -0
  252. package/test-project/workspaces/workspace-a/test/demo/package.json +25 -0
  253. package/test-project/workspaces/workspace-a/test/readme.md +12 -0
  254. package/test-project/workspaces/workspace-b/package.json +139 -0
  255. package/test-project/workspaces/workspace-b/readme.md +94 -0
  256. package/test-project/workspaces/workspace-b/requirements.txt +1 -0
  257. package/test-project/workspaces/workspace-b/test/sample-project/package.json +7 -0
  258. package/test-project/workspaces/workspace-b/themes/hexo-theme-flowbite/package.json +96 -0
  259. package/test-project/workspaces/workspace-b/themes/hexo-theme-flowbite/readme.md +156 -0
  260. package/tmp/rm-node-modules-test-project/package.json +17 -0
  261. package/tmp/rm-node-modules-test-project/packages/workspace-a/package.json +16 -0
  262. package/tmp/rm-node-modules-test-project/packages/workspace-b/package.json +16 -0
  263. package/tmp/test-repo/README.md +2 -35
  264. package/tmp/test-repo/package.json +13 -3
  265. package/docs-src/clean-github-actions-caches.md +0 -26
  266. package/docs-src/free-chatgpt.md +0 -26
  267. package/lib/binary-collections-config.cjs +0 -15
  268. package/lib/chunk-4EWQC6GZ.mjs +0 -382
  269. package/lib/chunk-4ZI7BQKQ.mjs +0 -381
  270. package/lib/chunk-5J2BEPY5.mjs +0 -83
  271. package/lib/chunk-AGZYRDC2.mjs +0 -323
  272. package/lib/chunk-BDCHCWHD.mjs +0 -136
  273. package/lib/chunk-BEZKJ25G.mjs +0 -140
  274. package/lib/chunk-DI5MDPSN.mjs +0 -386
  275. package/lib/chunk-GJTGHXRA.mjs +0 -356
  276. package/lib/chunk-HMRMTYZM.mjs +0 -40
  277. package/lib/chunk-HN52G2YL.mjs +0 -305
  278. package/lib/chunk-LEM5OMRP.mjs +0 -384
  279. package/lib/chunk-O6SWBEOQ.mjs +0 -81
  280. package/lib/chunk-RCP7DHVY.mjs +0 -190
  281. package/lib/chunk-SBNDSKG5.mjs +0 -136
  282. package/lib/chunk-U6SO4QEV.mjs +0 -320
  283. package/lib/chunk-XD6BJK6Q.mjs +0 -351
  284. package/lib/chunk-YXSFGA2D.mjs +0 -383
  285. package/lib/git/gitattributes.d.ts +0 -33
  286. package/lib/git/gitattributes.js +0 -223
  287. package/lib/ps/index.d.ts +0 -2
  288. package/lib/ps/index.js +0 -253
  289. package/tmp/typedoc/readme.md +0 -320
  290. /package/lib/{binary-collections-config.d.cts → binary-collections/config.d.cts} +0 -0
@@ -38,7 +38,17 @@ var import_puppeteer_extra_plugin_stealth = __toESM(require("puppeteer-extra-plu
38
38
  var import_upath = __toESM(require("upath"), 1);
39
39
  var COOKIE_DIR = import_upath.default.join(process.cwd(), "tmp", "cookies");
40
40
  var DEFAULT_COOKIE_PATH = import_upath.default.join(COOKIE_DIR, "cookies.json");
41
+ var NAVIGATION_TIMEOUT_MS = 9e4;
42
+ var NETWORK_IDLE_TIMEOUT_MS = 15e3;
43
+ var MAX_INLINE_QUESTION_FILE_BYTES = 2 * 1024;
41
44
  import_fs_extra.default.ensureDirSync(COOKIE_DIR);
45
+ async function gotoWithFallback(page, url) {
46
+ await page.goto(url, { waitUntil: "domcontentloaded", timeout: NAVIGATION_TIMEOUT_MS });
47
+ try {
48
+ await page.waitForNetworkIdle({ idleTime: 1e3, timeout: NETWORK_IDLE_TIMEOUT_MS });
49
+ } catch {
50
+ }
51
+ }
42
52
  async function saveCookies(page, path2 = DEFAULT_COOKIE_PATH) {
43
53
  const cookies = await page.cookies();
44
54
  import_fs_extra.default.writeFileSync(path2, JSON.stringify(cookies, null, 2));
@@ -57,7 +67,7 @@ async function navigatePage(page, url) {
57
67
  if (cookies) {
58
68
  await page.setCookie(...cookies);
59
69
  }
60
- await page.goto(url, { waitUntil: "networkidle0" });
70
+ await gotoWithFallback(page, url);
61
71
  await page.evaluate(() => {
62
72
  window.__domStillUpdating = true;
63
73
  if (window.__domObserver) {
@@ -97,46 +107,157 @@ function loadCookies(cookieFilePath = DEFAULT_COOKIE_PATH) {
97
107
  return JSON.parse(import_fs_extra.default.readFileSync(cookieFilePath));
98
108
  }
99
109
  async function writeQuestion(page, question) {
100
- const questions = question.split("\n");
101
110
  const promptTextarea = await page.waitForSelector("#prompt-textarea", { timeout: 3e4 });
102
111
  if (!promptTextarea) {
103
112
  console.log(
104
113
  "Cannot find the prompt input on the webpage. Please check whether you have access to chat.openai.com without logging in via your browser."
105
114
  );
106
- }
107
- await page.evaluate(() => {
108
- document.querySelector("#prompt-textarea").innerHTML = `<p></p>`;
109
- });
110
- if (questions.length === 1) {
111
- await page.type("#prompt-textarea", questions[0], { delay: 100 });
112
115
  return;
113
116
  }
114
- for (const q of questions) {
115
- await page.type("#prompt-textarea", q, { delay: 100 });
116
- if (q !== questions[questions.length - 1]) {
117
- await page.keyboard.down("Shift");
118
- await page.keyboard.press("Enter");
119
- await page.keyboard.up("Shift");
117
+ await page.evaluate((text) => {
118
+ const promptEl = document.querySelector("#prompt-textarea");
119
+ if (!promptEl) {
120
+ return;
121
+ }
122
+ promptEl.focus();
123
+ promptEl.innerHTML = "";
124
+ const lines = String(text).split("\n");
125
+ for (const line of lines) {
126
+ const p = document.createElement("p");
127
+ p.textContent = line;
128
+ promptEl.appendChild(p);
120
129
  }
130
+ promptEl.dispatchEvent(new InputEvent("beforeinput", { bubbles: true, inputType: "insertFromPaste", data: text }));
131
+ promptEl.dispatchEvent(new InputEvent("input", { bubbles: true, inputType: "insertFromPaste", data: text }));
132
+ promptEl.dispatchEvent(new Event("change", { bubbles: true }));
133
+ }, question);
134
+ const hasPromptText = await page.evaluate(() => {
135
+ const promptEl = document.querySelector("#prompt-textarea");
136
+ return Boolean(promptEl && promptEl.textContent && promptEl.textContent.trim().length > 0);
137
+ });
138
+ if (!hasPromptText) {
139
+ console.log("Prompt state not updated by DOM injection. Falling back to keyboard insertText.");
140
+ await promptTextarea.click({ clickCount: 1 });
141
+ await page.keyboard.down("Control");
142
+ await page.keyboard.press("KeyA");
143
+ await page.keyboard.up("Control");
144
+ await page.keyboard.insertText(question);
121
145
  }
122
146
  }
123
147
  async function clickSubmitButton(page) {
148
+ console.log("Attempting to click the submit button...");
124
149
  try {
125
- const fruitjuiceSendButton = await page.evaluate(() => {
126
- return document.querySelector('[data-testid="fruitjuice-send-button"]') !== null;
150
+ const userMessageCountBefore = await page.$$eval(
151
+ '[data-message-author-role="user"]',
152
+ (elements) => elements.length
153
+ );
154
+ const waitForSubmit = async (timeout = 5e3) => {
155
+ try {
156
+ await page.waitForFunction(
157
+ (previousCount) => {
158
+ const currentCount = document.querySelectorAll('[data-message-author-role="user"]').length;
159
+ return currentCount > previousCount;
160
+ },
161
+ { timeout },
162
+ userMessageCountBefore
163
+ );
164
+ return true;
165
+ } catch {
166
+ return false;
167
+ }
168
+ };
169
+ await page.waitForFunction(
170
+ () => {
171
+ const candidates = [
172
+ document.querySelector('[data-testid="fruitjuice-send-button"]'),
173
+ document.querySelector("#composer-submit-button"),
174
+ document.querySelector('[data-testid="send-button"]')
175
+ ].filter(Boolean);
176
+ return candidates.some((button) => {
177
+ const isDisabled = button.disabled || button.getAttribute("aria-disabled") === "true";
178
+ const isVisible = button.offsetParent !== null;
179
+ return !isDisabled && isVisible;
180
+ });
181
+ },
182
+ { timeout: 5e3 }
183
+ ).catch(() => {
184
+ });
185
+ const buttonDetails = await page.evaluate(() => {
186
+ const selectors = [
187
+ '[data-testid="fruitjuice-send-button"]',
188
+ "#composer-submit-button",
189
+ '[data-testid="send-button"]'
190
+ ];
191
+ const details = selectors.map((selector) => {
192
+ const el = document.querySelector(selector);
193
+ const exists = Boolean(el);
194
+ const disabled = exists ? Boolean(el.disabled || el.getAttribute("aria-disabled") === "true") : null;
195
+ const visible = exists ? el.offsetParent !== null : null;
196
+ return { selector, exists, disabled, visible };
197
+ });
198
+ return details;
127
199
  });
128
- const sendButton = await page.evaluate(() => {
129
- return document.querySelector('[data-testid="send-button"]') !== null;
200
+ console.log(`Submit button details: ${JSON.stringify(buttonDetails)}`);
201
+ const clickable = buttonDetails.find((item) => item.exists && item.visible && item.disabled === false);
202
+ const selectedSelector = clickable ? clickable.selector : null;
203
+ if (selectedSelector) {
204
+ await page.click(selectedSelector);
205
+ console.log(`Clicked submit button selector: ${selectedSelector}`);
206
+ if (await waitForSubmit(5e3)) {
207
+ console.log("Submission detected after selector click.");
208
+ return true;
209
+ }
210
+ const forcedClickWorked = await page.evaluate((selector) => {
211
+ const el = document.querySelector(selector);
212
+ if (!el) {
213
+ return false;
214
+ }
215
+ el.click();
216
+ return true;
217
+ }, selectedSelector);
218
+ if (forcedClickWorked) {
219
+ console.log(`Forced DOM click on selector: ${selectedSelector}`);
220
+ if (await waitForSubmit(5e3)) {
221
+ console.log("Submission detected after forced DOM click.");
222
+ return true;
223
+ }
224
+ }
225
+ }
226
+ console.log("Submit button path did not submit. Trying Enter key fallback on prompt.");
227
+ await page.focus("#prompt-textarea");
228
+ await page.keyboard.press("Enter");
229
+ if (await waitForSubmit(5e3)) {
230
+ console.log("Submission detected after Enter key fallback.");
231
+ return true;
232
+ }
233
+ const didRequestSubmit = await page.evaluate(() => {
234
+ const prompt = document.querySelector("#prompt-textarea");
235
+ if (!prompt) {
236
+ return false;
237
+ }
238
+ const form = prompt.closest("form");
239
+ if (!form) {
240
+ return false;
241
+ }
242
+ if (typeof form.requestSubmit === "function") {
243
+ form.requestSubmit();
244
+ } else {
245
+ form.submit();
246
+ }
247
+ return true;
130
248
  });
131
- if (fruitjuiceSendButton) {
132
- await page.click('[data-testid="fruitjuice-send-button"]');
133
- } else if (sendButton) {
134
- await page.click('[data-testid="send-button"]');
135
- } else {
136
- console.log("Neither send button is present");
249
+ if (didRequestSubmit) {
250
+ console.log("Triggered form submit fallback.");
251
+ if (await waitForSubmit(5e3)) {
252
+ console.log("Submission detected after form submit fallback.");
253
+ return true;
254
+ }
137
255
  }
256
+ console.log("Failed to submit prompt after all strategies.");
257
+ return false;
138
258
  } catch (e) {
139
259
  console.log(`Failed to click the send button: ${e}`);
260
+ return false;
140
261
  }
141
262
  }
142
263
  var lastMessageId = null;
@@ -209,11 +330,15 @@ async function isLoggedIn(page) {
209
330
  return result === true;
210
331
  }
211
332
  async function createBrowser(browserOptions = {}) {
333
+ const windowsChromeExecutable = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";
334
+ const hasWindowsChrome = process.platform === "win32" && import_fs_extra.default.existsSync(windowsChromeExecutable);
212
335
  const defaultOptions = {
213
336
  headless: false,
337
+ defaultViewport: null,
214
338
  userDataDir: import_upath.default.join(process.cwd(), "tmp/puppeteer-profile"),
215
339
  // Windows-specific options to handle browser launch issues
216
340
  args: [
341
+ "--start-maximized",
217
342
  "--no-sandbox",
218
343
  "--disable-setuid-sandbox",
219
344
  "--disable-dev-shm-usage",
@@ -226,10 +351,9 @@ async function createBrowser(browserOptions = {}) {
226
351
  "--disable-renderer-backgrounding"
227
352
  ],
228
353
  ignoreDefaultArgs: ["--disable-extensions"],
229
- ...process.platform === "win32" && {
230
- // Additional Windows-specific options
231
- executablePath: void 0
232
- // Let Puppeteer find Chrome automatically
354
+ ...hasWindowsChrome && {
355
+ // Prefer local Chrome installation when present on Windows.
356
+ executablePath: windowsChromeExecutable
233
357
  }
234
358
  };
235
359
  try {
@@ -239,8 +363,12 @@ async function createBrowser(browserOptions = {}) {
239
363
  try {
240
364
  return await import_puppeteer_extra.default.use((0, import_puppeteer_extra_plugin_stealth.default)()).launch({
241
365
  headless: browserOptions.headless || false,
242
- args: ["--no-sandbox", "--disable-setuid-sandbox"],
366
+ defaultViewport: null,
367
+ args: ["--start-maximized", "--no-sandbox", "--disable-setuid-sandbox"],
243
368
  ignoreDefaultArgs: false,
369
+ ...hasWindowsChrome && {
370
+ executablePath: windowsChromeExecutable
371
+ },
244
372
  ...browserOptions
245
373
  });
246
374
  } catch (fallbackError) {
@@ -265,7 +393,11 @@ async function loginToChatGpt() {
265
393
  if (loginButtonExists) {
266
394
  console.log("Login button found, clicking to log in...");
267
395
  await page.click('[data-testid="login-button"]');
268
- await page.waitForNavigation({ waitUntil: "networkidle0" });
396
+ await page.waitForNavigation({ waitUntil: "domcontentloaded", timeout: NAVIGATION_TIMEOUT_MS });
397
+ try {
398
+ await page.waitForNetworkIdle({ idleTime: 1e3, timeout: NETWORK_IDLE_TIMEOUT_MS });
399
+ } catch {
400
+ }
269
401
  console.log("Login process completed.");
270
402
  } else {
271
403
  console.log("No login required - user appears to be already logged in.");
@@ -275,6 +407,7 @@ async function runChatGpt(chatgptOptions = {}) {
275
407
  const headless = chatgptOptions.headless !== void 0 ? chatgptOptions.headless : true;
276
408
  const questionFile = chatgptOptions.questionFile;
277
409
  let question = chatgptOptions.question;
410
+ let shouldUploadQuestionFile = Boolean(questionFile);
278
411
  const responseFile = chatgptOptions.responseFile || import_upath.default.join(process.cwd(), "tmp", "response.txt");
279
412
  const noInputProvided = !question && !questionFile;
280
413
  const questionIsEmpty = question && question.trim().length === 0;
@@ -282,6 +415,22 @@ async function runChatGpt(chatgptOptions = {}) {
282
415
  if (noInputProvided || questionIsEmpty || questionFileIsEmpty) {
283
416
  throw new Error("You must provide a question or a question file.");
284
417
  }
418
+ if (!question && questionFile) {
419
+ if (!import_fs_extra.default.existsSync(questionFile)) {
420
+ throw new Error(`Question file does not exist: ${questionFile}`);
421
+ }
422
+ const questionFileStats = import_fs_extra.default.statSync(questionFile);
423
+ if (questionFileStats.size <= MAX_INLINE_QUESTION_FILE_BYTES) {
424
+ question = import_fs_extra.default.readFileSync(questionFile, "utf8").trim();
425
+ if (!question) {
426
+ throw new Error("Question file is empty.");
427
+ }
428
+ shouldUploadQuestionFile = false;
429
+ console.log(
430
+ `Question file is ${questionFileStats.size} bytes (<= ${MAX_INLINE_QUESTION_FILE_BYTES}). Sending as text prompt.`
431
+ );
432
+ }
433
+ }
285
434
  let browser;
286
435
  try {
287
436
  browser = await createBrowser({ headless });
@@ -294,7 +443,16 @@ async function runChatGpt(chatgptOptions = {}) {
294
443
  console.error("4. Close any running Chrome instances and try again");
295
444
  throw error;
296
445
  }
297
- const page = (await browser.pages()).length > 0 ? (await browser.pages())[0] : await browser.newPage();
446
+ const allPages = await browser.pages();
447
+ const page = allPages.length > 0 ? allPages[0] : await browser.newPage();
448
+ await page.bringToFront();
449
+ if (allPages.length > 1) {
450
+ for (const p of allPages) {
451
+ if (p !== page) {
452
+ await p.close();
453
+ }
454
+ }
455
+ }
298
456
  try {
299
457
  const url = "https://chat.openai.com";
300
458
  const navigate = await navigatePage(page, url);
@@ -313,12 +471,15 @@ async function runChatGpt(chatgptOptions = {}) {
313
471
  }
314
472
  if (question) {
315
473
  await writeQuestion(page, question);
316
- await clickSubmitButton(page);
474
+ const didSubmit = await clickSubmitButton(page);
475
+ if (!didSubmit) {
476
+ throw new Error("Prompt was not submitted. The composer button may be disabled or blocked.");
477
+ }
317
478
  await navigate.waitForDomIdle(1e3, 3e4);
318
479
  await waitForInitialResponse(page);
319
480
  await handleStreamingResponse(page, responseFile);
320
481
  await saveCookies(page, getCookiePathForUrl(url));
321
- } else if (questionFile) {
482
+ } else if (shouldUploadQuestionFile && questionFile) {
322
483
  await navigate.waitForDomIdle(2e3, 1e4);
323
484
  const isUserLoggedIn = await isLoggedIn(page);
324
485
  console.log(`Login status: ${isUserLoggedIn ? "Logged in" : "Not logged in"}`);
@@ -357,7 +518,10 @@ async function runChatGpt(chatgptOptions = {}) {
357
518
  await fileInput.uploadFile(questionFile);
358
519
  await navigate.waitForDomIdle(2e3, 15e3);
359
520
  console.log("File uploaded successfully");
360
- await clickSubmitButton(page);
521
+ const didSubmit = await clickSubmitButton(page);
522
+ if (!didSubmit) {
523
+ throw new Error("Prompt was not submitted after file upload.");
524
+ }
361
525
  await navigate.waitForDomIdle(1e3, 3e4);
362
526
  await waitForInitialResponse(page);
363
527
  await handleStreamingResponse(page, responseFile);