cleanup(skills): remove legacy guide bundle and harden skill migration/pruning
This commit is contained in:
@@ -3,19 +3,19 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Plus, Pencil, Trash2, Save, X, FileText } from 'lucide-react';
|
||||
|
||||
interface GuideMeta {
|
||||
interface SkillMeta {
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
interface Guide extends GuideMeta {
|
||||
interface Skill extends SkillMeta {
|
||||
content: string;
|
||||
}
|
||||
|
||||
export default function GuidesViewer() {
|
||||
const [guides, setGuides] = useState<GuideMeta[]>([]);
|
||||
const [guides, setGuides] = useState<SkillMeta[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [editing, setEditing] = useState<Guide | null>(null);
|
||||
const [editing, setEditing] = useState<Skill | null>(null);
|
||||
const [isNew, setIsNew] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
@@ -25,13 +25,13 @@ export default function GuidesViewer() {
|
||||
|
||||
const fetchGuides = async () => {
|
||||
try {
|
||||
const res = await fetch('/api/guides');
|
||||
const res = await fetch('/api/skills');
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
setGuides(data.data);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch guides:', err);
|
||||
console.error('Failed to fetch skills:', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -39,7 +39,7 @@ export default function GuidesViewer() {
|
||||
|
||||
const handleEdit = async (name: string) => {
|
||||
try {
|
||||
const res = await fetch(`/api/guides/${encodeURIComponent(name)}`);
|
||||
const res = await fetch(`/api/skills/${encodeURIComponent(name)}`);
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
setEditing(data.data);
|
||||
@@ -47,16 +47,16 @@ export default function GuidesViewer() {
|
||||
setError(null);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch guide:', err);
|
||||
console.error('Failed to fetch skill:', err);
|
||||
}
|
||||
};
|
||||
|
||||
const handleNew = () => {
|
||||
setEditing({
|
||||
name: '',
|
||||
description: '',
|
||||
content: '# New Guide\n\nWrite your guide content here...',
|
||||
});
|
||||
setEditing({
|
||||
name: '',
|
||||
description: '',
|
||||
content: '# New Skill\n\nWrite your skill content here...',
|
||||
});
|
||||
setIsNew(true);
|
||||
setError(null);
|
||||
};
|
||||
@@ -69,7 +69,7 @@ export default function GuidesViewer() {
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch(`/api/guides/${encodeURIComponent(editing.name)}`, {
|
||||
const res = await fetch(`/api/skills/${encodeURIComponent(editing.name)}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
@@ -81,20 +81,21 @@ export default function GuidesViewer() {
|
||||
if (data.success) {
|
||||
setEditing(null);
|
||||
fetchGuides();
|
||||
window.dispatchEvent(new Event('skills:updated'));
|
||||
window.dispatchEvent(new Event('guides:updated'));
|
||||
} else {
|
||||
setError(data.error || 'Failed to save');
|
||||
}
|
||||
} catch (err) {
|
||||
setError('Failed to save guide');
|
||||
setError('Failed to save skill');
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = async (name: string) => {
|
||||
if (!confirm(`Delete guide "${name}"?`)) return;
|
||||
if (!confirm(`Delete skill "${name}"?`)) return;
|
||||
|
||||
try {
|
||||
const res = await fetch(`/api/guides/${encodeURIComponent(name)}`, {
|
||||
const res = await fetch(`/api/skills/${encodeURIComponent(name)}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
const data = await res.json();
|
||||
@@ -103,13 +104,13 @@ export default function GuidesViewer() {
|
||||
window.dispatchEvent(new Event('guides:updated'));
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to delete guide:', err);
|
||||
console.error('Failed to delete skill:', err);
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div style={{ padding: '24px', color: '#666' }}>Loading guides...</div>
|
||||
<div style={{ padding: '24px', color: '#666' }}>Loading skills...</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -121,7 +122,7 @@ export default function GuidesViewer() {
|
||||
type="text"
|
||||
value={editing.name}
|
||||
onChange={(e) => setEditing({ ...editing, name: e.target.value })}
|
||||
placeholder="Guide name"
|
||||
placeholder="Skill name"
|
||||
disabled={!isNew}
|
||||
style={{
|
||||
flex: 1,
|
||||
@@ -193,7 +194,7 @@ export default function GuidesViewer() {
|
||||
<textarea
|
||||
value={editing.content}
|
||||
onChange={(e) => setEditing({ ...editing, content: e.target.value })}
|
||||
placeholder="Guide content (markdown)"
|
||||
placeholder="Skill content (markdown)"
|
||||
style={{
|
||||
flex: 1,
|
||||
padding: '12px',
|
||||
@@ -209,7 +210,7 @@ export default function GuidesViewer() {
|
||||
/>
|
||||
|
||||
<p style={{ color: '#666', fontSize: '12px', marginTop: '12px' }}>
|
||||
Guides are markdown files that external agents can read via MCP tools. Use them to provide context, instructions, or reference material.
|
||||
Skills are markdown files that agents can read for reusable procedural instructions.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
@@ -219,7 +220,7 @@ export default function GuidesViewer() {
|
||||
<div style={{ height: '100%', display: 'flex', flexDirection: 'column', padding: '24px' }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px' }}>
|
||||
<p style={{ color: '#888', fontSize: '13px', margin: 0 }}>
|
||||
Guides provide context and instructions for external AI agents via MCP.
|
||||
Skills provide reusable context and procedural instructions for agents.
|
||||
</p>
|
||||
<button
|
||||
onClick={handleNew}
|
||||
@@ -237,7 +238,7 @@ export default function GuidesViewer() {
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
<Plus size={14} /> New Guide
|
||||
<Plus size={14} /> New Skill
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -245,8 +246,8 @@ export default function GuidesViewer() {
|
||||
{guides.length === 0 ? (
|
||||
<div style={{ color: '#555', textAlign: 'center', paddingTop: '48px' }}>
|
||||
<FileText size={48} style={{ marginBottom: '12px', opacity: 0.5 }} />
|
||||
<p style={{ fontSize: '14px' }}>No guides yet</p>
|
||||
<p style={{ fontSize: '12px', color: '#444' }}>Create guides to help external agents understand your knowledge base</p>
|
||||
<p style={{ fontSize: '14px' }}>No skills yet</p>
|
||||
<p style={{ fontSize: '12px', color: '#444' }}>Create skills to guide how agents operate in your knowledge base</p>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
||||
|
||||
@@ -8,7 +8,7 @@ import ApiKeysViewer from './ApiKeysViewer';
|
||||
import DatabaseViewer from './DatabaseViewer';
|
||||
import ExternalAgentsPanel from './ExternalAgentsPanel';
|
||||
import ContextViewer from './ContextViewer';
|
||||
import GuidesViewer from './GuidesViewer';
|
||||
import SkillsViewer from './GuidesViewer';
|
||||
export type SettingsTab =
|
||||
| 'logs'
|
||||
| 'tools'
|
||||
@@ -140,7 +140,7 @@ export default function SettingsModal({ isOpen, onClose, initialTab }: SettingsM
|
||||
transition: 'all 0.2s'
|
||||
}}
|
||||
>
|
||||
Guides
|
||||
Skills
|
||||
</div>
|
||||
<div
|
||||
onClick={() => setActiveTab('apikeys')}
|
||||
@@ -284,7 +284,7 @@ export default function SettingsModal({ isOpen, onClose, initialTab }: SettingsM
|
||||
>
|
||||
{activeTab === 'logs' && 'System Logs'}
|
||||
{activeTab === 'tools' && 'Tools'}
|
||||
{activeTab === 'guides' && 'Guides'}
|
||||
{activeTab === 'guides' && 'Skills'}
|
||||
{activeTab === 'apikeys' && 'API Keys'}
|
||||
{activeTab === 'database' && 'Knowledge Database'}
|
||||
{activeTab === 'context' && 'Auto-Context'}
|
||||
@@ -318,7 +318,7 @@ export default function SettingsModal({ isOpen, onClose, initialTab }: SettingsM
|
||||
<div style={{ flex: 1, overflow: 'hidden' }}>
|
||||
{activeTab === 'logs' && <LogsViewer key={isOpen ? 'open' : 'closed'} />}
|
||||
{activeTab === 'tools' && <ToolsViewer />}
|
||||
{activeTab === 'guides' && <GuidesViewer />}
|
||||
{activeTab === 'guides' && <SkillsViewer />}
|
||||
{activeTab === 'apikeys' && <ApiKeysViewer />}
|
||||
{activeTab === 'database' && <DatabaseViewer />}
|
||||
{activeTab === 'context' && <ContextViewer />}
|
||||
|
||||
Reference in New Issue
Block a user