This commit is contained in:
Timothy Jaeryang Baek committed 2026-05-19 20:19:23 +04:00
1 parent d310a0777c
commit ef975649b2
3 files changed
+33 -45

No files matched your search

@@ -4,7 +4,7 @@
const i18n = getContext('i18n'); const i18n = getContext('i18n');
import { nameToId } from '$lib/utils'; import { extractFrontmatter, formatSkillName, nameToId } from '$lib/utils';
import CodeEditor from '$lib/components/common/CodeEditor.svelte'; import CodeEditor from '$lib/components/common/CodeEditor.svelte';
import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte'; import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import Badge from '$lib/components/common/Badge.svelte'; import Badge from '$lib/components/common/Badge.svelte';
@@ -375,6 +375,16 @@ class Pipe:
{boilerplate} {boilerplate}
onChange={(e) => { onChange={(e) => {
_content = e; _content = e;
if (!edit) {
const fm = extractFrontmatter(e);
if (fm.title && !name) {
name = formatSkillName(fm.title);
id = nameToId(fm.title);
}
if (fm.description && !meta.description) {
meta = { ...meta, description: fm.description };
}
}
}} }}
onSave={async () => { onSave={async () => {
if (formElement) { if (formElement) {
@@ -30,47 +30,21 @@
let accessGrants = []; let accessGrants = [];
let showAccessControlModal = false; let showAccessControlModal = false;
let hasManualEdit = false; $: if (!edit && !clone && name) {
let hasManualName = false; id = slugify(name);
let hasManualDescription = false; }
let isFrontmatterDetected = false;
// Auto-detect frontmatter and fill name/description in create mode const handleContentInput = () => {
$: if (!edit && content) { if (edit) return;
const fm = parseFrontmatter(content); const fm = parseFrontmatter(content);
if (fm.name) { if (fm.name && !name) {
isFrontmatterDetected = true; name = formatSkillName(fm.name);
if (!hasManualName) { id = fm.name;
name = formatSkillName(fm.name);
}
if (!hasManualEdit) {
id = fm.name;
}
} else {
isFrontmatterDetected = false;
} }
if (fm.description && !hasManualDescription) { if (fm.description && !description) {
description = fm.description; description = fm.description;
} }
} else if (!edit && !content) { };
isFrontmatterDetected = false;
}
$: if (!edit && !hasManualEdit && !isFrontmatterDetected) {
id = name !== '' ? slugify(name) : '';
}
function handleIdInput(e: Event) {
hasManualEdit = true;
}
function handleNameInput(e: Event) {
hasManualName = true;
}
function handleDescriptionInput(e: Event) {
hasManualDescription = true;
}
const submitHandler = async () => { const submitHandler = async () => {
if (disabled) { if (disabled) {
@@ -100,10 +74,6 @@
description = skill.description || ''; description = skill.description || '';
content = skill.content || ''; content = skill.content || '';
accessGrants = skill?.access_grants === undefined ? [] : skill?.access_grants; accessGrants = skill?.access_grants === undefined ? [] : skill?.access_grants;
if (name) hasManualName = true;
if (description) hasManualDescription = true;
if (id) hasManualEdit = true;
} }
}); });
</script> </script>
@@ -156,7 +126,6 @@
placeholder={$i18n.t('Skill Name')} placeholder={$i18n.t('Skill Name')}
aria-label={$i18n.t('Skill Name')} aria-label={$i18n.t('Skill Name')}
bind:value={name} bind:value={name}
on:input={handleNameInput}
required required
{disabled} {disabled}
/> />
@@ -202,7 +171,6 @@
placeholder={$i18n.t('Skill ID')} placeholder={$i18n.t('Skill ID')}
aria-label={$i18n.t('Skill ID')} aria-label={$i18n.t('Skill ID')}
bind:value={id} bind:value={id}
on:input={handleIdInput}
required required
disabled={edit} disabled={edit}
/> />
@@ -220,7 +188,6 @@
placeholder={$i18n.t('Skill Description')} placeholder={$i18n.t('Skill Description')}
aria-label={$i18n.t('Skill Description')} aria-label={$i18n.t('Skill Description')}
bind:value={description} bind:value={description}
on:input={handleDescriptionInput}
{disabled} {disabled}
/> />
</Tooltip> </Tooltip>
@@ -240,6 +207,7 @@
<textarea <textarea
class="w-full flex-1 text-xs bg-transparent outline-hidden resize-none font-mono px-4 py-3" class="w-full flex-1 text-xs bg-transparent outline-hidden resize-none font-mono px-4 py-3"
bind:value={content} bind:value={content}
on:input={handleContentInput}
placeholder={$i18n.t('Enter skill instructions in markdown...')} placeholder={$i18n.t('Enter skill instructions in markdown...')}
aria-label={$i18n.t('Skill Instructions')} aria-label={$i18n.t('Skill Instructions')}
required required
@@ -8,7 +8,7 @@
import { user } from '$lib/stores'; import { user } from '$lib/stores';
import { updateToolAccessGrants } from '$lib/apis/tools'; import { updateToolAccessGrants } from '$lib/apis/tools';
import { nameToId } from '$lib/utils'; import { extractFrontmatter, formatSkillName, nameToId } from '$lib/utils';
import CodeEditor from '$lib/components/common/CodeEditor.svelte'; import CodeEditor from '$lib/components/common/CodeEditor.svelte';
import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte'; import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte'; import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte';
@@ -312,6 +312,16 @@ class Tools:
{boilerplate} {boilerplate}
onChange={(e) => { onChange={(e) => {
_content = e; _content = e;
if (!edit) {
const fm = extractFrontmatter(e);
if (fm.title && !name) {
name = formatSkillName(fm.title);
id = nameToId(fm.title);
}
if (fm.description && !meta.description) {
meta = { ...meta, description: fm.description };
}
}
}} }}
onSave={async () => { onSave={async () => {
if (formElement) { if (formElement) {