chore: Rename project to AsiPilot
Browse files- README.md +1 -1
- package-lock.json +19 -19
- package.json +1 -1
- packages/client/index.html +2 -2
- packages/client/package.json +2 -2
- packages/client/src/components/ai/AgentResultsPanel.tsx +1 -1
- packages/client/src/components/editor/CodeEditor.tsx +3 -3
- packages/client/src/components/editor/EditorTabs.tsx +1 -1
- packages/client/src/components/explorer/FileTree.tsx +2 -2
- packages/client/src/components/landing/CTASection.tsx +1 -1
- packages/client/src/components/landing/FooterSection.tsx +2 -2
- packages/client/src/components/landing/Navbar.tsx +1 -1
- packages/client/src/components/landing/NumbersSection.tsx +1 -1
- packages/client/src/components/layout/IDEShell.tsx +23 -0
- packages/client/src/components/layout/PanelLayout.tsx +15 -45
- packages/client/src/components/layout/TopBar.tsx +1 -1
- packages/client/src/components/preview/LivePreview.tsx +18 -0
- packages/client/src/components/terminal/TerminalPanel.tsx +1 -2
- packages/client/src/hooks/useASI1Chat.ts +1 -1
- packages/client/src/hooks/useAgentReview.ts +1 -1
- packages/client/src/stores/aiStore.ts +1 -1
- packages/client/src/stores/fileStore.ts +6 -6
- packages/client/src/stores/githubStore.ts +1 -1
- packages/client/src/stores/settingsStore.ts +1 -1
- packages/server/package.json +2 -2
- packages/server/src/agents/base.agent.ts +1 -1
- packages/server/src/agents/documentation.agent.ts +1 -1
- packages/server/src/agents/orchestrator.ts +4 -4
- packages/server/src/agents/performance.agent.ts +1 -1
- packages/server/src/agents/security.agent.ts +1 -1
- packages/server/src/agents/style.agent.ts +1 -1
- packages/server/src/index.ts +1 -1
- packages/server/src/routes/analyze.routes.ts +1 -1
- packages/server/src/routes/chat.routes.ts +2 -2
- packages/server/src/routes/complete.routes.ts +1 -1
- packages/server/src/routes/github.routes.ts +1 -1
- packages/server/src/services/asi1-client.ts +1 -1
- packages/server/src/services/github.service.ts +2 -2
- packages/server/src/utils/file-utils.ts +1 -1
- packages/server/src/utils/logger.ts +1 -1
- packages/server/src/utils/token-counter.ts +1 -1
- packages/server/src/websocket/handler.ts +2 -2
- packages/shared/package.json +1 -1
README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
#
|
| 2 |
|
| 3 |
A browser-based IDE exclusively for frontend and web development, powered by ASI-1 Mini AI with multi-agent code review.
|
| 4 |
|
|
|
|
| 1 |
+
# AsiPilot
|
| 2 |
|
| 3 |
A browser-based IDE exclusively for frontend and web development, powered by ASI-1 Mini AI with multi-agent code review.
|
| 4 |
|
package-lock.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
{
|
| 2 |
-
"name": "
|
| 3 |
"version": "1.0.0",
|
| 4 |
"lockfileVersion": 3,
|
| 5 |
"requires": true,
|
| 6 |
"packages": {
|
| 7 |
"": {
|
| 8 |
-
"name": "
|
| 9 |
"version": "1.0.0",
|
| 10 |
"workspaces": [
|
| 11 |
"packages/*"
|
|
@@ -27,6 +27,18 @@
|
|
| 27 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 28 |
}
|
| 29 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
"node_modules/@babel/code-frame": {
|
| 31 |
"version": "7.29.0",
|
| 32 |
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
|
|
@@ -828,18 +840,6 @@
|
|
| 828 |
"url": "https://github.com/sponsors/ayuhito"
|
| 829 |
}
|
| 830 |
},
|
| 831 |
-
"node_modules/@frontendforge/client": {
|
| 832 |
-
"resolved": "packages/client",
|
| 833 |
-
"link": true
|
| 834 |
-
},
|
| 835 |
-
"node_modules/@frontendforge/server": {
|
| 836 |
-
"resolved": "packages/server",
|
| 837 |
-
"link": true
|
| 838 |
-
},
|
| 839 |
-
"node_modules/@frontendforge/shared": {
|
| 840 |
-
"resolved": "packages/shared",
|
| 841 |
-
"link": true
|
| 842 |
-
},
|
| 843 |
"node_modules/@ioredis/commands": {
|
| 844 |
"version": "1.5.1",
|
| 845 |
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.1.tgz",
|
|
@@ -6352,11 +6352,11 @@
|
|
| 6352 |
}
|
| 6353 |
},
|
| 6354 |
"packages/client": {
|
| 6355 |
-
"name": "@
|
| 6356 |
"version": "1.0.0",
|
| 6357 |
"dependencies": {
|
|
|
|
| 6358 |
"@fontsource/geist-sans": "^5.2.5",
|
| 6359 |
-
"@frontendforge/shared": "*",
|
| 6360 |
"@monaco-editor/react": "^4.6.0",
|
| 6361 |
"@radix-ui/react-dialog": "^1.0.5",
|
| 6362 |
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
|
@@ -6392,10 +6392,10 @@
|
|
| 6392 |
}
|
| 6393 |
},
|
| 6394 |
"packages/server": {
|
| 6395 |
-
"name": "@
|
| 6396 |
"version": "1.0.0",
|
| 6397 |
"dependencies": {
|
| 6398 |
-
"@
|
| 6399 |
"@octokit/rest": "^20.0.0",
|
| 6400 |
"axios": "^1.6.0",
|
| 6401 |
"cors": "^2.8.5",
|
|
@@ -6418,7 +6418,7 @@
|
|
| 6418 |
}
|
| 6419 |
},
|
| 6420 |
"packages/shared": {
|
| 6421 |
-
"name": "@
|
| 6422 |
"version": "1.0.0",
|
| 6423 |
"devDependencies": {
|
| 6424 |
"typescript": "^5.4.0"
|
|
|
|
| 1 |
{
|
| 2 |
+
"name": "asipilot",
|
| 3 |
"version": "1.0.0",
|
| 4 |
"lockfileVersion": 3,
|
| 5 |
"requires": true,
|
| 6 |
"packages": {
|
| 7 |
"": {
|
| 8 |
+
"name": "asipilot",
|
| 9 |
"version": "1.0.0",
|
| 10 |
"workspaces": [
|
| 11 |
"packages/*"
|
|
|
|
| 27 |
"url": "https://github.com/sponsors/sindresorhus"
|
| 28 |
}
|
| 29 |
},
|
| 30 |
+
"node_modules/@asipilot/client": {
|
| 31 |
+
"resolved": "packages/client",
|
| 32 |
+
"link": true
|
| 33 |
+
},
|
| 34 |
+
"node_modules/@asipilot/server": {
|
| 35 |
+
"resolved": "packages/server",
|
| 36 |
+
"link": true
|
| 37 |
+
},
|
| 38 |
+
"node_modules/@asipilot/shared": {
|
| 39 |
+
"resolved": "packages/shared",
|
| 40 |
+
"link": true
|
| 41 |
+
},
|
| 42 |
"node_modules/@babel/code-frame": {
|
| 43 |
"version": "7.29.0",
|
| 44 |
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
|
|
|
|
| 840 |
"url": "https://github.com/sponsors/ayuhito"
|
| 841 |
}
|
| 842 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 843 |
"node_modules/@ioredis/commands": {
|
| 844 |
"version": "1.5.1",
|
| 845 |
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.1.tgz",
|
|
|
|
| 6352 |
}
|
| 6353 |
},
|
| 6354 |
"packages/client": {
|
| 6355 |
+
"name": "@asipilot/client",
|
| 6356 |
"version": "1.0.0",
|
| 6357 |
"dependencies": {
|
| 6358 |
+
"@asipilot/shared": "*",
|
| 6359 |
"@fontsource/geist-sans": "^5.2.5",
|
|
|
|
| 6360 |
"@monaco-editor/react": "^4.6.0",
|
| 6361 |
"@radix-ui/react-dialog": "^1.0.5",
|
| 6362 |
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
|
|
|
| 6392 |
}
|
| 6393 |
},
|
| 6394 |
"packages/server": {
|
| 6395 |
+
"name": "@asipilot/server",
|
| 6396 |
"version": "1.0.0",
|
| 6397 |
"dependencies": {
|
| 6398 |
+
"@asipilot/shared": "*",
|
| 6399 |
"@octokit/rest": "^20.0.0",
|
| 6400 |
"axios": "^1.6.0",
|
| 6401 |
"cors": "^2.8.5",
|
|
|
|
| 6418 |
}
|
| 6419 |
},
|
| 6420 |
"packages/shared": {
|
| 6421 |
+
"name": "@asipilot/shared",
|
| 6422 |
"version": "1.0.0",
|
| 6423 |
"devDependencies": {
|
| 6424 |
"typescript": "^5.4.0"
|
package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
{
|
| 2 |
-
"name": "
|
| 3 |
"version": "1.0.0",
|
| 4 |
"private": true,
|
| 5 |
"workspaces": [
|
|
|
|
| 1 |
{
|
| 2 |
+
"name": "asipilot",
|
| 3 |
"version": "1.0.0",
|
| 4 |
"private": true,
|
| 5 |
"workspaces": [
|
packages/client/index.html
CHANGED
|
@@ -3,8 +3,8 @@
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8" />
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 6 |
-
<meta name="description" content="
|
| 7 |
-
<title>
|
| 8 |
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
| 9 |
</head>
|
| 10 |
<body>
|
|
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8" />
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 6 |
+
<meta name="description" content="AsiPilot — AI-powered browser IDE for frontend development with multi-agent code review, inline completions, and GitHub integration." />
|
| 7 |
+
<title>AsiPilot — AI-Powered Browser IDE</title>
|
| 8 |
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
| 9 |
</head>
|
| 10 |
<body>
|
packages/client/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
{
|
| 2 |
-
"name": "@
|
| 3 |
"version": "1.0.0",
|
| 4 |
"private": true,
|
| 5 |
"type": "module",
|
|
@@ -10,7 +10,7 @@
|
|
| 10 |
},
|
| 11 |
"dependencies": {
|
| 12 |
"@fontsource/geist-sans": "^5.2.5",
|
| 13 |
-
"@
|
| 14 |
"@monaco-editor/react": "^4.6.0",
|
| 15 |
"@radix-ui/react-dialog": "^1.0.5",
|
| 16 |
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
|
|
|
| 1 |
{
|
| 2 |
+
"name": "@asipilot/client",
|
| 3 |
"version": "1.0.0",
|
| 4 |
"private": true,
|
| 5 |
"type": "module",
|
|
|
|
| 10 |
},
|
| 11 |
"dependencies": {
|
| 12 |
"@fontsource/geist-sans": "^5.2.5",
|
| 13 |
+
"@asipilot/shared": "*",
|
| 14 |
"@monaco-editor/react": "^4.6.0",
|
| 15 |
"@radix-ui/react-dialog": "^1.0.5",
|
| 16 |
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
packages/client/src/components/ai/AgentResultsPanel.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button';
|
|
| 6 |
import { Shield, Zap, Paintbrush, FileText, ChevronDown, ChevronUp } from 'lucide-react';
|
| 7 |
import { useEditorStore } from '@/stores/editorStore';
|
| 8 |
import { cn } from '@/lib/utils';
|
| 9 |
-
import type { Finding, Severity } from '@
|
| 10 |
import { useState } from 'react';
|
| 11 |
|
| 12 |
const agentIcons: Record<string, typeof Shield> = {
|
|
|
|
| 6 |
import { Shield, Zap, Paintbrush, FileText, ChevronDown, ChevronUp } from 'lucide-react';
|
| 7 |
import { useEditorStore } from '@/stores/editorStore';
|
| 8 |
import { cn } from '@/lib/utils';
|
| 9 |
+
import type { Finding, Severity } from '@asipilot/shared';
|
| 10 |
import { useState } from 'react';
|
| 11 |
|
| 12 |
const agentIcons: Record<string, typeof Shield> = {
|
packages/client/src/components/editor/CodeEditor.tsx
CHANGED
|
@@ -24,7 +24,7 @@ export default function CodeEditor({ filePath, language }: CodeEditorProps) {
|
|
| 24 |
editorRef.current = editor;
|
| 25 |
|
| 26 |
// Define custom theme
|
| 27 |
-
monaco.editor.defineTheme('
|
| 28 |
base: 'vs-dark',
|
| 29 |
inherit: true,
|
| 30 |
rules: [
|
|
@@ -50,7 +50,7 @@ export default function CodeEditor({ filePath, language }: CodeEditorProps) {
|
|
| 50 |
'scrollbarSlider.hoverBackground': '#3a3a4a80',
|
| 51 |
},
|
| 52 |
});
|
| 53 |
-
monaco.editor.setTheme('
|
| 54 |
|
| 55 |
// Track cursor position
|
| 56 |
editor.onDidChangeCursorPosition((e: any) => {
|
|
@@ -97,7 +97,7 @@ export default function CodeEditor({ filePath, language }: CodeEditorProps) {
|
|
| 97 |
value={content}
|
| 98 |
onChange={handleChange}
|
| 99 |
onMount={handleMount}
|
| 100 |
-
theme="
|
| 101 |
options={{
|
| 102 |
fontSize,
|
| 103 |
tabSize,
|
|
|
|
| 24 |
editorRef.current = editor;
|
| 25 |
|
| 26 |
// Define custom theme
|
| 27 |
+
monaco.editor.defineTheme('asipilot-dark', {
|
| 28 |
base: 'vs-dark',
|
| 29 |
inherit: true,
|
| 30 |
rules: [
|
|
|
|
| 50 |
'scrollbarSlider.hoverBackground': '#3a3a4a80',
|
| 51 |
},
|
| 52 |
});
|
| 53 |
+
monaco.editor.setTheme('asipilot-dark');
|
| 54 |
|
| 55 |
// Track cursor position
|
| 56 |
editor.onDidChangeCursorPosition((e: any) => {
|
|
|
|
| 97 |
value={content}
|
| 98 |
onChange={handleChange}
|
| 99 |
onMount={handleMount}
|
| 100 |
+
theme="asipilot-dark"
|
| 101 |
options={{
|
| 102 |
fontSize,
|
| 103 |
tabSize,
|
packages/client/src/components/editor/EditorTabs.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import { X } from 'lucide-react';
|
| 2 |
import { useEditorStore } from '@/stores/editorStore';
|
| 3 |
import { cn } from '@/lib/utils';
|
| 4 |
-
import { getFileName } from '@
|
| 5 |
|
| 6 |
export default function EditorTabs() {
|
| 7 |
const openFiles = useEditorStore((s) => s.openFiles);
|
|
|
|
| 1 |
import { X } from 'lucide-react';
|
| 2 |
import { useEditorStore } from '@/stores/editorStore';
|
| 3 |
import { cn } from '@/lib/utils';
|
| 4 |
+
import { getFileName } from '@asipilot/shared';
|
| 5 |
|
| 6 |
export default function EditorTabs() {
|
| 7 |
const openFiles = useEditorStore((s) => s.openFiles);
|
packages/client/src/components/explorer/FileTree.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
| 1 |
import { useState } from 'react';
|
| 2 |
import { ChevronRight, ChevronDown, File, Folder, FolderOpen } from 'lucide-react';
|
| 3 |
-
import type { FileNode } from '@
|
| 4 |
import { useEditorStore } from '@/stores/editorStore';
|
| 5 |
import { useFileStore } from '@/stores/fileStore';
|
| 6 |
-
import { getLanguageFromPath } from '@
|
| 7 |
import { cn } from '@/lib/utils';
|
| 8 |
|
| 9 |
const FILE_ICONS: Record<string, string> = {
|
|
|
|
| 1 |
import { useState } from 'react';
|
| 2 |
import { ChevronRight, ChevronDown, File, Folder, FolderOpen } from 'lucide-react';
|
| 3 |
+
import type { FileNode } from '@asipilot/shared';
|
| 4 |
import { useEditorStore } from '@/stores/editorStore';
|
| 5 |
import { useFileStore } from '@/stores/fileStore';
|
| 6 |
+
import { getLanguageFromPath } from '@asipilot/shared';
|
| 7 |
import { cn } from '@/lib/utils';
|
| 8 |
|
| 9 |
const FILE_ICONS: Record<string, string> = {
|
packages/client/src/components/landing/CTASection.tsx
CHANGED
|
@@ -15,7 +15,7 @@ export default function CTASection() {
|
|
| 15 |
</p>
|
| 16 |
<div className="flex justify-center gap-4 mt-8">
|
| 17 |
<Link to="/ide">
|
| 18 |
-
<Button variant="hero">Launch
|
| 19 |
</Link>
|
| 20 |
<Button variant="heroSecondary">View on GitHub</Button>
|
| 21 |
</div>
|
|
|
|
| 15 |
</p>
|
| 16 |
<div className="flex justify-center gap-4 mt-8">
|
| 17 |
<Link to="/ide">
|
| 18 |
+
<Button variant="hero">Launch AsiPilot</Button>
|
| 19 |
</Link>
|
| 20 |
<Button variant="heroSecondary">View on GitHub</Button>
|
| 21 |
</div>
|
packages/client/src/components/landing/FooterSection.tsx
CHANGED
|
@@ -18,7 +18,7 @@ export default function FooterSection() {
|
|
| 18 |
<div className="w-7 h-7 rounded-lg bg-gradient-to-b from-secondary to-muted flex items-center justify-center">
|
| 19 |
<Terminal className="w-4 h-4 text-primary" />
|
| 20 |
</div>
|
| 21 |
-
<span className="text-xl font-semibold tracking-tight">
|
| 22 |
</Link>
|
| 23 |
<p className="text-muted-foreground text-sm mt-4 max-w-xs">
|
| 24 |
AI-powered browser IDE for frontend developers. Build, review, and ship with confidence.
|
|
@@ -44,7 +44,7 @@ export default function FooterSection() {
|
|
| 44 |
|
| 45 |
{/* Bottom Bar */}
|
| 46 |
<div className="border-t border-border/30 mt-12 pt-8 flex flex-col sm:flex-row justify-between items-center gap-4">
|
| 47 |
-
<p className="text-sm text-muted-foreground">© 2025
|
| 48 |
<div className="flex gap-6">
|
| 49 |
{['Privacy', 'Terms', 'Cookies'].map((item) => (
|
| 50 |
<a key={item} href="#" className="text-sm text-muted-foreground hover:text-foreground transition-colors">
|
|
|
|
| 18 |
<div className="w-7 h-7 rounded-lg bg-gradient-to-b from-secondary to-muted flex items-center justify-center">
|
| 19 |
<Terminal className="w-4 h-4 text-primary" />
|
| 20 |
</div>
|
| 21 |
+
<span className="text-xl font-semibold tracking-tight">AsiPilot</span>
|
| 22 |
</Link>
|
| 23 |
<p className="text-muted-foreground text-sm mt-4 max-w-xs">
|
| 24 |
AI-powered browser IDE for frontend developers. Build, review, and ship with confidence.
|
|
|
|
| 44 |
|
| 45 |
{/* Bottom Bar */}
|
| 46 |
<div className="border-t border-border/30 mt-12 pt-8 flex flex-col sm:flex-row justify-between items-center gap-4">
|
| 47 |
+
<p className="text-sm text-muted-foreground">© 2025 AsiPilot</p>
|
| 48 |
<div className="flex gap-6">
|
| 49 |
{['Privacy', 'Terms', 'Cookies'].map((item) => (
|
| 50 |
<a key={item} href="#" className="text-sm text-muted-foreground hover:text-foreground transition-colors">
|
packages/client/src/components/landing/Navbar.tsx
CHANGED
|
@@ -11,7 +11,7 @@ export default function Navbar() {
|
|
| 11 |
<div className="w-7 h-7 rounded-lg bg-gradient-to-b from-secondary to-muted flex items-center justify-center">
|
| 12 |
<Terminal className="w-4 h-4 text-primary" />
|
| 13 |
</div>
|
| 14 |
-
<span className="text-xl font-semibold tracking-tight text-foreground">
|
| 15 |
</Link>
|
| 16 |
|
| 17 |
{/* Nav Items */}
|
|
|
|
| 11 |
<div className="w-7 h-7 rounded-lg bg-gradient-to-b from-secondary to-muted flex items-center justify-center">
|
| 12 |
<Terminal className="w-4 h-4 text-primary" />
|
| 13 |
</div>
|
| 14 |
+
<span className="text-xl font-semibold tracking-tight text-foreground">AsiPilot</span>
|
| 15 |
</Link>
|
| 16 |
|
| 17 |
{/* Nav Items */}
|
packages/client/src/components/landing/NumbersSection.tsx
CHANGED
|
@@ -25,7 +25,7 @@ export default function NumbersSection() {
|
|
| 25 |
</p>
|
| 26 |
<p className="text-primary text-lg font-medium mt-2">Lines of code reviewed</p>
|
| 27 |
<p className="text-hero-sub max-w-md mx-auto mt-4">
|
| 28 |
-
Every day,
|
| 29 |
</p>
|
| 30 |
|
| 31 |
<div className="mt-24">
|
|
|
|
| 25 |
</p>
|
| 26 |
<p className="text-primary text-lg font-medium mt-2">Lines of code reviewed</p>
|
| 27 |
<p className="text-hero-sub max-w-md mx-auto mt-4">
|
| 28 |
+
Every day, AsiPilot's AI agents analyze thousands of files to keep codebases secure and performant.
|
| 29 |
</p>
|
| 30 |
|
| 31 |
<div className="mt-24">
|
packages/client/src/components/layout/IDEShell.tsx
CHANGED
|
@@ -3,15 +3,38 @@ import TopBar from './TopBar';
|
|
| 3 |
import StatusBar from './StatusBar';
|
| 4 |
import PanelLayout from './PanelLayout';
|
| 5 |
import { useFileStore } from '@/stores/fileStore';
|
|
|
|
| 6 |
|
| 7 |
export default function IDEShell() {
|
| 8 |
const [layout, setLayout] = useState<'editor' | 'split' | 'preview'>('split');
|
| 9 |
const initialize = useFileStore((s) => s.initialize);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
useEffect(() => {
|
| 12 |
initialize();
|
| 13 |
}, [initialize]);
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
return (
|
| 16 |
<div className="h-screen flex flex-col bg-background overflow-hidden">
|
| 17 |
<TopBar layout={layout} onLayoutChange={setLayout} />
|
|
|
|
| 3 |
import StatusBar from './StatusBar';
|
| 4 |
import PanelLayout from './PanelLayout';
|
| 5 |
import { useFileStore } from '@/stores/fileStore';
|
| 6 |
+
import { useEditorStore } from '@/stores/editorStore';
|
| 7 |
|
| 8 |
export default function IDEShell() {
|
| 9 |
const [layout, setLayout] = useState<'editor' | 'split' | 'preview'>('split');
|
| 10 |
const initialize = useFileStore((s) => s.initialize);
|
| 11 |
+
const initialized = useFileStore((s) => s.initialized);
|
| 12 |
+
const files = useFileStore((s) => s.files);
|
| 13 |
+
const addFile = useEditorStore((s) => s.addFile);
|
| 14 |
+
const openFiles = useEditorStore((s) => s.openFiles);
|
| 15 |
+
const [hasAutoOpened, setHasAutoOpened] = useState(false);
|
| 16 |
|
| 17 |
useEffect(() => {
|
| 18 |
initialize();
|
| 19 |
}, [initialize]);
|
| 20 |
|
| 21 |
+
useEffect(() => {
|
| 22 |
+
if (initialized && !hasAutoOpened) {
|
| 23 |
+
if (Object.keys(openFiles).length === 0 && files['index.html']) {
|
| 24 |
+
addFile('index.html', files['index.html'], 'html');
|
| 25 |
+
}
|
| 26 |
+
setHasAutoOpened(true);
|
| 27 |
+
}
|
| 28 |
+
}, [initialized, hasAutoOpened, files, openFiles, addFile]);
|
| 29 |
+
|
| 30 |
+
if (!initialized) {
|
| 31 |
+
return (
|
| 32 |
+
<div className="h-screen flex items-center justify-center bg-background">
|
| 33 |
+
<div className="text-muted-foreground animate-pulse font-mono text-sm">Initializing workspace...</div>
|
| 34 |
+
</div>
|
| 35 |
+
);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
return (
|
| 39 |
<div className="h-screen flex flex-col bg-background overflow-hidden">
|
| 40 |
<TopBar layout={layout} onLayoutChange={setLayout} />
|
packages/client/src/components/layout/PanelLayout.tsx
CHANGED
|
@@ -2,10 +2,7 @@ import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
|
|
| 2 |
import Sidebar from './Sidebar';
|
| 3 |
import MultiFileEditor from '@/components/editor/MultiFileEditor';
|
| 4 |
import LivePreview from '@/components/preview/LivePreview';
|
| 5 |
-
import TerminalPanel from '@/components/terminal/TerminalPanel';
|
| 6 |
import AIChatPanel from '@/components/ai/AIChatPanel';
|
| 7 |
-
import AgentResultsPanel from '@/components/ai/AgentResultsPanel';
|
| 8 |
-
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
|
| 9 |
|
| 10 |
interface PanelLayoutProps {
|
| 11 |
layout: 'editor' | 'split' | 'preview';
|
|
@@ -31,48 +28,21 @@ export default function PanelLayout({ layout }: PanelLayoutProps) {
|
|
| 31 |
|
| 32 |
<ResizeHandle direction="vertical" />
|
| 33 |
|
| 34 |
-
{/* Center: Editor +
|
| 35 |
-
<Panel defaultSize={52} minSize={30}>
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
</Panel>
|
| 50 |
-
</PanelGroup>
|
| 51 |
-
)}
|
| 52 |
-
</Panel>
|
| 53 |
-
|
| 54 |
-
<ResizeHandle direction="horizontal" />
|
| 55 |
-
|
| 56 |
-
{/* Bottom: Terminal + Agent Results */}
|
| 57 |
-
<Panel defaultSize={35} minSize={15} collapsible>
|
| 58 |
-
<Tabs defaultValue="terminal" className="h-full flex flex-col">
|
| 59 |
-
<TabsList className="h-8 rounded-none border-b border-border bg-background justify-start px-2">
|
| 60 |
-
<TabsTrigger value="terminal" className="text-xs h-7">Terminal</TabsTrigger>
|
| 61 |
-
<TabsTrigger value="agents" className="text-xs h-7">Agent Results</TabsTrigger>
|
| 62 |
-
<TabsTrigger value="console" className="text-xs h-7">Console</TabsTrigger>
|
| 63 |
-
</TabsList>
|
| 64 |
-
<TabsContent value="terminal" className="flex-1 min-h-0 mt-0">
|
| 65 |
-
<TerminalPanel />
|
| 66 |
-
</TabsContent>
|
| 67 |
-
<TabsContent value="agents" className="flex-1 min-h-0 mt-0 overflow-auto">
|
| 68 |
-
<AgentResultsPanel />
|
| 69 |
-
</TabsContent>
|
| 70 |
-
<TabsContent value="console" className="flex-1 min-h-0 mt-0 p-3">
|
| 71 |
-
<p className="text-xs text-muted-foreground">Console output from the preview iframe will appear here.</p>
|
| 72 |
-
</TabsContent>
|
| 73 |
-
</Tabs>
|
| 74 |
-
</Panel>
|
| 75 |
-
</PanelGroup>
|
| 76 |
</Panel>
|
| 77 |
|
| 78 |
<ResizeHandle direction="vertical" />
|
|
|
|
| 2 |
import Sidebar from './Sidebar';
|
| 3 |
import MultiFileEditor from '@/components/editor/MultiFileEditor';
|
| 4 |
import LivePreview from '@/components/preview/LivePreview';
|
|
|
|
| 5 |
import AIChatPanel from '@/components/ai/AIChatPanel';
|
|
|
|
|
|
|
| 6 |
|
| 7 |
interface PanelLayoutProps {
|
| 8 |
layout: 'editor' | 'split' | 'preview';
|
|
|
|
| 28 |
|
| 29 |
<ResizeHandle direction="vertical" />
|
| 30 |
|
| 31 |
+
{/* Center: Editor + Preview */}
|
| 32 |
+
<Panel defaultSize={52} minSize={30} className="flex flex-col overflow-hidden">
|
| 33 |
+
{layout === 'editor' && <MultiFileEditor />}
|
| 34 |
+
{layout === 'preview' && <LivePreview />}
|
| 35 |
+
{layout === 'split' && (
|
| 36 |
+
<PanelGroup direction="horizontal">
|
| 37 |
+
<Panel defaultSize={50}>
|
| 38 |
+
<MultiFileEditor />
|
| 39 |
+
</Panel>
|
| 40 |
+
<ResizeHandle direction="vertical" />
|
| 41 |
+
<Panel defaultSize={50}>
|
| 42 |
+
<LivePreview />
|
| 43 |
+
</Panel>
|
| 44 |
+
</PanelGroup>
|
| 45 |
+
)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
</Panel>
|
| 47 |
|
| 48 |
<ResizeHandle direction="vertical" />
|
packages/client/src/components/layout/TopBar.tsx
CHANGED
|
@@ -19,7 +19,7 @@ export default function TopBar({ layout, onLayoutChange }: TopBarProps) {
|
|
| 19 |
<button className="p-1.5 hover:bg-secondary rounded text-muted-foreground">
|
| 20 |
<Menu className="w-4 h-4" />
|
| 21 |
</button>
|
| 22 |
-
<span className="text-sm font-medium text-foreground ml-1">
|
| 23 |
|
| 24 |
<div className="flex-1" />
|
| 25 |
|
|
|
|
| 19 |
<button className="p-1.5 hover:bg-secondary rounded text-muted-foreground">
|
| 20 |
<Menu className="w-4 h-4" />
|
| 21 |
</button>
|
| 22 |
+
<span className="text-sm font-medium text-foreground ml-1">AsiPilot</span>
|
| 23 |
|
| 24 |
<div className="flex-1" />
|
| 25 |
|
packages/client/src/components/preview/LivePreview.tsx
CHANGED
|
@@ -29,6 +29,16 @@ export default function LivePreview() {
|
|
| 29 |
|
| 30 |
const viewport = viewports[viewportIndex];
|
| 31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
return (
|
| 33 |
<div className="flex flex-col h-full bg-background">
|
| 34 |
{/* Toolbar */}
|
|
@@ -40,6 +50,14 @@ export default function LivePreview() {
|
|
| 40 |
>
|
| 41 |
<RefreshCw className="w-3.5 h-3.5 text-muted-foreground" />
|
| 42 |
</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
{viewports.map((vp, i) => (
|
| 44 |
<button
|
| 45 |
key={vp.label}
|
|
|
|
| 29 |
|
| 30 |
const viewport = viewports[viewportIndex];
|
| 31 |
|
| 32 |
+
const handleOpenInNewTab = () => {
|
| 33 |
+
const newWindow = window.open('', '_blank');
|
| 34 |
+
if (newWindow) {
|
| 35 |
+
newWindow.document.open();
|
| 36 |
+
newWindow.document.write(srcdoc);
|
| 37 |
+
newWindow.document.close();
|
| 38 |
+
newWindow.document.title = 'AsiPilot Preview';
|
| 39 |
+
}
|
| 40 |
+
};
|
| 41 |
+
|
| 42 |
return (
|
| 43 |
<div className="flex flex-col h-full bg-background">
|
| 44 |
{/* Toolbar */}
|
|
|
|
| 50 |
>
|
| 51 |
<RefreshCw className="w-3.5 h-3.5 text-muted-foreground" />
|
| 52 |
</button>
|
| 53 |
+
<button
|
| 54 |
+
onClick={handleOpenInNewTab}
|
| 55 |
+
className="p-1.5 hover:bg-secondary rounded transition-colors"
|
| 56 |
+
title="Open in new tab"
|
| 57 |
+
>
|
| 58 |
+
<ExternalLink className="w-3.5 h-3.5 text-muted-foreground" />
|
| 59 |
+
</button>
|
| 60 |
+
<div className="w-px h-4 bg-border mx-1" />
|
| 61 |
{viewports.map((vp, i) => (
|
| 62 |
<button
|
| 63 |
key={vp.label}
|
packages/client/src/components/terminal/TerminalPanel.tsx
CHANGED
|
@@ -36,7 +36,7 @@ export default function TerminalPanel() {
|
|
| 36 |
terminal.open(containerRef.current);
|
| 37 |
fitAddon.fit();
|
| 38 |
|
| 39 |
-
terminal.writeln('\x1b[1;32m✦
|
| 40 |
terminal.writeln('\x1b[90mConnected to local environment.\x1b[0m');
|
| 41 |
terminal.writeln('');
|
| 42 |
terminal.write('\x1b[32m❯\x1b[0m ');
|
|
@@ -49,7 +49,6 @@ export default function TerminalPanel() {
|
|
| 49 |
terminal.writeln('');
|
| 50 |
if (currentLine.trim()) {
|
| 51 |
terminal.writeln(`\x1b[90m$ ${currentLine}\x1b[0m`);
|
| 52 |
-
terminal.writeln(`\x1b[33mNote:\x1b[0m Terminal commands run through the server WebSocket. Connect the server to enable command execution.`);
|
| 53 |
}
|
| 54 |
currentLine = '';
|
| 55 |
terminal.write('\x1b[32m❯\x1b[0m ');
|
|
|
|
| 36 |
terminal.open(containerRef.current);
|
| 37 |
fitAddon.fit();
|
| 38 |
|
| 39 |
+
terminal.writeln('\x1b[1;32m✦ AsiPilot Terminal\x1b[0m');
|
| 40 |
terminal.writeln('\x1b[90mConnected to local environment.\x1b[0m');
|
| 41 |
terminal.writeln('');
|
| 42 |
terminal.write('\x1b[32m❯\x1b[0m ');
|
|
|
|
| 49 |
terminal.writeln('');
|
| 50 |
if (currentLine.trim()) {
|
| 51 |
terminal.writeln(`\x1b[90m$ ${currentLine}\x1b[0m`);
|
|
|
|
| 52 |
}
|
| 53 |
currentLine = '';
|
| 54 |
terminal.write('\x1b[32m❯\x1b[0m ');
|
packages/client/src/hooks/useASI1Chat.ts
CHANGED
|
@@ -8,7 +8,7 @@ const ASI1_API_KEY = import.meta.env.VITE_ASI1_API_KEY || '';
|
|
| 8 |
const ASI1_MODEL = import.meta.env.VITE_ASI1_MODEL || 'asi1-mini';
|
| 9 |
|
| 10 |
const SYSTEM_PROMPT =
|
| 11 |
-
'You are
|
| 12 |
'CRITICAL INSTRUCTION: When you provide code that should be applied to a file, you MUST start the code block with a markdown bolded filename, followed immediately by the fenced code block. Example:\n' +
|
| 13 |
'**`src/App.tsx`**\n' +
|
| 14 |
'```tsx\n' +
|
|
|
|
| 8 |
const ASI1_MODEL = import.meta.env.VITE_ASI1_MODEL || 'asi1-mini';
|
| 9 |
|
| 10 |
const SYSTEM_PROMPT =
|
| 11 |
+
'You are AsiPilot AI, an expert frontend development assistant. You help with HTML, CSS, JavaScript, TypeScript, React, Vue, Svelte, Next.js, and more.\n' +
|
| 12 |
'CRITICAL INSTRUCTION: When you provide code that should be applied to a file, you MUST start the code block with a markdown bolded filename, followed immediately by the fenced code block. Example:\n' +
|
| 13 |
'**`src/App.tsx`**\n' +
|
| 14 |
'```tsx\n' +
|
packages/client/src/hooks/useAgentReview.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { useCallback, useState } from 'react';
|
|
| 2 |
import { useWebSocket } from './useWebSocket';
|
| 3 |
import { useAIStore } from '@/stores/aiStore';
|
| 4 |
import { useFileStore } from '@/stores/fileStore';
|
| 5 |
-
import type { AgentType, AgentProgressEvent, FullReviewResult } from '@
|
| 6 |
|
| 7 |
export function useAgentReview() {
|
| 8 |
const { socket } = useWebSocket();
|
|
|
|
| 2 |
import { useWebSocket } from './useWebSocket';
|
| 3 |
import { useAIStore } from '@/stores/aiStore';
|
| 4 |
import { useFileStore } from '@/stores/fileStore';
|
| 5 |
+
import type { AgentType, AgentProgressEvent, FullReviewResult } from '@asipilot/shared';
|
| 6 |
|
| 7 |
export function useAgentReview() {
|
| 8 |
const { socket } = useWebSocket();
|
packages/client/src/stores/aiStore.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import { create } from 'zustand';
|
| 2 |
-
import type { ChatMessage, AgentResult, Finding, AgentType } from '@
|
| 3 |
|
| 4 |
interface AIState {
|
| 5 |
messages: ChatMessage[];
|
|
|
|
| 1 |
import { create } from 'zustand';
|
| 2 |
+
import type { ChatMessage, AgentResult, Finding, AgentType } from '@asipilot/shared';
|
| 3 |
|
| 4 |
interface AIState {
|
| 5 |
messages: ChatMessage[];
|
packages/client/src/stores/fileStore.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import { create } from 'zustand';
|
| 2 |
-
import type { FileNode } from '@
|
| 3 |
|
| 4 |
const DEFAULT_FILES: Record<string, string> = {
|
| 5 |
'index.html': `<!DOCTYPE html>
|
|
@@ -12,7 +12,7 @@ const DEFAULT_FILES: Record<string, string> = {
|
|
| 12 |
</head>
|
| 13 |
<body>
|
| 14 |
<div id="app">
|
| 15 |
-
<h1>Hello,
|
| 16 |
<p>Start editing to see changes in the live preview.</p>
|
| 17 |
</div>
|
| 18 |
<script src="script.js"></script>
|
|
@@ -51,18 +51,18 @@ p {
|
|
| 51 |
color: #a0a0a0;
|
| 52 |
font-size: 1.1rem;
|
| 53 |
}`,
|
| 54 |
-
'script.js': `// Welcome to
|
| 55 |
-
console.log("Hello from
|
| 56 |
|
| 57 |
document.addEventListener('DOMContentLoaded', () => {
|
| 58 |
const app = document.getElementById('app');
|
| 59 |
const btn = document.createElement('button');
|
| 60 |
btn.textContent = 'Click me';
|
| 61 |
btn.style.cssText = 'margin-top:1.5rem;padding:0.75rem 2rem;background:#81f084;color:#000;border:none;border-radius:8px;font-size:1rem;cursor:pointer;font-weight:600';
|
| 62 |
-
btn.addEventListener('click', () => alert('
|
| 63 |
app?.appendChild(btn);
|
| 64 |
});`,
|
| 65 |
-
'README.md': `# My Project\n\nBuilt with
|
| 66 |
};
|
| 67 |
|
| 68 |
interface FileStore {
|
|
|
|
| 1 |
import { create } from 'zustand';
|
| 2 |
+
import type { FileNode } from '@asipilot/shared';
|
| 3 |
|
| 4 |
const DEFAULT_FILES: Record<string, string> = {
|
| 5 |
'index.html': `<!DOCTYPE html>
|
|
|
|
| 12 |
</head>
|
| 13 |
<body>
|
| 14 |
<div id="app">
|
| 15 |
+
<h1>Hello, AsiPilot!</h1>
|
| 16 |
<p>Start editing to see changes in the live preview.</p>
|
| 17 |
</div>
|
| 18 |
<script src="script.js"></script>
|
|
|
|
| 51 |
color: #a0a0a0;
|
| 52 |
font-size: 1.1rem;
|
| 53 |
}`,
|
| 54 |
+
'script.js': `// Welcome to AsiPilot!
|
| 55 |
+
console.log("Hello from AsiPilot!");
|
| 56 |
|
| 57 |
document.addEventListener('DOMContentLoaded', () => {
|
| 58 |
const app = document.getElementById('app');
|
| 59 |
const btn = document.createElement('button');
|
| 60 |
btn.textContent = 'Click me';
|
| 61 |
btn.style.cssText = 'margin-top:1.5rem;padding:0.75rem 2rem;background:#81f084;color:#000;border:none;border-radius:8px;font-size:1rem;cursor:pointer;font-weight:600';
|
| 62 |
+
btn.addEventListener('click', () => alert('AsiPilot is working!'));
|
| 63 |
app?.appendChild(btn);
|
| 64 |
});`,
|
| 65 |
+
'README.md': `# My Project\n\nBuilt with AsiPilot — the AI-powered browser IDE.\n`,
|
| 66 |
};
|
| 67 |
|
| 68 |
interface FileStore {
|
packages/client/src/stores/githubStore.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import { create } from 'zustand';
|
| 2 |
-
import type { FileNode } from '@
|
| 3 |
|
| 4 |
interface GitHubState {
|
| 5 |
owner: string;
|
|
|
|
| 1 |
import { create } from 'zustand';
|
| 2 |
+
import type { FileNode } from '@asipilot/shared';
|
| 3 |
|
| 4 |
interface GitHubState {
|
| 5 |
owner: string;
|
packages/client/src/stores/settingsStore.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import { create } from 'zustand';
|
| 2 |
-
import type { UserSettings } from '@
|
| 3 |
|
| 4 |
interface SettingsState extends UserSettings {
|
| 5 |
updateSetting: <K extends keyof UserSettings>(key: K, value: UserSettings[K]) => void;
|
|
|
|
| 1 |
import { create } from 'zustand';
|
| 2 |
+
import type { UserSettings } from '@asipilot/shared';
|
| 3 |
|
| 4 |
interface SettingsState extends UserSettings {
|
| 5 |
updateSetting: <K extends keyof UserSettings>(key: K, value: UserSettings[K]) => void;
|
packages/server/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
{
|
| 2 |
-
"name": "@
|
| 3 |
"version": "1.0.0",
|
| 4 |
"private": true,
|
| 5 |
"type": "module",
|
|
@@ -10,7 +10,7 @@
|
|
| 10 |
"start": "node dist/index.js"
|
| 11 |
},
|
| 12 |
"dependencies": {
|
| 13 |
-
"@
|
| 14 |
"@octokit/rest": "^20.0.0",
|
| 15 |
"axios": "^1.6.0",
|
| 16 |
"cors": "^2.8.5",
|
|
|
|
| 1 |
{
|
| 2 |
+
"name": "@asipilot/server",
|
| 3 |
"version": "1.0.0",
|
| 4 |
"private": true,
|
| 5 |
"type": "module",
|
|
|
|
| 10 |
"start": "node dist/index.js"
|
| 11 |
},
|
| 12 |
"dependencies": {
|
| 13 |
+
"@asipilot/shared": "*",
|
| 14 |
"@octokit/rest": "^20.0.0",
|
| 15 |
"axios": "^1.6.0",
|
| 16 |
"cors": "^2.8.5",
|
packages/server/src/agents/base.agent.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import crypto from 'crypto';
|
| 2 |
-
import { AgentResult, AgentOptions, Finding, AgentSummary, AgentType, estimateTokens } from '@
|
| 3 |
import { ASI1Client, asi1 } from '../services/asi1-client.js';
|
| 4 |
import { cache, CacheService } from '../services/cache.service.js';
|
| 5 |
import { logger } from '../utils/logger.js';
|
|
|
|
| 1 |
import crypto from 'crypto';
|
| 2 |
+
import { AgentResult, AgentOptions, Finding, AgentSummary, AgentType, estimateTokens } from '@asipilot/shared';
|
| 3 |
import { ASI1Client, asi1 } from '../services/asi1-client.js';
|
| 4 |
import { cache, CacheService } from '../services/cache.service.js';
|
| 5 |
import { logger } from '../utils/logger.js';
|
packages/server/src/agents/documentation.agent.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { AgentResult, AgentOptions, AgentType, DocMode } from '@
|
| 2 |
import { BaseAgent } from './base.agent.js';
|
| 3 |
import { parseJSONSafe } from '../utils/code-parser.js';
|
| 4 |
|
|
|
|
| 1 |
+
import { AgentResult, AgentOptions, AgentType, DocMode } from '@asipilot/shared';
|
| 2 |
import { BaseAgent } from './base.agent.js';
|
| 3 |
import { parseJSONSafe } from '../utils/code-parser.js';
|
| 4 |
|
packages/server/src/agents/orchestrator.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
| 3 |
AgentType, AgentResult, AgentProgressEvent, Finding, FullReviewResult,
|
| 4 |
QuickReviewResult, PRFixSet, FileChange, AgentOptions,
|
| 5 |
SEVERITY_ORDER, estimateTokens, ALL_AGENTS,
|
| 6 |
-
} from '@
|
| 7 |
import { SecurityAgent } from './security.agent.js';
|
| 8 |
import { PerformanceAgent } from './performance.agent.js';
|
| 9 |
import { StyleAgent } from './style.agent.js';
|
|
@@ -176,10 +176,10 @@ Respond with valid JSON:
|
|
| 176 |
const parsed = JSON.parse(response.choices[0]?.message?.content || '{}');
|
| 177 |
|
| 178 |
return {
|
| 179 |
-
branchName: `
|
| 180 |
commitMessage: parsed.commitMessage || 'fix: apply code review fixes',
|
| 181 |
-
prTitle: parsed.prTitle || '
|
| 182 |
-
prBody: parsed.prBody || 'Automated fixes from
|
| 183 |
fileChanges: parsed.fileChanges || [],
|
| 184 |
};
|
| 185 |
}
|
|
|
|
| 3 |
AgentType, AgentResult, AgentProgressEvent, Finding, FullReviewResult,
|
| 4 |
QuickReviewResult, PRFixSet, FileChange, AgentOptions,
|
| 5 |
SEVERITY_ORDER, estimateTokens, ALL_AGENTS,
|
| 6 |
+
} from '@asipilot/shared';
|
| 7 |
import { SecurityAgent } from './security.agent.js';
|
| 8 |
import { PerformanceAgent } from './performance.agent.js';
|
| 9 |
import { StyleAgent } from './style.agent.js';
|
|
|
|
| 176 |
const parsed = JSON.parse(response.choices[0]?.message?.content || '{}');
|
| 177 |
|
| 178 |
return {
|
| 179 |
+
branchName: `asipilot/fix-${Date.now()}`,
|
| 180 |
commitMessage: parsed.commitMessage || 'fix: apply code review fixes',
|
| 181 |
+
prTitle: parsed.prTitle || 'AsiPilot: Code Review Fixes',
|
| 182 |
+
prBody: parsed.prBody || 'Automated fixes from AsiPilot code review.',
|
| 183 |
fileChanges: parsed.fileChanges || [],
|
| 184 |
};
|
| 185 |
}
|
packages/server/src/agents/performance.agent.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { AgentResult, AgentOptions, AgentType } from '@
|
| 2 |
import { BaseAgent } from './base.agent.js';
|
| 3 |
|
| 4 |
export class PerformanceAgent extends BaseAgent {
|
|
|
|
| 1 |
+
import { AgentResult, AgentOptions, AgentType } from '@asipilot/shared';
|
| 2 |
import { BaseAgent } from './base.agent.js';
|
| 3 |
|
| 4 |
export class PerformanceAgent extends BaseAgent {
|
packages/server/src/agents/security.agent.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { AgentResult, AgentOptions, AgentType } from '@
|
| 2 |
import { BaseAgent } from './base.agent.js';
|
| 3 |
|
| 4 |
export class SecurityAgent extends BaseAgent {
|
|
|
|
| 1 |
+
import { AgentResult, AgentOptions, AgentType } from '@asipilot/shared';
|
| 2 |
import { BaseAgent } from './base.agent.js';
|
| 3 |
|
| 4 |
export class SecurityAgent extends BaseAgent {
|
packages/server/src/agents/style.agent.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { AgentResult, AgentOptions, AgentType } from '@
|
| 2 |
import { BaseAgent } from './base.agent.js';
|
| 3 |
|
| 4 |
export class StyleAgent extends BaseAgent {
|
|
|
|
| 1 |
+
import { AgentResult, AgentOptions, AgentType } from '@asipilot/shared';
|
| 2 |
import { BaseAgent } from './base.agent.js';
|
| 3 |
|
| 4 |
export class StyleAgent extends BaseAgent {
|
packages/server/src/index.ts
CHANGED
|
@@ -42,7 +42,7 @@ setupWebSocketHandlers(io);
|
|
| 42 |
|
| 43 |
// Start server
|
| 44 |
httpServer.listen(config.PORT, () => {
|
| 45 |
-
logger.info(`🚀
|
| 46 |
logger.info(` Environment: ${config.NODE_ENV}`);
|
| 47 |
logger.info(` Client URL: ${config.CLIENT_URL}`);
|
| 48 |
});
|
|
|
|
| 42 |
|
| 43 |
// Start server
|
| 44 |
httpServer.listen(config.PORT, () => {
|
| 45 |
+
logger.info(`🚀 AsiPilot server running on port ${config.PORT}`);
|
| 46 |
logger.info(` Environment: ${config.NODE_ENV}`);
|
| 47 |
logger.info(` Client URL: ${config.CLIENT_URL}`);
|
| 48 |
});
|
packages/server/src/routes/analyze.routes.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import { Router, Request, Response } from 'express';
|
| 2 |
import { orchestrator } from '../agents/orchestrator.js';
|
| 3 |
import { analyzeLimiter } from '../middleware/rate-limit.middleware.js';
|
| 4 |
-
import type { AgentType } from '@
|
| 5 |
|
| 6 |
const router = Router();
|
| 7 |
|
|
|
|
| 1 |
import { Router, Request, Response } from 'express';
|
| 2 |
import { orchestrator } from '../agents/orchestrator.js';
|
| 3 |
import { analyzeLimiter } from '../middleware/rate-limit.middleware.js';
|
| 4 |
+
import type { AgentType } from '@asipilot/shared';
|
| 5 |
|
| 6 |
const router = Router();
|
| 7 |
|
packages/server/src/routes/chat.routes.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import { Router, Request, Response } from 'express';
|
| 2 |
import { asi1 } from '../services/asi1-client.js';
|
| 3 |
import { defaultLimiter } from '../middleware/rate-limit.middleware.js';
|
| 4 |
-
import type { ASI1Message, ChatRequest } from '@
|
| 5 |
|
| 6 |
const router = Router();
|
| 7 |
|
|
@@ -16,7 +16,7 @@ router.post('/', defaultLimiter, async (req: Request, res: Response) => {
|
|
| 16 |
const messages: ASI1Message[] = [
|
| 17 |
{
|
| 18 |
role: 'system',
|
| 19 |
-
content: 'You are
|
| 20 |
},
|
| 21 |
...history,
|
| 22 |
{ role: 'user', content: message },
|
|
|
|
| 1 |
import { Router, Request, Response } from 'express';
|
| 2 |
import { asi1 } from '../services/asi1-client.js';
|
| 3 |
import { defaultLimiter } from '../middleware/rate-limit.middleware.js';
|
| 4 |
+
import type { ASI1Message, ChatRequest } from '@asipilot/shared';
|
| 5 |
|
| 6 |
const router = Router();
|
| 7 |
|
|
|
|
| 16 |
const messages: ASI1Message[] = [
|
| 17 |
{
|
| 18 |
role: 'system',
|
| 19 |
+
content: 'You are AsiPilot AI, an expert frontend development assistant. You help with HTML, CSS, JavaScript, TypeScript, React, Vue, Svelte, Next.js, Tailwind CSS, and all frontend technologies. Provide clear, concise, and accurate code with explanations. When showing code, use appropriate language tags in code blocks.',
|
| 20 |
},
|
| 21 |
...history,
|
| 22 |
{ role: 'user', content: message },
|
packages/server/src/routes/complete.routes.ts
CHANGED
|
@@ -3,7 +3,7 @@ import crypto from 'crypto';
|
|
| 3 |
import { asi1 } from '../services/asi1-client.js';
|
| 4 |
import { cache } from '../services/cache.service.js';
|
| 5 |
import { completionLimiter } from '../middleware/rate-limit.middleware.js';
|
| 6 |
-
import { CACHE_TTL } from '@
|
| 7 |
|
| 8 |
const router = Router();
|
| 9 |
|
|
|
|
| 3 |
import { asi1 } from '../services/asi1-client.js';
|
| 4 |
import { cache } from '../services/cache.service.js';
|
| 5 |
import { completionLimiter } from '../middleware/rate-limit.middleware.js';
|
| 6 |
+
import { CACHE_TTL } from '@asipilot/shared';
|
| 7 |
|
| 8 |
const router = Router();
|
| 9 |
|
packages/server/src/routes/github.routes.ts
CHANGED
|
@@ -44,7 +44,7 @@ router.post('/pr', defaultLimiter, async (req: Request, res: Response) => {
|
|
| 44 |
}
|
| 45 |
|
| 46 |
const prUrl = await github.createPR(
|
| 47 |
-
owner, repo, baseBranch || 'main', changes, title || '
|
| 48 |
);
|
| 49 |
|
| 50 |
res.json({ success: true, data: { prUrl } });
|
|
|
|
| 44 |
}
|
| 45 |
|
| 46 |
const prUrl = await github.createPR(
|
| 47 |
+
owner, repo, baseBranch || 'main', changes, title || 'AsiPilot Fixes', body || ''
|
| 48 |
);
|
| 49 |
|
| 50 |
res.json({ success: true, data: { prUrl } });
|
packages/server/src/services/asi1-client.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import axios, { AxiosInstance, AxiosError } from 'axios';
|
| 2 |
-
import { ASI1Message, ASI1Response, ASI1StreamResponse, ASI1_DEFAULTS } from '@
|
| 3 |
import { config } from '../config/env.js';
|
| 4 |
import { logger } from '../utils/logger.js';
|
| 5 |
import { stripCodeFences } from '../utils/code-parser.js';
|
|
|
|
| 1 |
import axios, { AxiosInstance, AxiosError } from 'axios';
|
| 2 |
+
import { ASI1Message, ASI1Response, ASI1StreamResponse, ASI1_DEFAULTS } from '@asipilot/shared';
|
| 3 |
import { config } from '../config/env.js';
|
| 4 |
import { logger } from '../utils/logger.js';
|
| 5 |
import { stripCodeFences } from '../utils/code-parser.js';
|
packages/server/src/services/github.service.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import { Octokit } from '@octokit/rest';
|
| 2 |
-
import { FileNode, FileChange, EXCLUDED_DIRECTORIES, FRONTEND_EXTENSIONS } from '@
|
| 3 |
import { config } from '../config/env.js';
|
| 4 |
import { logger } from '../utils/logger.js';
|
| 5 |
import { getLanguageFromPath, isBinaryFile } from '../utils/file-utils.js';
|
|
@@ -136,7 +136,7 @@ class GitHubService {
|
|
| 136 |
});
|
| 137 |
|
| 138 |
// Create branch
|
| 139 |
-
const branchName = `
|
| 140 |
await this.octokit.git.createRef({
|
| 141 |
owner, repo, ref: `refs/heads/${branchName}`, sha: commit.sha,
|
| 142 |
});
|
|
|
|
| 1 |
import { Octokit } from '@octokit/rest';
|
| 2 |
+
import { FileNode, FileChange, EXCLUDED_DIRECTORIES, FRONTEND_EXTENSIONS } from '@asipilot/shared';
|
| 3 |
import { config } from '../config/env.js';
|
| 4 |
import { logger } from '../utils/logger.js';
|
| 5 |
import { getLanguageFromPath, isBinaryFile } from '../utils/file-utils.js';
|
|
|
|
| 136 |
});
|
| 137 |
|
| 138 |
// Create branch
|
| 139 |
+
const branchName = `asipilot/fix-${Date.now()}`;
|
| 140 |
await this.octokit.git.createRef({
|
| 141 |
owner, repo, ref: `refs/heads/${branchName}`, sha: commit.sha,
|
| 142 |
});
|
packages/server/src/utils/file-utils.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { getLanguageFromPath, isBinaryFile, getFileExtension, getFileName } from '@
|
| 2 |
|
| 3 |
export { getLanguageFromPath, isBinaryFile, getFileExtension, getFileName };
|
| 4 |
|
|
|
|
| 1 |
+
import { getLanguageFromPath, isBinaryFile, getFileExtension, getFileName } from '@asipilot/shared';
|
| 2 |
|
| 3 |
export { getLanguageFromPath, isBinaryFile, getFileExtension, getFileName };
|
| 4 |
|
packages/server/src/utils/logger.ts
CHANGED
|
@@ -18,5 +18,5 @@ export const logger = winston.createLogger({
|
|
| 18 |
level: config.LOG_LEVEL,
|
| 19 |
format: config.NODE_ENV === 'production' ? prodFormat : devFormat,
|
| 20 |
transports: [new winston.transports.Console()],
|
| 21 |
-
defaultMeta: { service: '
|
| 22 |
});
|
|
|
|
| 18 |
level: config.LOG_LEVEL,
|
| 19 |
format: config.NODE_ENV === 'production' ? prodFormat : devFormat,
|
| 20 |
transports: [new winston.transports.Console()],
|
| 21 |
+
defaultMeta: { service: 'asipilot-server' },
|
| 22 |
});
|
packages/server/src/utils/token-counter.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
import { estimateTokens } from '@
|
| 2 |
import { logger } from './logger.js';
|
| 3 |
|
| 4 |
/**
|
|
|
|
| 1 |
+
import { estimateTokens } from '@asipilot/shared';
|
| 2 |
import { logger } from './logger.js';
|
| 3 |
|
| 4 |
/**
|
packages/server/src/websocket/handler.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { WS_EVENTS } from './events.js';
|
|
| 3 |
import { asi1 } from '../services/asi1-client.js';
|
| 4 |
import { orchestrator } from '../agents/orchestrator.js';
|
| 5 |
import { logger } from '../utils/logger.js';
|
| 6 |
-
import type { WSCompletionRequest, WSReviewRequest, WSChatMessage, AgentType } from '@
|
| 7 |
|
| 8 |
const activeAbortControllers = new Map<string, AbortController>();
|
| 9 |
|
|
@@ -74,7 +74,7 @@ export function setupWebSocketHandlers(io: SocketServer) {
|
|
| 74 |
const messages = [
|
| 75 |
{
|
| 76 |
role: 'system' as const,
|
| 77 |
-
content: 'You are
|
| 78 |
},
|
| 79 |
...data.history,
|
| 80 |
{ role: 'user' as const, content: data.message },
|
|
|
|
| 3 |
import { asi1 } from '../services/asi1-client.js';
|
| 4 |
import { orchestrator } from '../agents/orchestrator.js';
|
| 5 |
import { logger } from '../utils/logger.js';
|
| 6 |
+
import type { WSCompletionRequest, WSReviewRequest, WSChatMessage, AgentType } from '@asipilot/shared';
|
| 7 |
|
| 8 |
const activeAbortControllers = new Map<string, AbortController>();
|
| 9 |
|
|
|
|
| 74 |
const messages = [
|
| 75 |
{
|
| 76 |
role: 'system' as const,
|
| 77 |
+
content: 'You are AsiPilot AI, an expert frontend development assistant. You help with HTML, CSS, JavaScript, TypeScript, React, Vue, Svelte, Next.js, Tailwind CSS, and all frontend technologies. Provide clear, concise, and accurate code with explanations. When showing code, use appropriate language tags in code blocks.',
|
| 78 |
},
|
| 79 |
...data.history,
|
| 80 |
{ role: 'user' as const, content: data.message },
|
packages/shared/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
{
|
| 2 |
-
"name": "@
|
| 3 |
"version": "1.0.0",
|
| 4 |
"private": true,
|
| 5 |
"main": "./src/index.ts",
|
|
|
|
| 1 |
{
|
| 2 |
+
"name": "@asipilot/shared",
|
| 3 |
"version": "1.0.0",
|
| 4 |
"private": true,
|
| 5 |
"main": "./src/index.ts",
|