@kudoai/chatgpt.js 2.7.0 → 2.8.0

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.
@@ -389,7 +389,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
389
389
  try { await chatgpt.getChatData(); } catch { return; } // check if chat history exists
390
390
  chatgpt.menu.open(); setTimeout(() => { // open settings
391
391
  const settingsBtn = document.querySelector(
392
- 'a[role="menuitem"] svg path[d*="M11.6439 3C10.9352"]').parentNode.parentNode;
392
+ 'a[role="menuitem"] svg path[d*="M12.003 10.5a1.5"]')?.parentNode.parentNode;
393
393
  if (settingsBtn) settingsBtn.click();
394
394
  setTimeout(() => { // clear chats
395
395
  const settingsBtns = document.querySelectorAll('[id*=radix] button'),
@@ -842,12 +842,10 @@ const chatgpt = { // eslint-disable-line no-redeclare
842
842
  });});};
843
843
 
844
844
  // Return chat data
845
- return new Promise(resolve => { chatgpt.getAccessToken().then(token => {
846
- if (!detailsToGet.includes('msg')) getChatDetails(token, detailsToGet).then(data => {
847
- return resolve(data); // get just the chat details
848
- });
849
- else getChatMsgs(token).then(messages => { return resolve(messages); }); // otherwise get specific msg's
850
- });});
845
+ return new Promise(resolve => chatgpt.getAccessToken().then(token => {
846
+ return resolve(detailsToGet.includes('msg') ? getChatMsgs(token)
847
+ : getChatDetails(token, detailsToGet));
848
+ }));
851
849
  },
852
850
 
853
851
  getChatInput: function() { return chatgpt.getChatBox().value; },
