@benzsiangco/jarvis 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/bin/{jarvis.js → jarvis} +1 -1
- package/dist/cli.js +476 -350
- package/dist/electron/main.js +160 -0
- package/dist/electron/preload.js +19 -0
- package/package.json +21 -8
- package/skills.md +147 -0
- package/src/agents/index.ts +248 -0
- package/src/brain/loader.ts +136 -0
- package/src/cli.ts +411 -0
- package/src/config/index.ts +363 -0
- package/src/core/executor.ts +222 -0
- package/src/core/plugins.ts +148 -0
- package/src/core/types.ts +217 -0
- package/src/electron/main.ts +192 -0
- package/src/electron/preload.ts +25 -0
- package/src/electron/types.d.ts +20 -0
- package/src/index.ts +12 -0
- package/src/providers/antigravity-loader.ts +233 -0
- package/src/providers/antigravity.ts +585 -0
- package/src/providers/index.ts +523 -0
- package/src/sessions/index.ts +194 -0
- package/src/tools/index.ts +436 -0
- package/src/tui/index.tsx +784 -0
- package/src/utils/auth-prompt.ts +394 -0
- package/src/utils/index.ts +180 -0
- package/src/utils/native-picker.ts +71 -0
- package/src/utils/skills.ts +99 -0
- package/src/utils/table-integration-examples.ts +617 -0
- package/src/utils/table-utils.ts +401 -0
- package/src/web/build-ui.ts +27 -0
- package/src/web/server.ts +674 -0
- package/src/web/ui/dist/.gitkeep +0 -0
- package/src/web/ui/dist/main.css +1 -0
- package/src/web/ui/dist/main.js +320 -0
- package/src/web/ui/dist/main.js.map +20 -0
- package/src/web/ui/index.html +46 -0
- package/src/web/ui/src/App.tsx +143 -0
- package/src/web/ui/src/Modules/Safety/GuardianModal.tsx +83 -0
- package/src/web/ui/src/components/Layout/ContextPanel.tsx +243 -0
- package/src/web/ui/src/components/Layout/Header.tsx +91 -0
- package/src/web/ui/src/components/Layout/ModelSelector.tsx +235 -0
- package/src/web/ui/src/components/Layout/SessionStats.tsx +369 -0
- package/src/web/ui/src/components/Layout/Sidebar.tsx +895 -0
- package/src/web/ui/src/components/Modules/Chat/ChatStage.tsx +620 -0
- package/src/web/ui/src/components/Modules/Chat/MessageItem.tsx +446 -0
- package/src/web/ui/src/components/Modules/Editor/CommandInspector.tsx +71 -0
- package/src/web/ui/src/components/Modules/Editor/DiffViewer.tsx +83 -0
- package/src/web/ui/src/components/Modules/Terminal/TabbedTerminal.tsx +202 -0
- package/src/web/ui/src/components/Settings/SettingsModal.tsx +935 -0
- package/src/web/ui/src/config/models.ts +70 -0
- package/src/web/ui/src/main.tsx +13 -0
- package/src/web/ui/src/store/agentStore.ts +41 -0
- package/src/web/ui/src/store/uiStore.ts +64 -0
- package/src/web/ui/src/types/index.ts +54 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, appendFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
|
|
4
|
+
export interface Skill {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
category?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getSkillsPath(): string {
|
|
11
|
+
return join(process.cwd(), 'skills.md');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function hasSkillsFile(): boolean {
|
|
15
|
+
return existsSync(getSkillsPath());
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function loadSkills(): string {
|
|
19
|
+
const path = getSkillsPath();
|
|
20
|
+
if (!existsSync(path)) return '';
|
|
21
|
+
|
|
22
|
+
return readFileSync(path, 'utf-8');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function parseSkills(): Skill[] {
|
|
26
|
+
const content = loadSkills();
|
|
27
|
+
const skills: Skill[] = [];
|
|
28
|
+
const lines = content.split('\n');
|
|
29
|
+
|
|
30
|
+
let currentCategory = '';
|
|
31
|
+
let currentSkill: Partial<Skill> | null = null;
|
|
32
|
+
|
|
33
|
+
for (const line of lines) {
|
|
34
|
+
// Category: ## Category Name
|
|
35
|
+
if (line.startsWith('## ') && !line.startsWith('### ')) {
|
|
36
|
+
currentCategory = line.replace('## ', '').trim();
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Skill: ### Skill Name
|
|
41
|
+
if (line.startsWith('### ')) {
|
|
42
|
+
if (currentSkill && currentSkill.name) {
|
|
43
|
+
skills.push(currentSkill as Skill);
|
|
44
|
+
}
|
|
45
|
+
currentSkill = {
|
|
46
|
+
name: line.replace('### ', '').trim(),
|
|
47
|
+
description: '',
|
|
48
|
+
category: currentCategory
|
|
49
|
+
};
|
|
50
|
+
} else if (currentSkill) {
|
|
51
|
+
currentSkill.description += line + '\n';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (currentSkill && currentSkill.name) {
|
|
56
|
+
skills.push(currentSkill as Skill);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return skills.map(s => ({
|
|
60
|
+
...s,
|
|
61
|
+
description: s.description.trim()
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function saveSkills(content: string): void {
|
|
66
|
+
writeFileSync(getSkillsPath(), content, 'utf-8');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function addSkill(name: string, description: string): void {
|
|
70
|
+
const path = getSkillsPath();
|
|
71
|
+
const content = `\n## ${name}\n${description}\n`;
|
|
72
|
+
appendFileSync(path, content, 'utf-8');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Future: Auto-detect which skills to activate based on keywords
|
|
76
|
+
export function detectRelevantSkills(userMessage: string): string[] {
|
|
77
|
+
const message = userMessage.toLowerCase();
|
|
78
|
+
const keywords = {
|
|
79
|
+
'DevOps & Infrastructure': ['docker', 'container', 'proxmox', 'lxc', 'vm', 'systemd', 'linux'],
|
|
80
|
+
'Security & Hacking': ['security', 'penetration', 'hack', 'vulnerability', 'exploit', 'firewall'],
|
|
81
|
+
'Frontend Development': ['react', 'frontend', 'ui', 'css', 'tailwind', 'component'],
|
|
82
|
+
'Backend Development': ['api', 'backend', 'server', 'hono', 'database', 'auth'],
|
|
83
|
+
'SSH Automation': ['ssh', 'remote', 'server', 'tunnel', 'proxyjump'],
|
|
84
|
+
'Cloudflare Integration': ['cloudflare', 'tunnel', 'cdn', 'dns', 'waf'],
|
|
85
|
+
'TypeScript & JavaScript': ['typescript', 'javascript', 'node', 'bun', 'deno'],
|
|
86
|
+
'Database Management': ['postgres', 'mysql', 'redis', 'mongodb', 'sql'],
|
|
87
|
+
'CI/CD Pipelines': ['github actions', 'gitlab', 'ci/cd', 'pipeline', 'deployment'],
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const relevantCategories: string[] = [];
|
|
91
|
+
|
|
92
|
+
for (const [category, words] of Object.entries(keywords)) {
|
|
93
|
+
if (words.some(word => message.includes(word))) {
|
|
94
|
+
relevantCategories.push(category);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return relevantCategories;
|
|
99
|
+
}
|