fokan commited on
Commit
47b4206
·
verified ·
1 Parent(s): 69e3625

# VS Code AI Builder Extension — MVP

Browse files

> هدف الإضافة: بناء مواقع/تطبيقات كاملة من برومبت واحد، ورؤية المشروع المفتوح والتعديل على الملفات بشكل احترافي (Agentic Codegen) — شبيه Augment Code/Cline.

---

## 0) المزايا الأساسية

* **Build from Prompt**: توليد خطة + هيكل مشروع + كود أولي.
* **Project-Aware**: قراءة الشجرة، تلخيصها، والانطلاق منها (context packing).
* **Patch & Review**: استلام تغييرات بصيغة Unified Diff، عرضها، تطبيقها انتقائيًا.
* **Tasks Orchestrator**: تشغيل أوامر (npm/yarn/pnpm), dev server, linters، مع بث حي للّوغز في جانب.
* **Safe Mode**: Dry‑run، وحدود/قوائم سماح للمجلدات، طلب تأكيد قبل أي تغييرات كبيرة.
* **Provider‑agnostic**: يدعم OpenAI/Anthropic/Gemini عبر واجهة موحّدة.

---

## 1) أوامر الإضافة (Commands)

* `aiBuilder.buildFromPrompt` — “ابنِ مشروعي من هذا البرومبت…”.
* `aiBuilder.explainPlan` — عرض الخطة ومراحل التنفيذ قبل التطبيق.
* `aiBuilder.applyPlan` — تطبيق الخطة دفعة واحدة أو على مراحل.
* `aiBuilder.editSelection` — تعديل الجزء المحدد في الملف الحالي.
* `aiBuilder.refactorProject` — تحسين شامل مع حماية الاختبارات/الأنماط.
* `aiBuilder.runTask` — تشغيل مهام (install/build/dev/test) مع لوغ.

---

## 2) بنية المشروع

```
ai-builder-ext/
├─ package.json
├─ tsconfig.json
├─ src/
│ ├─ extension.ts
│ ├─ agent/
│ │ ├─ Agent.ts
│ │ ├─ Patch.ts
│ │ ├─ Context.ts
│ │ └─ Tools.ts
│ ├─ llm/
│ │ ├─ Provider.ts
│ │ ├─ OpenAIProvider.ts
│ │ ├─ AnthropicProvider.ts
│ │ └─ GeminiProvider.ts
│ ├─ ui/
│ │ ├─ Panel.ts
│ │ └─ webview.html
│ └─ util/
│ ├─ fs.ts
│ └─ diff.ts
└─ README.md
```

---

## 3) package.json (مختصر قابل للتشغيل)

```json
{
"name": "ai-builder-ext",
"displayName": "AI Builder — Agentic Codegen",
"publisher": "your-name",
"version": "0.0.1",
"engines": { "vscode": "^1.92.0" },
"categories": ["Other"],
"activationEvents": [
"onCommand:aiBuilder.buildFromPrompt",
"onCommand:aiBuilder.explainPlan",
"onCommand:aiBuilder.applyPlan",
"onCommand:aiBuilder.editSelection",
"onCommand:aiBuilder.refactorProject",
"onCommand:aiBuilder.runTask"
],
"contributes": {
"commands": [
{ "command": "aiBuilder.buildFromPrompt", "title": "AI: Build From Prompt" },
{ "command": "aiBuilder.explainPlan", "title": "AI: Show Plan" },
{ "command": "aiBuilder.applyPlan", "title": "AI: Apply Plan" },
{ "command": "aiBuilder.editSelection", "title": "AI: Edit Selection" },
{ "command": "aiBuilder.refactorProject", "title": "AI: Refactor Project" },
{ "command": "aiBuilder.runTask", "title": "AI: Run Task" }
],
"configuration": {
"type": "object",
"title": "AI Builder Settings",
"properties": {
"aiBuilder.provider": {
"type": "string",
"default": "openai",
"enum": ["openai", "anthropic", "gemini"],
"description": "LLM provider"
},
"aiBuilder.apiKey": {
"type": "string",
"default": "",
"description": "API Key (stored in VS Code SecretStorage)"
},
"aiBuilder.model": {
"type": "string",
"default": "gpt-4.1-mini",
"description": "Model name"
},
"aiBuilder.maxContextFiles": {
"type": "number",
"default": 200,
"description": "Max files to summarize in context"
},
"aiBuilder.allowWritePaths": {
"type": "array",
"items": {"type": "string"},
"default": ["src", "app", "public", "components"],
"description": "Directories allowed for write operations"
},
"aiBuilder.dryRun": {
"type": "boolean",
"default": true,
"description": "Preview patches without applying"
}
}
}
},
"main": "./dist/extension.js",
"scripts": {
"vscode:prepublish": "npm run build",
"build": "tsc -p .",
"watch": "tsc -watch -p ."
},
"devDependencies": {
"@types/node": "^20.11.28",
"@types/vscode": "^1.92.0",
"typescript": "^5.5.4"
},
"dependencies": {
"diff": "^5.2.0"
}
}
```