@@ -863,11 +861,13 @@ const chatgpt = { // eslint-disable-line no-redeclare
863
861
  getLastPrompt: function() { return chatgpt.getChatData('active', 'msg', 'user', 'latest'); },
864
862
  getLastResponse: function() { return chatgpt.getChatData('active', 'msg', 'chatgpt', 'latest'); },
865
863
 
866
- getNewChatLink: function() {
867
- for (const navLink of document.querySelectorAll('nav a')) {
868
- if (/(new|clear) chat/i.test(navLink.text)) {
869
- return navLink;
870
- }}},
864
+ getNewChatButton: function() {
865
+ for (const navBtnSVG of document.querySelectorAll('nav button svg'))
866
+ if (navBtnSVG.querySelector('path[d*="M15.673 3.913a3.121"]')) // new chat icon found
867
+ return navBtnSVG.parentNode;
868
+ },
869
+
870
+ getNewChatLink: function() { return document.querySelector('nav a[href="/"]'); },
871
871
 
872
872
  getRegenerateButton: function() {
873
873
  for (const mainSVG of document.querySelectorAll('main svg')) {
@@ -881,15 +881,17 @@ const chatgpt = { // eslint-disable-line no-redeclare
881
881
  // responseToGet = index of response to get (defaults to latest if '' unpassed)
882
882
  // regenResponseToGet = index of regenerated response to get (defaults to latest if '' unpassed)
883
883
 
884
- if (window.location.href.startsWith('https://chat.openai.com/c/'))
885
- return chatgpt.getResponseFromDOM.apply(null, arguments);
886
- else return chatgpt.getResponseFromAPI.apply(null, arguments);
884
+ return chatgpt.response.get(...arguments);
887
885
  },
888
886
 
889
887
  getResponseFromAPI: function(chatToGet, responseToGet) { return chatgpt.response.getFromAPI(chatToGet, responseToGet); },
890
888
  getResponseFromDOM: function(pos) { return chatgpt.response.getFromDOM(pos); },
891
889
  getScrollToBottomButton: function() { return document.querySelector('button[class*="cursor"][class*="bottom"]'); },
892
- getSendButton: function() { return document.querySelector('form button[class*="bottom"]'); },
890
+
891
+ getSendButton: function() {
892
+ return document.querySelector('[data-testid="send-button"]') // pre-GPT-4o
893
+ || document.querySelector('path[d*="M15.192 8.906a1.143"]')?.parentNode.parentNode; // post-GPT-4o
894
+ },
893
895
 
894
896
  getStopGeneratingButton: function() {
895
897
  for (const svg of document.querySelectorAll('form button svg')) {
@@ -907,11 +909,10 @@ const chatgpt = { // eslint-disable-line no-redeclare
907
909
  history: {
908
910
  isLoaded: function() {
909
911
  return new Promise(resolve => {
910
- const checkChatHistory = () => {
912
+ (function checkChatHistory() {
911
913
  if (document.querySelector('nav')) resolve(true);
912
914
  else setTimeout(checkChatHistory, 100);
913
- };
914
- checkChatHistory();
915
+ })();
915
916
  });}
916
917
  },
917
918
 
@@ -1054,10 +1055,11 @@ const chatgpt = { // eslint-disable-line no-redeclare
1054
1055
 
1055
1056
  isLoaded: function() {
1056
1057
  return new Promise(resolve => {
1057
- const intervalId = setInterval(() => {
1058
- if (document.querySelector('nav button[id*="menu"]')) {
1059
- clearInterval(intervalId); setTimeout(() => { resolve(true); }, 500);
1060
- }}, 100);});},
1058
+ (function checkIsLoaded() {
1059
+ if (chatgpt.getNewChatButton()) resolve(true);
1060
+ else setTimeout(checkIsLoaded, 100);
1061
+ })();
1062
+ });},
1061
1063
 
1062
1064
  isLightMode: function() { return document.documentElement.classList.toString().includes('light'); },
1063
1065
  isMobileDevice: function() { return chatgpt.browser.isMobile(); },
@@ -1154,16 +1156,14 @@ const chatgpt = { // eslint-disable-line no-redeclare
1154
1156
 
1155
1157
  close: function() {
1156
1158
  const menuBtn = document.querySelector('nav [id*="menu-button"][aria-expanded="true"]');
1157
- if (menuBtn)
1158
- try { menuBtn.click(); } catch (err) { console.error('Error while closing the menu'); throw new Error(err); }
1159
- else { console.error('Menu already hidden!'); throw new Error(); }
1159
+ if (menuBtn) try { menuBtn.click(); } catch (err) { return console.error(err.message); }
1160
+ else { console.info('Menu already hidden!'); }
1160
1161
  },
1161
1162
 
1162
1163
  open: function() {
1163
1164
  const menuBtn = document.querySelector('nav [id*="menu-button"][aria-expanded="false"]');
1164
- if (menuBtn)
1165
- try { menuBtn.click(); } catch (err) { console.error('Error while closing the menu'); throw new Error(err); }
1166
- else { console.error('Menu already hidden!'); throw new Error(); }
1165
+ if (menuBtn) try { menuBtn.click(); } catch (err) { return console.error(err.message); }
1166
+ else { console.info('Menu already open!'); }
1167
1167
  }
1168
1168
  },
1169
1169
 
@@ -1350,7 +1350,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
1350
1350
  randomFloat: function() {
1351
1351
  // * Generates a random, cryptographically secure value between 0 (inclusive) & 1 (exclusive)
1352
1352
  const crypto = window.crypto || window.msCrypto;
1353
- return crypto.getRandomValues(new Uint32Array(1))[0] / 0xFFFFFFFF;
1353
+ return crypto?.getRandomValues(new Uint32Array(1))[0] / 0xFFFFFFFF || Math.random();
1354
1354
  },
1355
1355
 
1356
1356
  refactor: function() { chatgpt.code.refactor(); },
@@ -1416,7 +1416,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
1416
1416
  // responseToGet = index of response to get (defaults to latest if '' unpassed)
1417
1417
  // regenResponseToGet = index of regenerated response to get (defaults to latest if '' unpassed)
1418
1418
 
1419
- if (window.location.href.startsWith('https://chat.openai.com/c/'))
1419
+ if (window.location.href.startsWith('https://chatgpt.com/c/'))
1420
1420
  return this.getFromDOM.apply(null, arguments);
1421
1421
  else return this.getFromAPI.apply(null, arguments);
1422
1422
  },
@@ -1461,7 +1461,7 @@ const chatgpt = { // eslint-disable-line no-redeclare
1461
1461
  );
1462
1462
  response = responseDivs[nthOfResponse - 1].textContent;
1463
1463
  }
1464
- response = response.replace(/^ChatGPTChatGPT/, ''); // strip sender name
1464
+ response = response.replace(/^ChatGPT(?:ChatGPT)?/, ''); // strip sender name
1465
1465
  }
1466
1466
  return response;
1467
1467
  },
