browse-code 0.2.11__tar.gz → 0.2.13__tar.gz

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 (23) hide show
  1. {browse_code-0.2.11 → browse_code-0.2.13}/PKG-INFO +1 -1
  2. browse_code-0.2.13/browse_code/__init__.py +1 -0
  3. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code/extension/content.js +37 -4
  4. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code.egg-info/PKG-INFO +1 -1
  5. {browse_code-0.2.11 → browse_code-0.2.13}/setup.py +1 -1
  6. browse_code-0.2.11/browse_code/__init__.py +0 -1
  7. {browse_code-0.2.11 → browse_code-0.2.13}/README.md +0 -0
  8. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code/cli.py +0 -0
  9. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code/extension/icon128.png +0 -0
  10. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code/extension/icon16.png +0 -0
  11. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code/extension/icon48.png +0 -0
  12. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code/extension/manifest.json +0 -0
  13. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code/extension/popup.html +0 -0
  14. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code/extension/popup.js +0 -0
  15. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code/extension/spoof.js +0 -0
  16. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code/server.py +0 -0
  17. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code.egg-info/SOURCES.txt +0 -0
  18. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code.egg-info/dependency_links.txt +0 -0
  19. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code.egg-info/entry_points.txt +0 -0
  20. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code.egg-info/requires.txt +0 -0
  21. {browse_code-0.2.11 → browse_code-0.2.13}/browse_code.egg-info/top_level.txt +0 -0
  22. {browse_code-0.2.11 → browse_code-0.2.13}/pyproject.toml +0 -0
  23. {browse_code-0.2.11 → browse_code-0.2.13}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: browse_code
3
- Version: 0.2.11
3
+ Version: 0.2.13
4
4
  Summary: Turn any AI chatbot into an autonomous coding agent
5
5
  Description-Content-Type: text/markdown
6
6
  Requires-Dist: fastapi
@@ -0,0 +1 @@
1
+ __version__ = "0.2.13"
@@ -8,6 +8,7 @@ if (hostname.includes('gemini.google.com')) {
8
8
  name: "Gemini",
9
9
  inputBox: 'rich-textarea div[contenteditable="true"], div[role="textbox"][contenteditable="true"], .ql-editor, textarea, input',
10
10
  sendBtn: 'button[aria-label*="Send"], button[aria-label*="send"], button[mattooltip*="Send"]',
11
+ stopBtn: 'button[aria-label*="Stop"], button[aria-label*="stop"], button[mattooltip*="Stop"]',
11
12
  responseContainer: 'message-content, model-response, .model-response-text'
12
13
  };
13
14
  } else if (hostname.includes('claude.ai')) {
@@ -15,6 +16,7 @@ if (hostname.includes('gemini.google.com')) {
15
16
  name: "Claude",
16
17
  inputBox: '.ProseMirror[contenteditable="true"]',
17
18
  sendBtn: 'button[aria-label*="Send"], button[aria-label*="send"]',
19
+ stopBtn: 'button[aria-label*="Stop"], button[aria-label*="stop"]',
18
20
  responseContainer: '.font-claude-response, .font-claude-message'
19
21
  };
20
22
  } else if (hostname.includes('huggingface.co')) {
@@ -22,6 +24,7 @@ if (hostname.includes('gemini.google.com')) {
22
24
  name: "HuggingFace",
23
25
  inputBox: 'input[name="prompt"]',
24
26
  sendBtn: 'button[type="submit"]',
27
+ stopBtn: 'button[aria-label*="Stop"], button:contains("Stop")',
25
28
  responseContainer: '.prose, .markdown, .break-words, [class*="message"]'
26
29
  };
27
30
  } else {
@@ -29,6 +32,7 @@ if (hostname.includes('gemini.google.com')) {
29
32
  name: "ChatGPT",
30
33
  inputBox: '#prompt-textarea',
31
34
  sendBtn: '[data-testid="send-button"], button[data-testid*="send"]',
35
+ stopBtn: 'button[aria-label*="Stop"], button[data-testid*="stop"]',
32
36
  responseContainer: '.markdown, .prose'
33
37
  };
34
38
  }
@@ -231,11 +235,34 @@ async function injectAndSend(promptText) {
231
235
 
232
236
  await new Promise(r => setTimeout(r, 800));
233
237
 
234
- const sendButton = document.querySelector(PLATFORM.sendBtn);
235
- if (sendButton && (!sendButton.disabled && sendButton.getAttribute('aria-disabled') !== 'true')) {
236
- sendButton.click();
237
- } else {
238
+ const trySend = () => {
239
+ const btn = document.querySelector(PLATFORM.sendBtn);
240
+ if (btn && !btn.disabled && btn.getAttribute('aria-disabled') !== 'true') {
241
+ btn.click();
242
+ return true;
243
+ }
244
+ return false;
245
+ };
246
+
247
+ if (!trySend()) {
238
248
  inputBox.dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, cancelable: true, key: 'Enter', code: 'Enter' }));
249
+
250
+ // If the user switched tabs, React might suspend and the button stays disabled.
251
+ // Setup an aggressive retry loop that clicks it the moment they focus the tab and React wakes up.
252
+ const clickInterval = setInterval(() => {
253
+ const currentText = inputBox.tagName === 'INPUT' || inputBox.tagName === 'TEXTAREA' ? inputBox.value : inputBox.textContent;
254
+ // Abort if the user manually cleared or changed the input significantly
255
+ if (!currentText || currentText.length < promptText.length * 0.5) {
256
+ clearInterval(clickInterval);
257
+ return;
258
+ }
259
+ if (trySend()) {
260
+ clearInterval(clickInterval);
261
+ }
262
+ }, 500);
263
+
264
+ // Clear interval after 15 seconds to avoid infinite loops
265
+ setTimeout(() => clearInterval(clickInterval), 15000);
239
266
  }
240
267
  }
241
268
 
@@ -257,6 +284,12 @@ function processQueue() {
257
284
  const userText = inputBox.tagName === 'INPUT' || inputBox.tagName === 'TEXTAREA' ? inputBox.value : inputBox.textContent;
258
285
  if (userText && userText.trim() !== "") return;
259
286
 
287
+ // Do not inject if the LLM is currently generating (Stop button is visible)
288
+ if (PLATFORM.stopBtn) {
289
+ const stopButton = document.querySelector(PLATFORM.stopBtn);
290
+ if (stopButton) return;
291
+ }
292
+
260
293
  const nextMessage = messageQueue.shift();
261
294
  isInjectingQueue = true;
262
295
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: browse_code
3
- Version: 0.2.11
3
+ Version: 0.2.13
4
4
  Summary: Turn any AI chatbot into an autonomous coding agent
5
5
  Description-Content-Type: text/markdown
6
6
  Requires-Dist: fastapi
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="browse_code",
5
- version="0.2.11",
5
+ version="0.2.13",
6
6
  description="Turn any AI chatbot into an autonomous coding agent",
7
7
  long_description=open("README.md").read(),
8
8
  long_description_content_type="text/markdown",
@@ -1 +0,0 @@
1
- __version__ = "0.2.11"
File without changes
File without changes