---

## 4) tsconfig.json

```json
{
"compilerOptions": {
"module": "commonjs",
"target": "es2020",
"outDir": "dist",
"lib": ["es2020"],
"sourceMap": true,
"rootDir": "src",
"strict": true,
"skipLibCheck": true
},
"include": ["src"]
}
```

---

## 5) src/extension.ts (تسجيل الأوامر والواجهة)

```ts
import * as vscode from 'vscode';
import { Agent } from './agent/Agent';
import { Panel } from './ui/Panel';

export async function activate(context: vscode.ExtensionContext) {
const panel = new Panel(context);
const agent = new Agent(context, panel);

context.subscriptions.push(
vscode.commands.registerCommand('aiBuilder.buildFromPrompt', async () => {
const prompt = await vscode.window.showInputBox({
prompt: 'اكتب وصفًا موجزًا للموقع/التطبيق المطلوب',
placeHolder: 'Landing page SaaS داكنة مع تسعير ولوحة إدارة...'
});
if (!prompt) return;
await agent.buildFromPrompt(prompt);
}),

vscode.commands.registerCommand('aiBuilder.explainPlan', async () => agent.showPlan()),
vscode.commands.registerCommand('aiBuilder.applyPlan', async () => agent.applyPlan()),

vscode.commands.registerCommand('aiBuilder.editSelection', async () => {
const editor = vscode.window.activeTextEditor;
if (!editor) return;
const selection = editor.document.getText(editor.selection);
const instruction = await vscode.window.showInputBox({ prompt: 'صف التعديل المطلوب' });
if (!instruction) return;
await agent.editSelection(editor.document.uri, editor.selection, selection, instruction);
}),

vscode.commands.registerCommand('aiBuilder.refactorProject', async () => agent.refactorProject()),
vscode.commands.registerCommand('aiBuilder.runTask', async () => agent.runTask())
);
}

export function deactivate() {}
```

---

## 6) src/agent/Agent.ts (حلقة الوكيل الأساسية)

```ts
import * as vscode from 'vscode';
import { getProvider } from '../llm/Provider';
import { collectContext } from './Context';
import { applyUnifiedDiff } from '../util/diff';
import { Panel } from '../ui/Panel';

export class Agent {
constructor(private ctx: vscode.ExtensionContext, private panel: Panel) {}

private plan: string | undefined;
private lastPatch: string | undefined;

async buildFromPrompt(userPrompt: string) {
this.panel.appendLog('Collecting project context...');
const context = await collectContext({ maxFiles: this.getCfg('aiBuilder.maxContextFiles') });

this.panel.show();
this.panel.setPlan('Generating plan...');

const provider = await getProvider(this.ctx);
const sys = SYSTEM_PROMPT;
const prompt = BUILD_PROMPT(userPrompt, context.summary);

const plan = await provider.complete(sys, prompt);
this.plan = plan;
this.panel.setPlan(plan);

// طلب Patch أولي
const patch = await provider.complete(sys, PATCH_PROMPT(context.filesIndex, plan));
this.lastPatch = patch;
this.panel.setPatch(patch);

if (this.getCfg('aiBuilder.dryRun')) {
this.panel.appendLog('Dry‑run enabled. Review patch before applying.');
return;
}
await this.applyPlan();
}

async showPlan() {
if (!this.plan) vscode.window.showWarningMessage('لا توجد خطة بعد');
else this.panel.setPlan(this.plan!);
}

async applyPlan() {
if (!this.lastPatch) return vscode.window.showWarningMessage('لا يوجد Patch للتطبيق');
await applyUnifiedDiff(this.lastPatch, this.getCfg('aiBuilder.allowWritePaths'));
vscode.window.showInformationMessage('تم تطبيق التغييرات.');
}

async editSelection(uri: vscode.Uri, sel: vscode.Range, code: string, instruction: string) {
const provider = await getProvider(this.ctx);
const sys = SYSTEM_PROMPT;
const msg = EDIT_SELECTION_PROMPT(uri.fsPath, code, instruction);
const patch = await provider.complete(sys, msg);
this.lastPatch = patch;
this.panel.setPatch(patch);
}

async refactorProject() { /* مشابه buildFromPrompt ولكن يركز على التحسين */ }
async runTask() { /* تنفيذ أمر في terminal + بث اللوغ للـ panel */ }

private getCfg(key: string) { return vscode.workspace.getConfiguration().get(key); }
}

const SYSTEM_PROMPT = `You are an expert software engineer agent. Always propose a PLAN then return changes as unified diffs. Respect allowed paths. Avoid destructive ops. Keep patches minimal and idempotent.`;

const BUILD_PROMPT = (userPrompt: string, projectSummary: string) => `
User Request:\n${userPrompt}\n\nProject Summary:\n${projectSummary}\n\nDeliverables:\n1) PLAN with steps.\n2) Minimal files list.\n3) Tech choices.\n`;

const PATCH_PROMPT = (filesIndex: string, plan: string) => `
You have file index:\n${filesIndex}\n\nBased on PLAN:\n${plan}\n\nReturn ONLY a unified diff patch to implement step 1. Use paths relative to workspace root.`;

const EDIT_SELECTION_PROMPT = (path: string, code: string, instruction: string) => `
File: ${path}
Selection:
"""
${code}
"""
Instruction: ${instruction}
Return a unified diff for this file only.`;
```