@@ -1641,10 +1641,6 @@ const chatgpt = { // eslint-disable-line no-redeclare
1641
1641
  elements: [], observer: {},
1642
1642
 
1643
1643
  activateObserver: function() {
1644
- const chatHistoryNav = document.querySelector('nav'),
1645
- firstButton = chatHistoryNav.querySelector('a');
1646
- if (chatgpt.history.isOff()) // Hide enable history spam div
1647
- try { firstButton.parentNode.nextElementSibling.style.display = 'none'; } catch (err) {}
1648
1644
 
1649
1645
  // Stop the previous observer to preserve resources
1650
1646
  if (this.observer instanceof MutationObserver)
@@ -1755,28 +1751,26 @@ const chatgpt = { // eslint-disable-line no-redeclare
1755
1751
  show: function() { this.isOff() ? this.toggle() : console.info('Sidebar already shown!'); },
1756
1752
  isOff: function() { return !this.isOn(); },
1757
1753
  isOn: function() {
1754
+ const sidebar = document.querySelector('#__next > div > div');
1758
1755
  return chatgpt.browser.isMobile() ?
1759
1756
  document.documentElement.style.overflow == 'hidden'
1760
- : document.querySelector('#__next > div > div').style.visibility != 'hidden';
1757
+ : sidebar.style.visibility != 'hidden' && sidebar.style.width != '0px';
1761
1758
  },
1762
1759
 
1763
1760
  toggle: function() {
1764
1761
  const isMobileDevice = chatgpt.browser.isMobile(),
1765
- navBtnSelector = isMobileDevice ? '#__next button' : 'main button' ,
1762
+ isGPT4oUI = !!document.documentElement.className.includes(' '),
1763
+ navBtnSelector = isMobileDevice ? '#__next button' : isGPT4oUI ? 'nav button' : 'main button',
1766
1764
  isToggleBtn = isMobileDevice ? () => true // since 1st one is toggle
1767
- : btn => Array.from(btn.querySelectorAll('*'))
1768
- .some(child => child.style.transform.includes('translateY'));
1765
+ : isGPT4oUI ? btn => btn.querySelectorAll('svg path[d*="M8.857 3h6.286c1.084"]').length > 0
1766
+ : /* post-GPT-4o desktop */ btn => [...btn.querySelectorAll('*')]
1767
+ .some(child => child.style.transform.includes('translateY'));
1769
1768
  for (const btn of document.querySelectorAll(navBtnSelector))
1770
1769
  if (isToggleBtn(btn)) { btn.click(); return; }
1771
1770
  }
1772
1771
  },
1773
1772
 
1774
- startNewChat: function() {
1775
- for (const navLink of document.querySelectorAll('nav a')) {
1776
- if (/(new|clear) chat/i.test(navLink.text)) {
1777
- navLink.click(); return;
1778
- }}},
1779
-
1773
+ startNewChat: function() { try { this.getNewChatButton().click(); } catch (err) { console.error(err.message); }},
1780
1774
  stop: function() { this.response.stopGenerating(); },
1781
1775
 
1782
1776
  suggest: async function(ideaType, details) {
@@ -1877,7 +1871,7 @@ for (const buttonAction of buttonActions) {
1877
1871
  }
1878
1872
 
1879
1873
  // Create alias functions
1880
- const functionAliases = [
1874
+ const funcAliases = [
1881
1875
  ['actAs', 'actas', 'act', 'become', 'persona', 'premadePrompt', 'preMadePrompt', 'prePrompt', 'preprompt', 'roleplay', 'rolePlay', 'rp'],
1882
1876
  ['activateAutoRefresh', 'activateAutoRefresher', 'activateRefresher', 'activateSessionRefresher',
1883
1877
  'autoRefresh', 'autoRefresher', 'autoRefreshSession', 'refresher', 'sessionRefresher'],
@@ -1888,6 +1882,7 @@ const functionAliases = [
1888
1882
  ['getFooterDiv', 'getFooter'],
1889
1883
  ['getHeaderDiv', 'getHeader'],
1890
1884
  ['getLastPrompt', 'getLastQuery', 'getMyLastMsg', 'getMyLastQuery'],
1885
+ ['getScrollToBottomButton', 'getScrollButton'],
1891
1886
  ['getTextarea', 'getTextArea', 'getChatbox', 'getChatBox'],
1892
1887
  ['isFullScreen', 'isFullscreen'],
1893
1888
  ['logOut', 'logout', 'logOff', 'logoff', 'signOut', 'signout', 'signOff', 'signoff'],
@@ -1903,6 +1898,7 @@ const functionAliases = [
1903
1898
  ['send', 'sendChat', 'sendMsg'],
1904
1899
  ['sendInNewChat', 'sendNewChat'],
1905
1900
  ['sentiment', 'analyzeSentiment', 'sentimentAnalysis'],
1901
+ ['startNewChat', 'new', 'newChat'],
1906
1902
  ['stop', 'stopGenerating'],
1907
1903
  ['suggest', 'suggestion', 'recommend'],
1908
1904
  ['toggleAutoRefresh', 'toggleAutoRefresher', 'toggleRefresher', 'toggleSessionRefresher'],
@@ -1937,7 +1933,7 @@ const camelCaser = (words) => {
1937
1933
  for (const prop in chatgpt) {
1938
1934
 
1939
1935
  // Create new function for each alias
1940
- for (const subAliases of functionAliases) {
1936
+ for (const subAliases of funcAliases) {
1941
1937
  if (subAliases.includes(prop)) {
1942
1938
  if (subAliases.some(element => element.includes('.'))) {
1943
1939
  const nestedFunction = subAliases.find(element => element.includes('.')).split('.')[1];
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "name": "ChatGPT Extension",
4
4
  "description": "A Chrome template to start using chatgpt.js like a boss!",
5
- "version": "2024.5.9",
5
+ "version": "2024.5.16",
6
6
  "author": "chatgpt.js",
7
7
  "icons": {
8
8
  "16": "icons/icon16.png",
@@ -17,7 +17,7 @@
17
17
  "resources": ["lib/settings-utils.js", "lib/chatgpt.js"]
18
18
  }],
19
19
  "content_scripts": [{
20
- "matches": ["https://chat.openai.com/*"],
20
+ "matches": ["https://chatgpt.com/*", "https://chat.openai.com/*"],
21
21
  "js": ["content.js"]
22
22
  }],
23
23
  "background": { "service_worker": "background.js" }
@@ -3,12 +3,12 @@
3
3
  // @description A Greasemonkey template to start using chatgpt.js like a boss
4
4
  // @author chatgpt.js
5
5
  // @namespace https://chatgpt.js.org
6
- // @version 2024.5.9
6
+ // @version 2024.5.16
7
7
  // @license MIT
8
8
  // @match https://chat.openai.com/*
9
9
  // @icon https://raw.githubusercontent.com/KudoAI/chatgpt.js-greasemonkey-starter/main/media/images/icons/robot/icon48.png
10
10
  // @icon64 https://raw.githubusercontent.com/KudoAI/chatgpt.js-greasemonkey-starter/main/media/images/icons/robot/icon64.png
11
- // @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@2.7.0/dist/chatgpt.min.js
11
+ // @require https://cdn.jsdelivr.net/npm/@kudoai/chatgpt.js@2.8.0/dist/chatgpt.min.js
12
12
  // @grant GM_getValue
13
13
  // @grant GM_setValue
14
14
  // @noframes