diff --git a/.replit b/.replit deleted file mode 100644 index 9851b6a..0000000 --- a/.replit +++ /dev/null @@ -1,47 +0,0 @@ -modules = ["nodejs-20"] -[agent] -expertMode = true -stack = "BEST_EFFORT_FALLBACK" - -[nix] -channel = "stable-25_05" - -[workflows] -runButton = "Project" - -[[workflows.workflow]] -name = "Project" -mode = "parallel" -author = "agent" - -[[workflows.workflow.tasks]] -task = "workflow.run" -args = "Start application" - -[[workflows.workflow]] -name = "Start application" -author = "agent" - -[[workflows.workflow.tasks]] -task = "shell.exec" -args = "bash start.sh" -waitForPort = 5000 - -[workflows.workflow.metadata] -outputType = "webview" - -[[ports]] -localPort = 3001 -externalPort = 3001 - -[[ports]] -localPort = 5000 -externalPort = 80 - -[[ports]] -localPort = 5001 -externalPort = 3002 - -[deployment] -deploymentTarget = "autoscale" -run = ["bash", "start.sh"] diff --git a/Assets/Ala-Alab Lettering.png b/Assets/Ala-Alab Lettering.png new file mode 100644 index 0000000..cd8a9af Binary files /dev/null and b/Assets/Ala-Alab Lettering.png differ diff --git a/Assets/Ala-Alab Logo.png b/Assets/Ala-Alab Logo.png new file mode 100644 index 0000000..33201d3 Binary files /dev/null and b/Assets/Ala-Alab Logo.png differ diff --git a/Assets/Team Logo Clean.png b/Assets/Team Logo Clean.png new file mode 100644 index 0000000..36e1af0 Binary files /dev/null and b/Assets/Team Logo Clean.png differ diff --git a/Assets/Team Logo Worded.png b/Assets/Team Logo Worded.png new file mode 100644 index 0000000..31dfb08 Binary files /dev/null and b/Assets/Team Logo Worded.png differ diff --git a/DEV_PLAN.md b/DEV_PLAN.md new file mode 100644 index 0000000..8cb3a2a --- /dev/null +++ b/DEV_PLAN.md @@ -0,0 +1,6 @@ +- [x] Step 0: Connectivity check complete +- [x] Step 1: /docs subfolders created +- [x] Step 2: Folders moved (or references fixed) into /docs +- [x] Step 3: /docs/README.md written +- [ ] Step 4: root README.md updated +- [ ] Step 5: local smoke test run diff --git a/Google Studio Output 2/LinkManager.tsx b/Google Studio Output 2/LinkManager.tsx new file mode 100644 index 0000000..91e2088 --- /dev/null +++ b/Google Studio Output 2/LinkManager.tsx @@ -0,0 +1,33 @@ +@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap'); +@import "tailwindcss"; + +@theme { + --font-sans: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif; + --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace; +} + +body { + font-family: var(--font-sans); + background-color: #fafafa; + color: #171717; + overflow-x: hidden; +} + +/* Custom scrollbar styling for a cleaner look */ +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background: #e5e5e5; + border-radius: 3px; +} + +::-webkit-scrollbar-thumb:hover { + background: #d4d4d4; +} diff --git a/Google Studio Output 2/PromptBuilder.tsx b/Google Studio Output 2/PromptBuilder.tsx new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/Google Studio Output 2/PromptBuilder.tsx @@ -0,0 +1 @@ +* diff --git a/Google Studio Output 2/README (1).md b/Google Studio Output 2/README (1).md new file mode 100644 index 0000000..d70127f --- /dev/null +++ b/Google Studio Output 2/README (1).md @@ -0,0 +1,20 @@ +
+GHBanner +
+ +# Run and deploy your AI Studio app + +This contains everything you need to run your app locally. + +View your app in AI Studio: https://ai.studio/apps/bfff2907-a29c-4f47-bbda-75ec49933072 + +## Run Locally + +**Prerequisites:** Node.js + + +1. Install dependencies: + `npm install` +2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key +3. Run the app: + `npm run dev` diff --git a/Google Studio Output 2/SyncedPacketReceiver.tsx b/Google Studio Output 2/SyncedPacketReceiver.tsx new file mode 100644 index 0000000..b1d0de3 --- /dev/null +++ b/Google Studio Output 2/SyncedPacketReceiver.tsx @@ -0,0 +1,240 @@ +import React, { useState } from 'react'; +import { useTabBridge } from './hooks/useTabBridge'; +import TabConnector from './components/TabConnector'; +import TranscriptParser from './components/TranscriptParser'; +import PromptBuilder from './components/PromptBuilder'; +import SyncedPacketReceiver from './components/SyncedPacketReceiver'; +import SyncHistoryPanel from './components/SyncHistoryPanel'; +import LinkManager from './components/LinkManager'; +import { ChatSession, SyncPacket } from './types'; +import { compilePortablePrompt } from './utils/templates'; +import { Sparkles, ArrowRightLeft, HelpCircle, BookOpen, AlertCircle, Laptop, Settings, ArrowRight, Clipboard } from 'lucide-react'; + +export default function App() { + const { + tabId, + tabName, + setTabName, + tabRole, + setTabRole, + connectedTabs, + incomingPacket, + setIncomingPacket, + beamSession, + sentHistory, + receivedHistory, + clearHistory, + triggerDiscovery, + } = useTabBridge(); + + const [currentSession, setCurrentSession] = useState(null); + const [showHowTo, setShowHowTo] = useState(true); + + // Handle accepting a beamed packet + const handleAcceptPacket = (packet: SyncPacket) => { + setCurrentSession(packet.session); + setIncomingPacket(null); + }; + + // Handle selecting a history packet + const handleSelectHistoryPacket = (packet: SyncPacket) => { + setCurrentSession(packet.session); + }; + + return ( +
+ {/* Header */} +
+
+
+
+ ⇄ +
+
+

