Files
dify/web/app/components/workflow/skill/start-tab/templates/template-to-upload.ts
yyh 038b03fa8e feat(skill): add script-driven full skill template generation
Add fetch-skill-templates.ts script that clones anthropics/skills repo
and generates complete directory trees (scripts, references, assets)
for all 16 skills with base64 encoding for binary files, replacing
the previous single-SKILL.md-only approach. Generated files are
lazy-loaded per skill on user click.
2026-01-30 16:10:18 +08:00

56 lines
1.6 KiB
TypeScript

import type { SkillTemplateNode } from './types'
import type { BatchUploadNodeInput } from '@/types/app-asset'
import { prepareSkillUploadFile } from '../../utils/skill-upload-utils'
type TemplateUploadData = {
tree: BatchUploadNodeInput[]
files: Map<string, File>
}
export async function buildUploadDataFromTemplate(
name: string,
children: SkillTemplateNode[],
): Promise<TemplateUploadData> {
const files = new Map<string, File>()
async function convertNode(
node: SkillTemplateNode,
pathPrefix: string,
): Promise<BatchUploadNodeInput> {
const currentPath = pathPrefix ? `${pathPrefix}/${node.name}` : node.name
if (node.node_type === 'folder') {
const converted = await Promise.all(
node.children.map(child => convertNode(child, currentPath)),
)
return { name: node.name, node_type: 'folder', children: converted }
}
let fileData: BlobPart
if (node.encoding === 'base64') {
const binary = atob(node.content)
const bytes = new Uint8Array(binary.length)
for (let i = 0; i < binary.length; i++)
bytes[i] = binary.charCodeAt(i)
fileData = bytes
}
else {
fileData = node.content
}
const raw = new File([fileData], node.name)
const prepared = await prepareSkillUploadFile(raw)
files.set(currentPath, prepared)
return { name: node.name, node_type: 'file', size: prepared.size }
}
const rootFolder: BatchUploadNodeInput = {
name,
node_type: 'folder',
children: await Promise.all(
children.map(child => convertNode(child, name)),
),
}
return { tree: [rootFolder], files }
}