feat: Added AI query UI

This commit is contained in:
Dhravya 2024-03-01 11:43:40 -07:00
parent b38605a336
commit b8e070c1ac
47 changed files with 1689 additions and 379 deletions

View file

@ -9,6 +9,7 @@ import {
} from "@langchain/cloudflare";
import { Ai } from '@cloudflare/ai';
import { OpenAIEmbeddings } from "./OpenAIEmbedder";
import { AiTextGenerationOutput } from "@cloudflare/ai/dist/tasks/text-generation";
export interface Env {
VECTORIZE_INDEX: VectorizeIndex;
@ -65,8 +66,10 @@ export default {
url: body.url,
user: body.user,
},
}
])
},
], {
ids: [`${body.url}`]
})
return new Response(JSON.stringify({ message: "Document Added" }), { status: 200 });
}
@ -76,6 +79,9 @@ export default {
const query = queryparams.get("q");
const topK = parseInt(queryparams.get("topK") ?? "5");
const user = queryparams.get("user")
const sourcesOnly = (queryparams.get("sourcesOnly") ?? "false")
if (!user) {
return new Response(JSON.stringify({ message: "Invalid User" }), { status: 400 });
}
@ -90,23 +96,67 @@ export default {
}
}
const resp = await store.similaritySearch(query, topK, filter)
const queryAsVector = await embeddings.embedQuery(query);
if (resp.length === 0) {
const resp = await env.VECTORIZE_INDEX.query(queryAsVector, {
topK,
filter
});
if (resp.count === 0) {
return new Response(JSON.stringify({ message: "No Results Found" }), { status: 400 });
}
const output = await ai.run('@cf/meta/llama-2-7b-chat-int8', {
prompt: `You are an agent that summarizes a page based on the query. Be direct and concise, don't say 'based on the context'.\n\n Context:\n${JSON.stringify(resp)} \nAnswer this question based on the context. Question: ${query}`,
})
const highScoreIds = resp.matches.filter(({ score }) => score > 0.3).map(({ id }) => id)
const cleanCitations = resp.map(
({ metadata }) => ({ url: metadata.url, title: metadata.title, description: metadata.description })
)
if (sourcesOnly === "true") {
return new Response(JSON.stringify({ ids: highScoreIds }), { status: 200 });
}
return new Response(JSON.stringify({
output, citations: cleanCitations
}), { status: 200 });
const vec = await env.VECTORIZE_INDEX.getByIds(highScoreIds)
if (vec.length === 0 || !vec[0].metadata) {
return new Response(JSON.stringify({ message: "No Results Found" }), { status: 400 });
}
const metadatas = vec.map(({ metadata }) => metadata)
console.log(metadatas)
// TODO: TAKE ALL THE HIGH SCORED IDS INTO CONSIDERATION
const output: AiTextGenerationOutput = await ai.run('@hf/thebloke/mistral-7b-instruct-v0.1-awq', {
prompt: `You are an agent that summarizes a page based on the query. Be direct and concise, don't say 'based on the context'.\n\n Context:\n${vec[0].metadata!.text} \nAnswer this question based on the context. Question: ${query}\nAnswer:`,
stream: true
}) as ReadableStream
return new Response(output, {
headers: {
"content-type": "text/event-stream",
},
});
}
else if (pathname === "/ask" && request.method === "POST") {
const body = await request.json() as {
query: string
};
if (!body.query) {
return new Response(JSON.stringify({ message: "Invalid Page Content" }), { status: 400 });
}
const output: AiTextGenerationOutput = await ai.run('@hf/thebloke/mistral-7b-instruct-v0.1-awq', {
prompt: `You are an agent that answers a question based on the query. Be direct and concise, don't say 'based on the context'.\n\n Context:\n${body.query} \nAnswer this question based on the context. Question: ${body.query}\nAnswer:`,
stream: true
}) as ReadableStream
return new Response(output, {
headers: {
"content-type": "text/event-stream",
},
});
}
},
};