+ LLM Chat Bridge + + v1.2 client-only + +

+

+ Seamless prompt portability and zero-API cross-tab synchronizer +

+
+
+ + {/* Network Banner */} +
+
+ + + Tabs Connected:{' '} + {connectedTabs.length + 1} + +
+
+
+
+ + {/* Main Workspace Grid */} +
+ {/* Onboarding walkthrough */} + {showHowTo && ( +
+
+ +
+
+
+ +
+
+

+ Seamless Conversational Portability +

+

+ Have you ever started a deep conversation in Gemini, only to reach its context limit, and want to continue it directly in Claude (or vice versa) without copy-pasting individual messages manually? +

+ + {/* Visual Steps */} +
+
+

+ 1 + Copy & Extract +

+

+ Press Ctrl+A then Ctrl+C on your Gemini page and paste it into the Parser. We'll strip out all the UI fluff, buttons, and ratings automatically! +

+
+
+

+ 2 + Arrange Tabs +

+

+ Click "Open Second Tab" and position the two tabs side-by-side. Make one the Gemini Companion and the other the Claude Companion. +

+
+
+

+ 3 + Beam Context +

+

+ Press "Beam" on Tab A. Your formatted, ready-to-paste context flies instantly over to Tab B. One-click copy, paste it in Claude, and pick up right where you left off! +

+
+
+
+
+
+ )} + +
+ {/* Left Column: Network & History Settings (3 cols) */} +
+ + + { + setCurrentSession(session); + }} + onCopyPrompt={(templateId = 'continuity') => { + if (!currentSession) return; + const compiled = compilePortablePrompt( + currentSession.messages, + currentSession.source, + templateId + ); + navigator.clipboard.writeText(compiled); + }} + /> + + + + {/* Zero API Architecture Guide */} +
+

+ + Security & Specs +

+

+ This utility operates entirely on client-side sandbox protocols using the HTML5 BroadcastChannel API. +

