Skip to content
← Public packages

@kentcdodds/skills

Store, retrieve, edit, version, and revert reusable agent skill documents via skillList then skillGet.

src/use-package-storage.ts

86 lines · 2.0 KB · TypeScript
import { getBackend } from './backend.ts'
import {
	ensureSchema,
	setMeta,
	upsertLegacyFile,
	upsertLegacySkill,
} from './db.ts'
import {
	listSkillIdsFromRepo,
	parseSkillMeta,
	readRepoFile,
	skillFilePath,
	skillMetaPath,
	withSkillsRepoSession,
} from './repo.ts'

export type UsePackageStorageResult = {
	backendBefore: string
	backendAfter: 'legacy'
	copied: string[]
	fileCount: number
	repoError: string | null
	durableHome: 'package-storage'
}

/**
 * Copy skill documents from the leftover plain `skills` repo into this
 * package's SQLite packageStorage, then switch reads/writes to `legacy`.
 * Package workflows cannot open user plain repos, so the registry's durable
 * home must be package storage.
 */
export default async function usePackageStorage(): Promise<UsePackageStorageResult> {
	await ensureSchema()
	const backendBefore = await getBackend()
	const copied: string[] = []
	let fileCount = 0
	let repoError: string | null = null

	try {
		await withSkillsRepoSession(async (session) => {
			const ids = await listSkillIdsFromRepo(session.id)
			for (const id of ids) {
				const meta = parseSkillMeta(
					await readRepoFile(session.id, skillMetaPath(id)),
				)
				if (!meta) continue
				await upsertLegacySkill({
					id,
					name: meta.name,
					description: meta.description,
					createdAt: meta.createdAt,
					updatedAt: meta.updatedAt,
				})
				for (const path of meta.files) {
					const content = await readRepoFile(
						session.id,
						skillFilePath(id, path),
					)
					if (content == null) continue
					await upsertLegacyFile({
						skillId: id,
						path,
						content,
						updatedAt: meta.updatedAt,
					})
					fileCount += 1
				}
				copied.push(id)
			}
		})
	} catch (error) {
		repoError = error instanceof Error ? error.message : String(error)
	}

	await setMeta('backend', 'legacy')
	await setMeta('durableHome', 'package-storage')

	return {
		backendBefore,
		backendAfter: 'legacy',
		copied,
		fileCount,
		repoError,
		durableHome: 'package-storage',
	}
}