diff --git a/MrBeast_Data_Brain.md b/MrBeast_Data_Brain.md deleted file mode 100644 index c39d368..0000000 --- a/MrBeast_Data_Brain.md +++ /dev/null @@ -1,133 +0,0 @@ -# MrBeast Premium Brain Pack (최신 10개 영상 정밀 스캔) - -> 이 문서는 Agent University (A.U) 전용 마크다운 형식으로 추출된 최고 등급 크리에이터 데이터셋입니다. -> 영상 데이터, 성과 지표(조회수, 좋아요 수, 댓글 수), 상세 설명, 태그, 풀스크립트가 담겨있습니다. - -## 🎬 [Can a Window Stop a Wrecking Ball?](https://youtu.be/6W_841xoprg) - -![Thumbnail](https://i.ytimg.com/vi/6W_841xoprg/maxresdefault.jpg) - -### 📊 [핵심 성과 지표 (KPI)] -- **Video ID:** `6W_841xoprg` -- **게시일:** `2026-04-14` -- **조회수:** `23,124,614 회` -- **좋아요 수:** `569,581 개` -- **댓글 수:** `6,236 개` - -### 🏷️ [태그 필드 (SEO Tags)] -태그 없음 - -### 📝 [디스크립션 (Description)] -```text - -``` - -### 🔊 [대본 파일 풀-스크립트 (Voice Transcript)] -> **(이 스크립트를 분석하여 알고리즘 방어율을 측정하세요.)** - -DROP THE WRECKING BALL. THAT DIDN'T WORK. LET'S TRY WOOD. DROP IT. OH, THAT WAS AWESOME. YOU KNOW WHAT'S MORE DURABLE than wood? Bricks. DROP IT. 1 2 3 OH! OH, IT WENT THROUGH ALL OF THEM. SUBSCRIBE IF YOU THINK THE NEXT ONE WILL STOP IT. DROP IT. OH! OH, IT WAS SO CLOSE. OH, RIGHT AWAY wrecking ball. - ---- - -## 🎬 [Don’t Eat The Spicy Yoshi Egg](https://youtu.be/VIJLIo5yT1I) - -![Thumbnail](https://i.ytimg.com/vi/VIJLIo5yT1I/maxresdefault.jpg) - -### 📊 [핵심 성과 지표 (KPI)] -- **Video ID:** `VIJLIo5yT1I` -- **게시일:** `2026-04-10` -- **조회수:** `60,378,398 회` -- **좋아요 수:** `1,160,164 개` -- **댓글 수:** `9,445 개` - -### 🏷️ [태그 필드 (SEO Tags)] -태그 없음 - -### 📝 [디스크립션 (Description)] -```text - -``` - -### 🔊 [대본 파일 풀-스크립트 (Voice Transcript)] -> **(이 스크립트를 분석하여 알고리즘 방어율을 측정하세요.)** - -Don't eat the spicy egg. I'm going to guess this isn't spicy. Okay, I passed. I passed. Why are you looking at me? I don't know the answer. Mhm, we're good. Oh, jeez. Okay, well Woah, woah, woah. Got to do that one. Woah, you're good. Mhm, this one. Oh, that was a big bite. >> That's good. These are Yoshi eggs that we made in collaboration with the new Super Mario Galaxy movie. This one doesn't look spicy. >> Are you sure? Mhm, okay. We passed. Oh, he passed. We're good. We're good. Just fully commit. [music] Woah, what? There's a one in three? Oh, no. Commit. Just commit. Yeah. So, what the heck? 50/50 chance. Oh, before I bite it, if you want to try these Yoshi eggs for yourself, they're [music] available at these retailers. Oh, uh all the hot. >> Yes. >> My homeboy. - ---- - -## 🎬 [$1 or Mystery Vial?](https://youtu.be/uNu6XEPTy5g) - -![Thumbnail](https://i.ytimg.com/vi/uNu6XEPTy5g/maxresdefault.jpg) - -### 📊 [핵심 성과 지표 (KPI)] -- **Video ID:** `uNu6XEPTy5g` -- **게시일:** `2026-04-07` -- **조회수:** `31,384,634 회` -- **좋아요 수:** `983,497 개` -- **댓글 수:** `12,067 개` - -### 🏷️ [태그 필드 (SEO Tags)] -태그 없음 - -### 📝 [디스크립션 (Description)] -```text - -``` - -### 🔊 [대본 파일 풀-스크립트 (Voice Transcript)] -> **(이 스크립트를 분석하여 알고리즘 방어율을 측정하세요.)** - -$1 or drink what's in this vial? Uh, I'll take the dollar. >> $100 or drink what's in this vial? >> What's in the vial? >> Compound V. Give it a try. Okay. Oh. Oh. Wow, that was quick to kick in. I want to see what else the other vials do. Okay, let's see what powers he gets. This is Compound V. Oh. Wait. Wait. Wait. Wait. That >> [screaming] >> Massive shout out to Vought Homelander for sending me so much Compound V. Actually, want to try one myself. What's up, bro? What are you doing here? Okay, try touching you real quick. Wait, I want to just see if you turn around. Look up. - ---- - -## 🎬 [50 Streamers Fight for $1,000,000](https://youtu.be/DXVHmGoCTco) - -![Thumbnail](https://i.ytimg.com/vi/DXVHmGoCTco/maxresdefault.jpg) - -### 📊 [핵심 성과 지표 (KPI)] -- **Video ID:** `DXVHmGoCTco` -- **게시일:** `2026-04-04` -- **조회수:** `87,487,275 회` -- **좋아요 수:** `2,305,643 개` -- **댓글 수:** `154,354 개` - -### 🏷️ [태그 필드 (SEO Tags)] -태그 없음 - -### 📝 [디스크립션 (Description)] -```text -i can't believe we got all these streamers together in one place lol - -Shopify empowers creators every single day to be entrepreneurs, founders, and CEOs. Now it’s your turn. Go to https://www.shopify.com/mrbeast to start your business today. - -Tomorrow for the livestream, join the chat and make sure your instagram or twitter handle is viewable on your YouTube bio, so I can contact you if you win! - -New Merch - https://mrbeast.store - -Check out Viewstats! - https://www.viewstats.com/ - -SUBSCRIBE OR I TAKE YOUR DOG -╔═╦╗╔╦╗╔═╦═╦╦╦╦╗╔═╗ -║╚╣║║║╚╣╚╣╔╣╔╣║╚╣═╣ -╠╗║╚╝║║╠╗║╚╣║║║║║═╣ -╚═╩══╩═╩═╩═╩╝╚╩═╩═╝ - -For any questions or inquiries regarding this video, please reach out to chucky@mrbeastbusiness.com - ----------------------------------------------------------------- -follow all of these or i will kick you -• Facebook - https://www.facebook.com/MrBeast/ -• Twitter - https://twitter.com/MrBeast -• Instagram - https://www.instagram.com/mrbeast -• Im Hiring! - https://www.mrbeastjobs.com/ --------------------------------------------------------------------- -``` - -### 🔊 [대본 파일 풀-스크립트 (Voice Transcript)] -> **(이 스크립트를 분석하여 알고리즘 방어율을 측정하세요.)** - - 여기 세계 최고의 스트리머 여기 세계 최고의 스트리머 50명을 이 큐브 안에 가둬놨습니다 50명을 이 큐브 안에 가둬놨습니다 마지막까지 남는 사람이 100만 달러를 가져갑니다! 마지막까지 남는 사람이 100만 달러를 가져갑니다! 여기 모인 사람들은 진짜 현존하는 여기 모인 사람들은 진짜 현존하는 월드클래스 스트리머들입니다 월드클래스 스트리머들입니다 끝까지 버티는 한 명이 상금 전부 가져갑니다 끝까지 버티는 한 명이 상금 전부 가져갑니다 같이 가는 거다 끝까지 같이 가, 알았지? 같이 가는 거다 끝까지 같이 가, 알았지? -여기 스페인어 쓰는 팀인가? -어, 여기 다 친구야 -여기 스페인어 쓰는 팀인가? -어, 여기 다 친구야 이건 완전 전략 싸움이야 나 지금 다 할 수 있어 이건 완전 전략 싸움이야 나 지금 다 할 수 있어 바닥에서 트워킹하라고 하면 할 거야 바닥에서 트워킹하라고 하면 할 거야 난 싫은데 난 싫은데 -아니, 그냥 시키면 하겠단 거지 -제발 안 해주면 좋겠어 -아니, 그냥 시키면 하겠단 거지 - -... (나머지 대본 내용 생략) -``` \ No newline at end of file diff --git a/README.md b/README.md index d725665..93aae1b 100644 --- a/README.md +++ b/README.md @@ -1,171 +1 @@ -

- Connect AI Logo -

- -

Connect AI

- -

- 100% Local · 100% Offline · 100% Free
- Your AI coding agent that lives entirely on your machine. -

- -

- version - license - platform - engine -

- ---- - -## Overview - -Connect AI is an **agentic AI coding assistant** that runs entirely on your local machine — no cloud, no API keys, no data leaves your computer. It reads your project, creates files, edits code, manages directories, and executes terminal commands — all through natural conversation. - -Built for **VS Code**, **Cursor**, and **Antigravity**. - ---- - -## ⚡ Agent Capabilities - -Connect AI doesn't just answer questions — it **acts**. Seven built-in agent actions give it full control over your development environment: - -| Action | Description | -|:--|:--| -| **📄 Create Files** | Generates new files and directories in your workspace | -| **✏️ Edit Files** | Finds and replaces specific code in existing files | -| **🗑️ Delete Files** | Removes files and folders | -| **📖 Read Files** | Reads any file in your workspace to understand context | -| **📂 Browse Directories** | Lists contents of any subdirectory | -| **🖥️ Run Terminal Commands** | Executes CLI commands (install, build, run, deploy) | -| **🧠 Second Brain** | Queries your personal knowledge base (GitHub-synced) | - -### How It Works - -``` -You: "React로 카운터 앱 만들어줘" - -Connect AI: - ✅ 생성: src/App.jsx - ✅ 생성: src/index.js - ✅ 생성: index.html - 🖥️ 실행: npm install react react-dom -``` - -All files are created **directly in your local workspace** — no copy-paste needed. - ---- - -## 🎨 Interface Features - -- **🔄 Real-time Streaming** — Token-by-token response rendering -- **⬛ Abort (Stop)** — Interrupt generation mid-stream -- **🔄 재생성** — Regenerate any response with one click -- **📎 Multimodal Input** — Paste images (Cmd+V) or attach files (+) -- **💡 Syntax Highlighting** — Cinematic code block rendering -- **⏱️ Thinking Bar** — Visual latency indicator during inference - ---- - -## 📥 Installation - -### Option 1: VSIX (Recommended) - -1. Download the latest `.vsix` from [Releases](https://github.com/wonseokjung/connect-ai/releases) -2. Open VS Code / Cursor / Antigravity -3. `Cmd+Shift+P` → **Extensions: Install from VSIX** → Select the file - -### Option 2: Build from Source - -```bash -git clone https://github.com/wonseokjung/connect-ai.git -cd connect-ai -npm install -npm run compile -npx vsce package -``` - ---- - -## ⚙️ Engine Setup - -Connect AI requires a local AI engine. Choose one: - -### Ollama (Recommended for Beginners) - -```bash -# 1. Install -brew install ollama - -# 2. Pull a model -ollama pull gemma3 - -# 3. Done — Ollama runs automatically in the background -``` - -### LM Studio (Recommended for Apple Silicon) - -1. Download from [lmstudio.ai](https://lmstudio.ai/) -2. Search and download a model (e.g., Gemma 4, Llama 3.1) -3. Go to **Developer tab** (`<>` icon) → **Start Server** -4. Ensure it shows `http://127.0.0.1:1234` -5. In Connect AI: **⚙️ Settings** → Select **LM Studio** - -> **💡 Tip:** In LM Studio, set **Context Length** to 8192+ for best results. - -### Supported Models - -| Model | Size | Best For | -|:--|:--|:--| -| Gemma 4 E2B | 4.4 GB | Vision + Code (Recommended) | -| Gemma 3 | 3-5 GB | Fast general coding | -| Llama 3.1 | 4-8 GB | Multi-language support | -| Qwen 3 | 4-8 GB | Strong instruction following | -| DeepSeek Coder | 6-16 GB | Code-heavy tasks | - ---- - -## 🧠 Second Brain (Knowledge Base) - -Sync a GitHub repository as your personal knowledge base. Connect AI will reference it when answering questions. - -1. Click **🧠** button in the chat header -2. Enter your GitHub repo URL -3. Toggle knowledge mode **ON** - -Your documents are stored locally at `~/.connect-ai-brain/`. - ---- - -## 🔒 Privacy - -- **Zero cloud dependency** — No internet required after setup -- **Zero data collection** — All code stays on your machine -- **Zero telemetry** — No analytics, no tracking - -Your code never leaves your computer. Period. - ---- - -## 🛠️ Configuration - -Access settings via the **⚙️** button in the chat panel: - -| Setting | Default | Description | -|:--|:--|:--| -| Engine | Ollama | Ollama or LM Studio | -| Temperature | 0.7 | Response creativity (0.0–1.0) | -| Top P | 0.9 | Nucleus sampling | -| Top K | 40 | Token selection range | - ---- - -## License - -MIT — Free to use, modify, and distribute. - ---- - -

- Designed & Developed by EZERAI × Connect AI -