---

## 7) src/agent/Context.ts (تلخيص المشروع)

```ts
import * as vscode from 'vscode';

export async function collectContext(opts: { maxFiles: number }): Promise<{ summary: string; filesIndex: string; }> {
const u

Files changed (6) hide show
  1. README.md +8 -5
  2. components/footer.js +147 -0
  3. components/navbar.js +104 -0
  4. index.html +304 -19
  5. script.js +70 -0
  6. style.css +58 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Vs Code Ai Builder
3
- emoji: 📚
4
- colorFrom: green
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: VS Code AI Builder 🚀
3
+ colorFrom: pink
4
+ colorTo: green
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
components/footer.js ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomFooter extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ footer {
7
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
8
+ color: white;
9
+ padding: 3rem 2rem 2rem;
10
+ margin-top: auto;
11
+ border-top: 1px solid rgba(55, 65, 81, 0.3);
12
+ }
13
+ .footer-content {
14
+ max-width: 1200px;
15
+ margin: 0 auto;
16
+ display: grid;
17
+ grid-template-columns: 2fr 1fr 1fr 1fr;
18
+ gap: 3rem;
19
+ margin-bottom: 2rem;
20
+ }
21
+ .footer-brand h3 {
22
+ font-size: 1.5rem;
23
+ font-weight: bold;
24
+ margin-bottom: 1rem;
25
+ background: linear-gradient(135deg, #60a5fa 0%, #a78bfa 100%);
26
+ -webkit-background-clip: text;
27
+ -webkit-text-fill-color: transparent;
28
+ }
29
+ .footer-brand p {
30
+ color: #9ca3af;
31
+ line-height: 1.6;
32
+ }
33
+ .footer-section h4 {
34
+ font-size: 1.1rem;
35
+ font-weight: 600;
36
+ margin-bottom: 1rem;
37
+ color: #e5e7eb;
38
+ }
39
+ .footer-section ul {
40
+ list-style: none;
41
+ padding: 0;
42
+ margin: 0;
43
+ }
44
+ .footer-section li {
45
+ margin-bottom: 0.5rem;
46
+ }
47
+ .footer-section a {
48
+ color: #9ca3af;
49
+ text-decoration: none;
50
+ transition: color 0.2s;
51
+ }
52
+ .footer-section a:hover {
53
+ color: #a78bfa;
54
+ }
55
+ .footer-bottom {
56
+ max-width: 1200px;
57
+ margin: 0 auto;
58
+ padding-top: 2rem;
59
+ border-top: 1px solid rgba(55, 65, 81, 0.3);
60
+ text-align: center;
61
+ color: #6b7280;
62
+ display: flex;
63
+ justify-content: space-between;
64
+ align-items: center;
65
+ }
66
+ .social-links {
67
+ display: flex;
68
+ gap: 1rem;
69
+ }
70
+ .social-links a {
71
+ color: #6b7280;
72
+ transition: color 0.2s;
73
+ }
74
+ .social-links a:hover {
75
+ color: #a78bfa;
76
+ }
77
+ @media (max-width: 768px) {
78
+ .footer-content {
79
+ grid-template-columns: 1fr;
80
+ gap: 2rem;
81
+ }
82
+ .footer-bottom {
83
+ flex-direction: column;
84
+ gap: 1rem;
85
+ text-align: center;
86
+ }
87
+ }
88
+ </style>
89
+ <footer>
90
+ <div class="footer-content">
91
+ <div class="footer-brand">
92
+ <h3>VS Code AI Builder</h3>
93
+ <p>Agentic Codegen Extension for VS Code. Build complete applications from natural language prompts with AI assistance.</p>
94
+ </div>
95
+ <div class="footer-section">
96
+ <h4>Features</h4>
97
+ <ul>
98
+ <li><a href="#features">Build from Prompt</a></li>
99
+ <li><a href="#features">Project-Aware</a></li>
100
+ <li><a href="#features">Patch & Review</a></li>
101
+ <li><a href="#features">Safe Mode</a></li>
102
+ </ul>
103
+ </div>
104
+ <div class="footer-section">
105
+ <h4>Commands</h4>
106
+ <ul>
107
+ <li><a href="#commands">Build From Prompt</a></li>
108
+ <li><a href="#commands">Edit Selection</a></li>
109
+ <li><a href="#commands">Refactor Project</a></li>
110
+ <li><a href="#commands">Run Task</a></li>
111
+ </ul>
112
+ </div>
113
+ <div class="footer-section">
114
+ <h4>Resources</h4>
115
+ <ul>
116
+ <li><a href="#installation">Documentation</a></li>
117
+ <li><a href="https://github.com">GitHub</a></li>
118
+ <li><a href="#installation">Quick Start</a></li>
119
+ <li><a href="#installation">Configuration</a></li>
120
+ </ul>
121
+ </div>
122
+ </div>
123
+ <div class="footer-bottom">
124
+ <p>&copy; 2024 VS Code AI Builder. All rights reserved.</p>
125
+ <div class="social-links">
126
+ <a href="https://github.com" target="_blank" rel="noopener noreferrer">
127
+ <svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
128
+ <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0m6 13.5c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5m-6 1c-1.7 0-3-1.3-3-3s1.3-3 3-3 3 1.3 3 3-1.3 3-3 3m-6-1c-.8 0-1.5-.7-1.5-1.5S5.2 9 6 9s1.5.7 1.5 1.5S6.8 13.5 6 13.5z"/>
129
+ </svg>
130
+ </a>
131
+ <a href="#" target="_blank" rel="noopener noreferrer">
132
+ <svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
133
+ <path d="M22.46 6c-.77.35-1.6.58-2.46.69.88-.53 1.56-1.37 1.88-2.38-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29 0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15 0 1.49.75 2.81 1.91 3.56-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07 4.28 4.28 0 0 0 4 2.98 8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21 16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56.84-.6 1.56-1.36 2.14-2.23z"/>
134
+ </svg>
135
+ </a>
136
+ <a href="#" target="_blank" rel="noopener noreferrer">
137
+ <svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
138
+ <path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zM5.838 12a6.162 6.162 0 1 1 12.324 0 6.162 6.162 0 0 1-12.324 0zM12 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm4.965-10.405a1.44 1.44 0 1 1 2.881.001 1.44 1.44 0 0 1-2.881-.001z"/>
139
+ </svg>
140
+ </a>
141
+ </div>
142
+ </div>
143
+ </footer>
144
+ `;
145
+ }
146
+ }
147
+ customElements.define('custom-footer', CustomFooter);
components/navbar.js ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomNavbar extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ nav {
7
+ background: rgba(17, 24, 39, 0.95);
8
+ backdrop-filter: blur(10px);
9
+ padding: 1rem 2rem;
10
+ display: flex;
11
+ justify-content: space-between;
12
+ align-items: center;
13
+ position: fixed;
14
+ top: 0;
15
+ left: 0;
16
+ right: 0;
17
+ z-index: 50;
18
+ border-bottom: 1px solid rgba(55, 65, 81, 0.5);
19
+ }
20
+ .logo {
21
+ color: white;
22
+ font-weight: bold;
23
+ font-size: 1.25rem;
24
+ display: flex;
25
+ align-items: center;
26
+ gap: 0.5rem;
27
+ }
28
+ .logo-icon {
29
+ width: 24px;
30
+ height: 24px;
31
+ }
32
+ ul {
33
+ display: flex;
34
+ gap: 2rem;
35
+ list-style: none;
36
+ margin: 0;
37
+ padding: 0;
38
+ }
39
+ a {
40
+ color: rgb(209, 213, 219);
41
+ text-decoration: none;
42
+ transition: all 0.2s;
43
+ font-weight: 500;
44
+ }
45
+ a:hover {
46
+ color: rgb(167, 139, 250);
47
+ }
48
+ .nav-actions {
49
+ display: flex;
50
+ gap: 1rem;
51
+ align-items: center;
52
+ }
53
+ .btn-primary {
54
+ background: linear-gradient(135deg, rgb(59, 130, 246) 0%, rgb(147, 51, 234) 100%);
55
+ color: white;
56
+ padding: 0.5rem 1rem;
57
+ border-radius: 0.5rem;
58
+ text-decoration: none;
59
+ font-weight: 600;
60
+ transition: all 0.2s;
61
+ }
62
+ .btn-primary:hover {
63
+ transform: translateY(-1px);
64
+ box-shadow: 0 4px 12px rgba(147, 51, 234, 0.3);
65
+ }
66
+ @media (max-width: 768px) {
67
+ nav {
68
+ padding: 1rem;
69
+ }
70
+ ul {
71
+ gap: 1rem;
72
+ font-size: 0.9rem;
73
+ }
74
+ .nav-actions {
75
+ display: none;
76
+ }
77
+ }
78
+ </style>
79
+ <nav>
80
+ <div class="logo">
81
+ <svg class="logo-icon" fill="currentColor" viewBox="0 0 24 24">
82
+ <path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m9 16v-2H6v2h9m3-4v-2H6v2h12z"/>
83
+ </svg>
84
+ AI Builder
85
+ </div>
86
+ <ul>
87
+ <li><a href="#hero">Home</a></li>
88
+ <li><a href="#features">Features</a></li>
89
+ <li><a href="#commands">Commands</a></li>
90
+ <li><a href="#installation">Install</a></li>
91
+ </ul>
92
+ <div class="nav-actions">
93
+ <a href="https://github.com" target="_blank" rel="noopener noreferrer">
94
+ <svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
95
+ <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0m6 13.5c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5 1.5.7 1.5 1.5-.7 1.5-1.5 1.5m-6 1c-1.7 0-3-1.3-3-3s1.3-3 3-3 3 1.3 3 3-1.3 3-3 3m-6-1c-.8 0-1.5-.7-1.5-1.5S5.2 9 6 9s1.5.7 1.5 1.5S6.8 13.5 6 13.5z"/>
96
+ </svg>
97
+ </a>
98
+ <a href="#hero" class="btn-primary">Get Started</a>
99
+ </div>
100
+ </nav>
101
+ `;
102
+ }
103
+ }
104
+ customElements.define('custom-navbar', CustomNavbar);
index.html CHANGED
@@ -1,19 +1,304 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>VS Code AI Builder Extension - MVP</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <link rel="stylesheet" href="style.css">
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ <script src="https://unpkg.com/feather-icons"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
13
+ </head>
14
+ <body class="bg-gray-900 text-gray-100 min-h-screen">
15
+ <custom-navbar></custom-navbar>
16
+
17
+ <!-- Hero Section -->
18
+ <section id="hero" class="relative min-h-screen flex items-center justify-center overflow-hidden">
19
+ <div id="vanta-bg" class="absolute inset-0"></div>
20
+ <div class="relative z-10 text-center px-4 max-w-6xl mx-auto">
21
+ <div class="mb-8">
22
+ <h1 class="text-5xl md:text-7xl font-bold bg-gradient-to-r from-blue-400 via-purple-500 to-pink-500 bg-clip-text text-transparent mb-4">
23
+ VS Code AI Builder
24
+ </h1>
25
+ <p class="text-xl md:text-2xl text-gray-300 mb-2">Agentic Codegen Extension</p>
26
+ <p class="text-lg text-gray-400 max-w-3xl mx-auto">
27
+ Build complete websites and applications from a single prompt. See your project open, edit files professionally, and enjoy seamless development.
28
+ </p>
29
+ </div>
30
+
31
+ <div class="flex flex-col sm:flex-row gap-4 justify-center mb-12">
32
+ <button class="bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700 text-white font-bold py-3 px-8 rounded-lg transform transition hover:scale-105 shadow-xl">
33
+ <i data-feather="code" class="inline mr-2"></i>
34
+ Get Started
35
+ </button>
36
+ <button class="bg-gray-800 hover:bg-gray-700 text-white font-bold py-3 px-8 rounded-lg border border-gray-700 transform transition hover:scale-105">
37
+ <i data-feather="github" class="inline mr-2"></i>
38
+ View on GitHub
39
+ </button>
40
+ </div>
41
+
42
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mt-16">
43
+ <div class="bg-gray-800 bg-opacity-50 backdrop-blur-sm rounded-lg p-6 transform transition hover:scale-105">
44
+ <div class="text-blue-400 mb-4">
45
+ <i data-feather="zap" class="w-12 h-12"></i>
46
+ </div>
47
+ <h3 class="text-xl font-semibold mb-2">Build from Prompt</h3>
48
+ <p class="text-gray-400">Generate project structure, plan, and initial code from natural language descriptions</p>
49
+ </div>
50
+ <div class="bg-gray-800 bg-opacity-50 backdrop-blur-sm rounded-lg p-6 transform transition hover:scale-105">
51
+ <div class="text-purple-400 mb-4">
52
+ <i data-feather="edit-3" class="w-12 h-12"></i>
53
+ </div>
54
+ <h3 class="text-xl font-semibold mb-2">Project-Aware</h3>
55
+ <p class="text-gray-400">Read tree structure, summarize context, and work with existing codebases</p>
56
+ </div>
57
+ <div class="bg-gray-800 bg-opacity-50 backdrop-blur-sm rounded-lg p-6 transform transition hover:scale-105">
58
+ <div class="text-pink-400 mb-4">
59
+ <i data-feather="shield" class="w-12 h-12"></i>
60
+ </div>
61
+ <h3 class="text-xl font-semibold mb-2">Safe Mode</h3>
62
+ <p class="text-gray-400">Dry-run, path allowlists, and confirmation prompts for safe development</p>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ </section>
67
+
68
+ <!-- Features Section -->
69
+ <section class="py-20 px-4">
70
+ <div class="max-w-6xl mx-auto">
71
+ <h2 class="text-4xl font-bold text-center mb-12 bg-gradient-to-r from-blue-400 to-purple-500 bg-clip-text text-transparent">
72
+ Core Features
73
+ </h2>
74
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
75
+ <div class="bg-gray-800 rounded-lg p-8 border border-gray-700 hover:border-purple-500 transition">
76
+ <h3 class="text-2xl font-semibold mb-4 text-purple-400">
77
+ <i data-feather="git-branch" class="inline mr-2"></i>
78
+ Patch & Review
79
+ </h3>
80
+ <p class="text-gray-300 mb-4">
81
+ Receive changes in Unified Diff format, preview them visually, and apply selectively with confidence.
82
+ </p>
83
+ <ul class="text-gray-400 space-y-2">
84
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Visual diff viewer</li>
85
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Selective patch application</li>
86
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Rollback support</li>
87
+ </ul>
88
+ </div>
89
+
90
+ <div class="bg-gray-800 rounded-lg p-8 border border-gray-700 hover:border-blue-500 transition">
91
+ <h3 class="text-2xl font-semibold mb-4 text-blue-400">
92
+ <i data-feather="terminal" class="inline mr-2"></i>
93
+ Tasks Orchestrator
94
+ </h3>
95
+ <p class="text-gray-300 mb-4">
96
+ Run commands (npm/yarn/pnpm), dev servers, linters with live log streaming in the panel.
97
+ </p>
98
+ <ul class="text-gray-400 space-y-2">
99
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Real-time log streaming</li>
100
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Task queue management</li>
101
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Error detection</li>
102
+ </ul>
103
+ </div>
104
+
105
+ <div class="bg-gray-800 rounded-lg p-8 border border-gray-700 hover:border-pink-500 transition">
106
+ <h3 class="text-2xl font-semibold mb-4 text-pink-400">
107
+ <i data-feather="cpu" class="inline mr-2"></i>
108
+ Provider-Agnostic
109
+ </h3>
110
+ <p class="text-gray-300 mb-4">
111
+ Works with OpenAI, Anthropic, Gemini, and other LLM providers through a unified interface.
112
+ </p>
113
+ <ul class="text-gray-400 space-y-2">
114
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Multiple provider support</li>
115
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Easy switching</li>
116
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>API key management</li>
117
+ </ul>
118
+ </div>
119
+
120
+ <div class="bg-gray-800 rounded-lg p-8 border border-gray-700 hover:border-green-500 transition">
121
+ <h3 class="text-2xl font-semibold mb-4 text-green-400">
122
+ <i data-feather="command" class="inline mr-2"></i>
123
+ Command Suite
124
+ </h3>
125
+ <p class="text-gray-300 mb-4">
126
+ Comprehensive set of commands for every development stage and use case.
127
+ </p>
128
+ <ul class="text-gray-400 space-y-2">
129
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Build from prompt</li>
130
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Edit selection</li>
131
+ <li><i data-feather="check-circle" class="inline mr-2 text-green-400"></i>Refactor project</li>
132
+ </ul>
133
+ </div>
134
+ </div>
135
+ </div>
136
+ </section>
137
+
138
+ <!-- Commands Section -->
139
+ <section class="py-20 px-4 bg-gray-800 bg-opacity-50">
140
+ <div class="max-w-6xl mx-auto">
141
+ <h2 class="text-4xl font-bold text-center mb-12 bg-gradient-to-r from-purple-400 to-pink-500 bg-clip-text text-transparent">
142
+ Available Commands
143
+ </h2>
144
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
145
+ <div class="bg-gray-900 rounded-lg p-6 border border-gray-700 hover:border-blue-500 transition group">
146
+ <code class="text-blue-400 font-mono text-sm">aiBuilder.buildFromPrompt</code>
147
+ <p class="text-gray-400 mt-2 group-hover:text-gray-300 transition">
148
+ Build project from natural language prompt
149
+ </p>
150
+ </div>
151
+ <div class="bg-gray-900 rounded-lg p-6 border border-gray-700 hover:border-purple-500 transition group">
152
+ <code class="text-purple-400 font-mono text-sm">aiBuilder.explainPlan</code>
153
+ <p class="text-gray-400 mt-2 group-hover:text-gray-300 transition">
154
+ Show the execution plan before applying
155
+ </p>
156
+ </div>
157
+ <div class="bg-gray-900 rounded-lg p-6 border border-gray-700 hover:border-pink-500 transition group">
158
+ <code class="text-pink-400 font-mono text-sm">aiBuilder.applyPlan</code>
159
+ <p class="text-gray-400 mt-2 group-hover:text-gray-300 transition">
160
+ Apply the generated plan to workspace
161
+ </p>
162
+ </div>
163
+ <div class="bg-gray-900 rounded-lg p-6 border border-gray-700 hover:border-green-500 transition group">
164
+ <code class="text-green-400 font-mono text-sm">aiBuilder.editSelection</code>
165
+ <p class="text-gray-400 mt-2 group-hover:text-gray-300 transition">
166
+ Edit selected code with AI assistance
167
+ </p>
168
+ </div>
169
+ <div class="bg-gray-900 rounded-lg p-6 border border-gray-700 hover:border-yellow-500 transition group">
170
+ <code class="text-yellow-400 font-mono text-sm">aiBuilder.refactorProject</code>
171
+ <p class="text-gray-400 mt-2 group-hover:text-gray-300 transition">
172
+ Comprehensive project refactoring
173
+ </p>
174
+ </div>
175
+ <div class="bg-gray-900 rounded-lg p-6 border border-gray-700 hover:border-red-500 transition group">
176
+ <code class="text-red-400 font-mono text-sm">aiBuilder.runTask</code>
177
+ <p class="text-gray-400 mt-2 group-hover:text-gray-300 transition">
178
+ Execute development tasks with live logs
179
+ </p>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ </section>
184
+
185
+ <!-- Project Structure -->
186
+ <section class="py-20 px-4">
187
+ <div class="max-w-6xl mx-auto">
188
+ <h2 class="text-4xl font-bold text-center mb-12 bg-gradient-to-r from-green-400 to-blue-500 bg-clip-text text-transparent">
189
+ Project Structure
190
+ </h2>
191
+ <div class="bg-gray-800 rounded-lg p-8 overflow-x-auto">
192
+ <pre class="text-gray-300 font-mono text-sm">
193
+ <code class="language-bash">ai-builder-ext/
194
+ ├─ package.json
195
+ ├─ tsconfig.json
196
+ ├─ src/
197
+ │ ├─ extension.ts
198
+ │ ├─ agent/
199
+ │ │ ├─ Agent.ts
200
+ │ │ ├─ Patch.ts
201
+ │ │ ├─ Context.ts
202
+ │ │ └─ Tools.ts
203
+ │ ├─ llm/
204
+ │ │ ├─ Provider.ts
205
+ │ │ ├─ OpenAIProvider.ts
206
+ │ │ ├─ AnthropicProvider.ts
207
+ │ │ └─ GeminiProvider.ts
208
+ │ ├─ ui/
209
+ │ │ ├─ Panel.ts
210
+ │ │ └─ webview.html
211
+ │ └─ util/
212
+ │ ├─ fs.ts
213
+ │ └─ diff.ts
214
+ └─ README.md</code>
215
+ </pre>
216
+ </div>
217
+ </div>
218
+ </section>
219
+
220
+ <!-- Installation Guide -->
221
+ <section class="py-20 px-4 bg-gray-800 bg-opacity-50">
222
+ <div class="max-w-6xl mx-auto">
223
+ <h2 class="text-4xl font-bold text-center mb-12 bg-gradient-to-r from-pink-400 to-purple-500 bg-clip-text text-transparent">
224
+ Quick Start
225
+ </h2>
226
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
227
+ <div class="bg-gray-900 rounded-lg p-8">
228
+ <h3 class="text-2xl font-semibold mb-6 text-purple-400">
229
+ <i data-feather="download" class="inline mr-2"></i>
230
+ Installation
231
+ </h3>
232
+ <div class="space-y-4">
233
+ <div class="bg-gray-800 rounded p-4">
234
+ <p class="text-gray-400 mb-2">Prerequisites:</p>
235
+ <ul class="text-gray-300 space-y-1">
236
+ <li>• VS Code 1.92.0+</li>
237
+ <li>• Node.js 18+</li>
238
+ </ul>
239
+ </div>
240
+ <div class="bg-gray-800 rounded p-4">
241
+ <p class="text-gray-400 mb-2">Install dependencies:</p>
242
+ <code class="text-blue-400 font-mono text-sm">npm i</code>
243
+ </div>
244
+ <div class="bg-gray-800 rounded p-4">
245
+ <p class="text-gray-400 mb-2">Build in watch mode:</p>
246
+ <code class="text-blue-400 font-mono text-sm">npm run watch</code>
247
+ </div>
248
+ <div class="bg-gray-800 rounded p-4">
249
+ <p class="text-gray-400 mb-2">Press F5 to launch extension</p>
250
+ </div>
251
+ </div>
252
+ </div>
253
+
254
+ <div class="bg-gray-900 rounded-lg p-8">
255
+ <h3 class="text-2xl font-semibold mb-6 text-blue-400">
256
+ <i data-feather="settings" class="inline mr-2"></i>
257
+ Configuration
258
+ </h3>
259
+ <div class="space-y-4">
260
+ <div class="bg-gray-800 rounded p-4">
261
+ <p class="text-gray-400 mb-2">Select provider:</p>
262
+ <code class="text-blue-400 font-mono text-sm">aiBuilder.provider</code>
263
+ <p class="text-gray-500 text-sm mt-1">Options: openai, anthropic, gemini</p>
264
+ </div>
265
+ <div class="bg-gray-800 rounded p-4">
266
+ <p class="text-gray-400 mb-2">Set API Key:</p>
267
+ <code class="text-blue-400 font-mono text-sm">aiBuilder.apiKey</code>
268
+ <p class="text-gray-500 text-sm mt-1">Stored securely in VS Code SecretStorage</p>
269
+ </div>
270
+ <div class="bg-gray-800 rounded p-4">
271
+ <p class="text-gray-400 mb-2">Enable safe mode:</p>
272
+ <code class="text-blue-400 font-mono text-sm">aiBuilder.dryRun: true</code>
273
+ <p class="text-gray-500 text-sm mt-1">Preview changes before applying</p>
274
+ </div>
275
+ </div>
276
+ </div>
277
+ </div>
278
+ </div>
279
+ </section>
280
+
281
+ <custom-footer></custom-footer>
282
+
283
+ <script src="components/navbar.js"></script>
284
+ <script src="components/footer.js"></script>
285
+ <script src="script.js"></script>
286
+ <script>feather.replace();</script>
287
+ <script>
288
+ VANTA.GLOBE({
289
+ el: "#vanta-bg",
290
+ mouseControls: true,
291
+ touchControls: true,
292
+ gyroControls: false,
293
+ minHeight: 200.00,
294
+ minWidth: 200.00,
295
+ scale: 1.00,
296
+ scaleMobile: 1.00,
297
+ color: 0x7c3aed,
298
+ backgroundColor: 0x111827,
299
+ size: 0.80
300
+ })
301
+ </script>
302
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
303
+ </body>
304
+ </html>
script.js ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Initialize tooltips and interactive elements
2
+ document.addEventListener('DOMContentLoaded', () => {
3
+ // Smooth scroll for anchor links
4
+ document.querySelectorAll('a[href^="#"]').forEach(anchor => {
5
+ anchor.addEventListener('click', function (e) {
6
+ e.preventDefault();
7
+ const target = document.querySelector(this.getAttribute('href'));
8
+ if (target) {
9
+ target.scrollIntoView({ behavior: 'smooth', block: 'start' });
10
+ }
11
+ });
12
+ });
13
+
14
+ // Add active state to navigation items
15
+ const sections = document.querySelectorAll('section[id]');
16
+ const navLinks = document.querySelectorAll('nav a[href^="#"]');
17
+
18
+ function highlightNav() {
19
+ const scrollY = window.pageYOffset;
20
+
21
+ sections.forEach(section => {
22
+ const sectionHeight = section.offsetHeight;
23
+ const sectionTop = section.offsetTop - 100;
24
+ const sectionId = section.getAttribute('id');
25
+
26
+ if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) {
27
+ navLinks.forEach(link => {
28
+ link.classList.remove('text-purple-400');
29
+ link.classList.add('text-gray-300');
30
+ });
31
+ document.querySelector(`nav a[href*="${sectionId}"]`)?.classList.add('text-purple-400');
32
+ }
33
+ });
34
+ }
35
+
36
+ window.addEventListener('scroll', highlightNav);
37
+ highlightNav();
38
+
39
+ // Animate elements on scroll
40
+ const observerOptions = {
41
+ threshold: 0.1,
42
+ rootMargin: '0px 0px -50px 0px'
43
+ };
44
+
45
+ const observer = new IntersectionObserver((entries) => {
46
+ entries.forEach(entry => {
47
+ if (entry.isIntersecting) {
48
+ entry.target.classList.add('animate-fade-in');
49
+ }
50
+ });
51
+ }, observerOptions);
52
+
53
+ // Observe all feature cards and sections
54
+ document.querySelectorAll('.bg-gray-800, .bg-gray-900').forEach(el => {
55
+ observer.observe(el);
56
+ });
57
+ });
58
+
59
+ // Add fade-in animation
60
+ const style = document.createElement('style');
61
+ style.textContent = `
62
+ @keyframes fade-in {
63
+ from { opacity: 0; transform: translateY(20px); }
64
+ to { opacity: 1; transform: translateY(0); }
65
+ }
66
+ .animate-fade-in {
67
+ animation: fade-in 0.6s ease-out forwards;
68
+ }
69
+ `;
70
+ document.head.appendChild(style);
style.css CHANGED
@@ -1,28 +1,68 @@
 
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
 
 
28
  }
 
 
 
 
 
1
+ /* Custom styles for AI Builder Extension */
2
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
3
+
4
  body {
5
+ font-family: 'Inter', sans-serif;
6
+ }
7
+
8
+ /* Smooth scrolling */
9
+ html {
10
+ scroll-behavior: smooth;
11
+ }
12
+
13
+ /* Custom scrollbar */
14
+ ::-webkit-scrollbar {
15
+ width: 8px;
16
+ }
17
+
18
+ ::-webkit-scrollbar-track {
19
+ background: #1f2937;
20
+ }
21
+
22
+ ::-webkit-scrollbar-thumb {
23
+ background: #4b5563;
24
+ border-radius: 4px;
25
+ }
26
+
27
+ ::-webkit-scrollbar-thumb:hover {
28
+ background: #6b7280;
29
+ }
30
+
31
+ /* Code block styles */
32
+ pre {
33
+ background: #1f2937 !important;
34
+ border: 1px solid #374151;
35
+ border-radius: 0.5rem;
36
+ }
37
+
38
+ /* Gradient text animation */
39
+ @keyframes gradient {
40
+ 0% { background-position: 0% 50%; }
41
+ 50% { background-position: 100% 50%; }
42
+ 100% { background-position: 0% 50%; }
43
  }
44
 
45
+ .animate-gradient {
46
+ background-size: 200% 200%;
47
+ animation: gradient 3s ease infinite;
48
  }
49
 
50
+ /* Glow effect */
51
+ .glow {
52
+ box-shadow: 0 0 20px rgba(139, 92, 246, 0.5);
 
 
53
  }
54
 
55
+ /* Hover glow */
56
+ .hover-glow:hover {
57
+ box-shadow: 0 0 30px rgba(139, 92, 246, 0.7);
 
 
 
58
  }
59
 
60
+ /* Pulse animation */
61
+ @keyframes pulse {
62
+ 0%, 100% { opacity: 1; }
63
+ 50% { opacity: 0.5; }
64
  }
65
+
66
+ .animate-pulse-slow {
67
+ animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
68
+ }