{$i18n.t('Skills')} • {$WEBUI_NAME} {#if loaded} { if (importFiles && importFiles.length > 0) { const file = importFiles[0]; const ext = file.name.split('.').pop()?.toLowerCase(); if (ext === 'json') { // JSON import: create skills via API const reader = new FileReader(); reader.onload = async (event) => { try { const content = event.target?.result; if (typeof content !== 'string') return; const parsedSkills = JSON.parse(content); const items = Array.isArray(parsedSkills) ? parsedSkills : [parsedSkills]; for (const skill of items) { await createNewSkill(localStorage.token, skill).catch((error) => { toast.error(`${error}`); }); } toast.success($i18n.t('Skill imported successfully')); page = 1; loadSkillItems(); _skills.set(await getSkills(localStorage.token)); } catch (e) { toast.error($i18n.t('Invalid JSON file')); } }; reader.readAsText(file); } else { // Markdown import: parse frontmatter and open in editor const reader = new FileReader(); reader.onload = (event) => { const mdContent = event.target?.result; if (typeof mdContent === 'string') { const fm = parseFrontmatter(mdContent); const fileName = file.name.replace(/\.md$/, ''); const rawName = fm.name || fileName; const displayName = formatSkillName(rawName); sessionStorage.skill = JSON.stringify({ name: displayName, id: fm.name || '', description: fm.description || '', content: mdContent, is_active: true, access_grants: [] }); goto('/workspace/skills/create'); } }; reader.readAsText(file); } importInputElement.value = ''; } }} />
{#if query}
{/if}
{ if (e.deltaY !== 0) { e.preventDefault(); e.currentTarget.scrollLeft += e.deltaY; } }} >
{ localStorage.workspaceViewOption = value; page = 1; await tick(); }} />
{#if filteredItems === null || loading}
{:else if (filteredItems ?? []).length !== 0}
{#each filteredItems as skill (skill.id)}
{ if (shouldIgnoreRowClick(e.target)) return; openSkill(skill); }} on:keydown={(e) => { if (e.currentTarget !== e.target) return; if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openSkill(skill); } }} >
{skill.name}
/{skill.id}
{dayjs((skill.updated_at ?? skill.created_at) * 1000).fromNow()}
{#if !skill.is_active} {/if} {#if !skill.write_access} {/if}
{#if skill.description}
{skill.description}
{/if}
{#if skill.write_access}
{#if shiftKey} {:else}
{ goto(`/workspace/skills/edit?id=${encodeURIComponent(skill.id)}`); }} cloneHandler={() => { cloneHandler(skill); }} exportHandler={() => { exportHandler(skill); }} deleteHandler={async () => { selectedSkill = skill; showDeleteConfirm = true; }} onClose={() => { openSkillMenuId = null; }} >
{/if}
{/if}
{/each}
{#if total > 30}
{/if} {:else}
📝
{$i18n.t('No skills found')}
{$i18n.t('Try adjusting your search or filter to find what you are looking for.')}
{/if}
{ deleteHandler(selectedSkill); }} >
{$i18n.t('This will delete')} {selectedSkill.name}.
{:else}
{/if}