+
    +
  • No server-side data collection or storage
  • +
  • No docker orchestrators, API keys, or databases needed
  • +
  • Your raw prompts and conversations remain completely local
  • +
  • Works offline under standard browser origins
  • +
+
+
+ + {/* Right Columns: Parser & Prompt Compiler Workspace (8 cols) */} +
+ {/* Step 1: Parser */} +
+ +
+ + {/* Step 2: Customizer & Beamer */} +
+ +
+
+
+
+ + {/* Floating Synced packet handler */} + setIncomingPacket(null)} + /> + + {/* Footer */} +
+
+

© 2026 LLM Chat Bridge. Made securely with zero external APIs.

+
+ +
+
+
+
+ ); +} + diff --git a/Google Studio Output 2/TranscriptParser.tsx b/Google Studio Output 2/TranscriptParser.tsx new file mode 100644 index 0000000..b170b15 --- /dev/null +++ b/Google Studio Output 2/TranscriptParser.tsx @@ -0,0 +1,223 @@ +import React, { useState, useEffect } from 'react'; +import { ChatSession, PromptTemplate, LLMPlatform } from '../types'; +import { PROMPT_TEMPLATES, compilePortablePrompt } from '../utils/templates'; +import { Send, Copy, Check, FileCheck, Sparkles, Sliders, ExternalLink, HelpCircle, MessageSquare } from 'lucide-react'; +import { motion } from 'motion/react'; + +interface PromptBuilderProps { + session: ChatSession | null; + beamSession: (session: ChatSession, targetRole?: string, note?: string) => boolean; + connectedCount: number; +} + +export default function PromptBuilder({ + session, + beamSession, + connectedCount, +}: PromptBuilderProps) { + const [selectedTemplateId, setSelectedTemplateId] = useState('continuity'); + const [compiledPrompt, setCompiledPrompt] = useState(''); + const [copied, setCopied] = useState(false); + const [beaming, setBeaming] = useState(false); + const [beamTarget, setBeamTarget] = useState('neutral'); + const [beamNote, setBeamNote] = useState(''); + + // Recompile whenever session or selected template change + useEffect(() => { + if (!session) { + setCompiledPrompt(''); + return; + } + const compiled = compilePortablePrompt(session.messages, session.source, selectedTemplateId); + setCompiledPrompt(compiled); + }, [session, selectedTemplateId]); + + const handleCopy = () => { + if (!compiledPrompt) return; + navigator.clipboard.writeText(compiledPrompt); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }; + + const handleBeam = () => { + if (!session) return; + setBeaming(true); + + // Beam using the hook function + const success = beamSession(session, beamTarget === 'neutral' ? undefined : beamTarget, beamNote); + + setTimeout(() => { + setBeaming(false); + setBeamNote(''); + }, 1200); + }; + + // Estimate words and approximate tokens + const wordCount = compiledPrompt ? compiledPrompt.split(/\s+/).filter(Boolean).length : 0; + const charCount = compiledPrompt ? compiledPrompt.length : 0; + const estTokens = Math.ceil(charCount / 3.8); + + const selectedTemplate = PROMPT_TEMPLATES.find((t) => t.id === selectedTemplateId); + + return ( +
+
+

+ + 2. Customize & Transport +

+

+ Wrap your parsed conversation and beam it instantly to other tabs or Claude +

+
+ + {!session ? ( +
+ +

Waiting for parsed chat...

+

+ Once you paste and extract a conversation in step 1, your portability formatting and tab-beaming controls will activate here. +

+
+ ) : ( +
+ {/* Template presets */} +
+ +
+ {PROMPT_TEMPLATES.map((tpl) => ( + + ))} +
+
+ + {/* Compiled text block */} +
+
+ + + CONSOLIDATED CONTEXT PROMPT + +
+ {charCount.toLocaleString()} chars + ~{estTokens.toLocaleString()} tokens +
+
+ +