aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMahesh Sanikommmu <[email protected]>2025-10-19 16:37:42 -0700
committerMahesh Sanikommmu <[email protected]>2025-10-19 16:37:42 -0700
commit73c54ff2e4fedfdaeb18a46d767fc877256e92f2 (patch)
tree082e5e31f1abc4a0080ee847e9f2dfda4201bba6 /apps
parentchore(browser-extension): t3 chat search memories (diff)
downloadsupermemory-73c54ff2e4fedfdaeb18a46d767fc877256e92f2.tar.xz
supermemory-73c54ff2e4fedfdaeb18a46d767fc877256e92f2.zip
feat: auto capture disabled by default
Diffstat (limited to 'apps')
-rw-r--r--apps/browser-extension/entrypoints/content/chatgpt.ts10
-rw-r--r--apps/browser-extension/entrypoints/content/claude.ts10
-rw-r--r--apps/browser-extension/entrypoints/content/t3.ts23
-rw-r--r--apps/browser-extension/entrypoints/popup/App.tsx109
-rw-r--r--apps/browser-extension/utils/constants.ts1
5 files changed, 140 insertions, 13 deletions
diff --git a/apps/browser-extension/entrypoints/content/chatgpt.ts b/apps/browser-extension/entrypoints/content/chatgpt.ts
index 73e0354f..20308728 100644
--- a/apps/browser-extension/entrypoints/content/chatgpt.ts
+++ b/apps/browser-extension/entrypoints/content/chatgpt.ts
@@ -640,6 +640,16 @@ function setupChatGPTPromptCapture() {
document.body.setAttribute("data-chatgpt-prompt-capture-setup", "true")
const capturePromptContent = async (source: string) => {
+ const result = await chrome.storage.local.get([
+ STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED,
+ ])
+ const autoCapturePromptsEnabled =
+ result[STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED] ?? false
+
+ if (!autoCapturePromptsEnabled) {
+ console.log("Auto capture prompts is disabled, skipping prompt capture")
+ return
+ }
const promptTextarea = document.getElementById("prompt-textarea")
let promptContent = ""
diff --git a/apps/browser-extension/entrypoints/content/claude.ts b/apps/browser-extension/entrypoints/content/claude.ts
index e0853d41..88874a3f 100644
--- a/apps/browser-extension/entrypoints/content/claude.ts
+++ b/apps/browser-extension/entrypoints/content/claude.ts
@@ -488,6 +488,16 @@ function setupClaudePromptCapture() {
}
document.body.setAttribute("data-claude-prompt-capture-setup", "true")
const captureClaudePromptContent = async (source: string) => {
+ const result = await chrome.storage.local.get([
+ STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED,
+ ])
+ const autoCapturePromptsEnabled =
+ result[STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED] ?? false
+
+ if (!autoCapturePromptsEnabled) {
+ console.log("Auto capture prompts is disabled, skipping prompt capture")
+ return
+ }
let promptContent = ""
const contentEditableDiv = document.querySelector(
diff --git a/apps/browser-extension/entrypoints/content/t3.ts b/apps/browser-extension/entrypoints/content/t3.ts
index 07a8781f..d1229e6d 100644
--- a/apps/browser-extension/entrypoints/content/t3.ts
+++ b/apps/browser-extension/entrypoints/content/t3.ts
@@ -497,6 +497,16 @@ function setupT3PromptCapture() {
document.body.setAttribute("data-t3-prompt-capture-setup", "true")
const captureT3PromptContent = async (source: string) => {
+ const result = await chrome.storage.local.get([
+ STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED,
+ ])
+ const autoCapturePromptsEnabled =
+ result[STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED] ?? false
+
+ if (!autoCapturePromptsEnabled) {
+ console.log("Auto capture prompts is disabled, skipping prompt capture")
+ return
+ }
let promptContent = ""
const textarea = document.querySelector("textarea") as HTMLTextAreaElement
@@ -599,6 +609,19 @@ function setupT3PromptCapture() {
if (promptContent.trim()) {
console.log("T3 prompt submitted via Enter key:", promptContent)
+ const result = await chrome.storage.local.get([
+ STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED,
+ ])
+ const autoCapturePromptsEnabled =
+ result[STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED] ?? false
+
+ if (!autoCapturePromptsEnabled) {
+ console.log(
+ "Auto capture prompts is disabled, skipping prompt capture",
+ )
+ return
+ }
+
try {
await browser.runtime.sendMessage({
action: MESSAGE_TYPES.CAPTURE_PROMPT,
diff --git a/apps/browser-extension/entrypoints/popup/App.tsx b/apps/browser-extension/entrypoints/popup/App.tsx
index c6e8468c..06aee4a4 100644
--- a/apps/browser-extension/entrypoints/popup/App.tsx
+++ b/apps/browser-extension/entrypoints/popup/App.tsx
@@ -11,6 +11,57 @@ import {
} from "../../utils/query-hooks"
import type { Project } from "../../utils/types"
+const Tooltip = ({
+ children,
+ content,
+}: {
+ children: React.ReactNode
+ content: string
+}) => {
+ const [isVisible, setIsVisible] = useState(false)
+
+ return (
+ <div className="relative inline-flex items-center gap-1">
+ <button
+ type="button"
+ onMouseEnter={() => setIsVisible(true)}
+ onMouseLeave={() => setIsVisible(false)}
+ className="cursor-help bg-transparent border-none p-0 text-left"
+ >
+ {children}
+ </button>
+ <button
+ type="button"
+ onMouseEnter={() => setIsVisible(true)}
+ onMouseLeave={() => setIsVisible(false)}
+ className="cursor-help bg-transparent border-none p-0 text-gray-400 hover:text-gray-600 transition-colors"
+ >
+ <svg
+ width="14"
+ height="14"
+ viewBox="0 0 24 24"
+ fill="none"
+ stroke="currentColor"
+ strokeWidth="2"
+ strokeLinecap="round"
+ strokeLinejoin="round"
+ >
+ <title>More information</title>
+ <circle cx="12" cy="12" r="10" />
+ <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" />
+ <line x1="12" y1="17" x2="12.01" y2="17" />
+ </svg>
+ </button>
+ {isVisible && (
+ <div className="absolute z-50 px-2 py-1 text-xs text-white bg-gray-800 rounded shadow-lg bottom-full right-0 mb-1 max-w-xs break-words">
+ {content}
+ <div className="absolute top-full right-4 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-800" />
+ </div>
+ )}
+ </div>
+ )
+}
+
function App() {
const [userSignedIn, setUserSignedIn] = useState<boolean>(false)
const [loading, setLoading] = useState<boolean>(true)
@@ -22,6 +73,8 @@ function App() {
"save",
)
const [autoSearchEnabled, setAutoSearchEnabled] = useState<boolean>(false)
+ const [autoCapturePromptsEnabled, setAutoCapturePromptsEnabled] =
+ useState<boolean>(false)
const [authInvalidated, setAuthInvalidated] = useState<boolean>(false)
const queryClient = useQueryClient()
@@ -43,6 +96,7 @@ function App() {
const result = await chrome.storage.local.get([
STORAGE_KEYS.BEARER_TOKEN,
STORAGE_KEYS.AUTO_SEARCH_ENABLED,
+ STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED,
])
const hasToken = !!result[STORAGE_KEYS.BEARER_TOKEN]
@@ -70,6 +124,10 @@ function App() {
const autoSearchSetting =
result[STORAGE_KEYS.AUTO_SEARCH_ENABLED] ?? false
setAutoSearchEnabled(autoSearchSetting)
+
+ const autoCapturePromptsSetting =
+ result[STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED] ?? false
+ setAutoCapturePromptsEnabled(autoCapturePromptsSetting)
} catch (error) {
console.error("Error checking auth status:", error)
setUserSignedIn(false)
@@ -178,6 +236,17 @@ function App() {
}
}
+ const handleAutoCapturePromptsToggle = async (enabled: boolean) => {
+ try {
+ await chrome.storage.local.set({
+ [STORAGE_KEYS.AUTO_CAPTURE_PROMPTS_ENABLED]: enabled,
+ })
+ setAutoCapturePromptsEnabled(enabled)
+ } catch (error) {
+ console.error("Error updating auto capture prompts setting:", error)
+ }
+ }
+
const handleSignOut = async () => {
try {
await chrome.storage.local.remove([STORAGE_KEYS.BEARER_TOKEN])
@@ -457,15 +526,13 @@ function App() {
<h3 className="text-base font-semibold text-black mb-3">
Chat Integration
</h3>
- <div className="flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-200">
- <div className="flex flex-col">
- <span className="text-sm font-medium text-black">
- Auto Search Memories
- </span>
- <span className="text-xs text-gray-500">
- Automatically search your memories while typing in chat
- apps
- </span>
+ <div className="flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-200 mb-3">
+ <div className="flex items-center">
+ <Tooltip content="Automatically search your memories while typing in chat apps">
+ <span className="text-sm font-medium text-black cursor-help">
+ Auto Search Memories
+ </span>
+ </Tooltip>
</div>
<label className="relative inline-flex items-center cursor-pointer">
<input
@@ -479,10 +546,26 @@ function App() {
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-gray-700" />
</label>
</div>
- <p className="text-xs text-gray-500 mt-2">
- When enabled, supermemory will search your memories as you
- type in ChatGPT, Claude, and T3.chat
- </p>
+ <div className="flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-200">
+ <div className="flex items-center">
+ <Tooltip content="Automatically save your prompts as memories in chat apps">
+ <span className="text-sm font-medium text-black cursor-help">
+ Auto Capture Prompts
+ </span>
+ </Tooltip>
+ </div>
+ <label className="relative inline-flex items-center cursor-pointer">
+ <input
+ checked={autoCapturePromptsEnabled}
+ className="sr-only peer"
+ onChange={(e) =>
+ handleAutoCapturePromptsToggle(e.target.checked)
+ }
+ type="checkbox"
+ />
+ <div className="w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-gray-700" />
+ </label>
+ </div>
</div>
</div>
)}
diff --git a/apps/browser-extension/utils/constants.ts b/apps/browser-extension/utils/constants.ts
index d459a0f0..16baaabd 100644
--- a/apps/browser-extension/utils/constants.ts
+++ b/apps/browser-extension/utils/constants.ts
@@ -22,6 +22,7 @@ export const STORAGE_KEYS = {
TWITTER_AUTH_TOKEN: "twitter-auth-token",
DEFAULT_PROJECT: "sm-default-project",
AUTO_SEARCH_ENABLED: "sm-auto-search-enabled",
+ AUTO_CAPTURE_PROMPTS_ENABLED: "sm-auto-capture-prompts-enabled",
} as const
/**