+built for antigravity diff --git a/check.js b/check.js deleted file mode 100644 index aa8dd30..0000000 --- a/check.js +++ /dev/null @@ -1,619 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.activate = activate; -exports.deactivate = deactivate; -const vscode = require("vscode"); -const axios_1 = require("axios"); -const fs = require("fs"); -const path = require("path"); -// ============================================================ -// Connect AI LAB — Full Agentic Local AI for VS Code -// 100% Offline · File Create · File Edit · Terminal · Multi-file Context -// ============================================================ -// Settings are read from VS Code configuration (File > Preferences > Settings) -function getConfig() { - const cfg = vscode.workspace.getConfiguration('connectAiLab'); - return { - ollamaBase: cfg.get('ollamaUrl', 'http://127.0.0.1:11434'), - defaultModel: cfg.get('defaultModel', 'gemma4:e2b'), - maxTreeFiles: cfg.get('maxContextFiles', 200), - timeout: cfg.get('requestTimeout', 300) * 1000, - }; -} -const EXCLUDED_DIRS = new Set([ - 'node_modules', '.git', '.vscode', 'out', 'dist', 'build', - '.next', '.cache', '__pycache__', '.DS_Store', 'coverage', - '.turbo', '.nuxt', '.output', 'vendor', 'target' -]); -const MAX_CONTEXT_SIZE = 40_000; // chars -const SYSTEM_PROMPT = `You are "Connect AI LAB", a premium agentic AI coding assistant running 100% offline on the user's machine. - -You have THREE powerful agent actions. Use them whenever appropriate: - -━━━ ACTION 1: CREATE NEW FILES ━━━ - -file content here - - -━━━ ACTION 2: EDIT EXISTING FILES ━━━ - -exact text to find in the file -replacement text - -You can have multiple / pairs inside one block. - -━━━ ACTION 3: RUN TERMINAL COMMANDS ━━━ -npm install express - -RULES: -1. ALWAYS respond in the same language the user uses. -2. Use agent actions automatically when the user's request requires creating, editing files, or running commands. -3. Outside of action blocks, briefly explain what you did. -4. For code that is just for explanation (not to be saved), use standard markdown code fences. -5. Be concise, professional, and helpful. -6. When editing files, the text must EXACTLY match existing content in the file.`; -// ============================================================ -// Extension Activation -// ============================================================ -function activate(context) { - console.log('Connect AI LAB extension activated.'); - const provider = new SidebarChatProvider(context.extensionUri, context); - context.subscriptions.push(vscode.window.registerWebviewViewProvider('local-ai-chat-view', provider, { - webviewOptions: { retainContextWhenHidden: true } - })); - // New Chat - context.subscriptions.push(vscode.commands.registerCommand('connect-ai-lab.newChat', () => { - provider.resetChat(); - })); - // Export Chat as Markdown - context.subscriptions.push(vscode.commands.registerCommand('connect-ai-lab.exportChat', async () => { - await provider.exportChat(); - })); - // Focus Chat Input (Cmd+L) - context.subscriptions.push(vscode.commands.registerCommand('connect-ai-lab.focusChat', () => { - provider.focusInput(); - })); - // Explain Selected Code (right-click menu) - context.subscriptions.push(vscode.commands.registerCommand('connect-ai-lab.explainSelection', () => { - const editor = vscode.window.activeTextEditor; - if (!editor) { - return; - } - const selection = editor.document.getText(editor.selection); - if (selection.trim()) { - provider.sendPromptFromExtension(`이 코드를 분석하고 설명해줘:\n\`\`\`\n${selection}\n\`\`\``); - } - })); -} -function deactivate() { } -// ============================================================ -// Sidebar Chat Provider -// ============================================================ -class SidebarChatProvider { - _extensionUri; - _view; - _chatHistory = []; - _terminal; - _ctx; - // 대화 표시용 (system prompt 제외, 유저에게 보여줄 것만 저장) - _displayMessages = []; - constructor(_extensionUri, ctx) { - this._extensionUri = _extensionUri; - this._ctx = ctx; - this._restoreHistory(); - } - /** 저장된 대화 기록 복원 */ - _restoreHistory() { - const saved = this._ctx.workspaceState.get('chatState'); - if (saved && saved.chat && saved.chat.length > 1) { - this._chatHistory = saved.chat; - this._displayMessages = saved.display || []; - } - else { - this._initHistory(); - } - } - /** 대화 기록 영구 저장 (워크스페이스 단위) */ - _saveHistory() { - this._ctx.workspaceState.update('chatState', { - chat: this._chatHistory, - display: this._displayMessages - }); - } - _initHistory() { - this._chatHistory = [{ role: 'system', content: SYSTEM_PROMPT }]; - this._displayMessages = []; - } - resetChat() { - this._initHistory(); - this._saveHistory(); - if (this._view) { - this._view.webview.postMessage({ type: 'clearChat' }); - } - vscode.window.showInformationMessage('Connect AI LAB: 새 대화가 시작되었습니다.'); - } - /** 대화를 Markdown 파일로 내보내기 */ - async exportChat() { - if (this._displayMessages.length === 0) { - vscode.window.showWarningMessage('내보낼 대화가 없습니다.'); - return; - } - let md = `# Connect AI LAB — 대화 기록\n\n_${new Date().toLocaleString('ko-KR')}_\n\n---\n\n`; - for (const m of this._displayMessages) { - const label = m.role === 'user' ? '**👤 You**' : '**✦ Connect AI LAB**'; - md += `### ${label}\n\n${m.text}\n\n---\n\n`; - } - const root = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; - if (root) { - const filePath = path.join(root, `chat-export-${Date.now()}.md`); - fs.writeFileSync(filePath, md, 'utf-8'); - const doc = await vscode.workspace.openTextDocument(filePath); - await vscode.window.showTextDocument(doc); - vscode.window.showInformationMessage(`대화가 ${path.basename(filePath)}로 저장되었습니다.`); - } - } - /** 채팅 입력창에 포커스 (Cmd+L) */ - focusInput() { - if (this._view) { - this._view.show?.(true); - this._view.webview.postMessage({ type: 'focusInput' }); - } - } - /** 외부에서 프롬프트 전송 (예: 코드 선택 → 설명) */ - sendPromptFromExtension(prompt) { - if (this._view) { - this._view.show?.(true); - // 약간의 딜레이 후 전송 (뷰가 보이기를 기다림) - setTimeout(() => { - this._view?.webview.postMessage({ type: 'injectPrompt', value: prompt }); - }, 300); - } - } - // -------------------------------------------------------- - // Webview Lifecycle - // -------------------------------------------------------- - resolveWebviewView(webviewView, _context, _token) { - this._view = webviewView; - webviewView.webview.options = { - enableScripts: true, - localResourceRoots: [this._extensionUri], - }; - webviewView.webview.html = this._getHtml(); - webviewView.webview.onDidReceiveMessage(async (msg) => { - switch (msg.type) { - case 'prompt': - await this._handlePrompt(msg.value, msg.model); - break; - case 'getModels': - await this._sendModels(); - break; - case 'newChat': - this.resetChat(); - break; - case 'ready': - // 웹뷰가 준비되면 저장된 대화 기록 복원 - this._restoreDisplayMessages(); - break; - } - }); - } - // -------------------------------------------------------- - // Fetch installed Ollama models - // -------------------------------------------------------- - async _sendModels() { - if (!this._view) { - return; - } - const { ollamaBase, defaultModel } = getConfig(); - try { - const res = await axios_1.default.get(`${ollamaBase}/api/tags`); - const models = res.data.models.map((m) => m.name); - this._view.webview.postMessage({ type: 'modelsList', value: models }); - } - catch { - this._view.webview.postMessage({ type: 'modelsList', value: [defaultModel] }); - } - } - /** 저장된 대화 메시지를 웹뷰에 다시 전송 (복원) */ - _restoreDisplayMessages() { - if (!this._view || this._displayMessages.length === 0) { - return; - } - this._view.webview.postMessage({ - type: 'restoreMessages', - value: this._displayMessages - }); - } - // -------------------------------------------------------- - // Build workspace file tree + read key files - // -------------------------------------------------------- - _getWorkspaceContext() { - const root = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; - if (!root) { - return ''; - } - // --- 1. File tree --- - const lines = []; - let count = 0; - const walk = (dir, prefix) => { - if (count >= getConfig().maxTreeFiles) { - return; - } - let entries; - try { - entries = fs.readdirSync(dir, { withFileTypes: true }); - } - catch { - return; - } - entries.sort((a, b) => { - if (a.isDirectory() && !b.isDirectory()) { - return -1; - } - if (!a.isDirectory() && b.isDirectory()) { - return 1; - } - return a.name.localeCompare(b.name); - }); - for (const entry of entries) { - if (count >= getConfig().maxTreeFiles) { - break; - } - if (EXCLUDED_DIRS.has(entry.name)) { - continue; - } - if (entry.name.startsWith('.') && entry.isDirectory()) { - continue; - } - if (entry.isDirectory()) { - lines.push(`${prefix}📁 ${entry.name}/`); - count++; - walk(path.join(dir, entry.name), prefix + ' '); - } - else { - lines.push(`${prefix}📄 ${entry.name}`); - count++; - } - } - }; - walk(root, ''); - let result = ''; - if (lines.length > 0) { - result += `\n\n[프로젝트 파일 구조]\n${lines.join('\n')}`; - } - // --- 2. Auto-read key project files --- - const keyFiles = [ - 'package.json', 'tsconfig.json', 'vite.config.ts', 'vite.config.js', - 'next.config.js', 'next.config.ts', 'README.md', - 'index.html', 'app.js', 'app.ts', 'main.ts', 'main.js', - 'src/index.ts', 'src/index.js', 'src/App.tsx', 'src/App.jsx', - 'src/main.ts', 'src/main.js' - ]; - let totalRead = 0; - const MAX_AUTO_READ = 15_000; // chars total - for (const kf of keyFiles) { - if (totalRead >= MAX_AUTO_READ) { - break; - } - const abs = path.join(root, kf); - if (fs.existsSync(abs)) { - try { - const content = fs.readFileSync(abs, 'utf-8'); - if (content.length < 5000) { - result += `\n\n[파일 내용: ${kf}]\n\`\`\`\n${content}\n\`\`\``; - totalRead += content.length; - } - } - catch { /* skip */ } - } - } - return result; - } - // -------------------------------------------------------- - // Handle user prompt → Ollama → agent actions → response - // -------------------------------------------------------- - async _handlePrompt(prompt, modelName) { - if (!this._view) { - return; - } - try { - // 1. Context: active editor content - const editor = vscode.window.activeTextEditor; - let contextBlock = ''; - if (editor && editor.document.uri.scheme === 'file') { - const text = editor.document.getText(); - const name = path.basename(editor.document.fileName); - if (text.trim().length > 0 && text.length < MAX_CONTEXT_SIZE) { - contextBlock = `\n\n[Currently open file: ${name}]\n\`\`\`\n${text}\n\`\`\``; - } - } - // 2. Context: workspace file tree + key file contents - const workspaceCtx = this._getWorkspaceContext(); - // 3. Push user message - this._chatHistory.push({ - role: 'user', - content: prompt + contextBlock + workspaceCtx - }); - // 저장용: 유저 메시지 기록 (프롬프트만, 컨텍스트 제외) - this._displayMessages.push({ text: prompt, role: 'user' }); - // 4. Call Ollama - const { ollamaBase, defaultModel, timeout } = getConfig(); - const response = await axios_1.default.post(`${ollamaBase}/api/chat`, { - model: modelName || defaultModel, - messages: this._chatHistory, - stream: false, - }, { timeout }); - const aiMessage = response.data.message.content; - this._chatHistory.push({ role: 'assistant', content: aiMessage }); - // 5. Execute agent actions - const report = this._executeActions(aiMessage); - // 6. Send to webview - let output = aiMessage; - if (report.length > 0) { - output += `\n\n---\n📦 **에이전트 작업 결과**\n${report.join('\n')}`; - } - this._view.webview.postMessage({ type: 'response', value: output }); - // 저장용: AI 응답 기록 - this._displayMessages.push({ text: output, role: 'ai' }); - this._saveHistory(); - } - catch (error) { - const errMsg = error.code === 'ECONNREFUSED' - ? '⚠️ Ollama 서버에 연결할 수 없습니다.\n터미널에서 `ollama serve`를 실행해주세요.' - : `⚠️ 오류: ${error.message}`; - this._view.webview.postMessage({ type: 'error', value: errMsg }); - } - } - // -------------------------------------------------------- - // Execute ALL agent actions from AI response - // -------------------------------------------------------- - _executeActions(aiMessage) { - const report = []; - const rootPath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; - if (!rootPath) { - const hasActions = /([\s\S]*?)<\/create_file>/g; - let match; - let firstCreatedFile = ''; - while ((match = createRegex.exec(aiMessage)) !== null) { - const relPath = match[1].trim(); - const content = match[2].replace(/^\n/, ''); // remove leading newline only - try { - const absPath = path.join(rootPath, relPath); - const dir = path.dirname(absPath); - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); - } - fs.writeFileSync(absPath, content, 'utf-8'); - report.push(`✅ 생성: ${relPath}`); - if (!firstCreatedFile) { - firstCreatedFile = absPath; - } - } - catch (err) { - report.push(`❌ 생성 실패: ${relPath} — ${err.message}`); - } - } - // Open first created file - if (firstCreatedFile) { - vscode.window.showTextDocument(vscode.Uri.file(firstCreatedFile), { preview: false }); - } - // ACTION 2: Edit files - const editRegex = /([\s\S]*?)<\/edit_file>/g; - while ((match = editRegex.exec(aiMessage)) !== null) { - const relPath = match[1].trim(); - const body = match[2]; - const absPath = path.join(rootPath, relPath); - if (!fs.existsSync(absPath)) { - report.push(`❌ 편집 실패: ${relPath} — 파일이 존재하지 않습니다.`); - continue; - } - try { - let fileContent = fs.readFileSync(absPath, 'utf-8'); - const findReplaceRegex = /([\s\S]*?)<\/find>\s*([\s\S]*?)<\/replace>/g; - let frMatch; - let editCount = 0; - while ((frMatch = findReplaceRegex.exec(body)) !== null) { - const findText = frMatch[1]; - const replaceText = frMatch[2]; - if (fileContent.includes(findText)) { - fileContent = fileContent.replace(findText, replaceText); - editCount++; - } - else { - report.push(`⚠️ ${relPath}: 일치하는 텍스트를 찾지 못했습니다.`); - } - } - if (editCount > 0) { - fs.writeFileSync(absPath, fileContent, 'utf-8'); - report.push(`✏️ 편집 완료: ${relPath} (${editCount}건 수정)`); - // Open edited file - vscode.window.showTextDocument(vscode.Uri.file(absPath), { preview: false }); - } - } - catch (err) { - report.push(`❌ 편집 실패: ${relPath} — ${err.message}`); - } - } - // ACTION 3: Run commands - const cmdRegex = /([\s\S]*?)<\/run_command>/g; - while ((match = cmdRegex.exec(aiMessage)) !== null) { - const cmd = match[1].trim(); - try { - if (!this._terminal || this._terminal.exitStatus !== undefined) { - this._terminal = vscode.window.createTerminal({ - name: '🚀 Connect AI LAB', - cwd: rootPath - }); - } - this._terminal.show(); - this._terminal.sendText(cmd); - report.push(`🖥️ 실행: ${cmd}`); - } - catch (err) { - report.push(`❌ 명령 실패: ${cmd} — ${err.message}`); - } - } - // Show notification - const successCount = report.filter(r => r.startsWith('✅') || r.startsWith('✏️') || r.startsWith('🖥️')).length; - if (successCount > 0) { - vscode.window.showInformationMessage(`Connect AI LAB: ${successCount}개 에이전트 작업 완료!`); - } - return report; - } - // ============================================================ - // Webview HTML — Premium UI v2 - // ============================================================ - // ============================================================ - // Webview HTML — Premium UI v2 (Zero External Dependencies) - // ============================================================ - _getHtml() { - return ` - -Connect AI LAB - -
Connect AI LAB
-
-
- -
Connect AI LAB
-
100% \ub85c\uceec \u00b7 100% \uc624\ud504\ub77c\uc778 \u00b7 100% \ubb34\ub8cc
\ud504\ub85c\uc81d\ud2b8\ub97c \uc774\ud574\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uace0, \uc2e4\ud589\ud569\ub2c8\ub2e4.
-
\ud83d\udcc1 \ud30c\uc77c \uc0dd\uc131
\u270f\ufe0f \ucf54\ub4dc \ud3b8\uc9d1
\ud83d\udda5\ufe0f \ud130\ubbf8\ub110
\ud83d\udd0d \ubd84\uc11d
-
- - - - -
-
- -
-`; - } -} -//# sourceMappingURL=extension.js.map \ No newline at end of file diff --git a/ehalsh.txt b/ehalsh.txt deleted file mode 100644 index e69de29..0000000 diff --git a/fix.js b/fix.js deleted file mode 100644 index dbf9158..0000000 --- a/fix.js +++ /dev/null @@ -1,14 +0,0 @@ -const fs = require('fs'); -let code = fs.readFileSync('src/extension.ts', 'utf8'); -let lines = code.split('\n'); - -const correctCode = ` t=t.replace(/([\\\\s\\\\S]*?)<\\\\/create_file>/g,(_,p,c)=>'
\\ud83d\\udcc1 '+esc(p)+' \\u2014 \\uc790\\ub3d9 \\uc0dd\\uc131\\ub428
'+esc(c)+'
'); - t=t.replace(/([\\\\s\\\\S]*?)<\\\\/edit_file>/g,(_,p,c)=>'
\\u270f\\ufe0f '+esc(p)+' \\u2014 \\ud3b8\\uc9d1\\ub428
'+esc(c)+'
'); - t=t.replace(/([\\\\s\\\\S]*?)<\\\\/run_command>/g,(_,c)=>'
\\u25b6 '+esc(c)+'
'); - t=t.replace(/\\\`\\\`\\\`(\\\\w*)\\\\n([\\\\s\\\\S]*?)\\\`\\\`\\\`/g,(_,lang,c)=>{const l=lang||'code';return '
'+l+'
'+esc(c)+'
'}); - t=t.replace(/\\\`([^\\\`]+)\\\`/g,(_,c)=>''+esc(c)+''); - t=t.replace(/\\\\*\\\\*([^*]+)\\\\*\\\\*/g,'$1');`; - -lines.splice(614, 7, correctCode); -fs.writeFileSync('src/extension.ts', lines.join('\n')); -console.log('Fixed regex lines!'); diff --git a/fix.py b/fix.py deleted file mode 100644 index 6e3d92b..0000000 --- a/fix.py +++ /dev/null @@ -1,26 +0,0 @@ -import sys - -with open('src/extension.ts', 'r') as f: - content = f.read() - -start_idx = content.find('function fmt(t){') -end_idx = content.find('function copyCode(btn)') - -if start_idx != -1 and end_idx != -1: - new_fmt = """function fmt(t){ - // Use simple string templates without regex literals - t=t.replace(new RegExp('([\\\\s\\\\S]*?)<\\\\/create_file>', 'g'),(_,p,c)=>'
\\ud83d\\udcc1 '+esc(p)+' \\u2014 \\uc790\\ub3d9 \\uc0dd\\uc131\\ub428
'+esc(c)+'
'); - t=t.replace(new RegExp('([\\\\s\\\\S]*?)<\\\\/edit_file>', 'g'),(_,p,c)=>'
\\u270f\\ufe0f '+esc(p)+' \\u2014 \\ud3b8\\uc9d1\\ub428
'+esc(c)+'
'); - t=t.replace(new RegExp('([\\\\s\\\\S]*?)<\\\\/run_command>', 'g'),(_,c)=>'
\\u25b6 '+esc(c)+'
'); - t=t.replace(new RegExp('\\\\`\\\\`\\\\`(\\\\w*)\\\\n([\\\\s\\\\S]*?)\\\\`\\\\`\\\\`', 'g'),(_,lang,c)=>{const l=lang||'code';return '
'+l+'
'+esc(c)+'
'}); - t=t.replace(new RegExp('\\\\`([^\\\\`]+)\\\\`', 'g'),(_,c)=>''+esc(c)+''); - t=t.replace(new RegExp('\\\\*\\\\*([^*]+)\\\\*\\\\*', 'g'),'$1'); - return t; -} -""" - new_content = content[:start_idx] + new_fmt + content[end_idx:] - with open('src/extension.ts', 'w') as f: - f.write(new_content) - print("Successfully replaced fmt function.") -else: - print("Could not find start or end index.") diff --git a/fix2.js b/fix2.js deleted file mode 100644 index d03319a..0000000 --- a/fix2.js +++ /dev/null @@ -1,28 +0,0 @@ -const fs = require('fs'); -let code = fs.readFileSync('src/extension.ts', 'utf8'); -let lines = code.split('\n'); - -const correctCode = `function fmt(t){ - // Use new RegExp with string literals to avoid ALL JS parser escaping hell with regex literals containing forward slashes - const createRe = new RegExp('([\\\\\\\\s\\\\\\\\S]*?)<\\\\\\\\/create_file>', 'g'); - const editRe = new RegExp('([\\\\\\\\s\\\\\\\\S]*?)<\\\\\\\\/edit_file>', 'g'); - const runRe = new RegExp('([\\\\\\\\s\\\\\\\\S]*?)<\\\\\\\\/run_command>', 'g'); - const mdCodeRe = new RegExp('\\\\`\\\\`\\\\`(\\\\\\\\w*)\\\\\\\\n([\\\\\\\\s\\\\\\\\S]*?)\\\\`\\\\`\\\\`', 'g'); - const inlineCodeRe = new RegExp('\\\\`([^\\\\`]+)\\\\`', 'g'); - const boldRe = new RegExp('\\\\\\\\*\\\\\\\\*([^*]+)\\\\\\\\*\\\\\\\\*', 'g'); - - t=t.replace(createRe,(_,p,c)=>'
\\ud83d\\udcc1 '+esc(p)+' \\u2014 \\uc790\\ub3d9 \\uc0dd\\uc131\\ub428
'+esc(c)+'
'); - t=t.replace(editRe,(_,p,c)=>'
\\u270f\\ufe0f '+esc(p)+' \\u2014 \\ud3b8\\uc9d1\\ub428
'+esc(c)+'
'); - t=t.replace(runRe,(_,c)=>'
\\u25b6 '+esc(c)+'
'); - t=t.replace(mdCodeRe,(_,lang,c)=>{const l=lang||'code';return '
'+l+'
'+esc(c)+'
'}); - t=t.replace(inlineCodeRe,(_,c)=>''+esc(c)+''); - t=t.replace(boldRe,'$1'); - return t; -}`; - -// Find where function fmt(t){ starts and replace it -let start = lines.findIndex(l => l.includes('function fmt(t){')); -let end = lines.findIndex((l, i) => i > start && l.includes('return t;')) + 1; -lines.splice(start, end - start + 1, correctCode); -fs.writeFileSync('src/extension.ts', lines.join('\n')); -console.log('Fixed regex lines with RegExp approach!'); diff --git a/fix3.py b/fix3.py deleted file mode 100644 index baaf9a0..0000000 --- a/fix3.py +++ /dev/null @@ -1,28 +0,0 @@ -import sys - -with open('src/extension.ts', 'r') as f: - content = f.read() - -start_idx = content.find('function fmt(t){') -end_idx = content.find('function copyCode(btn)') - -if start_idx != -1 and end_idx != -1: - new_fmt = r"""function fmt(t){ - t=t.replace(/([\s\S]*?)<\/create_file>/g,(_,p,c)=>'
\ud83d\udcc1 '+esc(p)+' \u2014 \uc790\ub3d9 \uc0dd\uc131\ub428
'+esc(c)+'
'); - t=t.replace(/([\s\S]*?)<\/edit_file>/g,(_,p,c)=>'
\u270f\ufe0f '+esc(p)+' \u2014 \ud3b8\uc9d1\ub428
'+esc(c)+'
'); - t=t.replace(/([\s\S]*?)<\/run_command>/g,(_,c)=>'
\u25b6 '+esc(c)+'
'); - t=t.replace(/```(\w*)\n([\s\S]*?)```/g,(_,lang,c)=>{const l=lang||'code';return '
'+l+'
'+esc(c)+'
'}); - t=t.replace(/`([^`]+)`/g,(_,c)=>''+esc(c)+''); - t=t.replace(/\*\*([^*]+)\*\*/g,'$1'); - return t; -} -""" - # Fix the double-backslash needed in TS template string: - new_fmt = new_fmt.replace('\\', '\\\\') - - new_content = content[:start_idx] + new_fmt + content[end_idx:] - with open('src/extension.ts', 'w') as f: - f.write(new_content) - print("Successfully replaced fmt function.") -else: - print("Could not find start or end index.") diff --git a/fix4.py b/fix4.py deleted file mode 100644 index 4015657..0000000 --- a/fix4.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys - -with open('src/extension.ts', 'r') as f: - text = f.read() - -start_idx = text.find('function fmt(t){') -end_idx = text.find('function copyCode(btn)') - -# I will avoid ALL slashes and regex literals entirely, and use purely new RegExp("...", "g") syntax with properly escaped backslashes for JS strings. -new_fmt = """function fmt(t){ - t=t.replace(new RegExp('([\\\\\\\\s\\\\\\\\S]*?)<\\\\\\\\/create_file>', 'g'),(_,p,c)=>'
\\uD83D\\uDCC1 '+esc(p)+' \\u2014 \\uC790\\uB3D9 \\uC0DD\\uC131\\uB428
'+esc(c)+'
'); - t=t.replace(new RegExp('([\\\\\\\\s\\\\\\\\S]*?)<\\\\\\\\/edit_file>', 'g'),(_,p,c)=>'
\\u270F\\uFE0F '+esc(p)+' \\u2014 \\uD3B8\\uC9D1\\uB428
'+esc(c)+'
'); - t=t.replace(new RegExp('([\\\\\\\\s\\\\\\\\S]*?)<\\\\\\\\/run_command>', 'g'),(_,c)=>'
\\u25B6 '+esc(c)+'
'); - t=t.replace(new RegExp('\\\\\\\\`\\\\\\\\`\\\\\\\\`(\\\\\\\\w*)\\\\\\\\n([\\\\\\\\s\\\\\\\\S]*?)\\\\\\\\`\\\\\\\\`\\\\\\\\`', 'g'),(_,lang,c)=>{const l=lang||'code';return '
'+l+'
'+esc(c)+'
'}); - t=t.replace(new RegExp('\\\\\\\\`([^\\\\\\\\`]+)\\\\\\\\`', 'g'),(_,c)=>''+esc(c)+''); - t=t.replace(new RegExp('\\\\\\\\*\\\\\\\\*([^*]+)\\\\\\\\*\\\\\\\\*', 'g'),'$1'); - return t; -} -""" - -if start_idx != -1 and end_idx != -1: - text = text[:start_idx] + new_fmt + text[end_idx:] - with open('src/extension.ts', 'w') as f: - f.write(text) - print("Fixed!") diff --git a/fix_final.py b/fix_final.py deleted file mode 100644 index 199a7f2..0000000 --- a/fix_final.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys - -with open('src/extension.ts', 'r') as f: - text = f.read() - -start_idx = text.find('function fmt(t){') -end_idx = text.find('function copyCode(btn)') - -# I will avoid ALL backticks (use \\x60) and slashes and regex literals entirely, and use purely new RegExp("...", "g") syntax with properly escaped backslashes for JS strings. -new_fmt = """function fmt(t){ - t=t.replace(new RegExp('([\\\\s\\\\S]*?)<\\\\/create_file>', 'g'),(_,p,c)=>'
\\uD83D\\uDCC1 '+esc(p)+' \\u2014 \\uC790\\uB3D9 \\uC0DD\\uC131\\uB428
'+esc(c)+'
'); - t=t.replace(new RegExp('([\\\\s\\\\S]*?)<\\\\/edit_file>', 'g'),(_,p,c)=>'
\\u270F\\uFE0F '+esc(p)+' \\u2014 \\uD3B8\\uC9D1\\uB428
'+esc(c)+'
'); - t=t.replace(new RegExp('([\\\\s\\\\S]*?)<\\\\/run_command>', 'g'),(_,c)=>'
\\u25B6 '+esc(c)+'
'); - t=t.replace(new RegExp('\\\\x60\\\\x60\\\\x60(\\\\w*)\\\\n([\\\\s\\\\S]*?)\\\\x60\\\\x60\\\\x60', 'g'),(_,lang,c)=>{const l=lang||'code';return '
'+l+'
'+esc(c)+'
'}); - t=t.replace(new RegExp('\\\\x60([^\\\\x60]+)\\\\x60', 'g'),(_,c)=>''+esc(c)+''); - t=t.replace(new RegExp('\\\\*\\\\*([^*]+)\\\\*\\\\*', 'g'),'$1'); - return t; -} -""" - -if start_idx != -1 and end_idx != -1: - text = text[:start_idx] + new_fmt + text[end_idx:] - with open('src/extension.ts', 'w') as f: - f.write(text) - print("Fixed!") diff --git a/patch.py b/patch.py deleted file mode 100644 index bcf7f9b..0000000 --- a/patch.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys - -with open('src/extension.ts', 'r') as f: - text = f.read() - -# Replace the beginning of " -script_try_end = """} catch(err) { - document.body.innerHTML = '

\u26a0\ufe0f WEBVIEW JS CRASH

' + err.name + ': ' + err.message + '\\n' + err.stack + '
'; -} -""" - -text = text.replace(script_start, script_try_start) -text = text.replace(script_end, script_try_end) - -# Also let's rename the view and extension id to completely bypass any cache or conflicts -text = text.replace("'local-ai-chat-view'", "'connect-ai-lab-v2-view'") - -with open('src/extension.ts', 'w') as f: - f.write(text) - -print("Patch applied.") diff --git a/preview-out.html b/preview-out.html deleted file mode 100644 index 456a364..0000000 --- a/preview-out.html +++ /dev/null @@ -1,140 +0,0 @@ - - -Connect AI LAB - -
Connect AI LAB
-
-
- -
Connect AI LAB
-
100% \ub85c\uceec \u00b7 100% \uc624\ud504\ub77c\uc778 \u00b7 100% \ubb34\ub8cc
\ud504\ub85c\uc81d\ud2b8\ub97c \uc774\ud574\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uace0, \uc2e4\ud589\ud569\ub2c8\ub2e4.
-
\ud83d\udcc1 \ud30c\uc77c \uc0dd\uc131
\u270f\ufe0f \ucf54\ub4dc \ud3b8\uc9d1
\ud83d\udda5\ufe0f \ud130\ubbf8\ub110
\ud83d\udd0d \ubd84\uc11d
-
- - - - -
-
- -
-`; - } -}; -// Annotate the CommonJS export names for ESM import in node: -0 && (module.exports = { - activate, - deactivate -}); -/*! Bundled license information: - -mime-db/index.js: - (*! - * mime-db - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015-2022 Douglas Christopher Wilson - * MIT Licensed - *) - -mime-types/index.js: - (*! - * mime-types - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - *) -*/ diff --git a/test.html b/test.html deleted file mode 100644 index 7650337..0000000 --- a/test.html +++ /dev/null @@ -1,368 +0,0 @@ - - -Connect AI - -
Connect AI
-
-
-
-
- -
Connect AI
-
\uBCF4\uC548 \xB7 \uBE44\uC6A9\uCD5C\uC801\uD654 \xB7 \uC9C0\uC2DD\uC5F0\uACB0
\uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uACE0, \uC2E4\uD589\uD569\uB2C8\uB2E4.
-
-
-
- -
-
-
- \ No newline at end of file diff --git a/test.js b/test.js deleted file mode 100644 index f8ad119..0000000 --- a/test.js +++ /dev/null @@ -1,2 +0,0 @@ -var code = "\nfunction highlight(code,lang){\n let h=esc(code);\n h=h.replace(/(\\/\\/[^\\n]*)/g,'$1');\n h=h.replace(/(#[^\\n]*)/g,'$1');\n h=h.replace(/(\\/\\*[\\s\\S]*?\\*\\/)/g,'$1');\n h=h.replace(/("[^&]*?"|'[^&]*?')/g,'$1');\n h=h.replace(/\\b(function|const|let|var|return|if|else|for|while|class|import|export|from|default|async|await|try|catch|throw|new|this|def|self|print|lambda|yield|with|as|raise|except|finally)\\b/g,'$1');\n h=h.replace(/\\b(\\d+\\.?\\d*)\\b/g,'$1');\n h=h.replace(/\\b(True|False|None|true|false|null|undefined|NaN)\\b/g,'$1');\n h=h.replace(/\\b(String|Number|Boolean|Array|Object|Map|Set|Promise|void|int|float|str|list|dict|tuple)\\b/g,'$1');\n h=h.replace(/([=!<>+\\-*/%|&^~?:]+)/g,'$1');\n}\n"; -console.log(code); diff --git a/test.ts b/test.ts deleted file mode 100644 index 00d6d00..0000000 --- a/test.ts +++ /dev/null @@ -1,15 +0,0 @@ -const code = ` -function highlight(code,lang){ - let h=esc(code); - h=h.replace(/(\\/\\/[^\\n]*)/g,'$1'); - h=h.replace(/(#[^\\n]*)/g,'$1'); - h=h.replace(/(\\/\\*[\\s\\S]*?\\*\\/)/g,'$1'); - h=h.replace(/("[^&]*?"|'[^&]*?')/g,'$1'); - h=h.replace(/\\b(function|const|let|var|return|if|else|for|while|class|import|export|from|default|async|await|try|catch|throw|new|this|def|self|print|lambda|yield|with|as|raise|except|finally)\\b/g,'$1'); - h=h.replace(/\\b(\\d+\\.?\\d*)\\b/g,'$1'); - h=h.replace(/\\b(True|False|None|true|false|null|undefined|NaN)\\b/g,'$1'); - h=h.replace(/\\b(String|Number|Boolean|Array|Object|Map|Set|Promise|void|int|float|str|list|dict|tuple)\\b/g,'$1'); - h=h.replace(/([=!<>+\\-*/%|&^~?:]+)/g,'$1'); -} -`; -console.log(code); diff --git a/test10.js b/test10.js deleted file mode 100644 index 8723fa7..0000000 --- a/test10.js +++ /dev/null @@ -1,9 +0,0 @@ -const templateHTML = ` - -`; -console.log(templateHTML); -const {JSDOM} = require('jsdom'); -try { new JSDOM(templateHTML, {runScripts:'dangerously'}); console.log('JSDOM OK'); } catch(e) { console.error('ERR:', e.message); } diff --git a/test11.js b/test11.js deleted file mode 100644 index ff3b5ca..0000000 --- a/test11.js +++ /dev/null @@ -1,19 +0,0 @@ -const templateHTML = ` - -`; -const {JSDOM} = require('jsdom'); -try { new JSDOM(templateHTML, {runScripts:'dangerously'}); console.log('JSDOM OK'); } catch(e) { console.error('ERR:', e.message); } diff --git a/test12.js b/test12.js deleted file mode 100644 index 93a170a..0000000 --- a/test12.js +++ /dev/null @@ -1,11 +0,0 @@ -const ext = require('./out/extension'); -const fs = require('fs'); -const code = fs.readFileSync('out/extension.js', 'utf8'); -const match = code.match(/_getHtml.*?_getHtml\(\)\s*\{\s*return\s+(`(?:[^`]|\\`)*`);?/m); -if (match) { - const html = eval(match[1]); - const lines = html.split('\n'); - console.log("Total lines:", lines.length); - console.log("Line 50:", lines[49]); - console.log("Line 100:", lines[99]); -} diff --git a/test13.js b/test13.js deleted file mode 100644 index b2eebb3..0000000 --- a/test13.js +++ /dev/null @@ -1,16 +0,0 @@ -const Module = require('module'); -const originalRequire = Module.prototype.require; -Module.prototype.require = function(request) { - if (request === 'vscode') return {}; - return originalRequire.apply(this, arguments); -}; - -const fs = require('fs'); -const code = fs.readFileSync('out/extension.js', 'utf8'); -const match = code.match(/_getHtml.*?([\s\S]*?)<\/html>.*?;/m); -if (match) { - const html = match[1] + ""; - const lines = html.split('\n'); - console.log("Total lines:", lines.length); - // print from line 60 to end -} diff --git a/test14.js b/test14.js deleted file mode 100644 index 497d021..0000000 --- a/test14.js +++ /dev/null @@ -1,14 +0,0 @@ -const ext = require('./out/extension'); -const fs = require('fs'); -const code = fs.readFileSync('out/extension.js', 'utf8'); -const match = code.match(/_getHtml.*?\{\s*return\s+(`(?:[^`]|\\`)*`);/m); -if (match) { - let templateBody = match[1]; - const html = eval(templateBody); - const lines = html.split('\n'); - console.log("Line 92:", lines[91]); - console.log("Line 93:", lines[92]); - console.log("Line 94:", lines[93]); - console.log("Line 95:", lines[94]); - console.log("Line 96:", lines[95]); -} diff --git a/test15.js b/test15.js deleted file mode 100644 index cf26320..0000000 --- a/test15.js +++ /dev/null @@ -1,18 +0,0 @@ -const Module = require('module'); -const originalRequire = Module.prototype.require; -Module.prototype.require = function(request) { - if (request === 'vscode') return {}; - return originalRequire.apply(this, arguments); -}; -const fs = require('fs'); -const code = fs.readFileSync('out/extension.js', 'utf8'); -const match = code.match(/_getHtml.*?_getHtml\(\)\s*\{\s*return\s+(`(?:[^`]|\\`)*`);?/m); -if (match) { - const html = eval(match[1]); - const lines = html.split('\n'); - console.log("Line 92:", lines[91]); - console.log("Line 93:", lines[92]); - console.log("Line 94:", lines[93]); - console.log("Line 95:", lines[94]); - console.log("Line 96:", lines[95]); -} diff --git a/test16.js b/test16.js deleted file mode 100644 index fb642b8..0000000 --- a/test16.js +++ /dev/null @@ -1,8 +0,0 @@ -const fs = require('fs'); -let html = fs.readFileSync('test.html', 'utf8'); -const lines = html.split('\n'); -console.log("Line 92:", lines[91]); -console.log("Line 93:", lines[92]); -console.log("Line 94:", lines[93]); -console.log("Line 95:", lines[94]); -console.log("Line 96:", lines[95]); diff --git a/test17.js b/test17.js deleted file mode 100644 index d9b3d32..0000000 --- a/test17.js +++ /dev/null @@ -1,4 +0,0 @@ -const s = `\\/\\/[^\\n]*`; -console.log("Characters in string:"); -for (let i = 0; i < s.length; i++) console.log(s[i], s.charCodeAt(i)); -console.log("Printed:", s); diff --git a/test18.js b/test18.js deleted file mode 100644 index 5e6cc95..0000000 --- a/test18.js +++ /dev/null @@ -1,8 +0,0 @@ -const templateHTML = ` - -`; -const {JSDOM} = require('jsdom'); -try { new JSDOM(templateHTML, {runScripts:'dangerously'}); console.log('JSDOM OK'); } catch(e) { console.error('ERR:', e.message); } diff --git a/test19.js b/test19.js deleted file mode 100644 index 27ffada..0000000 --- a/test19.js +++ /dev/null @@ -1,20 +0,0 @@ -const templateHTML = ` - -`; -const {JSDOM} = require('jsdom'); -try { new JSDOM(templateHTML, {runScripts:'dangerously'}); console.log('JSDOM OK'); } catch(e) { console.error('ERR:', e.message); } diff --git a/test20.js b/test20.js deleted file mode 100644 index f95a449..0000000 --- a/test20.js +++ /dev/null @@ -1,8 +0,0 @@ -const templateHTML = ` - -`; -const {JSDOM} = require('jsdom'); -try { new JSDOM(templateHTML, {runScripts:'dangerously'}); console.log('JSDOM OK'); } catch(e) { console.error('ERR:', e.message); } diff --git a/test21.js b/test21.js deleted file mode 100644 index beadedc..0000000 --- a/test21.js +++ /dev/null @@ -1,29 +0,0 @@ -var esc = function (s) { return s; }; -function getHtml() { - var pendingFiles = [{ name: 'foo' }]; - var text = 'bar'; - var t = ''; - if ((t.match(/\`\`\`/g) || []).length % 2 !== 0) - t += '\\\\n\`\`\`'; - var h = "var x = 1; // test"; - h = h.replace(new RegExp("(\\\\/\\\\/[^\\\\n]*)", "g"), '$1'); - h = h.replace(new RegExp("(#[^\\\\n]*)", "g"), '$1'); - h = h.replace(new RegExp("(\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)", "g"), '$1'); - h = h.replace(/("[^&]*?"|'[^&]*?')/g, '$1'); - h = h.replace(new RegExp("\\\\b(function|const|let|var|return|if|else|for|while|class|import|export|from|default|async|await|try|catch|throw|new|this|def|self|print|lambda|yield|with|as|raise|except|finally)\\\\b", "g"), '$1'); - h = h.replace(new RegExp("\\\\b(\\\\d+\\\\.?\\\\d*)\\\\b", "g"), '$1'); - h = h.replace(new RegExp("\\\\b(True|False|None|true|false|null|undefined|NaN)\\\\b", "g"), '$1'); - h = h.replace(new RegExp("\\\\b(String|Number|Boolean|Array|Object|Map|Set|Promise|void|int|float|str|list|dict|tuple)\\\\b", "g"), '$1'); - h = h.replace(/([=!+\\-*/%|&^~?:]+)/g, '$1'); - var displayText = text + (pendingFiles.length > 0 ? '\\\\n\\ud83d\\udcce ' + pendingFiles.map(function (f) { return f.name; }).join(', ') : ''); - return "\n \n "); -} -var html = getHtml(); -var JSDOM = require('jsdom').JSDOM; -try { - new JSDOM(html, { runScripts: 'dangerously' }); - console.log('JSDOM OK'); -} -catch (e) { - console.error('ERR:', e.message); -} diff --git a/test21.ts b/test21.ts deleted file mode 100644 index 6f37ed3..0000000 --- a/test21.ts +++ /dev/null @@ -1,42 +0,0 @@ -const esc = (s:string)=>s; -function getHtml() { - let pendingFiles = [{name: 'foo'}]; - let text = 'bar'; - let t = ''; - if((t.match(/\`\`\`/g)||[]).length % 2 !== 0) t += '\\\\n\`\`\`'; - - let h = "var x = 1; // test"; - h=h.replace(new RegExp("(\\\\/\\\\/[^\\\\n]*)", "g"),'$1'); - h=h.replace(new RegExp("(#[^\\\\n]*)", "g"),'$1'); - h=h.replace(new RegExp("(\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)", "g"),'$1'); - h=h.replace(/("[^&]*?"|'[^&]*?')/g,'$1'); - h=h.replace(new RegExp("\\\\b(function|const|let|var|return|if|else|for|while|class|import|export|from|default|async|await|try|catch|throw|new|this|def|self|print|lambda|yield|with|as|raise|except|finally)\\\\b", "g"),'$1'); - h=h.replace(new RegExp("\\\\b(\\\\d+\\\\.?\\\\d*)\\\\b", "g"),'$1'); - h=h.replace(new RegExp("\\\\b(True|False|None|true|false|null|undefined|NaN)\\\\b", "g"),'$1'); - h=h.replace(new RegExp("\\\\b(String|Number|Boolean|Array|Object|Map|Set|Promise|void|int|float|str|list|dict|tuple)\\\\b", "g"),'$1'); - h=h.replace(/([=!+\\-*/%|&^~?:]+)/g,'$1'); - - const displayText=text+(pendingFiles.length>0?'\\\\n\\ud83d\\udcce '+pendingFiles.map(f=>f.name).join(', '):''); - - return ` - - `; -} -const html = getHtml(); -const {JSDOM} = require('jsdom'); -try { new JSDOM(html, {runScripts:'dangerously'}); console.log('JSDOM OK'); } catch(e) { console.error('ERR:', e.message); } diff --git a/test22.js b/test22.js deleted file mode 100644 index 9e52bda..0000000 --- a/test22.js +++ /dev/null @@ -1,19 +0,0 @@ -var esc = function (s) { return s; }; -function getHtml() { - var pendingFiles = [{ name: 'foo' }]; - var text = 'bar'; - var t = ''; - if ((t.match(/\`\`\`/g) || []).length % 2 !== 0) - t += '\\\\n\`\`\`'; - var displayText = text + (pendingFiles.length > 0 ? '\\\\n\\ud83d\\udcce ' + pendingFiles.map(function (f) { return f.name; }).join(', ') : ''); - return "\n \n "); -} -var html = getHtml(); -var JSDOM = require('jsdom').JSDOM; -try { - new JSDOM(html, { runScripts: 'dangerously' }); - console.log('JSDOM OK'); -} -catch (e) { - console.error('ERR:', e.message); -} diff --git a/test22.ts b/test22.ts deleted file mode 100644 index e3710e2..0000000 --- a/test22.ts +++ /dev/null @@ -1,31 +0,0 @@ -const esc = (s:string)=>s; -function getHtml() { - let pendingFiles = [{name: 'foo'}]; - let text = 'bar'; - let t = ''; - if((t.match(/\`\`\`/g)||[]).length % 2 !== 0) t += '\\\\n\`\`\`'; - - const displayText=text+(pendingFiles.length>0?'\\\\n\\ud83d\\udcce '+pendingFiles.map(f=>f.name).join(', '):''); - - return ` - - `; -} -const html = getHtml(); -const {JSDOM} = require('jsdom'); -try { new JSDOM(html, {runScripts:'dangerously'}); console.log('JSDOM OK'); } catch(e) { console.error('ERR:', e.message); } diff --git a/test23.js b/test23.js deleted file mode 100644 index 485ac91..0000000 --- a/test23.js +++ /dev/null @@ -1,17 +0,0 @@ -const Module = require('module'); -const originalRequire = Module.prototype.require; -Module.prototype.require = function(request) { - if (request === 'vscode') return { window: {}, workspace: {}, Uri: {}, EventEmitter: class {} }; - return originalRequire.apply(this, arguments); -}; -const fs = require('fs'); -const code = fs.readFileSync('out/extension.js', 'utf8'); -const match = code.match(/_getHtml.*?([\s\S]*?)<\/html>.*?;/m); -if (!match) { - const match2 = code.match(/_getHtml.*?\{\s*return\s+(`(?:[^`]|\\`)*`);?/m); - if (match2) { - const html = eval(match2[1]); - const {JSDOM} = require('jsdom'); - try { new JSDOM(html, {runScripts:'dangerously'}); console.log('JSDOM EVAL OK'); } catch(e) { console.error('EVAL ERR:', e.message); } - } else { console.log('no match2 either'); } -} diff --git a/test4.js b/test4.js deleted file mode 100644 index d1be385..0000000 --- a/test4.js +++ /dev/null @@ -1,10 +0,0 @@ -const ext = require('./out/extension'); -const html = ext.ConnectAIPanel.prototype._getHtml.call({_getHtml: ext.ConnectAIPanel.prototype._getHtml}); -require('fs').writeFileSync('test4.html', html); -const {JSDOM} = require('jsdom'); -try { - new JSDOM(html, {runScripts:'dangerously'}); - console.log("JSDOM OK"); -} catch(e) { - console.log("JSDOM FATAL ERROR:", e.message); -} diff --git a/test5.js b/test5.js deleted file mode 100644 index 95c7fa4..0000000 --- a/test5.js +++ /dev/null @@ -1,17 +0,0 @@ -const Module = require('module'); -const originalRequire = Module.prototype.require; -Module.prototype.require = function(request) { - if (request === 'vscode') return { window: {}, workspace: {}, Uri: {}, EventEmitter: class {} }; - return originalRequire.apply(this, arguments); -}; - -const fs = require('fs'); -let html = fs.readFileSync('test.html', 'utf8'); - -const {JSDOM} = require('jsdom'); -try { - new JSDOM(html, {runScripts:'dangerously'}); - console.log("JSDOM OK"); -} catch(e) { - console.log("JSDOM FATAL ERROR:", e.message); -} diff --git a/test6.js b/test6.js deleted file mode 100644 index 7b15f7d..0000000 --- a/test6.js +++ /dev/null @@ -1,37 +0,0 @@ -const Module = require('module'); -const originalRequire = Module.prototype.require; -Module.prototype.require = function(request) { - if (request === 'vscode') return { window: {}, workspace: {}, Uri: {}, EventEmitter: class {} }; - return originalRequire.apply(this, arguments); -}; -const ext = require('./out/extension'); - -// Try calling _getHtml -let html; -try { - html = ext.ConnectAIPanel.prototype._getHtml.call({_getHtml: ext.ConnectAIPanel.prototype._getHtml}); -} catch(e) { - console.log("Could not call _getHtml directly:", e.message); - // Alternative: match from the original code and eval it - const fs = require('fs'); - const code = fs.readFileSync('out/extension.js', 'utf8'); - const match = code.match(/_getHtml.*?_getHtml\(\)\s*\{\s*return\s+(`(?:[^`]|\\`)*`);?/m); - if (match) { - html = eval(match[1]); - } -} - -if (!html) { - console.log("Failed to get html"); - process.exit(1); -} - -const fs = require('fs'); -fs.writeFileSync('test_eval2.html', html); -const {JSDOM} = require('jsdom'); -try { - new JSDOM(html, {runScripts:'dangerously'}); - console.log("JSDOM OK"); -} catch(e) { - console.log("JSDOM FATAL ERROR:", e.message); -} diff --git a/test7.js b/test7.js deleted file mode 100644 index 16f72f9..0000000 --- a/test7.js +++ /dev/null @@ -1,4 +0,0 @@ -const fs=require('fs'); -let t=fs.readFileSync('out/extension.js', 'utf8'); -let m = t.match(/h=h\.replace\([^)]*\)/g); -console.log(m); diff --git a/test8.js b/test8.js deleted file mode 100644 index 6b057f1..0000000 --- a/test8.js +++ /dev/null @@ -1,4 +0,0 @@ -const fs=require('fs'); -let t=fs.readFileSync('out/extension.js', 'utf8'); -let m = t.match(/h=h\.replace\([^)]*\)/g); -m.forEach(x => console.log(x)); diff --git a/test9.js b/test9.js deleted file mode 100644 index bb9b8e4..0000000 --- a/test9.js +++ /dev/null @@ -1,7 +0,0 @@ -const templateHTML = ` - -`; -console.log(templateHTML); diff --git a/test_ax.js b/test_ax.js deleted file mode 100644 index 05cc2ac..0000000 --- a/test_ax.js +++ /dev/null @@ -1,17 +0,0 @@ -const axios = require('axios'); -async function run() { - try { - const res = await axios.post('http://127.0.0.1:1234/v1/chat/completions', { - model: 'test', messages: [{role:'user', content:'hi'}], stream: true - }, {responseType: 'stream'}); - } catch (error) { - if (error.response?.data?.on) { - let buf=''; - error.response.data.on('data', c=>buf+=c.toString()); - error.response.data.on('end', () => console.log('Parsed stream error:', JSON.parse(buf).error.message)); - } else { - console.log('Plain error msg:', error.message); - } - } -} -run(); diff --git a/test_ax2.js b/test_ax2.js deleted file mode 100644 index 4d8f553..0000000 --- a/test_ax2.js +++ /dev/null @@ -1,15 +0,0 @@ -const axios = require('axios'); -async function run() { - try { - await axios.post('http://127.0.0.1:1234/v1/chat/completions', {model:'test',messages:[{role:'user',content:'a'}]}, {responseType:'stream'}); - } catch(error) { - const status = error.response?.status; - console.log('STATUS:', status); - if (error.response?.data?.on) { - let b=''; - error.response.data.on('data',c=>b+=c.toString()); - error.response.data.on('end',()=>console.log('BODY:', b)); - } - } -} -run(); diff --git a/test_eval.js b/test_eval.js deleted file mode 100644 index c373835..0000000 --- a/test_eval.js +++ /dev/null @@ -1,16 +0,0 @@ -const axios = require('axios'); -async function test() { - const targetUrl = 'http://127.0.0.1:11434/api/chat'; - const payload = { - model: "gemma4:e2b", - messages: [{ role: "user", content: "hello" }], - stream: false - }; - try { - const res = await axios.post(targetUrl, payload); - console.log("SUCCESS:", res.data); - } catch(err) { - console.log("ERROR:", err.response ? err.response.data : err.message); - } -} -test(); diff --git a/test_eval.py b/test_eval.py deleted file mode 100644 index b58e414..0000000 --- a/test_eval.py +++ /dev/null @@ -1,9 +0,0 @@ -import requests -import json - -try: - res = requests.post('http://127.0.0.1:4825/api/evaluate', json={"prompt": "1+1은?"}) - print(res.status_code) - print(res.text) -except Exception as e: - print(e) diff --git a/test_eval2.js b/test_eval2.js deleted file mode 100644 index 0026b69..0000000 --- a/test_eval2.js +++ /dev/null @@ -1,6 +0,0 @@ -const axios = require('axios'); -axios.post('http://127.0.0.1:1234/v1/chat/completions', { - model: 'google/gemma-4-e2b', - messages: [{'role':'user','content':'당신은 AI 에이전트의 역량을 검증하는 자동 채점관입니다.\n\n[평가 과제]\ntest\n\n위 문제에 대해 스스로 완벽한 답안을 도출해 본 뒤, 그 수준이 100점 만점에 몇 점에 해당하는지 자체 평가하십시오. 출력 포맷은 반드시 아래 1줄의 순수 JSON이어야 합니다.\n{ "score": 점수숫자, "reason": "이 점수를 준 이유를 한글로 간략히 작성" }'}], - stream: false -}).then(r => console.log(r.data.choices[0].message.content)).catch(e => console.error(e)); diff --git a/test_eval3.js b/test_eval3.js deleted file mode 100644 index ab2c3dd..0000000 --- a/test_eval3.js +++ /dev/null @@ -1,2 +0,0 @@ -const axios = require('axios'); -axios.get('http://127.0.0.1:4825/ping').then(r => console.log(r.data)).catch(e => console.error(e)); diff --git a/test_final.js b/test_final.js deleted file mode 100644 index 765d6ff..0000000 --- a/test_final.js +++ /dev/null @@ -1,22 +0,0 @@ -var esc = function (s) { return s; }; -function getHtml() { - var pendingFiles = [{ name: 'foo' }]; - var text = 'bar'; - var t = ''; - if ((t.match(/\`\`\`/g) || []).length % 2 !== 0) - t += '\\\\n\`\`\`'; - var h = "var x = 1; // test"; - h = h.replace(/(\\/, { 2: }[ ^ ], n, * ) / g, '$1'; - ; - h = h.replace(/(#[^\\\\n]*)/g, '$1'); - h = h.replace(/(\\/, { 1: }, * [s, S] * ? : , * , /{1})/g, '$1'); - h = h.replace(/("[^&]*?"|'[^&]*?')/g, '$1'); - h = h.replace(/\\b(function|const|let|var|return|if|else|for|while|class|import|export|from|default|async|await|try|catch|throw|new|this|def|self|print|lambda|yield|with|as|raise|except|finally)\\b/g, '$1'); - h = h.replace(/\\b(\\d+\\.?\\d*)\\b/g, '$1'); - h = h.replace(/\\b(True|False|None|true|false|null|undefined|NaN)\\b/g, '$1'); - h = h.replace(/\\b(String|Number|Boolean|Array|Object|Map|Set|Promise|void|int|float|str|list|dict|tuple)\\b/g, '$1'); - h = h.replace(/([=!+\\-*/%|&^~?:]+)/g, '$1'); - var displayText = text + (pendingFiles.length > 0 ? '\\\\n\\ud83d\\udcce ' + pendingFiles.map(function (f) { return f.name; }).join(', ') : ''); - return "\n \n "); -} -console.log(getHtml()); diff --git a/test_final.ts b/test_final.ts deleted file mode 100644 index 14fb6b0..0000000 --- a/test_final.ts +++ /dev/null @@ -1,29 +0,0 @@ -const esc = (s:string)=>s; -function getHtml() { - let pendingFiles = [{name: 'foo'}]; - let text = 'bar'; - let t = ''; - if((t.match(/\`\`\`/g)||[]).length % 2 !== 0) t += '\\\\n\`\`\`'; - - let h = "var x = 1; // test"; - h=h.replace(/(\\/{2}[^\\\\n]*)/g,'$1'); - h=h.replace(/(#[^\\\\n]*)/g,'$1'); - h=h.replace(/(\\/{1}\\*[\\s\\S]*?\\*\\/{1})/g,'$1'); - h=h.replace(/("[^&]*?"|'[^&]*?')/g,'$1'); - h=h.replace(/\\b(function|const|let|var|return|if|else|for|while|class|import|export|from|default|async|await|try|catch|throw|new|this|def|self|print|lambda|yield|with|as|raise|except|finally)\\b/g,'$1'); - h=h.replace(/\\b(\\d+\\.?\\d*)\\b/g,'$1'); - h=h.replace(/\\b(True|False|None|true|false|null|undefined|NaN)\\b/g,'$1'); - h=h.replace(/\\b(String|Number|Boolean|Array|Object|Map|Set|Promise|void|int|float|str|list|dict|tuple)\\b/g,'$1'); - h=h.replace(/([=!+\\-*/%|&^~?:]+)/g,'$1'); - - const displayText=text+(pendingFiles.length>0?'\\\\n\\ud83d\\udcce '+pendingFiles.map(f=>f.name).join(', '):''); - - return ` - - `; -} -console.log(getHtml()); diff --git a/test_flags.js b/test_flags.js deleted file mode 100644 index e4db8ad..0000000 --- a/test_flags.js +++ /dev/null @@ -1,8 +0,0 @@ -const html = ` h=h.replace(/([=!<>+\\\\-*/%|&^~?:]+)/g,'$1');`; -console.log(html); -try { - eval(html); - console.log("OK"); -} catch(e) { - console.log("ERROR:", e.message); -} diff --git a/test_flags2.js b/test_flags2.js deleted file mode 100644 index f92ffd1..0000000 --- a/test_flags2.js +++ /dev/null @@ -1,13 +0,0 @@ -const lines = [ - `h=h.replace(/(\\\\/\\\\/[^\\\\n]*)/g,'');`, - `h=h.replace(/(#[^\\\\n]*)/g,'');`, - `h=h.replace(/(\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)/g,'');`, -]; -for(let line of lines) { - try { - eval(line); - console.log("OK:", line); - } catch(e) { - console.log("ERROR:", e.message, "ON", line); - } -} diff --git a/test_flags3.js b/test_flags3.js deleted file mode 100644 index 747bbc0..0000000 --- a/test_flags3.js +++ /dev/null @@ -1,13 +0,0 @@ -const lines = [ - `h=h.replace(/(\\/\\/[^\\n]*)/g,'');`, - `h=h.replace(/(#[^\\n]*)/g,'');`, - `h=h.replace(/(\\/\\*[\\s\\S]*?\\*\\/)/g,'');`, -]; -for(let line of lines) { - try { - eval(line); - console.log("OK:", line); - } catch(e) { - console.log("ERROR:", e.message, "ON:", line); - } -} diff --git a/test_html.js b/test_html.js deleted file mode 100644 index 03dcd64..0000000 --- a/test_html.js +++ /dev/null @@ -1,20 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -var fs = require("fs"); -var text = fs.readFileSync('src/extension.ts', 'utf-8'); -var match = text.match(/_getHtml.*?\{([\s\S]*?)^\s*\}/m); -if (match) { - var inner = match[1]; - // extract the returned string - var strMatch = inner.match(/return\s+`(.*)`/ms); - if (strMatch) { - fs.writeFileSync('test.html', strMatch[1]); - console.log("Wrote test.html length", strMatch[1].length); - } - else { - console.log('no string'); - } -} -else { - console.log('no func'); -} diff --git a/test_html.ts b/test_html.ts deleted file mode 100644 index dd70783..0000000 --- a/test_html.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as fs from 'fs'; -const text = fs.readFileSync('src/extension.ts', 'utf-8'); -const match = text.match(/_getHtml.*?\{([\s\S]*?)^\s*\}/m); -if (match) { - let inner = match[1]; - // extract the returned string - const strMatch = inner.match(/return\s+`(.*)`/ms); - if (strMatch) { - fs.writeFileSync('test.html', strMatch[1]); - console.log("Wrote test.html length", strMatch[1].length); - } else { console.log('no string'); } -} else { console.log('no func'); } diff --git a/test_html2.js b/test_html2.js deleted file mode 100644 index 7d1e745..0000000 --- a/test_html2.js +++ /dev/null @@ -1,369 +0,0 @@ -const html = ` - -Connect AI - -
Connect AI
-
-
-
-
- -
Connect AI
-
\ubcf4\uc548 \u00b7 \ube44\uc6a9\ucd5c\uc801\ud654 \u00b7 \uc9c0\uc2dd\uc5f0\uacb0
\ud504\ub85c\uc81d\ud2b8\ub97c \uc774\ud574\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uace0, \uc2e4\ud589\ud569\ub2c8\ub2e4.
-
-
-
- -
-
-
-`; -fs.writeFileSync('test_eval3.html', html); -console.log(html.length); \ No newline at end of file diff --git a/test_html2.ts b/test_html2.ts deleted file mode 100644 index 385a868..0000000 --- a/test_html2.ts +++ /dev/null @@ -1,8 +0,0 @@ -import * as fs from 'fs'; -const base = fs.readFileSync('src/extension.ts', 'utf-8'); -const match = base.match(/_getHtml.*?\{\s*return\s+(`(?:[^`]|\\`)*`);/m); -if (match) { - let templateBody = match[1]; - // make it a valid JS file - fs.writeFileSync('test_html2.js', `const html = ${templateBody};\nfs.writeFileSync('test_eval3.html', html);\nconsole.log(html.length);`); -} diff --git a/test_jsdom.js b/test_jsdom.js deleted file mode 100644 index ae2c3e9..0000000 --- a/test_jsdom.js +++ /dev/null @@ -1,9 +0,0 @@ -const orig = ` - -`; -const {JSDOM} = require('jsdom'); -try { new JSDOM(orig, {runScripts:'dangerously'}); console.log('JSDOM OK'); } catch(e) { console.error('ERR:', e.message); } diff --git a/test_ollama.py b/test_ollama.py deleted file mode 100644 index 95301fb..0000000 --- a/test_ollama.py +++ /dev/null @@ -1,9 +0,0 @@ -import requests -import json - -try: - res = requests.post('http://127.0.0.1:11434/api/generate', json={"model": "gemma4:e2b", "prompt": "1+1은?", "stream": False}) - print(res.status_code) - print(res.text) -except Exception as e: - print(e) diff --git a/test_regex_isolated.js b/test_regex_isolated.js deleted file mode 100644 index e2aeb00..0000000 --- a/test_regex_isolated.js +++ /dev/null @@ -1,4 +0,0 @@ -// Test just the create_file regex pattern in isolation -const t = 'console.log("hi")'; -const result = t.replace(/([\s\S]*?)<\/create_file>/g, 'MATCH:$1:$2'); -console.log(result); diff --git a/test_script.js b/test_script.js deleted file mode 100644 index 8334690..0000000 --- a/test_script.js +++ /dev/null @@ -1,192 +0,0 @@ - -window.onerror = function(msg, url, line, col, error) { - document.body.innerHTML += '
ERROR: ' + msg + ' at line ' + line + '
'; -}; -window.addEventListener('unhandledrejection', function(event) { - document.body.innerHTML += '
PROMISE REJECTION: ' + event.reason + '
'; -}); -try { -const vscode=acquireVsCodeApi(),chat=document.getElementById('chat'),input=document.getElementById('input'), -sendBtn=document.getElementById('sendBtn'),stopBtn=document.getElementById('stopBtn'), -modelSel=document.getElementById('modelSel'),newChatBtn=document.getElementById('newChatBtn'),settingsBtn=document.getElementById('settingsBtn'),brainBtn=document.getElementById('brainBtn'), -attachBtn=document.getElementById('attachBtn'),fileInput=document.getElementById('fileInput'),attachPreview=document.getElementById('attachPreview'), -thinkingBar=document.getElementById('thinkingBar'); -let loader=null,sending=false,pendingFiles=[]; - -/* Syntax Highlighting (lightweight) */ -function highlight(code,lang){ - let h=esc(code); - h=h.replace(/(\\/\\/[^\\n]*)/g,'$1'); - h=h.replace(/(#[^\\n]*)/g,'$1'); - h=h.replace(/(\\/\\*[\\s\\S]*?\\*\\/)/g,'$1'); - h=h.replace(/("[^&]*?"|'[^&]*?')/g,'$1'); - h=h.replace(/\\b(function|const|let|var|return|if|else|for|while|class|import|export|from|default|async|await|try|catch|throw|new|this|def|self|print|lambda|yield|with|as|raise|except|finally)\\b/g,'$1'); - h=h.replace(/\\b(\\d+\\.?\\d*)\\b/g,'$1'); - h=h.replace(/\\b(True|False|None|true|false|null|undefined|NaN)\\b/g,'$1'); - h=h.replace(/\\b(String|Number|Boolean|Array|Object|Map|Set|Promise|void|int|float|str|list|dict|tuple)\\b/g,'$1'); - h=h.replace(/([=!<>+\\-*/%|&^~?:]+)/g,'$1'); - return h; -} - -/* Clipboard Paste (Ctrl+V images) */ -input.addEventListener('paste',(e)=>{ - const items=e.clipboardData&&e.clipboardData.items; - if(!items)return; - for(const item of items){ - if(item.type.startsWith('image/')){ - e.preventDefault(); - const file=item.getAsFile(); - if(!file)return; - const reader=new FileReader(); - reader.onload=()=>{ - const base64=reader.result.split(',')[1]; - pendingFiles.push({name:'clipboard-image.png',type:file.type,data:base64}); - renderPreview(); - }; - reader.readAsDataURL(file); - return; - } - } -}); -vscode.postMessage({type:'getModels'}); -setTimeout(()=>vscode.postMessage({type:'ready'}),300); -input.addEventListener('input',()=>{input.style.height='auto';input.style.height=Math.min(input.scrollHeight,150)+'px'}); -function getTime(){return new Date().toLocaleTimeString('ko-KR',{hour:'2-digit',minute:'2-digit'})} -function esc(s){const d=document.createElement('div');d.innerText=s;return d.innerHTML} -function fmt(t){ - if(t.lastIndexOf(' t.lastIndexOf('')) t += ''; - if(t.lastIndexOf(' t.lastIndexOf('
')) t += ''; - if(t.lastIndexOf(' t.lastIndexOf('')) t += ''; - if((t.match(/\`\`\`/g)||[]).length % 2 !== 0) t += '\\n\`\`\`'; - - const blocks = []; - function pushB(h){ blocks.push(h); return '__B' + (blocks.length-1) + '__'; } - t=t.replace(/([\\s\\S]*?)<\\/create_file>/g,(_,p,c)=>pushB('
\u{1F4C1} '+esc(p)+' \u2014 \uC790\uB3D9 \uC0DD\uC131\uB428
'+esc(c)+'
')); - t=t.replace(/([\\s\\S]*?)<\\/edit_file>/g,(_,p,c)=>pushB('
\u270F\uFE0F '+esc(p)+' \u2014 \uD3B8\uC9D1\uB428
'+esc(c)+'
')); - t=t.replace(/([\\s\\S]*?)<\\/run_command>/g,(_,c)=>pushB('
\u25B6 '+esc(c)+'
')); - t=t.replace(/\`\`\`(\\w*)\\n([\\s\\S]*?)\`\`\`/g,(_,lang,c)=>{const l=lang||'code';return pushB('
'+esc(l)+'
'+highlight(c,l)+'
');}); - t=t.replace(/\`([^\`]+)\`/g,(_,c)=>pushB(''+esc(c)+'')); - t=esc(t); - t=t.replace(/\\*\\*([^*]+)\\*\\*/g,'$1'); - t=t.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '$1'); - t=t.replace(/__B(\\d+)__/g, (_,i)=>blocks[i]); - return t; -} -function copyCode(btn){const code=btn.parentElement.querySelector('code');if(!code)return;navigator.clipboard.writeText(code.innerText).then(()=>{btn.textContent='\u2713 Copied';btn.classList.add('copied');setTimeout(()=>{btn.textContent='Copy';btn.classList.remove('copied')},1500)})} -function addMsg(text,role){ - const isUser=role==='user',isErr=role==='error'; - const el=document.createElement('div');el.className='msg'+(isUser?' msg-user':'')+(isErr?' msg-error':''); - const head=document.createElement('div');head.className='msg-head'; - head.innerHTML=(isUser?'
\u{1F464}
You':'
\u2726
Connect AI')+''+getTime()+''; - const body=document.createElement('div');body.className='msg-body'; - if(isUser){body.innerText=text}else{body.innerHTML=fmt(text)} - el.appendChild(head);el.appendChild(body);chat.appendChild(el);chat.scrollTop=chat.scrollHeight; -} -function showLoader(){loader=document.createElement('div');loader.className='msg';loader.innerHTML='
\u2726
Connect AI'+getTime()+'
\uC0DD\uAC01\uD558\uB294 \uC911...
';chat.appendChild(loader);chat.scrollTop=chat.scrollHeight;thinkingBar.classList.add('active')} -function hideLoader(){if(loader&&loader.parentNode)loader.parentNode.removeChild(loader);loader=null;thinkingBar.classList.remove('active')} -function setSending(v){sending=v;sendBtn.disabled=v;stopBtn.classList.toggle('visible',v);input.disabled=v;if(!v){input.focus();thinkingBar.classList.remove('active')}} -function send(){ - const text=input.value.trim(); - if((!text&&pendingFiles.length===0)||sending)return; - document.body.classList.remove('init'); - const w=document.querySelector('.welcome');if(w)w.remove(); - document.querySelectorAll('.quick-actions').forEach(e=>e.remove()); - const displayText=text+(pendingFiles.length>0?' -\u{1F4CE} '+pendingFiles.map(f=>f.name).join(', '):''); - addMsg(displayText,'user'); - input.value='';input.style.height='auto';setSending(true);showLoader(); - if(pendingFiles.length>0){ - vscode.postMessage({type:'promptWithFile',value:text||'\uC774 \uD30C\uC77C\uC744 \uBD84\uC11D\uD574\uC8FC\uC138\uC694.',model:modelSel.value,files:pendingFiles}); - pendingFiles=[];attachPreview.innerHTML='';attachPreview.classList.remove('visible'); - } else { - vscode.postMessage({type:'prompt',value:text,model:modelSel.value}); - } -} - -/* Attachment Logic */ -attachBtn.addEventListener('click',()=>fileInput.click()); -fileInput.addEventListener('change',()=>{ - const files=Array.from(fileInput.files); - files.forEach(file=>{ - const reader=new FileReader(); - reader.onload=()=>{ - const base64=reader.result.split(',')[1]; - pendingFiles.push({name:file.name,type:file.type,data:base64}); - renderPreview(); - }; - reader.readAsDataURL(file); - }); - fileInput.value=''; -}); -function renderPreview(){ - attachPreview.innerHTML=''; - if(pendingFiles.length===0){attachPreview.classList.remove('visible');return;} - attachPreview.classList.add('visible'); - pendingFiles.forEach((f,i)=>{ - const chip=document.createElement('div');chip.className='attach-chip'; - const isImg=f.type.startsWith('image/'); - if(isImg){ - const thumb=document.createElement('img');thumb.className='attach-thumb';thumb.src='data:'+f.type+';base64,'+f.data;chip.appendChild(thumb); - } else { - const icon=document.createElement('span');icon.className='chip-icon';icon.textContent=f.type.startsWith('audio/')?'\u{1F3A7}':'\u{1F4C4}';chip.appendChild(icon); - } - const nm=document.createElement('span');nm.className='chip-name';nm.textContent=f.name;chip.appendChild(nm); - const rm=document.createElement('span');rm.className='chip-remove';rm.textContent='\u2715'; - rm.addEventListener('click',()=>{pendingFiles.splice(i,1);renderPreview();}); - chip.appendChild(rm); - attachPreview.appendChild(chip); - }); -} -document.addEventListener('click',e=>{if(e.target.classList.contains('qa-btn')){const p=e.target.getAttribute('data-prompt');if(p){input.value=p;send()}}}); -sendBtn.addEventListener('click',send); -input.addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();send()}}); -newChatBtn.addEventListener('click',()=>vscode.postMessage({type:'newChat'})); -settingsBtn.addEventListener('click',()=>vscode.postMessage({type:'openSettings'})); -brainBtn.addEventListener('click',()=>vscode.postMessage({type:'syncBrain'})); -stopBtn.addEventListener('click',()=>{vscode.postMessage({type:'stopGeneration'});hideLoader();setSending(false);if(streamBody){streamBody.classList.remove('stream-active')}streamEl=null;streamBody=null;}); -let streamEl=null,streamBody=null; -window.addEventListener('message',e=>{const msg=e.data;switch(msg.type){ - case 'response':hideLoader();setSending(false);addMsg(msg.value,'ai');break; - case 'error':hideLoader();setSending(false);addMsg(msg.value,'error');break; - case 'streamStart':{ - hideLoader(); - streamEl=document.createElement('div');streamEl.className='msg'; - const h=document.createElement('div');h.className='msg-head'; - h.innerHTML='
\u2726
Connect AI'+getTime()+''; - streamBody=document.createElement('div');streamBody.className='msg-body stream-active'; - streamEl.appendChild(h);streamEl.appendChild(streamBody);chat.appendChild(streamEl);chat.scrollTop=chat.scrollHeight; - break;} - case 'streamChunk':{ - if(streamBody){streamBody.innerHTML=fmt(streamBody._raw=(streamBody._raw||'')+msg.value);chat.scrollTop=chat.scrollHeight;} - break;} - case 'streamEnd':{ - if(streamBody)streamBody.classList.remove('stream-active'); - /* Add regenerate button */ - if(streamEl){ - const rb=document.createElement('button');rb.className='regen-btn';rb.innerHTML='\u{1F504} Regenerate'; - rb.addEventListener('click',()=>{rb.remove();vscode.postMessage({type:'regenerate'});showLoader();setSending(true);}); - streamEl.appendChild(rb); - } - setSending(false);streamEl=null;streamBody=null; - break;} - case 'modelsList':modelSel.innerHTML='';msg.value.forEach(m=>{const o=document.createElement('option');o.value=m;o.textContent=m;modelSel.appendChild(o)});break; - case 'clearChat': - document.body.classList.add('init'); - chat.innerHTML='
Connect AI
\uBCF4\uC548 \xB7 \uBE44\uC6A9\uCD5C\uC801\uD654 \xB7 \uC9C0\uC2DD\uC5F0\uACB0
\uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uACE0, \uC2E4\uD589\uD569\uB2C8\uB2E4.
'; - break; - case 'restoreMessages': - chat.innerHTML=''; - if(msg.value&&msg.value.length>0){ - document.body.classList.remove('init'); - msg.value.forEach(m=>addMsg(m.text,m.role)); - } else { - document.body.classList.add('init'); - chat.innerHTML='
Connect AI
\uBCF4\uC548 \xB7 \uBE44\uC6A9\uCD5C\uC801\uD654 \xB7 \uC9C0\uC2DD\uC5F0\uACB0
\uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uACE0, \uC2E4\uD589\uD569\uB2C8\uB2E4.
'; - } - break; - case 'focusInput':input.focus();break; - case 'injectPrompt':input.value=msg.value;input.style.height='auto';input.style.height=Math.min(input.scrollHeight,150)+'px';send();break; -} }); -} catch(err) { - document.body.innerHTML = '

\u26A0\uFE0F WEBVIEW JS CRASH

' + err.name + ': ' + err.message + '\\n' + err.stack + '
'; -} diff --git a/test_v2.html b/test_v2.html deleted file mode 100644 index 9242eb5..0000000 --- a/test_v2.html +++ /dev/null @@ -1,367 +0,0 @@ - - -Connect AI - -
Connect AI
-
-
-
-
- -
Connect AI
-
\uBCF4\uC548 \xB7 \uBE44\uC6A9\uCD5C\uC801\uD654 \xB7 \uC9C0\uC2DD\uC5F0\uACB0
\uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uACE0, \uC2E4\uD589\uD569\uB2C8\uB2E4.
-
-
-
- -
-
-
- \ No newline at end of file diff --git a/test_v2_full.js b/test_v2_full.js deleted file mode 100644 index bc316e7..0000000 --- a/test_v2_full.js +++ /dev/null @@ -1,18 +0,0 @@ -const Module = require('module'); -const originalRequire = Module.prototype.require; -Module.prototype.require = function(request) { - if (request === 'vscode') return { window: {}, workspace: {}, Uri: {}, EventEmitter: class {} }; - return originalRequire.apply(this, arguments); -}; -const fs = require('fs'); -const connectAI = require('./out/extension'); -const htmlSource = connectAI.ConnectAIPanel.prototype._getHtml.toString(); -const htmlBodyMatch = htmlSource.match(/return\s+`([\s\S]*?)`/); -if (htmlBodyMatch) { - const evaluateTemplateString = new Function('return `' + htmlBodyMatch[1] + '`'); - const evaluatedHtml = evaluateTemplateString(); - const {JSDOM} = require('jsdom'); - try { new JSDOM(evaluatedHtml, {runScripts:'dangerously'}); console.log('JSDOM FULL HTML OK'); } catch(e) { console.error('EVAL ERR:', e.stack); } -} else { - console.log('no match'); -} diff --git a/test_v2_script.js b/test_v2_script.js deleted file mode 100644 index 5161c90..0000000 --- a/test_v2_script.js +++ /dev/null @@ -1,191 +0,0 @@ - -window.onerror = function(msg, url, line, col, error) { - document.body.innerHTML += '
ERROR: ' + msg + ' at line ' + line + '
'; -}; -window.addEventListener('unhandledrejection', function(event) { - document.body.innerHTML += '
PROMISE REJECTION: ' + event.reason + '
'; -}); -try { -const vscode=acquireVsCodeApi(),chat=document.getElementById('chat'),input=document.getElementById('input'), -sendBtn=document.getElementById('sendBtn'),stopBtn=document.getElementById('stopBtn'), -modelSel=document.getElementById('modelSel'),newChatBtn=document.getElementById('newChatBtn'),settingsBtn=document.getElementById('settingsBtn'),brainBtn=document.getElementById('brainBtn'), -attachBtn=document.getElementById('attachBtn'),fileInput=document.getElementById('fileInput'),attachPreview=document.getElementById('attachPreview'), -thinkingBar=document.getElementById('thinkingBar'); -let loader=null,sending=false,pendingFiles=[]; - -/* Syntax Highlighting (lightweight) */ -function highlight(code,lang){ - let h=esc(code); - h=h.replace(new RegExp("(\\\\/\\\\/[^\\\\n]*)", "g"),'$1'); - h=h.replace(new RegExp("(#[^\\\\n]*)", "g"),'$1'); - h=h.replace(new RegExp("(\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)", "g"),'$1'); - h=h.replace(/("[^&]*?"|'[^&]*?')/g,'$1'); - h=h.replace(new RegExp("\\\\b(function|const|let|var|return|if|else|for|while|class|import|export|from|default|async|await|try|catch|throw|new|this|def|self|print|lambda|yield|with|as|raise|except|finally)\\\\b", "g"),'$1'); - h=h.replace(new RegExp("\\\\b(\\\\d+\\\\.?\\\\d*)\\\\b", "g"),'$1'); - h=h.replace(new RegExp("\\\\b(True|False|None|true|false|null|undefined|NaN)\\\\b", "g"),'$1'); - h=h.replace(new RegExp("\\\\b(String|Number|Boolean|Array|Object|Map|Set|Promise|void|int|float|str|list|dict|tuple)\\\\b", "g"),'$1'); - h=h.replace(/([=!+*/%|&^~?:-]+)/g,'$1'); - return h; -} - -/* Clipboard Paste (Ctrl+V images) */ -input.addEventListener('paste',(e)=>{ - const items=e.clipboardData&&e.clipboardData.items; - if(!items)return; - for(const item of items){ - if(item.type.startsWith('image/')){ - e.preventDefault(); - const file=item.getAsFile(); - if(!file)return; - const reader=new FileReader(); - reader.onload=()=>{ - const base64=reader.result.split(',')[1]; - pendingFiles.push({name:'clipboard-image.png',type:file.type,data:base64}); - renderPreview(); - }; - reader.readAsDataURL(file); - return; - } - } -}); -vscode.postMessage({type:'getModels'}); -setTimeout(()=>vscode.postMessage({type:'ready'}),300); -input.addEventListener('input',()=>{input.style.height='auto';input.style.height=Math.min(input.scrollHeight,150)+'px'}); -function getTime(){return new Date().toLocaleTimeString('ko-KR',{hour:'2-digit',minute:'2-digit'})} -function esc(s){const d=document.createElement('div');d.innerText=s;return d.innerHTML} -function fmt(t){ - if(t.lastIndexOf(' t.lastIndexOf('')) t += ''; - if(t.lastIndexOf(' t.lastIndexOf('')) t += ''; - if(t.lastIndexOf(' t.lastIndexOf('
')) t += ''; - if((t.match(/\`\`\`/g)||[]).length % 2 !== 0) t += '\\\\n\`\`\`'; - - const blocks = []; - function pushB(h){ blocks.push(h); return '__B' + (blocks.length-1) + '__'; } - t=t.replace(/([\\s\\S]*?)<\\/create_file>/g,(_,p,c)=>pushB('
\u{1F4C1} '+esc(p)+' \u2014 \uC790\uB3D9 \uC0DD\uC131\uB428
'+esc(c)+'
')); - t=t.replace(/([\\s\\S]*?)<\\/edit_file>/g,(_,p,c)=>pushB('
\u270F\uFE0F '+esc(p)+' \u2014 \uD3B8\uC9D1\uB428
'+esc(c)+'
')); - t=t.replace(/([\\s\\S]*?)<\\/run_command>/g,(_,c)=>pushB('
\u25B6 '+esc(c)+'
')); - t=t.replace(/\`\`\`(\\w*)\\n([\\s\\S]*?)\`\`\`/g,(_,lang,c)=>{const l=lang||'code';return pushB('
'+esc(l)+'
'+highlight(c,l)+'
');}); - t=t.replace(/\`([^\`]+)\`/g,(_,c)=>pushB(''+esc(c)+'')); - t=esc(t); - t=t.replace(/\\*\\*([^*]+)\\*\\*/g,'$1'); - t=t.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '$1'); - t=t.replace(/__B(\\d+)__/g, (_,i)=>blocks[i]); - return t; -} -function copyCode(btn){const code=btn.parentElement.querySelector('code');if(!code)return;navigator.clipboard.writeText(code.innerText).then(()=>{btn.textContent='\u2713 Copied';btn.classList.add('copied');setTimeout(()=>{btn.textContent='Copy';btn.classList.remove('copied')},1500)})} -function addMsg(text,role){ - const isUser=role==='user',isErr=role==='error'; - const el=document.createElement('div');el.className='msg'+(isUser?' msg-user':'')+(isErr?' msg-error':''); - const head=document.createElement('div');head.className='msg-head'; - head.innerHTML=(isUser?'
\u{1F464}
You':'
\u2726
Connect AI')+''+getTime()+''; - const body=document.createElement('div');body.className='msg-body'; - if(isUser){body.innerText=text}else{body.innerHTML=fmt(text)} - el.appendChild(head);el.appendChild(body);chat.appendChild(el);chat.scrollTop=chat.scrollHeight; -} -function showLoader(){loader=document.createElement('div');loader.className='msg';loader.innerHTML='
\u2726
Connect AI'+getTime()+'
\uC0DD\uAC01\uD558\uB294 \uC911...
';chat.appendChild(loader);chat.scrollTop=chat.scrollHeight;thinkingBar.classList.add('active')} -function hideLoader(){if(loader&&loader.parentNode)loader.parentNode.removeChild(loader);loader=null;thinkingBar.classList.remove('active')} -function setSending(v){sending=v;sendBtn.disabled=v;stopBtn.classList.toggle('visible',v);input.disabled=v;if(!v){input.focus();thinkingBar.classList.remove('active')}} -function send(){ - const text=input.value.trim(); - if((!text&&pendingFiles.length===0)||sending)return; - document.body.classList.remove('init'); - const w=document.querySelector('.welcome');if(w)w.remove(); - document.querySelectorAll('.quick-actions').forEach(e=>e.remove()); - const displayText=text+(pendingFiles.length>0?'\\\\n\\ud83d\\udcce '+pendingFiles.map(f=>f.name).join(', '):''); - addMsg(displayText,'user'); - input.value='';input.style.height='auto';setSending(true);showLoader(); - if(pendingFiles.length>0){ - vscode.postMessage({type:'promptWithFile',value:text||'\uC774 \uD30C\uC77C\uC744 \uBD84\uC11D\uD574\uC8FC\uC138\uC694.',model:modelSel.value,files:pendingFiles}); - pendingFiles=[];attachPreview.innerHTML='';attachPreview.classList.remove('visible'); - } else { - vscode.postMessage({type:'prompt',value:text,model:modelSel.value}); - } -} - -/* Attachment Logic */ -attachBtn.addEventListener('click',()=>fileInput.click()); -fileInput.addEventListener('change',()=>{ - const files=Array.from(fileInput.files); - files.forEach(file=>{ - const reader=new FileReader(); - reader.onload=()=>{ - const base64=reader.result.split(',')[1]; - pendingFiles.push({name:file.name,type:file.type,data:base64}); - renderPreview(); - }; - reader.readAsDataURL(file); - }); - fileInput.value=''; -}); -function renderPreview(){ - attachPreview.innerHTML=''; - if(pendingFiles.length===0){attachPreview.classList.remove('visible');return;} - attachPreview.classList.add('visible'); - pendingFiles.forEach((f,i)=>{ - const chip=document.createElement('div');chip.className='attach-chip'; - const isImg=f.type.startsWith('image/'); - if(isImg){ - const thumb=document.createElement('img');thumb.className='attach-thumb';thumb.src='data:'+f.type+';base64,'+f.data;chip.appendChild(thumb); - } else { - const icon=document.createElement('span');icon.className='chip-icon';icon.textContent=f.type.startsWith('audio/')?'\u{1F3A7}':'\u{1F4C4}';chip.appendChild(icon); - } - const nm=document.createElement('span');nm.className='chip-name';nm.textContent=f.name;chip.appendChild(nm); - const rm=document.createElement('span');rm.className='chip-remove';rm.textContent='\u2715'; - rm.addEventListener('click',()=>{pendingFiles.splice(i,1);renderPreview();}); - chip.appendChild(rm); - attachPreview.appendChild(chip); - }); -} -document.addEventListener('click',e=>{if(e.target.classList.contains('qa-btn')){const p=e.target.getAttribute('data-prompt');if(p){input.value=p;send()}}}); -sendBtn.addEventListener('click',send); -input.addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();send()}}); -newChatBtn.addEventListener('click',()=>vscode.postMessage({type:'newChat'})); -settingsBtn.addEventListener('click',()=>vscode.postMessage({type:'openSettings'})); -brainBtn.addEventListener('click',()=>vscode.postMessage({type:'syncBrain'})); -stopBtn.addEventListener('click',()=>{vscode.postMessage({type:'stopGeneration'});hideLoader();setSending(false);if(streamBody){streamBody.classList.remove('stream-active')}streamEl=null;streamBody=null;}); -let streamEl=null,streamBody=null; -window.addEventListener('message',e=>{const msg=e.data;switch(msg.type){ - case 'response':hideLoader();setSending(false);addMsg(msg.value,'ai');break; - case 'error':hideLoader();setSending(false);addMsg(msg.value,'error');break; - case 'streamStart':{ - hideLoader(); - streamEl=document.createElement('div');streamEl.className='msg'; - const h=document.createElement('div');h.className='msg-head'; - h.innerHTML='
\u2726
Connect AI'+getTime()+''; - streamBody=document.createElement('div');streamBody.className='msg-body stream-active'; - streamEl.appendChild(h);streamEl.appendChild(streamBody);chat.appendChild(streamEl);chat.scrollTop=chat.scrollHeight; - break;} - case 'streamChunk':{ - if(streamBody){streamBody.innerHTML=fmt(streamBody._raw=(streamBody._raw||'')+msg.value);chat.scrollTop=chat.scrollHeight;} - break;} - case 'streamEnd':{ - if(streamBody)streamBody.classList.remove('stream-active'); - /* Add regenerate button */ - if(streamEl){ - const rb=document.createElement('button');rb.className='regen-btn';rb.innerHTML='\u{1F504} Regenerate'; - rb.addEventListener('click',()=>{rb.remove();vscode.postMessage({type:'regenerate'});showLoader();setSending(true);}); - streamEl.appendChild(rb); - } - setSending(false);streamEl=null;streamBody=null; - break;} - case 'modelsList':modelSel.innerHTML='';msg.value.forEach(m=>{const o=document.createElement('option');o.value=m;o.textContent=m;modelSel.appendChild(o)});break; - case 'clearChat': - document.body.classList.add('init'); - chat.innerHTML='
Connect AI
\uBCF4\uC548 \xB7 \uBE44\uC6A9\uCD5C\uC801\uD654 \xB7 \uC9C0\uC2DD\uC5F0\uACB0
\uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uACE0, \uC2E4\uD589\uD569\uB2C8\uB2E4.
'; - break; - case 'restoreMessages': - chat.innerHTML=''; - if(msg.value&&msg.value.length>0){ - document.body.classList.remove('init'); - msg.value.forEach(m=>addMsg(m.text,m.role)); - } else { - document.body.classList.add('init'); - chat.innerHTML='
Connect AI
\uBCF4\uC548 \xB7 \uBE44\uC6A9\uCD5C\uC801\uD654 \xB7 \uC9C0\uC2DD\uC5F0\uACB0
\uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uACE0, \uC2E4\uD589\uD569\uB2C8\uB2E4.
'; - } - break; - case 'focusInput':input.focus();break; - case 'injectPrompt':input.value=msg.value;input.style.height='auto';input.style.height=Math.min(input.scrollHeight,150)+'px';send();break; -} }); -} catch(err) { - document.body.innerHTML = '

\u26A0\uFE0F WEBVIEW JS CRASH

' + err.name + ': ' + err.message + '\\n' + err.stack + '
'; -} diff --git a/test_verify.html b/test_verify.html deleted file mode 100644 index 9242eb5..0000000 --- a/test_verify.html +++ /dev/null @@ -1,367 +0,0 @@ - - -Connect AI - -
Connect AI
-
-
-
-
- -
Connect AI
-
\uBCF4\uC548 \xB7 \uBE44\uC6A9\uCD5C\uC801\uD654 \xB7 \uC9C0\uC2DD\uC5F0\uACB0
\uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uACE0, \uC2E4\uD589\uD569\uB2C8\uB2E4.
-
-
-
- -
-
-
- \ No newline at end of file diff --git a/test_verify_script.js b/test_verify_script.js deleted file mode 100644 index 5161c90..0000000 --- a/test_verify_script.js +++ /dev/null @@ -1,191 +0,0 @@ - -window.onerror = function(msg, url, line, col, error) { - document.body.innerHTML += '
ERROR: ' + msg + ' at line ' + line + '
'; -}; -window.addEventListener('unhandledrejection', function(event) { - document.body.innerHTML += '
PROMISE REJECTION: ' + event.reason + '
'; -}); -try { -const vscode=acquireVsCodeApi(),chat=document.getElementById('chat'),input=document.getElementById('input'), -sendBtn=document.getElementById('sendBtn'),stopBtn=document.getElementById('stopBtn'), -modelSel=document.getElementById('modelSel'),newChatBtn=document.getElementById('newChatBtn'),settingsBtn=document.getElementById('settingsBtn'),brainBtn=document.getElementById('brainBtn'), -attachBtn=document.getElementById('attachBtn'),fileInput=document.getElementById('fileInput'),attachPreview=document.getElementById('attachPreview'), -thinkingBar=document.getElementById('thinkingBar'); -let loader=null,sending=false,pendingFiles=[]; - -/* Syntax Highlighting (lightweight) */ -function highlight(code,lang){ - let h=esc(code); - h=h.replace(new RegExp("(\\\\/\\\\/[^\\\\n]*)", "g"),'$1'); - h=h.replace(new RegExp("(#[^\\\\n]*)", "g"),'$1'); - h=h.replace(new RegExp("(\\\\/\\\\*[\\\\s\\\\S]*?\\\\*\\\\/)", "g"),'$1'); - h=h.replace(/("[^&]*?"|'[^&]*?')/g,'$1'); - h=h.replace(new RegExp("\\\\b(function|const|let|var|return|if|else|for|while|class|import|export|from|default|async|await|try|catch|throw|new|this|def|self|print|lambda|yield|with|as|raise|except|finally)\\\\b", "g"),'$1'); - h=h.replace(new RegExp("\\\\b(\\\\d+\\\\.?\\\\d*)\\\\b", "g"),'$1'); - h=h.replace(new RegExp("\\\\b(True|False|None|true|false|null|undefined|NaN)\\\\b", "g"),'$1'); - h=h.replace(new RegExp("\\\\b(String|Number|Boolean|Array|Object|Map|Set|Promise|void|int|float|str|list|dict|tuple)\\\\b", "g"),'$1'); - h=h.replace(/([=!+*/%|&^~?:-]+)/g,'$1'); - return h; -} - -/* Clipboard Paste (Ctrl+V images) */ -input.addEventListener('paste',(e)=>{ - const items=e.clipboardData&&e.clipboardData.items; - if(!items)return; - for(const item of items){ - if(item.type.startsWith('image/')){ - e.preventDefault(); - const file=item.getAsFile(); - if(!file)return; - const reader=new FileReader(); - reader.onload=()=>{ - const base64=reader.result.split(',')[1]; - pendingFiles.push({name:'clipboard-image.png',type:file.type,data:base64}); - renderPreview(); - }; - reader.readAsDataURL(file); - return; - } - } -}); -vscode.postMessage({type:'getModels'}); -setTimeout(()=>vscode.postMessage({type:'ready'}),300); -input.addEventListener('input',()=>{input.style.height='auto';input.style.height=Math.min(input.scrollHeight,150)+'px'}); -function getTime(){return new Date().toLocaleTimeString('ko-KR',{hour:'2-digit',minute:'2-digit'})} -function esc(s){const d=document.createElement('div');d.innerText=s;return d.innerHTML} -function fmt(t){ - if(t.lastIndexOf(' t.lastIndexOf('')) t += ''; - if(t.lastIndexOf(' t.lastIndexOf('')) t += ''; - if(t.lastIndexOf(' t.lastIndexOf('
')) t += ''; - if((t.match(/\`\`\`/g)||[]).length % 2 !== 0) t += '\\\\n\`\`\`'; - - const blocks = []; - function pushB(h){ blocks.push(h); return '__B' + (blocks.length-1) + '__'; } - t=t.replace(/([\\s\\S]*?)<\\/create_file>/g,(_,p,c)=>pushB('
\u{1F4C1} '+esc(p)+' \u2014 \uC790\uB3D9 \uC0DD\uC131\uB428
'+esc(c)+'
')); - t=t.replace(/([\\s\\S]*?)<\\/edit_file>/g,(_,p,c)=>pushB('
\u270F\uFE0F '+esc(p)+' \u2014 \uD3B8\uC9D1\uB428
'+esc(c)+'
')); - t=t.replace(/([\\s\\S]*?)<\\/run_command>/g,(_,c)=>pushB('
\u25B6 '+esc(c)+'
')); - t=t.replace(/\`\`\`(\\w*)\\n([\\s\\S]*?)\`\`\`/g,(_,lang,c)=>{const l=lang||'code';return pushB('
'+esc(l)+'
'+highlight(c,l)+'
');}); - t=t.replace(/\`([^\`]+)\`/g,(_,c)=>pushB(''+esc(c)+'')); - t=esc(t); - t=t.replace(/\\*\\*([^*]+)\\*\\*/g,'$1'); - t=t.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '$1'); - t=t.replace(/__B(\\d+)__/g, (_,i)=>blocks[i]); - return t; -} -function copyCode(btn){const code=btn.parentElement.querySelector('code');if(!code)return;navigator.clipboard.writeText(code.innerText).then(()=>{btn.textContent='\u2713 Copied';btn.classList.add('copied');setTimeout(()=>{btn.textContent='Copy';btn.classList.remove('copied')},1500)})} -function addMsg(text,role){ - const isUser=role==='user',isErr=role==='error'; - const el=document.createElement('div');el.className='msg'+(isUser?' msg-user':'')+(isErr?' msg-error':''); - const head=document.createElement('div');head.className='msg-head'; - head.innerHTML=(isUser?'
\u{1F464}
You':'
\u2726
Connect AI')+''+getTime()+''; - const body=document.createElement('div');body.className='msg-body'; - if(isUser){body.innerText=text}else{body.innerHTML=fmt(text)} - el.appendChild(head);el.appendChild(body);chat.appendChild(el);chat.scrollTop=chat.scrollHeight; -} -function showLoader(){loader=document.createElement('div');loader.className='msg';loader.innerHTML='
\u2726
Connect AI'+getTime()+'
\uC0DD\uAC01\uD558\uB294 \uC911...
';chat.appendChild(loader);chat.scrollTop=chat.scrollHeight;thinkingBar.classList.add('active')} -function hideLoader(){if(loader&&loader.parentNode)loader.parentNode.removeChild(loader);loader=null;thinkingBar.classList.remove('active')} -function setSending(v){sending=v;sendBtn.disabled=v;stopBtn.classList.toggle('visible',v);input.disabled=v;if(!v){input.focus();thinkingBar.classList.remove('active')}} -function send(){ - const text=input.value.trim(); - if((!text&&pendingFiles.length===0)||sending)return; - document.body.classList.remove('init'); - const w=document.querySelector('.welcome');if(w)w.remove(); - document.querySelectorAll('.quick-actions').forEach(e=>e.remove()); - const displayText=text+(pendingFiles.length>0?'\\\\n\\ud83d\\udcce '+pendingFiles.map(f=>f.name).join(', '):''); - addMsg(displayText,'user'); - input.value='';input.style.height='auto';setSending(true);showLoader(); - if(pendingFiles.length>0){ - vscode.postMessage({type:'promptWithFile',value:text||'\uC774 \uD30C\uC77C\uC744 \uBD84\uC11D\uD574\uC8FC\uC138\uC694.',model:modelSel.value,files:pendingFiles}); - pendingFiles=[];attachPreview.innerHTML='';attachPreview.classList.remove('visible'); - } else { - vscode.postMessage({type:'prompt',value:text,model:modelSel.value}); - } -} - -/* Attachment Logic */ -attachBtn.addEventListener('click',()=>fileInput.click()); -fileInput.addEventListener('change',()=>{ - const files=Array.from(fileInput.files); - files.forEach(file=>{ - const reader=new FileReader(); - reader.onload=()=>{ - const base64=reader.result.split(',')[1]; - pendingFiles.push({name:file.name,type:file.type,data:base64}); - renderPreview(); - }; - reader.readAsDataURL(file); - }); - fileInput.value=''; -}); -function renderPreview(){ - attachPreview.innerHTML=''; - if(pendingFiles.length===0){attachPreview.classList.remove('visible');return;} - attachPreview.classList.add('visible'); - pendingFiles.forEach((f,i)=>{ - const chip=document.createElement('div');chip.className='attach-chip'; - const isImg=f.type.startsWith('image/'); - if(isImg){ - const thumb=document.createElement('img');thumb.className='attach-thumb';thumb.src='data:'+f.type+';base64,'+f.data;chip.appendChild(thumb); - } else { - const icon=document.createElement('span');icon.className='chip-icon';icon.textContent=f.type.startsWith('audio/')?'\u{1F3A7}':'\u{1F4C4}';chip.appendChild(icon); - } - const nm=document.createElement('span');nm.className='chip-name';nm.textContent=f.name;chip.appendChild(nm); - const rm=document.createElement('span');rm.className='chip-remove';rm.textContent='\u2715'; - rm.addEventListener('click',()=>{pendingFiles.splice(i,1);renderPreview();}); - chip.appendChild(rm); - attachPreview.appendChild(chip); - }); -} -document.addEventListener('click',e=>{if(e.target.classList.contains('qa-btn')){const p=e.target.getAttribute('data-prompt');if(p){input.value=p;send()}}}); -sendBtn.addEventListener('click',send); -input.addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();send()}}); -newChatBtn.addEventListener('click',()=>vscode.postMessage({type:'newChat'})); -settingsBtn.addEventListener('click',()=>vscode.postMessage({type:'openSettings'})); -brainBtn.addEventListener('click',()=>vscode.postMessage({type:'syncBrain'})); -stopBtn.addEventListener('click',()=>{vscode.postMessage({type:'stopGeneration'});hideLoader();setSending(false);if(streamBody){streamBody.classList.remove('stream-active')}streamEl=null;streamBody=null;}); -let streamEl=null,streamBody=null; -window.addEventListener('message',e=>{const msg=e.data;switch(msg.type){ - case 'response':hideLoader();setSending(false);addMsg(msg.value,'ai');break; - case 'error':hideLoader();setSending(false);addMsg(msg.value,'error');break; - case 'streamStart':{ - hideLoader(); - streamEl=document.createElement('div');streamEl.className='msg'; - const h=document.createElement('div');h.className='msg-head'; - h.innerHTML='
\u2726
Connect AI'+getTime()+''; - streamBody=document.createElement('div');streamBody.className='msg-body stream-active'; - streamEl.appendChild(h);streamEl.appendChild(streamBody);chat.appendChild(streamEl);chat.scrollTop=chat.scrollHeight; - break;} - case 'streamChunk':{ - if(streamBody){streamBody.innerHTML=fmt(streamBody._raw=(streamBody._raw||'')+msg.value);chat.scrollTop=chat.scrollHeight;} - break;} - case 'streamEnd':{ - if(streamBody)streamBody.classList.remove('stream-active'); - /* Add regenerate button */ - if(streamEl){ - const rb=document.createElement('button');rb.className='regen-btn';rb.innerHTML='\u{1F504} Regenerate'; - rb.addEventListener('click',()=>{rb.remove();vscode.postMessage({type:'regenerate'});showLoader();setSending(true);}); - streamEl.appendChild(rb); - } - setSending(false);streamEl=null;streamBody=null; - break;} - case 'modelsList':modelSel.innerHTML='';msg.value.forEach(m=>{const o=document.createElement('option');o.value=m;o.textContent=m;modelSel.appendChild(o)});break; - case 'clearChat': - document.body.classList.add('init'); - chat.innerHTML='
Connect AI
\uBCF4\uC548 \xB7 \uBE44\uC6A9\uCD5C\uC801\uD654 \xB7 \uC9C0\uC2DD\uC5F0\uACB0
\uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uACE0, \uC2E4\uD589\uD569\uB2C8\uB2E4.
'; - break; - case 'restoreMessages': - chat.innerHTML=''; - if(msg.value&&msg.value.length>0){ - document.body.classList.remove('init'); - msg.value.forEach(m=>addMsg(m.text,m.role)); - } else { - document.body.classList.add('init'); - chat.innerHTML='
Connect AI
\uBCF4\uC548 \xB7 \uBE44\uC6A9\uCD5C\uC801\uD654 \xB7 \uC9C0\uC2DD\uC5F0\uACB0
\uD504\uB85C\uC81D\uD2B8\uB97C \uC774\uD574\uD558\uACE0, \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uACE0, \uC2E4\uD589\uD569\uB2C8\uB2E4.
'; - } - break; - case 'focusInput':input.focus();break; - case 'injectPrompt':input.value=msg.value;input.style.height='auto';input.style.height=Math.min(input.scrollHeight,150)+'px';send();break; -} }); -} catch(err) { - document.body.innerHTML = '

\u26A0\uFE0F WEBVIEW JS CRASH

' + err.name + ': ' + err.message + '\\n' + err.stack + '
'; -}