BIN
apps/extension/dist.zip Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -1,11 +1,17 @@
{
"manifest_version": 3,
"name": "Extension",
"name": "SuperMemory",
"version": "1.0.0",
"action": {
"default_popup": "index.html"
},
"content_scripts" : [
"icons": {
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"content_scripts": [
{
"js": [
"src/content.tsx"
@ -25,5 +31,5 @@
],
"background": {
"service_worker": "src/background.ts"
}
}
}

View file

@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@radix-ui/react-tooltip": "^1.0.7",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},

View file

@ -14,7 +14,7 @@ function App() {
if (loginButton) {
if (jwt) {
fetch('http://localhost:3000/api/me', {
fetch('https://anycontext.dhr.wtf/api/me', {
headers: {
Authorization: `Bearer ${jwt}`,
},
@ -43,7 +43,7 @@ function App() {
<button
onClick={() =>
chrome.tabs.create({
url: 'http://localhost:3000/api/auth/signin',
url: 'https://anycontext.dhr.wtf/api/auth/signin',
})
}
id="login"

View file

@ -1,8 +1,14 @@
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import './ext.css';
import './dist.css';
import { Input } from './components/ui/input';
import { Button } from './components/ui/button';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from './components/ui/tooltip';
function sendUrlToAPI() {
// get the current URL
@ -20,136 +26,294 @@ function sendUrlToAPI() {
}
}
function SideBar() {
function SideBar({ jwt }: { jwt: string }) {
const [isOpen, setIsOpen] = useState(false);
const [input, setInput] = useState('');
const [savedWebsites, setSavedWebsites] = useState<string[]>([]);
const [isSendingData, setIsSendingData] = useState(false);
const [toBeParsed, setToBeParsed] = useState('');
const [aiResponse, setAIResponse] = useState<string>('');
const [lastQuestion, setLastQuestion] = useState<string>('');
const handleStreamData = (newChunk: string) => {
// Append the new chunk to the existing data to be parsed
setToBeParsed((prev) => prev + newChunk);
};
const queryApi = async () => {
const content = document.documentElement.innerText;
setAIResponse('');
const query = `Answer this question based on this query: ${input}\n\n${content}`;
chrome.runtime.sendMessage({ type: 'queryApi', input: query, jwt });
};
useEffect(() => {
if (typeof window === 'undefined') return;
chrome.runtime.onMessage.addListener((message) => {
if (message.action === 'streamData') {
console.log(message.data);
handleStreamData(message.data);
} else if (message.action === 'streamEnd') {
setLastQuestion(input);
setInput('');
setToBeParsed('');
}
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
// Define a function to try parsing the accumulated data
const tryParseAccumulatedData = () => {
// Attempt to parse the "toBeParsed" state as JSON
try {
// Split the accumulated data by the known delimiter "\n\n"
const parts = toBeParsed.split('\n\n');
let remainingData = '';
// Process each part to extract JSON objects
parts.forEach((part, index) => {
try {
const parsedPart = JSON.parse(part.replace('data: ', '')); // Try to parse the part as JSON
// If the part is the last one and couldn't be parsed, keep it to accumulate more data
if (index === parts.length - 1 && !parsedPart) {
remainingData = part;
} else if (parsedPart && parsedPart.response) {
// If the part is parsable and has the "response" field, update the AI response state
setAIResponse((prev) => prev + parsedPart.response);
}
} catch (error) {
// If parsing fails and it's not the last part, it's a malformed JSON
if (index !== parts.length - 1) {
console.error('Malformed JSON part: ', part);
} else {
// If it's the last part, it may be incomplete, so keep it
remainingData = part;
}
}
});
// Update the toBeParsed state to only contain the unparsed remainder
if (remainingData !== toBeParsed) {
setToBeParsed(remainingData);
}
} catch (error) {
console.error('Error parsing accumulated data: ', error);
}
};
// Call the parsing function if there's data to be parsed
if (toBeParsed) {
tryParseAccumulatedData();
}
}, [toBeParsed]);
return (
<>
{isOpen && (
<div
onClick={() => setIsOpen(false)}
className="anycontext-overlay"
></div>
)}
<TooltipProvider>
{isOpen && (
<div
onClick={() => setIsOpen(false)}
className="anycontext-overlay"
></div>
)}
{isOpen ? (
<motion.div
initial={{ x: '100%' }}
animate={{ x: 0 }}
exit={{ x: '100%' }}
transition={{ duration: 0.3 }}
className="anycontext-sidebar anycontext-relative"
>
<div className="anycontext-sidebar-content anycontext-text-black anycontext-px-4 anycontext-relative">
<h1 className="anycontext-header">Ask a question to this page</h1>
{isOpen ? (
<motion.div
initial={{ x: '100%' }}
animate={{ x: 0 }}
exit={{ x: '100%' }}
transition={{ duration: 0.3 }}
className="anycontext-sidebar anycontext-relative"
>
<div className="anycontext-sidebar-content anycontext-text-black anycontext-px-4 anycontext-relative">
<h1 className="anycontext-header anycontext-font-sans">
Ask a question to this page
</h1>
{/* Three buttons as options to choose from */}
<div className="anycontext-flex anycontext-flex-col anycontext-gap-4 anycontext-mt-8 anycontext-px-4">
<Button className="anycontext-w-full">Summarize content</Button>
<Button className="anycontext-w-full">
What's the most important?
</Button>
<Button className="anycontext-w-full anycontext-bg-gradient-to-tr anycontext-from-purple-400 anycontext-to-purple-600">
Save to memory
</Button>
{/* Three buttons as options to choose from */}
{!input && (
<div className="anycontext-flex anycontext-flex-col anycontext-gap-4 anycontext-mt-8 anycontext-px-4">
<Button
onClick={async () => {
setInput('Summarise the content of this web page');
await queryApi();
}}
className="anycontext-w-full"
>
Summarize content
</Button>
<Button
onClick={async () => {
setInput(
'Whats the most important points of this page? Answer in points.',
);
await queryApi();
}}
className="anycontext-w-full"
>
What's the most important?
</Button>
<Button
onClick={() => {
setIsOpen(false);
sendUrlToAPI();
setIsSendingData(true);
setTimeout(() => {
setIsSendingData(false);
setSavedWebsites([
...savedWebsites,
window.location.href,
]);
}, 1000);
}}
className="anycontext-w-full anycontext-bg-gradient-to-tr anycontext-from-purple-400 anycontext-to-purple-600"
>
Save to memory
</Button>
</div>
)}
{lastQuestion && (
<div className="anycontext-mb-4">
<h2 className="anycontext-text-lg anycontext-font-semibold">
{lastQuestion}
</h2>
</div>
)}
<div className="anycontext-px-4 anycontext-max-h-[75vh] anycontext-overflow-y-auto anycontext-mt-8">
{aiResponse.replace('</s>', '')}
</div>
<form
onSubmit={async (e) => {
e.preventDefault();
await queryApi();
setInput('');
}}
className="anycontext-flex anycontext-absolute anycontext-bottom-0 anycontext-w-full anycontext-gap-4 anycontext-justify-between anycontext-px-4"
>
<Input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Ask anything about this website"
className="anycontext-mb-4 anycontext-text-black anycontext-outline"
/>
<Button onClick={async () => queryApi()}>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="lucide lucide-send-horizontal"
>
<path d="m3 3 3 9-3 9 19-9Z" />
<path d="M6 12h16" />
</svg>
</Button>
</form>
</div>
<div className="anycontext-flex anycontext-absolute anycontext-bottom-0 anycontext-w-full anycontext-gap-4 anycontext-justify-between anycontext-px-4">
<Input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Ask anything about this website"
className="anycontext-mb-4 anycontext-text-black anycontext-outline"
/>
<Button>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="lucide lucide-send-horizontal"
</motion.div>
) : (
<div className="anycontext-flex anycontext-flex-col anycontext-gap-2 anycontext-fixed anycontext-bottom-12 anycontext-right-0 anycontext-z-[99999]">
<Tooltip delayDuration={300}>
<TooltipTrigger>
<button
onClick={() => setIsOpen(true)}
className="anycontext-open-button"
>
<path d="m3 3 3 9-3 9 19-9Z" />
<path d="M6 12h16" />
</svg>
</Button>
</div>
</div>
</motion.div>
) : (
<div className="anycontext-flex anycontext-flex-col anycontext-gap-2 anycontext-fixed anycontext-bottom-12 anycontext-right-0 anycontext-z-[99999]">
<button
onClick={() => setIsOpen(true)}
className="anycontext-open-button"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="lucide lucide-panel-right-open"
>
<rect width="18" height="18" x="3" y="3" rx="2" />
<path d="M15 3v18" />
<path d="m10 15-3-3 3-3" />
</svg>
</button>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="lucide lucide-panel-right-open"
>
<rect width="18" height="18" x="3" y="3" rx="2" />
<path d="M15 3v18" />
<path d="m10 15-3-3 3-3" />
</svg>
</button>
</TooltipTrigger>
<TooltipContent side="left">
<p>Open Sidebar</p>
</TooltipContent>
</Tooltip>
<button
onClick={() => {
sendUrlToAPI();
setIsSendingData(true);
setTimeout(() => {
setIsSendingData(false);
setSavedWebsites([...savedWebsites, window.location.href]);
}, 1000);
}}
className="anycontext-open-button"
>
{savedWebsites.includes(window.location.href) ? (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="lucide lucide-file-check-2"
>
<path d="M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4" />
<path d="M14 2v4a2 2 0 0 0 2 2h4" />
<path d="m3 15 2 2 4-4" />
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
className={`w-5 h-5 ${isSendingData ? 'anycontext-animate-spin' : ''}`}
>
<path d="M15.98 1.804a1 1 0 0 0-1.96 0l-.24 1.192a1 1 0 0 1-.784.785l-1.192.238a1 1 0 0 0 0 1.962l1.192.238a1 1 0 0 1 .785.785l.238 1.192a1 1 0 0 0 1.962 0l.238-1.192a1 1 0 0 1 .785-.785l1.192-.238a1 1 0 0 0 0-1.962l-1.192-.238a1 1 0 0 1-.785-.785l-.238-1.192ZM6.949 5.684a1 1 0 0 0-1.898 0l-.683 2.051a1 1 0 0 1-.633.633l-2.051.683a1 1 0 0 0 0 1.898l2.051.684a1 1 0 0 1 .633.632l.683 2.051a1 1 0 0 0 1.898 0l.683-2.051a1 1 0 0 1 .633-.633l2.051-.683a1 1 0 0 0 0-1.898l-2.051-.683a1 1 0 0 1-.633-.633L6.95 5.684ZM13.949 13.684a1 1 0 0 0-1.898 0l-.184.551a1 1 0 0 1-.632.633l-.551.183a1 1 0 0 0 0 1.898l.551.183a1 1 0 0 1 .633.633l.183.551a1 1 0 0 0 1.898 0l.184-.551a1 1 0 0 1 .632-.633l.551-.183a1 1 0 0 0 0-1.898l-.551-.184a1 1 0 0 1-.633-.632l-.183-.551Z" />
</svg>
)}
</button>
</div>
)}
<Tooltip delayDuration={300}>
<TooltipTrigger>
<button
onClick={() => {
sendUrlToAPI();
setIsSendingData(true);
setTimeout(() => {
setIsSendingData(false);
setSavedWebsites([
...savedWebsites,
window.location.href,
]);
}, 1000);
}}
disabled={savedWebsites.includes(window.location.href)}
className="anycontext-open-button disabled:anycontext-opacity-30"
>
{savedWebsites.includes(window.location.href) ? (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
className="lucide lucide-file-check-2"
>
<path d="M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4" />
<path d="M14 2v4a2 2 0 0 0 2 2h4" />
<path d="m3 15 2 2 4-4" />
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
className={`anycontext-w-5 anycontext-h-5 ${isSendingData ? 'anycontext-animate-spin' : ''}`}
>
<path d="M15.98 1.804a1 1 0 0 0-1.96 0l-.24 1.192a1 1 0 0 1-.784.785l-1.192.238a1 1 0 0 0 0 1.962l1.192.238a1 1 0 0 1 .785.785l.238 1.192a1 1 0 0 0 1.962 0l.238-1.192a1 1 0 0 1 .785-.785l1.192-.238a1 1 0 0 0 0-1.962l-1.192-.238a1 1 0 0 1-.785-.785l-.238-1.192ZM6.949 5.684a1 1 0 0 0-1.898 0l-.683 2.051a1 1 0 0 1-.633.633l-2.051.683a1 1 0 0 0 0 1.898l2.051.684a1 1 0 0 1 .633.632l.683 2.051a1 1 0 0 0 1.898 0l.683-2.051a1 1 0 0 1 .633-.633l2.051-.683a1 1 0 0 0 0-1.898l-2.051-.683a1 1 0 0 1-.633-.633L6.95 5.684ZM13.949 13.684a1 1 0 0 0-1.898 0l-.184.551a1 1 0 0 1-.632.633l-.551.183a1 1 0 0 0 0 1.898l.551.183a1 1 0 0 1 .633.633l.183.551a1 1 0 0 0 1.898 0l.184-.551a1 1 0 0 1 .632-.633l.551-.183a1 1 0 0 0 0-1.898l-.551-.184a1 1 0 0 1-.633-.632l-.183-.551Z" />
</svg>
)}
</button>
</TooltipTrigger>
<TooltipContent side="left">
<p>
{savedWebsites.includes(window.location.href)
? 'Added to memory'
: 'Add to memory'}
</p>
</TooltipContent>
</Tooltip>
</div>
)}
</TooltipProvider>
</>
);
}

View file

@ -1,4 +1,4 @@
chrome.runtime.onMessage.addListener((request, _, sendResponse) => {
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.type === "getJwt") {
chrome.storage.local.get(["jwt"], ({ jwt }) => {
sendResponse({ jwt });
@ -17,7 +17,7 @@ chrome.runtime.onMessage.addListener((request, _, sendResponse) => {
console.error("No JWT found");
return;
}
fetch("http://localhost:3000/api/store", {
fetch("https://anycontext.dhr.wtf/api/store", {
method: "POST",
headers: {
"Authorization": `Bearer ${jwt}`,
@ -27,4 +27,42 @@ chrome.runtime.onMessage.addListener((request, _, sendResponse) => {
});
})();
}
else if (request.type === "queryApi") {
const input = request.input;
const jwt = request.jwt;
(async () => {
await fetch("https://anycontext.dhr.wtf/api/ask", {
method: "POST",
headers: {
"Authorization": `Bearer ${jwt}`,
},
body: JSON.stringify({
query: input,
}),
}).then(async response => {
if (!response.body) {
throw new Error("No response body");
}
if (!sender.tab?.id) {
throw new Error("No tab ID");
}
const reader = response.body.getReader();
// eslint-disable-next-line no-constant-condition
while (true) {
const { done, value } = await reader.read();
if (done) break;
// For simplicity, we're sending chunks as they come.
// This might need to be adapted based on your data and needs.
const chunkAsString = new TextDecoder('utf-8').decode(value).replace("data: ", "")
chrome.tabs.sendMessage(sender.tab.id, { action: "streamData", data: chunkAsString });
}
// Notify the content script that the stream is complete.
chrome.tabs.sendMessage(sender.tab.id, { action: "streamEnd" });
});
// Indicate that sendResponse will be called asynchronously.
return true;
})();
}
});

View file

@ -0,0 +1,28 @@
import * as React from "react"
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
import { cn } from "../../lib/utils"
const TooltipProvider = TooltipPrimitive.Provider
const Tooltip = TooltipPrimitive.Root
const TooltipTrigger = TooltipPrimitive.Trigger
const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"anycontext-z-50 anycontext-overflow-hidden anycontext-rounded-md anycontext-border anycontext-border-stone-200 anycontext-bg-white anycontext-px-3 anycontext-py-1.5 anycontext-text-sm anycontext-text-stone-950 anycontext-shadow-md anycontext-animate-in anycontext-fade-in-0 anycontext-zoom-in-95 data-[state=closed]:anycontext-animate-out data-[state=closed]:anycontext-fade-out-0 data-[state=closed]:anycontext-zoom-out-95 data-[side=bottom]:anycontext-slide-in-from-top-2 data-[side=left]:anycontext-slide-in-from-right-2 data-[side=right]:anycontext-slide-in-from-left-2 data-[side=top]:anycontext-slide-in-from-bottom-2 dark:anycontext-border-stone-800 dark:anycontext-bg-stone-950 dark:anycontext-text-stone-50",
className
)}
{...props}
/>
))
TooltipContent.displayName = TooltipPrimitive.Content.displayName
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }

View file

@ -32,6 +32,13 @@ appContainer.style.zIndex = '9999';
import ReactDOM from 'react-dom/client';
import SideBar from './SideBar';
ReactDOM.createRoot(
document.getElementById('anycontext-app-container')!,
).render(<SideBar />);
// get JWT from local storage
const jwt = chrome.storage.local.get('jwt').then((data) => {
return data.jwt;
}) as Promise<string>
jwt.then((jwt) => {
ReactDOM.createRoot(
document.getElementById('anycontext-app-container')!,
).render(<SideBar jwt={jwt} />);
});

951
apps/extension/src/dist.css Normal file
View file

@ -0,0 +1,951 @@
*,
::before,
::after {
box-sizing: border-box;
/* 1 */
border-width: 0;
/* 2 */
border-style: solid;
/* 2 */
border-color: #e5e7eb;
/* 2 */
}
::before,
::after {
--tw-content: '';
}
/*
1. Use a consistent sensible line-height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.
3. Use a more readable tab size.
4. Use the user's configured `sans` font-family by default.
5. Use the user's configured `sans` font-feature-settings by default.
6. Use the user's configured `sans` font-variation-settings by default.
7. Disable tap highlights on iOS
*/
/* Make elements with the HTML hidden attribute stay hidden by default */
[hidden] {
display: none;
}
*,
::before,
::after {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
::backdrop {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
.anycontext-fixed {
position: fixed;
}
.anycontext-absolute {
position: absolute;
}
.anycontext-relative {
position: relative;
}
.anycontext-bottom-0 {
bottom: 0px;
}
.anycontext-bottom-12 {
bottom: 3rem;
}
.anycontext-right-0 {
right: 0px;
}
.anycontext-z-50 {
z-index: 50;
}
.anycontext-z-\[99999\] {
z-index: 99999;
}
.anycontext-mb-4 {
margin-bottom: 1rem;
}
.anycontext-mt-8 {
margin-top: 2rem;
}
.anycontext-flex {
display: flex;
}
.anycontext-inline-flex {
display: inline-flex;
}
.anycontext-h-10 {
height: 2.5rem;
}
.anycontext-h-11 {
height: 2.75rem;
}
.anycontext-h-5 {
height: 1.25rem;
}
.anycontext-h-9 {
height: 2.25rem;
}
.anycontext-max-h-\[75vh\] {
max-height: 75vh;
}
.anycontext-w-10 {
width: 2.5rem;
}
.anycontext-w-5 {
width: 1.25rem;
}
.anycontext-w-full {
width: 100%;
}
@keyframes anycontext-spin {
to {
transform: rotate(360deg);
}
}
.anycontext-animate-spin {
animation: anycontext-spin 1s linear infinite;
}
.anycontext-flex-col {
flex-direction: column;
}
.anycontext-items-center {
align-items: center;
}
.anycontext-justify-center {
justify-content: center;
}
.anycontext-justify-between {
justify-content: space-between;
}
.anycontext-gap-2 {
gap: 0.5rem;
}
.anycontext-gap-4 {
gap: 1rem;
}
.anycontext-overflow-hidden {
overflow: hidden;
}
.anycontext-overflow-y-auto {
overflow-y: auto;
}
.anycontext-whitespace-nowrap {
white-space: nowrap;
}
.anycontext-rounded-md {
border-radius: 0.375rem;
}
.anycontext-border {
border-width: 1px;
}
.anycontext-border-stone-200 {
--tw-border-opacity: 1;
border-color: rgb(231 229 228 / var(--tw-border-opacity));
}
.anycontext-bg-red-500 {
--tw-bg-opacity: 1;
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
}
.anycontext-bg-stone-100 {
--tw-bg-opacity: 1;
background-color: rgb(245 245 244 / var(--tw-bg-opacity));
}
.anycontext-bg-stone-900 {
--tw-bg-opacity: 1;
background-color: rgb(28 25 23 / var(--tw-bg-opacity));
}
.anycontext-bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.anycontext-bg-gradient-to-tr {
background-image: linear-gradient(to top right, var(--tw-gradient-stops));
}
.anycontext-from-purple-400 {
--tw-gradient-from: #c084fc var(--tw-gradient-from-position);
--tw-gradient-to: rgb(192 132 252 / 0) var(--tw-gradient-to-position);
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.anycontext-to-purple-600 {
--tw-gradient-to: #9333ea var(--tw-gradient-to-position);
}
.anycontext-px-3 {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
.anycontext-px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.anycontext-px-8 {
padding-left: 2rem;
padding-right: 2rem;
}
.anycontext-py-1 {
padding-top: 0.25rem;
padding-bottom: 0.25rem;
}
.anycontext-py-1\.5 {
padding-top: 0.375rem;
padding-bottom: 0.375rem;
}
.anycontext-py-2 {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
.anycontext-font-sans {
font-family: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
.anycontext-text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
}
.anycontext-text-lg {
font-size: 1.125rem;
line-height: 1.75rem;
}
.anycontext-font-medium {
font-weight: 500;
}
.anycontext-font-semibold {
font-weight: 600;
}
.anycontext-text-black {
--tw-text-opacity: 1;
color: rgb(0 0 0 / var(--tw-text-opacity));
}
.anycontext-text-stone-50 {
--tw-text-opacity: 1;
color: rgb(250 250 249 / var(--tw-text-opacity));
}
.anycontext-text-stone-900 {
--tw-text-opacity: 1;
color: rgb(28 25 23 / var(--tw-text-opacity));
}
.anycontext-text-stone-950 {
--tw-text-opacity: 1;
color: rgb(12 10 9 / var(--tw-text-opacity));
}
.anycontext-underline-offset-4 {
text-underline-offset: 4px;
}
.anycontext-shadow-md {
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
0 2px 4px -2px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.anycontext-outline {
outline-style: solid;
}
.anycontext-ring-offset-white {
--tw-ring-offset-color: #fff;
}
.anycontext-transition-colors {
transition-property: color, background-color, border-color,
text-decoration-color, fill, stroke;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
@keyframes enter {
from {
opacity: var(--tw-enter-opacity, 1);
transform: translate3d(
var(--tw-enter-translate-x, 0),
var(--tw-enter-translate-y, 0),
0
)
scale3d(
var(--tw-enter-scale, 1),
var(--tw-enter-scale, 1),
var(--tw-enter-scale, 1)
)
rotate(var(--tw-enter-rotate, 0));
}
}
@keyframes exit {
to {
opacity: var(--tw-exit-opacity, 1);
transform: translate3d(
var(--tw-exit-translate-x, 0),
var(--tw-exit-translate-y, 0),
0
)
scale3d(
var(--tw-exit-scale, 1),
var(--tw-exit-scale, 1),
var(--tw-exit-scale, 1)
)
rotate(var(--tw-exit-rotate, 0));
}
}
.anycontext-animate-in {
animation-name: enter;
animation-duration: 150ms;
--tw-enter-opacity: initial;
--tw-enter-scale: initial;
--tw-enter-rotate: initial;
--tw-enter-translate-x: initial;
--tw-enter-translate-y: initial;
}
.anycontext-fade-in-0 {
--tw-enter-opacity: 0;
}
.anycontext-zoom-in-95 {
--tw-enter-scale: 0.95;
}
/* ext.css - Assuming this is your CSS file */
.anycontext-overlay {
position: fixed;
top: 0;
left: 0;
min-height: 100vh;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 99998;
}
.anycontext-sidebar {
position: fixed;
top: 0;
right: 0;
min-height: 100vh;
width: 100%;
max-width: 31%;
/* Responsive width */
z-index: 99999;
padding: 8px 16px;
/* px-4 py-2 */
}
.anycontext-sidebar-content {
position: relative;
display: flex;
flex-direction: column;
height: 95vh;
background-color: white;
border-radius: 8px;
/* rounded-lg */
padding: 8px;
/* px-2 */
box-shadow:
0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -1px rgba(0, 0, 0, 0.06);
/* shadow-md */
}
.anycontext-close-button {
position: absolute;
right: 0;
padding: 8px;
/* p-2 */
border-radius: 4px;
/* rounded-md */
margin: 8px;
/* m-2 */
}
.anycontext-close-button:hover {
background-color: rgba(114, 87, 255, 0.5);
/* hover:bg-[#7257ff]/50 */
color: white;
/* hover:text-white */
}
.anycontext-open-button {
color: white;
background-color: #7257ff;
background-opacity: 75%;
cursor: pointer;
padding: 8px;
/* px-4 py-2 */
border-radius: 4px 0 0 4px;
/* rounded-l-md */
display: flex;
align-items: center;
justify-content: space-between;
}
.anycontext-header {
margin: 16px;
/* m-4 */
font-weight: 600;
/* font-semibold */
font-size: 1.25rem;
/* text-xl */
color: black;
}
.anycontext-icon {
height: 24px;
/* h-6 */
width: 24px;
/* w-6 */
}
.file\:anycontext-border-0::file-selector-button {
border-width: 0px;
}
.file\:anycontext-bg-transparent::file-selector-button {
background-color: transparent;
}
.file\:anycontext-text-sm::file-selector-button {
font-size: 0.875rem;
line-height: 1.25rem;
}
.file\:anycontext-font-medium::file-selector-button {
font-weight: 500;
}
.placeholder\:anycontext-text-stone-500::-moz-placeholder {
--tw-text-opacity: 1;
color: rgb(120 113 108 / var(--tw-text-opacity));
}
.placeholder\:anycontext-text-stone-500::placeholder {
--tw-text-opacity: 1;
color: rgb(120 113 108 / var(--tw-text-opacity));
}
.hover\:anycontext-bg-red-500\/90:hover {
background-color: rgb(239 68 68 / 0.9);
}
.hover\:anycontext-bg-stone-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(245 245 244 / var(--tw-bg-opacity));
}
.hover\:anycontext-bg-stone-100\/80:hover {
background-color: rgb(245 245 244 / 0.8);
}
.hover\:anycontext-bg-stone-900\/90:hover {
background-color: rgb(28 25 23 / 0.9);
}
.hover\:anycontext-text-stone-900:hover {
--tw-text-opacity: 1;
color: rgb(28 25 23 / var(--tw-text-opacity));
}
.hover\:anycontext-underline:hover {
text-decoration-line: underline;
}
.focus-visible\:anycontext-outline-none:focus-visible {
outline: 2px solid transparent;
outline-offset: 2px;
}
.focus-visible\:anycontext-ring-2:focus-visible {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0
calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
var(--tw-shadow, 0 0 #0000);
}
.focus-visible\:anycontext-ring-stone-950:focus-visible {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(12 10 9 / var(--tw-ring-opacity));
}
.focus-visible\:anycontext-ring-offset-2:focus-visible {
--tw-ring-offset-width: 2px;
}
.disabled\:anycontext-pointer-events-none:disabled {
pointer-events: none;
}
.disabled\:anycontext-cursor-not-allowed:disabled {
cursor: not-allowed;
}
.disabled\:anycontext-opacity-30:disabled {
opacity: 0.3;
}
.disabled\:anycontext-opacity-50:disabled {
opacity: 0.5;
}
.data-\[state\=closed\]\:anycontext-animate-out[data-state='closed'] {
animation-name: exit;
animation-duration: 150ms;
--tw-exit-opacity: initial;
--tw-exit-scale: initial;
--tw-exit-rotate: initial;
--tw-exit-translate-x: initial;
--tw-exit-translate-y: initial;
}
.data-\[state\=closed\]\:anycontext-fade-out-0[data-state='closed'] {
--tw-exit-opacity: 0;
}
.data-\[state\=closed\]\:anycontext-zoom-out-95[data-state='closed'] {
--tw-exit-scale: 0.95;
}
.data-\[side\=bottom\]\:anycontext-slide-in-from-top-2[data-side='bottom'] {
--tw-enter-translate-y: -0.5rem;
}
.data-\[side\=left\]\:anycontext-slide-in-from-right-2[data-side='left'] {
--tw-enter-translate-x: 0.5rem;
}
.data-\[side\=right\]\:anycontext-slide-in-from-left-2[data-side='right'] {
--tw-enter-translate-x: -0.5rem;
}
.data-\[side\=top\]\:anycontext-slide-in-from-bottom-2[data-side='top'] {
--tw-enter-translate-y: 0.5rem;
}
:is(.anycontext-dark .dark\:anycontext-border-stone-800) {
--tw-border-opacity: 1;
border-color: rgb(41 37 36 / var(--tw-border-opacity));
}
:is(.anycontext-dark .dark\:anycontext-bg-red-900) {
--tw-bg-opacity: 1;
background-color: rgb(127 29 29 / var(--tw-bg-opacity));
}
:is(.anycontext-dark .dark\:anycontext-bg-stone-50) {
--tw-bg-opacity: 1;
background-color: rgb(250 250 249 / var(--tw-bg-opacity));
}
:is(.anycontext-dark .dark\:anycontext-bg-stone-800) {
--tw-bg-opacity: 1;
background-color: rgb(41 37 36 / var(--tw-bg-opacity));
}
:is(.anycontext-dark .dark\:anycontext-bg-stone-950) {
--tw-bg-opacity: 1;
background-color: rgb(12 10 9 / var(--tw-bg-opacity));
}
:is(.anycontext-dark .dark\:anycontext-text-stone-50) {
--tw-text-opacity: 1;
color: rgb(250 250 249 / var(--tw-text-opacity));
}
:is(.anycontext-dark .dark\:anycontext-text-stone-900) {
--tw-text-opacity: 1;
color: rgb(28 25 23 / var(--tw-text-opacity));
}
:is(.anycontext-dark .dark\:anycontext-ring-offset-stone-950) {
--tw-ring-offset-color: #0c0a09;
}
:is(
.anycontext-dark .dark\:placeholder\:anycontext-text-stone-400
)::-moz-placeholder {
--tw-text-opacity: 1;
color: rgb(168 162 158 / var(--tw-text-opacity));
}
:is(
.anycontext-dark .dark\:placeholder\:anycontext-text-stone-400
)::placeholder {
--tw-text-opacity: 1;
color: rgb(168 162 158 / var(--tw-text-opacity));
}
:is(.anycontext-dark .dark\:hover\:anycontext-bg-red-900\/90:hover) {
background-color: rgb(127 29 29 / 0.9);
}
:is(.anycontext-dark .dark\:hover\:anycontext-bg-stone-50\/90:hover) {
background-color: rgb(250 250 249 / 0.9);
}
:is(.anycontext-dark .dark\:hover\:anycontext-bg-stone-800:hover) {
--tw-bg-opacity: 1;
background-color: rgb(41 37 36 / var(--tw-bg-opacity));
}
:is(.anycontext-dark .dark\:hover\:anycontext-bg-stone-800\/80:hover) {
background-color: rgb(41 37 36 / 0.8);
}
:is(.anycontext-dark .dark\:hover\:anycontext-text-stone-50:hover) {
--tw-text-opacity: 1;
color: rgb(250 250 249 / var(--tw-text-opacity));
}
:is(
.anycontext-dark
.dark\:focus-visible\:anycontext-ring-stone-300:focus-visible
) {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(214 211 209 / var(--tw-ring-opacity));
}

View file

@ -68,6 +68,7 @@
font-weight: 600; /* font-semibold */
font-size: 1.25rem; /* text-xl */
color: black;
}
.anycontext-icon {

View file

@ -1,13 +1,25 @@
import { defineConfig } from 'vite'
import { Plugin, defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { crx } from '@crxjs/vite-plugin'
import manifest from './manifest.json'
import path from 'path'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const viteManifestHackIssue846: Plugin & { renderCrxManifest: (manifest: unknown, bundle: any) => void } = {
// Workaround from https://github.com/crxjs/chrome-extension-tools/issues/846#issuecomment-1861880919.
name: 'manifestHackIssue846',
renderCrxManifest(_manifest, bundle) {
bundle['manifest.json'] = bundle['.vite/manifest.json']
bundle['manifest.json'].fileName = 'manifest.json'
delete bundle['.vite/manifest.json']
},
}
export default defineConfig({
plugins: [
react(),
crx({ manifest }),
viteManifestHackIssue846
],
resolve: {
alias: {

View file

@ -1 +1 @@
zeBMgIwALetIL8b61U2zt
SZ4Exe9taZXwJYa8jYKvH

View file

@ -1,27 +1,27 @@
{
"pages": {
"/not-found": [
"static/chunks/webpack-21d4c12a2c3dbbeb.js",
"static/chunks/30b509c0-d7721ce4b2012053.js",
"static/chunks/25-2f3c60275645c813.js",
"static/chunks/webpack-3b758eebb48586bf.js",
"static/chunks/30b509c0-b94fb950b6812fcf.js",
"static/chunks/25-2a3c58bcd630d074.js",
"static/chunks/main-app-8b951cccf46caf8d.js",
"static/chunks/app/not-found-dbc30055295c6650.js"
],
"/layout": [
"static/chunks/webpack-21d4c12a2c3dbbeb.js",
"static/chunks/30b509c0-d7721ce4b2012053.js",
"static/chunks/25-2f3c60275645c813.js",
"static/chunks/webpack-3b758eebb48586bf.js",
"static/chunks/30b509c0-b94fb950b6812fcf.js",
"static/chunks/25-2a3c58bcd630d074.js",
"static/chunks/main-app-8b951cccf46caf8d.js",
"static/css/121145655fed7988.css",
"static/chunks/app/layout-50c1233b87ae0cb3.js"
"static/css/4af939cd84b2835e.css",
"static/chunks/app/layout-1db733038de334b4.js"
],
"/page": [
"static/chunks/webpack-21d4c12a2c3dbbeb.js",
"static/chunks/30b509c0-d7721ce4b2012053.js",
"static/chunks/25-2f3c60275645c813.js",
"static/chunks/webpack-3b758eebb48586bf.js",
"static/chunks/30b509c0-b94fb950b6812fcf.js",
"static/chunks/25-2a3c58bcd630d074.js",
"static/chunks/main-app-8b951cccf46caf8d.js",
"static/chunks/555-34d63392644740e6.js",
"static/chunks/app/page-79713ef49f738bb2.js"
"static/chunks/574-80ad862bf72ba403.js",
"static/chunks/app/page-1e365ec6a3d98fff.js"
]
}
}

View file

@ -1 +1 @@
{"/favicon.ico/route":"/favicon.ico","/api/[...nextauth]/route":"/api/[...nextauth]","/_not-found":"/_not-found","/api/me/route":"/api/me","/api/hello/route":"/api/hello","/page":"/","/api/query/route":"/api/query","/api/store/route":"/api/store"}
{"/favicon.ico/route":"/favicon.ico","/api/[...nextauth]/route":"/api/[...nextauth]","/api/ask/route":"/api/ask","/_not-found":"/_not-found","/api/query/route":"/api/query","/api/store/route":"/api/store","/api/me/route":"/api/me","/page":"/"}

View file

@ -5,26 +5,26 @@
"devFiles": [],
"ampDevFiles": [],
"lowPriorityFiles": [
"static/zeBMgIwALetIL8b61U2zt/_buildManifest.js",
"static/zeBMgIwALetIL8b61U2zt/_ssgManifest.js"
"static/SZ4Exe9taZXwJYa8jYKvH/_buildManifest.js",
"static/SZ4Exe9taZXwJYa8jYKvH/_ssgManifest.js"
],
"rootMainFiles": [
"static/chunks/webpack-21d4c12a2c3dbbeb.js",
"static/chunks/30b509c0-d7721ce4b2012053.js",
"static/chunks/25-2f3c60275645c813.js",
"static/chunks/webpack-3b758eebb48586bf.js",
"static/chunks/30b509c0-b94fb950b6812fcf.js",
"static/chunks/25-2a3c58bcd630d074.js",
"static/chunks/main-app-8b951cccf46caf8d.js"
],
"pages": {
"/_app": [
"static/chunks/webpack-21d4c12a2c3dbbeb.js",
"static/chunks/webpack-3b758eebb48586bf.js",
"static/chunks/framework-c25027af42eb8c45.js",
"static/chunks/main-6d41ecb2c0d95e72.js",
"static/chunks/main-51d5b132fa0042d3.js",
"static/chunks/pages/_app-508d387925ef2fa9.js"
],
"/_error": [
"static/chunks/webpack-21d4c12a2c3dbbeb.js",
"static/chunks/webpack-3b758eebb48586bf.js",
"static/chunks/framework-c25027af42eb8c45.js",
"static/chunks/main-6d41ecb2c0d95e72.js",
"static/chunks/main-51d5b132fa0042d3.js",
"static/chunks/pages/_error-e16765248192e4ee.js"
]
},

View file

@ -1 +1 @@
self.__PRERENDER_MANIFEST="{\"version\":4,\"routes\":{\"/favicon.ico\":{\"initialHeaders\":{\"cache-control\":\"public, max-age=0, must-revalidate\",\"content-type\":\"image/x-icon\",\"x-next-cache-tags\":\"_N_T_/layout,_N_T_/favicon.ico/layout,_N_T_/favicon.ico/route,_N_T_/favicon.ico\"},\"experimentalBypassFor\":[{\"type\":\"header\",\"key\":\"Next-Action\"},{\"type\":\"header\",\"key\":\"content-type\",\"value\":\"multipart/form-data\"}],\"initialRevalidateSeconds\":false,\"srcRoute\":\"/favicon.ico\",\"dataRoute\":null}},\"dynamicRoutes\":{},\"notFoundRoutes\":[],\"preview\":{\"previewModeId\":\"eec28fc4f2627ee504c2d62bbb16d4ad\",\"previewModeSigningKey\":\"265546bc15c8e2692a8be9d81b334c1d10bb0142715bec1eee5f391f2f96368b\",\"previewModeEncryptionKey\":\"55691b1366fd02a8a2a2eeb29636ad652cf2b769507cebe7b52f51e05bea6c9e\"}}"
self.__PRERENDER_MANIFEST="{\"version\":4,\"routes\":{\"/favicon.ico\":{\"initialHeaders\":{\"cache-control\":\"public, max-age=0, must-revalidate\",\"content-type\":\"image/x-icon\",\"x-next-cache-tags\":\"_N_T_/layout,_N_T_/favicon.ico/layout,_N_T_/favicon.ico/route,_N_T_/favicon.ico\"},\"experimentalBypassFor\":[{\"type\":\"header\",\"key\":\"Next-Action\"},{\"type\":\"header\",\"key\":\"content-type\",\"value\":\"multipart/form-data\"}],\"initialRevalidateSeconds\":false,\"srcRoute\":\"/favicon.ico\",\"dataRoute\":null}},\"dynamicRoutes\":{},\"notFoundRoutes\":[],\"preview\":{\"previewModeId\":\"e4ba113888e03f26a4eee0b8ca6ece6c\",\"previewModeSigningKey\":\"7047ed031db73a9e82a9147c13f2e0d97adb2c07d3cd7eb4972bcb5e9612f01f\",\"previewModeEncryptionKey\":\"5c96a6033288dd1855a88d98fe5296fa66465a1ee6c67d572017105dacbacccb\"}}"

View file

@ -1 +1 @@
{"version":4,"routes":{"/favicon.ico":{"initialHeaders":{"cache-control":"public, max-age=0, must-revalidate","content-type":"image/x-icon","x-next-cache-tags":"_N_T_/layout,_N_T_/favicon.ico/layout,_N_T_/favicon.ico/route,_N_T_/favicon.ico"},"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data"}],"initialRevalidateSeconds":false,"srcRoute":"/favicon.ico","dataRoute":null}},"dynamicRoutes":{},"notFoundRoutes":[],"preview":{"previewModeId":"eec28fc4f2627ee504c2d62bbb16d4ad","previewModeSigningKey":"265546bc15c8e2692a8be9d81b334c1d10bb0142715bec1eee5f391f2f96368b","previewModeEncryptionKey":"55691b1366fd02a8a2a2eeb29636ad652cf2b769507cebe7b52f51e05bea6c9e"}}
{"version":4,"routes":{"/favicon.ico":{"initialHeaders":{"cache-control":"public, max-age=0, must-revalidate","content-type":"image/x-icon","x-next-cache-tags":"_N_T_/layout,_N_T_/favicon.ico/layout,_N_T_/favicon.ico/route,_N_T_/favicon.ico"},"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data"}],"initialRevalidateSeconds":false,"srcRoute":"/favicon.ico","dataRoute":null}},"dynamicRoutes":{},"notFoundRoutes":[],"preview":{"previewModeId":"e4ba113888e03f26a4eee0b8ca6ece6c","previewModeSigningKey":"7047ed031db73a9e82a9147c13f2e0d97adb2c07d3cd7eb4972bcb5e9612f01f","previewModeEncryptionKey":"5c96a6033288dd1855a88d98fe5296fa66465a1ee6c67d572017105dacbacccb"}}

View file

@ -1,10 +1,10 @@
{
"/favicon.ico/route": "app/favicon.ico/route.js",
"/api/[...nextauth]/route": "app/api/[...nextauth]/route.js",
"/api/ask/route": "app/api/ask/route.js",
"/_not-found": "app/_not-found.js",
"/api/me/route": "app/api/me/route.js",
"/api/hello/route": "app/api/hello/route.js",
"/page": "app/page.js",
"/api/query/route": "app/api/query/route.js",
"/api/store/route": "app/api/store/route.js"
"/api/store/route": "app/api/store/route.js",
"/api/me/route": "app/api/me/route.js",
"/page": "app/page.js"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"version":1,"functions":{"/api/[...nextauth]":{},"/_not-found":{},"/api/query":{},"/api/hello":{},"/api/me":{},"/api/store":{},"/":{}}}
{"version":1,"functions":{"/api/[...nextauth]":{},"/_not-found":{},"/api/ask":{},"/api/store":{},"/":{},"/api/query":{},"/api/me":{}}}

View file

@ -1 +1 @@
self.__BUILD_MANIFEST={polyfillFiles:["static/chunks/polyfills-c67a75d1b6f99dc8.js"],devFiles:[],ampDevFiles:[],lowPriorityFiles:["static/zeBMgIwALetIL8b61U2zt/_buildManifest.js","static/zeBMgIwALetIL8b61U2zt/_ssgManifest.js"],rootMainFiles:["static/chunks/webpack-21d4c12a2c3dbbeb.js","static/chunks/30b509c0-d7721ce4b2012053.js","static/chunks/25-2f3c60275645c813.js","static/chunks/main-app-8b951cccf46caf8d.js"],pages:{"/_app":["static/chunks/webpack-21d4c12a2c3dbbeb.js","static/chunks/framework-c25027af42eb8c45.js","static/chunks/main-6d41ecb2c0d95e72.js","static/chunks/pages/_app-508d387925ef2fa9.js"],"/_error":["static/chunks/webpack-21d4c12a2c3dbbeb.js","static/chunks/framework-c25027af42eb8c45.js","static/chunks/main-6d41ecb2c0d95e72.js","static/chunks/pages/_error-e16765248192e4ee.js"]},ampFirstPages:[]};
self.__BUILD_MANIFEST={polyfillFiles:["static/chunks/polyfills-c67a75d1b6f99dc8.js"],devFiles:[],ampDevFiles:[],lowPriorityFiles:["static/SZ4Exe9taZXwJYa8jYKvH/_buildManifest.js","static/SZ4Exe9taZXwJYa8jYKvH/_ssgManifest.js"],rootMainFiles:["static/chunks/webpack-3b758eebb48586bf.js","static/chunks/30b509c0-b94fb950b6812fcf.js","static/chunks/25-2a3c58bcd630d074.js","static/chunks/main-app-8b951cccf46caf8d.js"],pages:{"/_app":["static/chunks/webpack-3b758eebb48586bf.js","static/chunks/framework-c25027af42eb8c45.js","static/chunks/main-51d5b132fa0042d3.js","static/chunks/pages/_app-508d387925ef2fa9.js"],"/_error":["static/chunks/webpack-3b758eebb48586bf.js","static/chunks/framework-c25027af42eb8c45.js","static/chunks/main-51d5b132fa0042d3.js","static/chunks/pages/_error-e16765248192e4ee.js"]},ampFirstPages:[]};

View file

@ -22,6 +22,26 @@
"wasm": [],
"assets": []
},
"/api/ask/route": {
"files": [
"server/middleware-build-manifest.js",
"server/middleware-react-loadable-manifest.js",
"server/next-font-manifest.js",
"prerender-manifest.js",
"server/edge-runtime-webpack.js",
"server/app/api/ask/route.js"
],
"name": "app/api/ask/route",
"page": "/api/ask/route",
"matchers": [
{
"regexp": "^/api/ask$",
"originalSource": "/api/ask"
}
],
"wasm": [],
"assets": []
},
"/_not-found": {
"files": [
"server/server-reference-manifest.js",
@ -44,68 +64,6 @@
"wasm": [],
"assets": []
},
"/api/me/route": {
"files": [
"server/middleware-build-manifest.js",
"server/middleware-react-loadable-manifest.js",
"server/next-font-manifest.js",
"prerender-manifest.js",
"server/edge-runtime-webpack.js",
"server/app/api/me/route.js"
],
"name": "app/api/me/route",
"page": "/api/me/route",
"matchers": [
{
"regexp": "^/api/me$",
"originalSource": "/api/me"
}
],
"wasm": [],
"assets": []
},
"/api/hello/route": {
"files": [
"server/middleware-build-manifest.js",
"server/middleware-react-loadable-manifest.js",
"server/next-font-manifest.js",
"prerender-manifest.js",
"server/edge-runtime-webpack.js",
"server/app/api/hello/route.js"
],
"name": "app/api/hello/route",
"page": "/api/hello/route",
"matchers": [
{
"regexp": "^/api/hello$",
"originalSource": "/api/hello"
}
],
"wasm": [],
"assets": []
},
"/page": {
"files": [
"server/server-reference-manifest.js",
"server/app/page_client-reference-manifest.js",
"server/middleware-build-manifest.js",
"server/middleware-react-loadable-manifest.js",
"server/next-font-manifest.js",
"prerender-manifest.js",
"server/edge-runtime-webpack.js",
"server/app/page.js"
],
"name": "app/page",
"page": "/page",
"matchers": [
{
"regexp": "^/$",
"originalSource": "/"
}
],
"wasm": [],
"assets": []
},
"/api/query/route": {
"files": [
"server/middleware-build-manifest.js",
@ -145,6 +103,48 @@
],
"wasm": [],
"assets": []
},
"/api/me/route": {
"files": [
"server/middleware-build-manifest.js",
"server/middleware-react-loadable-manifest.js",
"server/next-font-manifest.js",
"prerender-manifest.js",
"server/edge-runtime-webpack.js",
"server/app/api/me/route.js"
],
"name": "app/api/me/route",
"page": "/api/me/route",
"matchers": [
{
"regexp": "^/api/me$",
"originalSource": "/api/me"
}
],
"wasm": [],
"assets": []
},
"/page": {
"files": [
"server/server-reference-manifest.js",
"server/app/page_client-reference-manifest.js",
"server/middleware-build-manifest.js",
"server/middleware-react-loadable-manifest.js",
"server/next-font-manifest.js",
"prerender-manifest.js",
"server/edge-runtime-webpack.js",
"server/app/page.js"
],
"name": "app/page",
"page": "/page",
"matchers": [
{
"regexp": "^/$",
"originalSource": "/"
}
],
"wasm": [],
"assets": []
}
},
"version": 2

View file

@ -1 +1 @@
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>500: Internal Server Error</title><meta name="next-head-count" content="3"/><noscript data-n-css=""></noscript><script defer="" crossorigin="" nomodule="" src="/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="/_next/static/chunks/webpack-21d4c12a2c3dbbeb.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/framework-c25027af42eb8c45.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/main-6d41ecb2c0d95e72.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/pages/_app-508d387925ef2fa9.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/pages/_error-e16765248192e4ee.js" defer="" crossorigin=""></script><script src="/_next/static/zeBMgIwALetIL8b61U2zt/_buildManifest.js" defer="" crossorigin=""></script><script src="/_next/static/zeBMgIwALetIL8b61U2zt/_ssgManifest.js" defer="" crossorigin=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json" crossorigin="">{"props":{"pageProps":{"statusCode":500}},"page":"/_error","query":{},"buildId":"zeBMgIwALetIL8b61U2zt","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>500: Internal Server Error</title><meta name="next-head-count" content="3"/><noscript data-n-css=""></noscript><script defer="" crossorigin="" nomodule="" src="/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js"></script><script src="/_next/static/chunks/webpack-3b758eebb48586bf.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/framework-c25027af42eb8c45.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/main-51d5b132fa0042d3.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/pages/_app-508d387925ef2fa9.js" defer="" crossorigin=""></script><script src="/_next/static/chunks/pages/_error-e16765248192e4ee.js" defer="" crossorigin=""></script><script src="/_next/static/SZ4Exe9taZXwJYa8jYKvH/_buildManifest.js" defer="" crossorigin=""></script><script src="/_next/static/SZ4Exe9taZXwJYa8jYKvH/_ssgManifest.js" defer="" crossorigin=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json" crossorigin="">{"props":{"pageProps":{"statusCode":500}},"page":"/_error","query":{},"buildId":"SZ4Exe9taZXwJYa8jYKvH","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>

View file

@ -1 +1 @@
self.__RSC_SERVER_MANIFEST="{\"node\":{},\"edge\":{},\"encryptionKey\":\"jC38kDpo53s1Ff6OtApSOund+QoMdB73vPnuTeph7WE=\"}"
self.__RSC_SERVER_MANIFEST="{\"node\":{},\"edge\":{},\"encryptionKey\":\"6HacWHHCotXxM5Rb1Gn4nq4dxcgTOeE9p7T5IGYQPSY=\"}"

View file

@ -1 +1 @@
{"node":{},"edge":{},"encryptionKey":"jC38kDpo53s1Ff6OtApSOund+QoMdB73vPnuTeph7WE="}
{"node":{},"edge":{},"encryptionKey":"6HacWHHCotXxM5Rb1Gn4nq4dxcgTOeE9p7T5IGYQPSY="}

File diff suppressed because one or more lines are too long

View file

@ -13,7 +13,9 @@
},
"dependencies": {
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="299" height="186" fill="none"><g clip-path="url(#a)"><rect width="299" height="186" fill="#EAEAEA" rx="3"/><g stroke="#C9C9C9" opacity=".5"><path d="m71.594 205.646 224-224M95.173 205.646l224-224M118.752 205.646l224-224M142.331 205.646l224-224M165.91 205.646l224-224M189.489 205.646l224-224M213.067 205.646l224-224M236.646 205.646l224-224M260.226 205.646l224-224M283.804 205.646l224-224M-211.354 205.646l224-224M-187.774 205.646l223.999-224M-164.196 205.646l224-224M-140.617 205.646l224-224M-117.038 205.646l224-224M-93.459 205.646l224-224M-69.88 205.646l224-224M-46.301 205.646l224-224M-22.722 205.646l224-224M.857 205.646l224-224M24.436 205.646l224-224M48.015 205.646l224-224M272.723 205.646l-224-224M249.144 205.646l-224-224M225.564 205.646l-224-224M201.985 205.646l-224-224M178.407 205.646l-224-224M154.828 205.646l-224-224M131.249 205.646l-224-224M107.67 205.646l-224-224M84.09 205.646l-224-224M60.511 205.646l-224-224M36.933 205.646l-224-224M13.354 205.646l-224-224M508.512 205.646l-224-224M484.933 205.646l-224-224M461.354 205.646l-224-224M437.775 205.646l-224-224M414.196 205.646l-224-224M390.617 205.646l-224-224M367.038 205.646l-224-224M343.459 205.646l-224-224M319.88 205.646l-224-224M296.3 205.646l-224-224"/></g><g stroke="#C9C9C9" opacity=".5"><path d="m83.594 205.646 224-224M107.173 205.646l224-224M130.752 205.646l224-224M154.331 205.646l224-224M177.91 205.646l224-224M201.489 205.646l224-224M225.067 205.646l224-224M248.646 205.646l224-224M272.226 205.646l224-224M295.804 205.646l224-224M-199.354 205.646l224-224M-175.774 205.646l223.999-224M-152.196 205.646l224-224M-128.617 205.646l224-224M-105.038 205.646l224-224M-81.459 205.646l224-224M-57.88 205.646l224-224M-34.301 205.646l224-224M-10.722 205.646l224-224M12.857 205.646l224-224M36.436 205.646l224-224M60.015 205.646l224-224M284.723 205.646l-224-224M261.144 205.646l-224-224M237.564 205.646l-224-224M213.985 205.646l-224-224M190.407 205.646l-224-224M166.828 205.646l-224-224M143.249 205.646l-224-224M119.67 205.646l-224-224M96.09 205.646l-224-224M72.511 205.646l-224-224M48.933 205.646l-224-224M25.354 205.646l-224-224M520.512 205.646l-224-224M496.933 205.646l-224-224M473.354 205.646l-224-224M449.775 205.646l-224-224M426.196 205.646l-224-224M402.617 205.646l-224-224M379.038 205.646l-224-224M355.459 205.646l-224-224M331.88 205.646l-224-224M308.3 205.646l-224-224"/></g></g><defs><clipPath id="a"><rect width="299" height="186" fill="#fff" rx="3"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="299" height="186" fill="none"><g clip-path="url(#a)"><rect width="299" height="186" fill="#EAEAEA" rx="3"/><g stroke="#C9C9C9" opacity=".5"><path d="m71.594 205.646 224-224M95.173 205.646l224-224M118.752 205.646l224-224M142.331 205.646l224-224M165.91 205.646l224-224M189.489 205.646l224-224M213.067 205.646l224-224M236.646 205.646l224-224M260.226 205.646l224-224M283.804 205.646l224-224M-211.354 205.646l224-224M-187.774 205.646l223.999-224M-164.196 205.646l224-224M-140.617 205.646l224-224M-117.038 205.646l224-224M-93.459 205.646l224-224M-69.88 205.646l224-224M-46.301 205.646l224-224M-22.722 205.646l224-224M.857 205.646l224-224M24.436 205.646l224-224M48.015 205.646l224-224M272.723 205.646l-224-224M249.144 205.646l-224-224M225.564 205.646l-224-224M201.985 205.646l-224-224M178.407 205.646l-224-224M154.828 205.646l-224-224M131.249 205.646l-224-224M107.67 205.646l-224-224M84.09 205.646l-224-224M60.511 205.646l-224-224M36.933 205.646l-224-224M13.354 205.646l-224-224M508.512 205.646l-224-224M484.933 205.646l-224-224M461.354 205.646l-224-224M437.775 205.646l-224-224M414.196 205.646l-224-224M390.617 205.646l-224-224M367.038 205.646l-224-224M343.459 205.646l-224-224M319.88 205.646l-224-224M296.3 205.646l-224-224"/></g><g stroke="#C9C9C9" opacity=".5"><path d="m83.594 205.646 224-224M107.173 205.646l224-224M130.752 205.646l224-224M154.331 205.646l224-224M177.91 205.646l224-224M201.489 205.646l224-224M225.067 205.646l224-224M248.646 205.646l224-224M272.226 205.646l224-224M295.804 205.646l224-224M-199.354 205.646l224-224M-175.774 205.646l223.999-224M-152.196 205.646l224-224M-128.617 205.646l224-224M-105.038 205.646l224-224M-81.459 205.646l224-224M-57.88 205.646l224-224M-34.301 205.646l224-224M-10.722 205.646l224-224M12.857 205.646l224-224M36.436 205.646l224-224M60.015 205.646l224-224M284.723 205.646l-224-224M261.144 205.646l-224-224M237.564 205.646l-224-224M213.985 205.646l-224-224M190.407 205.646l-224-224M166.828 205.646l-224-224M143.249 205.646l-224-224M119.67 205.646l-224-224M96.09 205.646l-224-224M72.511 205.646l-224-224M48.933 205.646l-224-224M25.354 205.646l-224-224M520.512 205.646l-224-224M496.933 205.646l-224-224M473.354 205.646l-224-224M449.775 205.646l-224-224M426.196 205.646l-224-224M402.617 205.646l-224-224M379.038 205.646l-224-224M355.459 205.646l-224-224M331.88 205.646l-224-224M308.3 205.646l-224-224"/></g></g><defs><clipPath id="a"><rect width="299" height="186" fill="#fff" rx="3"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -24,22 +24,26 @@ export async function GET(req: NextRequest) {
const session = {session: sessionData[0], user: user[0]}
const query = new URL(req.url).searchParams.get("q");
const sourcesOnly = new URL(req.url).searchParams.get("sourcesOnly") ?? "false";
if (!query) {
return new Response(JSON.stringify({ message: "Invalid query" }), { status: 400 });
}
const resp = await fetch(`https://cf-ai-backend.dhravya.workers.dev/query?q=${query}&user=${session.user.email ?? session.user.name}`, {
const resp = await fetch(`https://cf-ai-backend.dhravya.workers.dev/query?q=${query}&user=${session.user.email ?? session.user.name}&sourcesOnly=${sourcesOnly}`, {
headers: {
"X-Custom-Auth-Key": env.BACKEND_SECURITY_KEY,
}
})
const data = await resp.json()
if (resp.status !== 200) {
return new Response(JSON.stringify({ message: "Error in CF function", error: data }), { status: resp.status });
if (resp.status !== 200 || !resp.ok) {
const errorData = await resp.json();
return new Response(JSON.stringify({ message: "Error in CF function", error: errorData }), { status: resp.status });
}
return new Response(JSON.stringify({ message: "OK", data: data }), { status: 200 });
// Stream the response back to the client
const { readable, writable } = new TransformStream();
resp && resp.body!.pipeTo(writable);
return new Response(readable, { status: 200 });
}

View file

@ -80,6 +80,8 @@ export async function POST(req: NextRequest) {
const _ = await res.text();
console.log(_)
if (res.status !== 200) {
return NextResponse.json({ message: "Error", error: "Error in CF function" }, { status: 500 });
}

View file

@ -1,16 +1,135 @@
import Image from "next/image";
import MessagePoster from "./MessagePoster";
import { cookies } from "next/headers";
import { Component } from "@/components/component";
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { CardContent, Card } from '@/components/ui/card';
import { db } from '@/server/db';
import {
sessions,
storedContent,
userStoredContent,
users,
} from '@/server/db/schema';
import { eq, inArray } from 'drizzle-orm';
import { cookies, headers } from 'next/headers';
import { redirect } from 'next/navigation';
import { Label } from '@/components/ui/label';
import Image from 'next/image';
import QueryAI from '@/components/QueryAI';
export const runtime = 'edge';
export default function Home() {
const token = cookies().get('next-auth.session-token')?.value ?? cookies().get("__Secure-authjs.session-token")?.value ?? cookies().get("authjs.session-token")?.value
export default async function Home() {
const token =
cookies().get('next-auth.session-token')?.value ??
cookies().get('__Secure-authjs.session-token')?.value ??
cookies().get('authjs.session-token')?.value ??
headers().get('Authorization')?.replace('Bearer ', '');
if (!token) {
return redirect('/api/auth/signin');
}
const session = await db
.select()
.from(sessions)
.where(eq(sessions.sessionToken, token!));
if (!session || session.length === 0) {
return redirect('/api/auth/signin');
}
const userContent = await db
.select()
.from(userStoredContent)
.where(eq(userStoredContent.userId, session[0].userId));
const userData = await db
.select()
.from(users)
.where(eq(users.id, session[0].userId))
.limit(1);
if (!userData || userData.length === 0) {
return redirect('/api/auth/signin');
}
const listOfContent =
userContent.map((content) => content.contentId).length > 0
? userContent.map((content) => content.contentId)
: [1];
const posts = await db
.select()
.from(storedContent)
.where(inArray(storedContent.id, listOfContent));
return (
<main>
{token && <MessagePoster jwt={token} />}
<Component/>
</main>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col items-center">
<div className="flex flex-col mt-16">
<div className="flex flex-col md:flex-row gap-4">
<Image
className="rounded-2xl"
src="/logo.png"
width={120}
height={120}
alt="logo"
/>
<div className="mt-4 text-gray-400 max-w-md">
<h1 className="text-xl font-bold text-white">SuperMemory</h1>
Remember that one thing you read a while ago? We got you covered.
Add the extension, click a button and I'll remember it for you.{' '}
<a
href="https://github.com/dhravyashah/anycontext"
target="_blank"
rel="noreferrer"
className="text-sky-500"
>
Get the Extension
</a>
</div>
</div>
</div>
<QueryAI />
{/* TODO: LABEL THE WEBSITES USING A CLASSIFICATION MODEL */}
{/* <nav className="flex space-x-2 my-4">
<Badge variant="secondary">Technology (2)</Badge>
<Badge variant="secondary">Business & Finance (1)</Badge>
<Badge variant="secondary">Education & Career (1)</Badge>
</nav> */}
<main className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mt-16">
{posts.reverse().map((post) => (
<a
href={post.url}
target="_blank"
rel="noreferrer"
className="hover:scale-105 ease-in-out transition-transform duration-300"
>
<Card className="w-full">
<img
alt="Not found"
className="w-full h-48 object-cover rounded-md"
height="200"
src={
post.image && post.image !== 'Image not found'
? post.image
: '/placeholder.svg'
}
style={{
aspectRatio: '300/200',
objectFit: 'cover',
}}
width="300"
/>
<CardContent>
<h3 className="text-lg font-semibold mt-4">{post.title}</h3>
<p className="text-sm text-gray-600">{post.baseUrl}</p>
<p className="text-sm">{post.description}</p>
</CardContent>
</Card>
</a>
))}
</main>
</div>
);
}

View file

@ -1,87 +0,0 @@
import { Input } from '@/components/ui/input';
import { AvatarImage, AvatarFallback, Avatar } from '@/components/ui/avatar';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { CardContent, CardFooter, Card } from '@/components/ui/card';
import { db } from '@/server/db';
import { storedContent } from '@/server/db/schema';
import { parser } from 'html-metadata-parser';
import { getMetaData } from '@/server/helpers';
export async function Component() {
// const posts = await db.query.storedContent.findMany({
// where: (users, { eq }) => eq(users.id, 1),
// });
return (
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<header className="flex justify-between items-center py-6">
<div className="flex items-center space-x-4">
<FlagIcon className="h-8 w-8 text-blue-500" />
<h1 className="text-3xl font-bold text-gray-900">zenfetch</h1>
</div>
<div className="flex items-center space-x-4">
<Input className="w-72" placeholder="Search..." />
<Avatar>
<AvatarImage
alt="User avatar"
src="/placeholder.svg?height=32&width=32"
/>
<AvatarFallback>U</AvatarFallback>
</Avatar>
<Button className="whitespace-nowrap" variant="outline">
Chat with AI
</Button>
</div>
</header>
<nav className="flex space-x-2 my-4">
<Badge variant="secondary">Technology (2)</Badge>
<Badge variant="secondary">Business & Finance (1)</Badge>
<Badge variant="secondary">Education & Career (1)</Badge>
</nav>
<main className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* {metadata.map((post) => (
<Card className="w-full">
<img
alt="Hard drive"
className="w-full h-48 object-cover"
height="200"
src={post.image}
style={{
aspectRatio: '300/200',
objectFit: 'cover',
}}
width="300"
/>
<CardContent>
<h3 className="text-lg font-semibold mt-4">{post.title}</h3>
<p className="text-sm text-gray-600">{post.baseUrl}</p>
<p className="text-sm">{post.description}</p>
</CardContent>
</Card>
))} */}
</main>
</div>
);
}
function FlagIcon(props: React.SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z" />
<line x1="4" x2="4" y1="22" y2="15" />
</svg>
);
}

View file

@ -10,16 +10,15 @@ export const {
} = NextAuth({
secret: env.NEXTAUTH_SECRET,
trustHost: true,
// callbacks: {
// session: ({ session, token }) => ({
// ...session,
// user: {
// // ...session.user,
// id: token.id as string,
// token: token,
// },
// })
// },
callbacks: {
session: ({ session, token, user }) => ({
...session,
user: {
...session.user,
id: user.id
},
})
},
adapter: DrizzleAdapter(db),
providers: [
Google({

View file

@ -42,6 +42,7 @@
"@langchain/cloudflare": "^0.0.3",
"@t3-oss/env-nextjs": "^0.9.2",
"@types/chrome": "^0.0.261",
"ai": "^3.0.0",
"better-sqlite3": "^9.4.3",
"dotenv-cli": "^7.3.0",
"drizzle-orm": "^0.29.4",
@ -50,6 +51,8 @@
"html-metadata": "^1.7.1",
"html-metadata-parser": "^2.0.4",
"lucide-react": "^0.343.0",
"next-auth": "beta"
"next-auth": "beta",
"react-markdown": "^9.0.1",
"remark-gfm": "^4.0.0"
}
}