skilld 1.5.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/agent.mjs +2 -2
- package/dist/_chunks/assemble.mjs +1 -0
- package/dist/_chunks/assemble.mjs.map +1 -1
- package/dist/_chunks/author.mjs +4 -2
- package/dist/_chunks/author.mjs.map +1 -1
- package/dist/_chunks/cache.mjs +2 -39
- package/dist/_chunks/cache.mjs.map +1 -1
- package/dist/_chunks/cache2.mjs +2 -1
- package/dist/_chunks/cache2.mjs.map +1 -1
- package/dist/_chunks/cli-helpers.mjs +6 -28
- package/dist/_chunks/cli-helpers.mjs.map +1 -1
- package/dist/_chunks/cli-helpers2.mjs +11 -0
- package/dist/_chunks/core.mjs +1 -0
- package/dist/_chunks/embedding-cache.mjs +3 -60
- package/dist/_chunks/embedding-cache2.mjs +61 -0
- package/dist/_chunks/embedding-cache2.mjs.map +1 -0
- package/dist/_chunks/index.d.mts +13 -21
- package/dist/_chunks/index.d.mts.map +1 -1
- package/dist/_chunks/index2.d.mts +32 -600
- package/dist/_chunks/index2.d.mts.map +1 -1
- package/dist/_chunks/index3.d.mts +615 -0
- package/dist/_chunks/index3.d.mts.map +1 -0
- package/dist/_chunks/install.mjs +6 -4
- package/dist/_chunks/install.mjs.map +1 -1
- package/dist/_chunks/list.mjs +2 -1
- package/dist/_chunks/list.mjs.map +1 -1
- package/dist/_chunks/pool.mjs +2 -123
- package/dist/_chunks/pool2.mjs +118 -0
- package/dist/_chunks/pool2.mjs.map +1 -0
- package/dist/_chunks/prepare.mjs +34 -78
- package/dist/_chunks/prepare.mjs.map +1 -1
- package/dist/_chunks/prepare2.mjs +93 -0
- package/dist/_chunks/prepare2.mjs.map +1 -0
- package/dist/_chunks/retriv.mjs +172 -0
- package/dist/_chunks/retriv.mjs.map +1 -0
- package/dist/_chunks/search-interactive.mjs +4 -3
- package/dist/_chunks/search-interactive.mjs.map +1 -1
- package/dist/_chunks/search.mjs +12 -320
- package/dist/_chunks/search2.mjs +319 -0
- package/dist/_chunks/search2.mjs.map +1 -0
- package/dist/_chunks/setup.mjs +3 -2
- package/dist/_chunks/setup.mjs.map +1 -1
- package/dist/_chunks/skills.mjs +1 -1
- package/dist/_chunks/sync-shared.mjs +2 -0
- package/dist/_chunks/sync-shared2.mjs +4 -3
- package/dist/_chunks/sync-shared2.mjs.map +1 -1
- package/dist/_chunks/sync.mjs +7 -7
- package/dist/_chunks/sync.mjs.map +1 -1
- package/dist/_chunks/sync2.mjs +21 -0
- package/dist/_chunks/uninstall.mjs +5 -2
- package/dist/_chunks/uninstall.mjs.map +1 -1
- package/dist/_chunks/wizard.mjs +186 -0
- package/dist/_chunks/wizard.mjs.map +1 -0
- package/dist/agent/index.mjs +1 -0
- package/dist/cache/index.d.mts +1 -1
- package/dist/cache/index.mjs +2 -1
- package/dist/cli-entry.d.mts +1 -0
- package/dist/cli-entry.mjs +11 -0
- package/dist/cli-entry.mjs.map +1 -0
- package/dist/cli.mjs +12 -188
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +3 -2
- package/dist/prepare.d.mts +1 -0
- package/dist/prepare.mjs +93 -0
- package/dist/prepare.mjs.map +1 -0
- package/dist/retriv/index.d.mts +2 -46
- package/dist/retriv/index.mjs +2 -171
- package/dist/sources/index.d.mts +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +1 -1
- package/dist/_chunks/embedding-cache.mjs.map +0 -1
- package/dist/_chunks/pool.mjs.map +0 -1
- package/dist/_chunks/search.mjs.map +0 -1
- package/dist/retriv/index.d.mts.map +0 -1
- package/dist/retriv/index.mjs.map +0 -1
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import "./agent.mjs";
|
|
2
2
|
import { t as CACHE_DIR } from "./config.mjs";
|
|
3
|
+
import "./prepare.mjs";
|
|
3
4
|
import "./sanitize.mjs";
|
|
4
5
|
import "./cache.mjs";
|
|
5
6
|
import "./yaml.mjs";
|
|
6
7
|
import "./markdown.mjs";
|
|
8
|
+
import "./retriv.mjs";
|
|
7
9
|
import { r as mapInsert, t as SHARED_SKILLS_DIR } from "./shared.mjs";
|
|
8
10
|
import "./sources.mjs";
|
|
9
11
|
import { a as targets } from "./detect.mjs";
|
|
10
12
|
import "./prompts.mjs";
|
|
11
|
-
import {
|
|
13
|
+
import { E as getRegisteredProjects, b as sharedArgs, f as isInteractive, j as unregisterProject } from "./cli-helpers.mjs";
|
|
12
14
|
import { i as readLock } from "./lockfile.mjs";
|
|
13
15
|
import "./skills.mjs";
|
|
14
16
|
import "./formatting.mjs";
|
|
17
|
+
import "./wizard.mjs";
|
|
15
18
|
import { i as SKILLD_MARKER_START, r as SKILLD_MARKER_END } from "./sync-shared2.mjs";
|
|
16
|
-
import "./
|
|
19
|
+
import "./pool2.mjs";
|
|
17
20
|
import "./sync.mjs";
|
|
18
21
|
import { join } from "pathe";
|
|
19
22
|
import { existsSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uninstall.mjs","names":["agents"],"sources":["../../src/commands/uninstall.ts"],"sourcesContent":["import type { AgentType } from '../agent/index.ts'\nimport { existsSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { join } from 'pathe'\nimport { agents } from '../agent/index.ts'\nimport { CACHE_DIR } from '../cache/index.ts'\nimport { isInteractive, sharedArgs } from '../cli-helpers.ts'\nimport { getRegisteredProjects, unregisterProject } from '../core/config.ts'\nimport { readLock } from '../core/lockfile.ts'\nimport { mapInsert, SHARED_SKILLS_DIR } from '../core/shared.ts'\nimport { SKILLD_MARKER_END, SKILLD_MARKER_START } from './sync.ts'\n\n/**\n * Remove the skilld marker block from an agent's instruction file.\n * For .mdc files (dedicated skilld files), delete the entire file.\n * Also cleans up legacy .cursorrules markers for backwards compat.\n */\nfunction removeAgentInstructions(agent: AgentType, projectPath: string): boolean {\n const agentConfig = agents[agent]\n if (!agentConfig.instructionFile)\n return false\n\n let removed = false\n\n // Handle current instruction file\n const filePath = join(projectPath, agentConfig.instructionFile)\n if (agentConfig.instructionFile.endsWith('.mdc')) {\n // MDC files are dedicated skilld files - just delete\n if (existsSync(filePath)) {\n rmSync(filePath)\n removed = true\n }\n // Also clean up legacy .cursorrules markers (cursor-specific)\n if (agent === 'cursor')\n removed = removeMarkerBlock(join(projectPath, '.cursorrules')) || removed\n }\n else if (existsSync(filePath)) {\n removed = removeMarkerBlock(filePath)\n }\n\n return removed\n}\n\nfunction removeMarkerBlock(filePath: string): boolean {\n if (!existsSync(filePath))\n return false\n\n const content = readFileSync(filePath, 'utf-8')\n const startIdx = content.indexOf(SKILLD_MARKER_START)\n if (startIdx === -1)\n return false\n\n const endIdx = content.indexOf(SKILLD_MARKER_END, startIdx)\n if (endIdx === -1)\n return false\n\n // Remove marker block plus surrounding blank lines\n const before = content.slice(0, startIdx).replace(/\\n+$/, '')\n const after = content.slice(endIdx + SKILLD_MARKER_END.length).replace(/^\\n+/, '')\n const updated = before + (before && after ? '\\n' : '') + after\n\n if (updated.trim() === '') {\n rmSync(filePath)\n }\n else {\n writeFileSync(filePath, updated.endsWith('\\n') ? updated : `${updated}\\n`)\n }\n return true\n}\n\nexport interface UninstallOptions {\n scope?: 'project' | 'all'\n agent?: AgentType\n yes: boolean\n}\n\n/**\n * Uninstall skilld skills by scope:\n * - project: Remove project skills (cwd)\n * - all: All registered projects + global skills + cache\n */\nexport async function uninstallCommand(opts: UninstallOptions): Promise<void> {\n let scope = opts.scope\n const registeredProjects = getRegisteredProjects()\n\n // Prompt for scope if not provided\n if (!scope) {\n if (!isInteractive()) {\n scope = 'project'\n }\n else {\n const allHint = registeredProjects.length > 0\n ? `${registeredProjects.length} projects + global + cache`\n : 'global skills + cache'\n\n const selected = await p.select({\n message: 'What do you want to uninstall?',\n options: [\n { label: 'This project', value: 'project', hint: 'current project only' },\n { label: 'Everything', value: 'all', hint: allHint },\n ],\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Cancelled')\n return\n }\n scope = selected as 'project' | 'all'\n }\n }\n\n interface RemoveItem { label: string, path: string, version?: string }\n const toRemove: RemoveItem[] = []\n const seenPaths = new Set<string>()\n const projectsToUnregister: string[] = []\n const agentFilter = opts.agent ? [opts.agent] : undefined\n\n const addToRemove = (label: string, path: string, version?: string) => {\n if (seenPaths.has(path))\n return\n seenPaths.add(path)\n toRemove.push({ label, path, version })\n }\n\n // Helper to add skills from a lockfile\n const addSkillsFromLock = (skillsDir: string, label: string): string[] => {\n const trackedNames: string[] = []\n const lock = readLock(skillsDir)\n\n if (lock?.skills) {\n for (const [skillName, info] of Object.entries(lock.skills)) {\n trackedNames.push(skillName)\n const skillDir = join(skillsDir, skillName)\n if (existsSync(skillDir)) {\n const version = info.version ? `${info.version.split('.').slice(0, 2).join('.')}.x` : undefined\n addToRemove(`${label}: ${skillName}`, skillDir, version)\n }\n }\n\n // Also add the lockfile itself\n const lockPath = join(skillsDir, 'skilld-lock.yaml')\n if (existsSync(lockPath)) {\n addToRemove(`${label}: skilld-lock.yaml`, lockPath)\n }\n }\n\n return trackedNames\n }\n\n // Helper to find untracked skills in a directory\n const findUntrackedSkills = (skillsDir: string, trackedNames: string[]): string[] => {\n if (!existsSync(skillsDir))\n return []\n const tracked = new Set(trackedNames)\n return readdirSync(skillsDir)\n .filter(f => !f.startsWith('.') && f !== 'skilld-lock.yaml' && !tracked.has(f))\n }\n\n // Track untracked skills per directory (dedupe by path)\n const untrackedByDir = new Map<string, { label: string, skills: string[] }>()\n const processedDirs = new Set<string>()\n\n // Helper to process a skills directory (with deduping)\n const processSkillsDir = (skillsDir: string, label: string) => {\n if (processedDirs.has(skillsDir))\n return\n processedDirs.add(skillsDir)\n\n const tracked = addSkillsFromLock(skillsDir, label)\n const untracked = findUntrackedSkills(skillsDir, tracked)\n if (untracked.length > 0) {\n untrackedByDir.set(skillsDir, { label, skills: untracked })\n }\n }\n\n // Project skills\n if (scope === 'project') {\n // Shared dir\n const sharedDir = join(process.cwd(), SHARED_SKILLS_DIR)\n if (existsSync(sharedDir))\n processSkillsDir(sharedDir, 'project (.skills)')\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n processSkillsDir(join(process.cwd(), agent.skillsDir), 'project')\n }\n projectsToUnregister.push(process.cwd())\n }\n\n // All registered projects + global\n if (scope === 'all') {\n const projectPaths = registeredProjects.length > 0 ? registeredProjects : [process.cwd()]\n\n // Show which projects will be affected\n if (registeredProjects.length > 0) {\n p.log.info('Projects to uninstall from:')\n for (const proj of projectPaths) {\n p.log.message(` ${proj}`)\n }\n }\n\n // Project skills from lockfiles\n for (const projectPath of projectPaths) {\n if (!existsSync(projectPath))\n continue\n\n const shortPath = projectPath.replace(process.env.HOME || '', '~')\n\n // Shared dir\n const sharedDir = join(projectPath, SHARED_SKILLS_DIR)\n if (existsSync(sharedDir))\n processSkillsDir(sharedDir, `${shortPath} (.skills)`)\n\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n processSkillsDir(join(projectPath, agent.skillsDir), shortPath)\n }\n\n projectsToUnregister.push(projectPath)\n }\n\n // Global skills from lockfiles\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n if (!agent.globalSkillsDir)\n continue\n processSkillsDir(agent.globalSkillsDir, 'user')\n }\n\n // Cache directory\n if (existsSync(CACHE_DIR)) {\n addToRemove('~/.skilld cache', CACHE_DIR)\n }\n }\n\n // Warn about untracked skills that will remain (grouped by label, deduped)\n if (untrackedByDir.size > 0) {\n const groupedUntracked = new Map<string, Set<string>>()\n for (const [_dir, { label, skills }] of untrackedByDir) {\n const set = mapInsert(groupedUntracked, label, () => new Set())\n for (const s of skills) set.add(s)\n }\n\n const totalUntracked = [...groupedUntracked.values()].reduce((sum, s) => sum + s.size, 0)\n p.log.warn(`${totalUntracked} untracked skill(s) will remain (not managed by skilld):`)\n for (const [label, skills] of groupedUntracked) {\n p.log.message(` ${label}: ${[...skills].join(', ')}`)\n }\n }\n\n if (toRemove.length === 0) {\n p.log.info('Nothing to uninstall')\n return\n }\n\n // Group by prefix for display\n const groups = new Map<string, Array<{ name: string, version?: string }>>()\n for (const item of toRemove) {\n const [prefix, name] = item.label.includes(': ')\n ? item.label.split(': ', 2)\n : ['other', item.label]\n mapInsert(groups, prefix!, () => []).push({ name: name!, version: item.version })\n }\n\n const formatGroup = (items: Array<{ name: string, version?: string }>) =>\n items.map(i => i.version ? `${i.name}@${i.version}` : i.name).join(', ')\n\n p.log.info(`Will remove ${toRemove.length} items:`)\n for (const [prefix, items] of groups) {\n p.log.message(` ${prefix}: ${formatGroup(items)}`)\n }\n\n if (!opts.yes && isInteractive()) {\n const confirmed = await p.confirm({\n message: 'Proceed with uninstall?',\n })\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel('Cancelled')\n return\n }\n }\n\n // Remove all items\n for (const item of toRemove) {\n rmSync(item.path, { recursive: true, force: true })\n }\n\n // Show grouped removal summary\n for (const [prefix, items] of groups) {\n p.log.success(`Removed ${prefix}: ${formatGroup(items)}`)\n }\n\n // Remove skilld instructions from agent instruction files\n const agentTypes = agentFilter || (Object.keys(agents) as AgentType[])\n for (const proj of projectsToUnregister) {\n for (const agent of agentTypes) {\n if (removeAgentInstructions(agent, proj)) {\n const file = agents[agent].instructionFile!\n p.log.success(`Cleaned ${file}`)\n }\n }\n }\n\n // Unregister projects from config (skip if cache dir was removed — config is gone)\n if (scope !== 'all') {\n for (const proj of projectsToUnregister) {\n unregisterProject(proj)\n }\n }\n\n p.outro('skilld uninstalled')\n}\n\nexport const uninstallCommandDef = defineCommand({\n meta: { name: 'uninstall', description: 'Remove skilld data' },\n args: {\n ...sharedArgs,\n },\n async run({ args }) {\n p.intro(`\\x1B[1m\\x1B[35mskilld\\x1B[0m uninstall`)\n return uninstallCommand({\n scope: args.global ? 'all' : undefined,\n agent: args.agent as AgentType | undefined,\n yes: args.yes,\n })\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"uninstall.mjs","names":["agents"],"sources":["../../src/commands/uninstall.ts"],"sourcesContent":["import type { AgentType } from '../agent/index.ts'\nimport { existsSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { join } from 'pathe'\nimport { agents } from '../agent/index.ts'\nimport { CACHE_DIR } from '../cache/index.ts'\nimport { isInteractive, sharedArgs } from '../cli-helpers.ts'\nimport { getRegisteredProjects, unregisterProject } from '../core/config.ts'\nimport { readLock } from '../core/lockfile.ts'\nimport { mapInsert, SHARED_SKILLS_DIR } from '../core/shared.ts'\nimport { SKILLD_MARKER_END, SKILLD_MARKER_START } from './sync.ts'\n\n/**\n * Remove the skilld marker block from an agent's instruction file.\n * For .mdc files (dedicated skilld files), delete the entire file.\n * Also cleans up legacy .cursorrules markers for backwards compat.\n */\nfunction removeAgentInstructions(agent: AgentType, projectPath: string): boolean {\n const agentConfig = agents[agent]\n if (!agentConfig.instructionFile)\n return false\n\n let removed = false\n\n // Handle current instruction file\n const filePath = join(projectPath, agentConfig.instructionFile)\n if (agentConfig.instructionFile.endsWith('.mdc')) {\n // MDC files are dedicated skilld files - just delete\n if (existsSync(filePath)) {\n rmSync(filePath)\n removed = true\n }\n // Also clean up legacy .cursorrules markers (cursor-specific)\n if (agent === 'cursor')\n removed = removeMarkerBlock(join(projectPath, '.cursorrules')) || removed\n }\n else if (existsSync(filePath)) {\n removed = removeMarkerBlock(filePath)\n }\n\n return removed\n}\n\nfunction removeMarkerBlock(filePath: string): boolean {\n if (!existsSync(filePath))\n return false\n\n const content = readFileSync(filePath, 'utf-8')\n const startIdx = content.indexOf(SKILLD_MARKER_START)\n if (startIdx === -1)\n return false\n\n const endIdx = content.indexOf(SKILLD_MARKER_END, startIdx)\n if (endIdx === -1)\n return false\n\n // Remove marker block plus surrounding blank lines\n const before = content.slice(0, startIdx).replace(/\\n+$/, '')\n const after = content.slice(endIdx + SKILLD_MARKER_END.length).replace(/^\\n+/, '')\n const updated = before + (before && after ? '\\n' : '') + after\n\n if (updated.trim() === '') {\n rmSync(filePath)\n }\n else {\n writeFileSync(filePath, updated.endsWith('\\n') ? updated : `${updated}\\n`)\n }\n return true\n}\n\nexport interface UninstallOptions {\n scope?: 'project' | 'all'\n agent?: AgentType\n yes: boolean\n}\n\n/**\n * Uninstall skilld skills by scope:\n * - project: Remove project skills (cwd)\n * - all: All registered projects + global skills + cache\n */\nexport async function uninstallCommand(opts: UninstallOptions): Promise<void> {\n let scope = opts.scope\n const registeredProjects = getRegisteredProjects()\n\n // Prompt for scope if not provided\n if (!scope) {\n if (!isInteractive()) {\n scope = 'project'\n }\n else {\n const allHint = registeredProjects.length > 0\n ? `${registeredProjects.length} projects + global + cache`\n : 'global skills + cache'\n\n const selected = await p.select({\n message: 'What do you want to uninstall?',\n options: [\n { label: 'This project', value: 'project', hint: 'current project only' },\n { label: 'Everything', value: 'all', hint: allHint },\n ],\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Cancelled')\n return\n }\n scope = selected as 'project' | 'all'\n }\n }\n\n interface RemoveItem { label: string, path: string, version?: string }\n const toRemove: RemoveItem[] = []\n const seenPaths = new Set<string>()\n const projectsToUnregister: string[] = []\n const agentFilter = opts.agent ? [opts.agent] : undefined\n\n const addToRemove = (label: string, path: string, version?: string) => {\n if (seenPaths.has(path))\n return\n seenPaths.add(path)\n toRemove.push({ label, path, version })\n }\n\n // Helper to add skills from a lockfile\n const addSkillsFromLock = (skillsDir: string, label: string): string[] => {\n const trackedNames: string[] = []\n const lock = readLock(skillsDir)\n\n if (lock?.skills) {\n for (const [skillName, info] of Object.entries(lock.skills)) {\n trackedNames.push(skillName)\n const skillDir = join(skillsDir, skillName)\n if (existsSync(skillDir)) {\n const version = info.version ? `${info.version.split('.').slice(0, 2).join('.')}.x` : undefined\n addToRemove(`${label}: ${skillName}`, skillDir, version)\n }\n }\n\n // Also add the lockfile itself\n const lockPath = join(skillsDir, 'skilld-lock.yaml')\n if (existsSync(lockPath)) {\n addToRemove(`${label}: skilld-lock.yaml`, lockPath)\n }\n }\n\n return trackedNames\n }\n\n // Helper to find untracked skills in a directory\n const findUntrackedSkills = (skillsDir: string, trackedNames: string[]): string[] => {\n if (!existsSync(skillsDir))\n return []\n const tracked = new Set(trackedNames)\n return readdirSync(skillsDir)\n .filter(f => !f.startsWith('.') && f !== 'skilld-lock.yaml' && !tracked.has(f))\n }\n\n // Track untracked skills per directory (dedupe by path)\n const untrackedByDir = new Map<string, { label: string, skills: string[] }>()\n const processedDirs = new Set<string>()\n\n // Helper to process a skills directory (with deduping)\n const processSkillsDir = (skillsDir: string, label: string) => {\n if (processedDirs.has(skillsDir))\n return\n processedDirs.add(skillsDir)\n\n const tracked = addSkillsFromLock(skillsDir, label)\n const untracked = findUntrackedSkills(skillsDir, tracked)\n if (untracked.length > 0) {\n untrackedByDir.set(skillsDir, { label, skills: untracked })\n }\n }\n\n // Project skills\n if (scope === 'project') {\n // Shared dir\n const sharedDir = join(process.cwd(), SHARED_SKILLS_DIR)\n if (existsSync(sharedDir))\n processSkillsDir(sharedDir, 'project (.skills)')\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n processSkillsDir(join(process.cwd(), agent.skillsDir), 'project')\n }\n projectsToUnregister.push(process.cwd())\n }\n\n // All registered projects + global\n if (scope === 'all') {\n const projectPaths = registeredProjects.length > 0 ? registeredProjects : [process.cwd()]\n\n // Show which projects will be affected\n if (registeredProjects.length > 0) {\n p.log.info('Projects to uninstall from:')\n for (const proj of projectPaths) {\n p.log.message(` ${proj}`)\n }\n }\n\n // Project skills from lockfiles\n for (const projectPath of projectPaths) {\n if (!existsSync(projectPath))\n continue\n\n const shortPath = projectPath.replace(process.env.HOME || '', '~')\n\n // Shared dir\n const sharedDir = join(projectPath, SHARED_SKILLS_DIR)\n if (existsSync(sharedDir))\n processSkillsDir(sharedDir, `${shortPath} (.skills)`)\n\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n processSkillsDir(join(projectPath, agent.skillsDir), shortPath)\n }\n\n projectsToUnregister.push(projectPath)\n }\n\n // Global skills from lockfiles\n for (const [name, agent] of Object.entries(agents)) {\n if (agentFilter && !agentFilter.includes(name as AgentType))\n continue\n if (!agent.globalSkillsDir)\n continue\n processSkillsDir(agent.globalSkillsDir, 'user')\n }\n\n // Cache directory\n if (existsSync(CACHE_DIR)) {\n addToRemove('~/.skilld cache', CACHE_DIR)\n }\n }\n\n // Warn about untracked skills that will remain (grouped by label, deduped)\n if (untrackedByDir.size > 0) {\n const groupedUntracked = new Map<string, Set<string>>()\n for (const [_dir, { label, skills }] of untrackedByDir) {\n const set = mapInsert(groupedUntracked, label, () => new Set())\n for (const s of skills) set.add(s)\n }\n\n const totalUntracked = [...groupedUntracked.values()].reduce((sum, s) => sum + s.size, 0)\n p.log.warn(`${totalUntracked} untracked skill(s) will remain (not managed by skilld):`)\n for (const [label, skills] of groupedUntracked) {\n p.log.message(` ${label}: ${[...skills].join(', ')}`)\n }\n }\n\n if (toRemove.length === 0) {\n p.log.info('Nothing to uninstall')\n return\n }\n\n // Group by prefix for display\n const groups = new Map<string, Array<{ name: string, version?: string }>>()\n for (const item of toRemove) {\n const [prefix, name] = item.label.includes(': ')\n ? item.label.split(': ', 2)\n : ['other', item.label]\n mapInsert(groups, prefix!, () => []).push({ name: name!, version: item.version })\n }\n\n const formatGroup = (items: Array<{ name: string, version?: string }>) =>\n items.map(i => i.version ? `${i.name}@${i.version}` : i.name).join(', ')\n\n p.log.info(`Will remove ${toRemove.length} items:`)\n for (const [prefix, items] of groups) {\n p.log.message(` ${prefix}: ${formatGroup(items)}`)\n }\n\n if (!opts.yes && isInteractive()) {\n const confirmed = await p.confirm({\n message: 'Proceed with uninstall?',\n })\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel('Cancelled')\n return\n }\n }\n\n // Remove all items\n for (const item of toRemove) {\n rmSync(item.path, { recursive: true, force: true })\n }\n\n // Show grouped removal summary\n for (const [prefix, items] of groups) {\n p.log.success(`Removed ${prefix}: ${formatGroup(items)}`)\n }\n\n // Remove skilld instructions from agent instruction files\n const agentTypes = agentFilter || (Object.keys(agents) as AgentType[])\n for (const proj of projectsToUnregister) {\n for (const agent of agentTypes) {\n if (removeAgentInstructions(agent, proj)) {\n const file = agents[agent].instructionFile!\n p.log.success(`Cleaned ${file}`)\n }\n }\n }\n\n // Unregister projects from config (skip if cache dir was removed — config is gone)\n if (scope !== 'all') {\n for (const proj of projectsToUnregister) {\n unregisterProject(proj)\n }\n }\n\n p.outro('skilld uninstalled')\n}\n\nexport const uninstallCommandDef = defineCommand({\n meta: { name: 'uninstall', description: 'Remove skilld data' },\n args: {\n ...sharedArgs,\n },\n async run({ args }) {\n p.intro(`\\x1B[1m\\x1B[35mskilld\\x1B[0m uninstall`)\n return uninstallCommand({\n scope: args.global ? 'all' : undefined,\n agent: args.agent as AgentType | undefined,\n yes: args.yes,\n })\n },\n})\n"],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { c as getOAuthProviderList, i as getAvailableModels, l as loginOAuthProvider, o as getModelName } from "./agent.mjs";
|
|
2
|
+
import { a as targets } from "./detect.mjs";
|
|
3
|
+
import { M as updateConfig, T as defaultFeatures, f as isInteractive, h as pickModel, n as NO_MODELS_MESSAGE, r as OAUTH_NOTE } from "./cli-helpers.mjs";
|
|
4
|
+
import { execSync } from "node:child_process";
|
|
5
|
+
import * as p from "@clack/prompts";
|
|
6
|
+
//#region src/commands/wizard.ts
|
|
7
|
+
function hasGhCli() {
|
|
8
|
+
if (process.env.SKILLD_NO_GH) return false;
|
|
9
|
+
try {
|
|
10
|
+
execSync("gh --version", { stdio: "ignore" });
|
|
11
|
+
return true;
|
|
12
|
+
} catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async function runWizard(opts = {}) {
|
|
17
|
+
if (!isInteractive()) return false;
|
|
18
|
+
const agentLabel = opts.agent ? targets[opts.agent].displayName : null;
|
|
19
|
+
const skillsDir = opts.agent ? targets[opts.agent].skillsDir : ".claude/skills";
|
|
20
|
+
const agentLine = agentLabel ? `\n\x1B[90mTarget agent: ${agentLabel}\x1B[0m` : "";
|
|
21
|
+
p.note(`Your AI agent reads docs from its training data - but APIs change,
|
|
22
|
+
versions drift, and patterns go stale. Skilld fixes this.
|
|
23
|
+
|
|
24
|
+
It generates a [1mSKILL.md[0m - a markdown reference card built from
|
|
25
|
+
the [1mactual docs, issues, and release notes[0m for the exact
|
|
26
|
+
package versions in your project. Your agent reads this file
|
|
27
|
+
every session - no hallucinated APIs.
|
|
28
|
+
|
|
29
|
+
[1mHow it works:[0m
|
|
30
|
+
1. Fetch docs, issues, and types for your packages
|
|
31
|
+
2. Optionally compress with an LLM into a concise cheat sheet
|
|
32
|
+
|
|
33
|
+
\x1B[90mExample: \`skilld add vue\` creates ${skillsDir}/vue-skilld/SKILL.md\nYour agent then knows the right APIs, gotchas, and patterns\nfor your exact version.\x1B[0m${agentLine}`, "Welcome to skilld");
|
|
34
|
+
const ghInstalled = hasGhCli();
|
|
35
|
+
if (ghInstalled) p.log.success("GitHub CLI detected — will use it to pull issues and discussions.");
|
|
36
|
+
else p.log.info("\x1B[90mGitHub CLI not installed — issues and discussions disabled.\n Install later to enable: \x1B[36mhttps://cli.github.com\x1B[0m");
|
|
37
|
+
const selected = await p.multiselect({
|
|
38
|
+
message: "What data sources should skills include?",
|
|
39
|
+
options: [
|
|
40
|
+
{
|
|
41
|
+
label: "Local search",
|
|
42
|
+
value: "search",
|
|
43
|
+
hint: "query engine for `skilld search` across all skill docs"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
label: "Release notes",
|
|
47
|
+
value: "releases",
|
|
48
|
+
hint: "changelogs and migration notes per version"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
label: "GitHub issues",
|
|
52
|
+
value: "issues",
|
|
53
|
+
hint: "common bugs, workarounds, and solutions",
|
|
54
|
+
disabled: !ghInstalled
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
label: "GitHub discussions",
|
|
58
|
+
value: "discussions",
|
|
59
|
+
hint: "community Q&A and usage examples",
|
|
60
|
+
disabled: !ghInstalled
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
initialValues: [...Object.entries(defaultFeatures).filter(([, v]) => v).map(([k]) => k), ...ghInstalled ? ["issues", "discussions"] : []],
|
|
64
|
+
required: false
|
|
65
|
+
});
|
|
66
|
+
if (p.isCancel(selected)) {
|
|
67
|
+
p.cancel("Setup cancelled");
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
const features = {
|
|
71
|
+
search: selected.includes("search"),
|
|
72
|
+
issues: selected.includes("issues"),
|
|
73
|
+
discussions: selected.includes("discussions"),
|
|
74
|
+
releases: selected.includes("releases")
|
|
75
|
+
};
|
|
76
|
+
p.note("An LLM can optionally summarize raw docs into a focused reference\nhighlighting best practices, gotchas, and migrations.\n\n\x1B[1mWithout LLM:\x1B[0m ~2 KB skill with package metadata, types, and links\n\x1B[1mWith LLM:\x1B[0m ~5 KB skill with curated gotchas, patterns, and migration notes\n\n\x1B[1mThis is a one-time build step\x1B[0m - it generates the SKILL.md, then your\ncoding agent reads the result every session. Can be a different model.\n\n\x1B[90mWorks with API keys, existing subscriptions (Claude Pro, ChatGPT Plus,\nCopilot, Gemini) via OAuth, or CLI tools (claude, gemini, codex).\x1B[0m", "Enhancement model (optional)");
|
|
77
|
+
let modelId;
|
|
78
|
+
let skippedEnhancement = false;
|
|
79
|
+
let oauthJustConnected = false;
|
|
80
|
+
while (true) {
|
|
81
|
+
const allModels = process.env.SKILLD_NO_AGENTS ? [] : await getAvailableModels();
|
|
82
|
+
if (allModels.length === 0) p.log.warn(NO_MODELS_MESSAGE);
|
|
83
|
+
else if (oauthJustConnected) p.log.step(`${allModels.length} models now available. Select one below.`);
|
|
84
|
+
else {
|
|
85
|
+
const providers = /* @__PURE__ */ new Set();
|
|
86
|
+
for (const m of allModels) {
|
|
87
|
+
const vendor = m.vendorGroup ?? m.providerName;
|
|
88
|
+
if (!m.id.startsWith("pi:")) providers.add(`${vendor} via CLI`);
|
|
89
|
+
else if (m.hint?.includes("API key")) providers.add(`${vendor} via API key`);
|
|
90
|
+
else if (m.hint?.includes("OAuth")) providers.add(`${vendor} via OAuth`);
|
|
91
|
+
}
|
|
92
|
+
if (providers.size > 0) p.log.success(`Found: ${[...providers].join(", ")}`);
|
|
93
|
+
}
|
|
94
|
+
const choice = await pickModel(allModels, {
|
|
95
|
+
before: allModels.length > 0 ? [{
|
|
96
|
+
label: "Auto",
|
|
97
|
+
value: "_auto",
|
|
98
|
+
hint: "picks best available model from connected providers"
|
|
99
|
+
}] : [],
|
|
100
|
+
after: [{
|
|
101
|
+
label: "Connect OAuth provider...",
|
|
102
|
+
value: "_connect",
|
|
103
|
+
hint: "use existing Claude Pro, ChatGPT Plus, etc."
|
|
104
|
+
}, {
|
|
105
|
+
label: "Skip enhancement",
|
|
106
|
+
value: "_skip",
|
|
107
|
+
hint: "base skill with docs, issues, and types - add LLM later via `skilld config`"
|
|
108
|
+
}]
|
|
109
|
+
});
|
|
110
|
+
if (choice === null) {
|
|
111
|
+
p.cancel("Setup cancelled");
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
if (choice === "_connect") {
|
|
115
|
+
await wizardConnectProvider();
|
|
116
|
+
oauthJustConnected = true;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (choice === "_skip") {
|
|
120
|
+
skippedEnhancement = true;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
if (choice === "_auto") break;
|
|
124
|
+
modelId = choice;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
updateConfig({
|
|
128
|
+
features,
|
|
129
|
+
...modelId ? {
|
|
130
|
+
model: modelId,
|
|
131
|
+
skipLlm: false
|
|
132
|
+
} : {
|
|
133
|
+
model: void 0,
|
|
134
|
+
skipLlm: skippedEnhancement
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
const modelSummary = modelId ? getModelName(modelId) : skippedEnhancement ? "none (raw docs)" : "auto";
|
|
138
|
+
const featureList = Object.entries(features).filter(([, v]) => v).map(([k]) => k).join(", ") || "none";
|
|
139
|
+
p.log.success(`Model: ${modelSummary} · Features: ${featureList}`);
|
|
140
|
+
if (opts.showOutro !== false) p.note("Run \x1B[36mskilld add <pkg>\x1B[0m to generate skills for specific packages\nRun \x1B[36mskilld\x1B[0m to scan your project and pick packages interactively\nRun \x1B[36mskilld config\x1B[0m to change settings later", "Setup complete");
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
async function wizardConnectProvider() {
|
|
144
|
+
p.note(OAUTH_NOTE, "How OAuth works");
|
|
145
|
+
const providers = getOAuthProviderList();
|
|
146
|
+
const provider = await p.select({
|
|
147
|
+
message: "Connect provider",
|
|
148
|
+
options: providers.map((pr) => ({
|
|
149
|
+
label: pr.name,
|
|
150
|
+
value: pr.id,
|
|
151
|
+
hint: pr.loggedIn ? "connected" : void 0
|
|
152
|
+
}))
|
|
153
|
+
});
|
|
154
|
+
if (p.isCancel(provider)) return;
|
|
155
|
+
const spinner = p.spinner();
|
|
156
|
+
spinner.start("Connecting...");
|
|
157
|
+
const success = await loginOAuthProvider(provider, {
|
|
158
|
+
onAuth: (url, instructions) => {
|
|
159
|
+
spinner.stop("Open this URL in your browser:");
|
|
160
|
+
p.log.info(` \x1B[36m${url}\x1B[0m`);
|
|
161
|
+
if (instructions) p.log.info(` \x1B[90m${instructions}\x1B[0m`);
|
|
162
|
+
spinner.start("Waiting for authentication...");
|
|
163
|
+
},
|
|
164
|
+
onPrompt: async (message, placeholder) => {
|
|
165
|
+
const value = await p.text({
|
|
166
|
+
message,
|
|
167
|
+
placeholder
|
|
168
|
+
});
|
|
169
|
+
if (p.isCancel(value)) return "";
|
|
170
|
+
return value;
|
|
171
|
+
},
|
|
172
|
+
onProgress: (msg) => p.log.step(msg)
|
|
173
|
+
}).catch((err) => {
|
|
174
|
+
spinner.stop(`Login failed: ${err.message}`);
|
|
175
|
+
return false;
|
|
176
|
+
});
|
|
177
|
+
spinner.stop();
|
|
178
|
+
if (success) {
|
|
179
|
+
const name = providers.find((pr) => pr.id === provider)?.name ?? provider;
|
|
180
|
+
p.log.success(`Connected to ${name}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
export { runWizard as t };
|
|
185
|
+
|
|
186
|
+
//# sourceMappingURL=wizard.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wizard.mjs","names":["agents"],"sources":["../../src/commands/wizard.ts"],"sourcesContent":["import type { AgentType, OptimizeModel } from '../agent/index.ts'\nimport type { FeaturesConfig } from '../core/config.ts'\nimport { execSync } from 'node:child_process'\nimport * as p from '@clack/prompts'\nimport { getOAuthProviderList, loginOAuthProvider } from '../agent/clis/pi-ai.ts'\nimport { agents, getAvailableModels, getModelName } from '../agent/index.ts'\nimport { isInteractive, NO_MODELS_MESSAGE, OAUTH_NOTE, pickModel } from '../cli-helpers.ts'\nimport { defaultFeatures, updateConfig } from '../core/config.ts'\n\nfunction hasGhCli(): boolean {\n if (process.env.SKILLD_NO_GH)\n return false\n try {\n execSync('gh --version', { stdio: 'ignore' })\n return true\n }\n catch {\n return false\n }\n}\n\nexport interface WizardOptions {\n /** Resolved target agent, if known */\n agent?: AgentType\n /** Show next-steps outro when done (default: true) */\n showOutro?: boolean\n}\n\nexport async function runWizard(opts: WizardOptions = {}): Promise<boolean> {\n if (!isInteractive())\n return false\n\n const agentLabel = opts.agent ? agents[opts.agent].displayName : null\n const skillsDir = opts.agent ? agents[opts.agent].skillsDir : '.claude/skills'\n const agentLine = agentLabel\n ? `\\n\\x1B[90mTarget agent: ${agentLabel}\\x1B[0m`\n : ''\n\n p.note(\n `Your AI agent reads docs from its training data - but APIs change,\\n`\n + `versions drift, and patterns go stale. Skilld fixes this.\\n`\n + `\\n`\n + `It generates a \\x1B[1mSKILL.md\\x1B[0m - a markdown reference card built from\\n`\n + `the \\x1B[1mactual docs, issues, and release notes\\x1B[0m for the exact\\n`\n + `package versions in your project. Your agent reads this file\\n`\n + `every session - no hallucinated APIs.\\n`\n + `\\n`\n + `\\x1B[1mHow it works:\\x1B[0m\\n`\n + ` 1. Fetch docs, issues, and types for your packages\\n`\n + ` 2. Optionally compress with an LLM into a concise cheat sheet\\n`\n + `\\n`\n + `\\x1B[90mExample: \\`skilld add vue\\` creates ${skillsDir}/vue-skilld/SKILL.md\\n`\n + `Your agent then knows the right APIs, gotchas, and patterns\\n`\n + `for your exact version.\\x1B[0m${\n agentLine}`,\n 'Welcome to skilld',\n )\n\n const ghInstalled = hasGhCli()\n\n if (ghInstalled) {\n p.log.success(\n 'GitHub CLI detected — will use it to pull issues and discussions.',\n )\n }\n else {\n p.log.info(\n '\\x1B[90mGitHub CLI not installed — issues and discussions disabled.\\n'\n + ' Install later to enable: \\x1B[36mhttps://cli.github.com\\x1B[0m',\n )\n }\n\n // Feature toggles\n const selected = await p.multiselect({\n message: 'What data sources should skills include?',\n options: [\n { label: 'Local search', value: 'search' as const, hint: 'query engine for `skilld search` across all skill docs' },\n { label: 'Release notes', value: 'releases' as const, hint: 'changelogs and migration notes per version' },\n { label: 'GitHub issues', value: 'issues' as const, hint: 'common bugs, workarounds, and solutions', disabled: !ghInstalled },\n { label: 'GitHub discussions', value: 'discussions' as const, hint: 'community Q&A and usage examples', disabled: !ghInstalled },\n ],\n initialValues: [\n ...Object.entries(defaultFeatures)\n .filter(([, v]) => v)\n .map(([k]) => k),\n ...(ghInstalled ? ['issues', 'discussions'] as const : []),\n ] as Array<keyof FeaturesConfig>,\n required: false,\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Setup cancelled')\n return false\n }\n\n const features: FeaturesConfig = {\n search: selected.includes('search'),\n issues: selected.includes('issues'),\n discussions: selected.includes('discussions'),\n releases: selected.includes('releases'),\n }\n\n // Enhancement model - optional, independent of target agent\n p.note(\n 'An LLM can optionally summarize raw docs into a focused reference\\n'\n + 'highlighting best practices, gotchas, and migrations.\\n'\n + '\\n'\n + '\\x1B[1mWithout LLM:\\x1B[0m ~2 KB skill with package metadata, types, and links\\n'\n + '\\x1B[1mWith LLM:\\x1B[0m ~5 KB skill with curated gotchas, patterns, and migration notes\\n'\n + '\\n'\n + '\\x1B[1mThis is a one-time build step\\x1B[0m - it generates the SKILL.md, then your\\n'\n + 'coding agent reads the result every session. Can be a different model.\\n'\n + '\\n'\n + '\\x1B[90mWorks with API keys, existing subscriptions (Claude Pro, ChatGPT Plus,\\n'\n + 'Copilot, Gemini) via OAuth, or CLI tools (claude, gemini, codex).\\x1B[0m',\n 'Enhancement model (optional)',\n )\n\n let modelId: OptimizeModel | undefined\n let skippedEnhancement = false\n let oauthJustConnected = false\n\n // Loop so user can connect OAuth then come back to pick a model\n while (true) {\n const allModels = process.env.SKILLD_NO_AGENTS ? [] : await getAvailableModels()\n\n if (allModels.length === 0) {\n p.log.warn(NO_MODELS_MESSAGE)\n }\n else if (oauthJustConnected) {\n p.log.step(`${allModels.length} models now available. Select one below.`)\n }\n else {\n // Show which providers were found by name (e.g. \"Anthropic via CLI, OpenAI via API key\")\n const providers = new Set<string>()\n for (const m of allModels) {\n const vendor = m.vendorGroup ?? m.providerName\n if (!m.id.startsWith('pi:'))\n providers.add(`${vendor} via CLI`)\n else if (m.hint?.includes('API key'))\n providers.add(`${vendor} via API key`)\n else if (m.hint?.includes('OAuth'))\n providers.add(`${vendor} via OAuth`)\n }\n if (providers.size > 0)\n p.log.success(`Found: ${[...providers].join(', ')}`)\n }\n\n const choice = await pickModel(allModels, {\n before: allModels.length > 0\n ? [{ label: 'Auto', value: '_auto', hint: 'picks best available model from connected providers' }]\n : [],\n after: [\n { label: 'Connect OAuth provider...', value: '_connect', hint: 'use existing Claude Pro, ChatGPT Plus, etc.' },\n { label: 'Skip enhancement', value: '_skip', hint: 'base skill with docs, issues, and types - add LLM later via `skilld config`' },\n ],\n })\n\n if (choice === null) {\n p.cancel('Setup cancelled')\n return false\n }\n\n if (choice === '_connect') {\n await wizardConnectProvider()\n oauthJustConnected = true\n continue\n }\n\n if (choice === '_skip') {\n skippedEnhancement = true\n break\n }\n if (choice === '_auto')\n break\n\n modelId = choice as OptimizeModel\n break\n }\n\n updateConfig({\n features,\n ...(modelId\n ? { model: modelId, skipLlm: false }\n : { model: undefined, skipLlm: skippedEnhancement }),\n })\n\n // Summary of what was saved\n const modelSummary = modelId\n ? getModelName(modelId)\n : skippedEnhancement\n ? 'none (raw docs)'\n : 'auto'\n const featureList = Object.entries(features).filter(([, v]) => v).map(([k]) => k).join(', ') || 'none'\n p.log.success(`Model: ${modelSummary} · Features: ${featureList}`)\n\n if (opts.showOutro !== false) {\n p.note(\n 'Run \\x1B[36mskilld add <pkg>\\x1B[0m to generate skills for specific packages\\n'\n + 'Run \\x1B[36mskilld\\x1B[0m to scan your project and pick packages interactively\\n'\n + 'Run \\x1B[36mskilld config\\x1B[0m to change settings later',\n 'Setup complete',\n )\n }\n return true\n}\n\nasync function wizardConnectProvider(): Promise<void> {\n p.note(OAUTH_NOTE, 'How OAuth works')\n\n const providers = getOAuthProviderList()\n const provider = await p.select({\n message: 'Connect provider',\n options: providers.map(pr => ({\n label: pr.name,\n value: pr.id,\n hint: pr.loggedIn ? 'connected' : undefined,\n })),\n })\n\n if (p.isCancel(provider))\n return\n\n const spinner = p.spinner()\n spinner.start('Connecting...')\n\n const success = await loginOAuthProvider(provider as string, {\n onAuth: (url, instructions) => {\n spinner.stop('Open this URL in your browser:')\n p.log.info(` \\x1B[36m${url}\\x1B[0m`)\n if (instructions)\n p.log.info(` \\x1B[90m${instructions}\\x1B[0m`)\n spinner.start('Waiting for authentication...')\n },\n onPrompt: async (message, placeholder) => {\n const value = await p.text({ message, placeholder })\n if (p.isCancel(value))\n return ''\n return value as string\n },\n onProgress: msg => p.log.step(msg),\n }).catch((err: Error) => {\n spinner.stop(`Login failed: ${err.message}`)\n return false\n })\n\n spinner.stop()\n\n if (success) {\n const name = providers.find(pr => pr.id === provider)?.name ?? provider\n p.log.success(`Connected to ${name}`)\n }\n}\n"],"mappings":"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"}
|
package/dist/agent/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { a as getModelLabel, i as getAvailableModels, o as getModelName, r as createToolProgress, s as optimizeDocs, t as detectImportedPackages } from "../_chunks/agent.mjs";
|
|
2
2
|
import "../_chunks/config.mjs";
|
|
3
|
+
import "../_chunks/prepare.mjs";
|
|
3
4
|
import "../_chunks/sanitize.mjs";
|
|
4
5
|
import "../_chunks/cache.mjs";
|
|
5
6
|
import "../_chunks/yaml.mjs";
|
package/dist/cache/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as REPOS_DIR, C as
|
|
1
|
+
import { A as REPOS_DIR, C as linkShippedSkill, D as CachedPackage, E as CachedDoc, M as getRepoCacheDir, O as CACHE_DIR, S as getShippedSkills, T as CacheConfig, _ as readCachedSection, a as clearCache, b as writeToRepoCache, c as hasShippedDocs, d as linkPkg, f as linkPkgNamed, g as readCachedDocs, h as listReferenceFiles, i as clearAllCache, j as getPackageDbPath, k as REFERENCES_DIR, l as isCached, m as listCached, n as getCacheKey, o as ensureCacheDir, p as linkRepoCachedDir, r as getVersionKey, s as getPkgKeyFiles, t as getCacheDir, u as linkCachedDir, v as writeSections, w as resolvePkgDir, x as ShippedSkill, y as writeToCache } from "../_chunks/index.mjs";
|
|
2
2
|
export { CACHE_DIR, CacheConfig, CachedDoc, CachedPackage, REFERENCES_DIR, REPOS_DIR, ShippedSkill, clearAllCache, clearCache, ensureCacheDir, getCacheDir, getCacheKey, getPackageDbPath, getPkgKeyFiles, getRepoCacheDir, getShippedSkills, getVersionKey, hasShippedDocs, isCached, linkCachedDir, linkPkg, linkPkgNamed, linkRepoCachedDir, linkShippedSkill, listCached, listReferenceFiles, readCachedDocs, readCachedSection, resolvePkgDir, writeSections, writeToCache, writeToRepoCache };
|
package/dist/cache/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { a as getRepoCacheDir, c as getVersionKey, i as getPackageDbPath, n as REFERENCES_DIR, o as getCacheDir, r as REPOS_DIR, s as getCacheKey, t as CACHE_DIR } from "../_chunks/config.mjs";
|
|
2
|
+
import { n as linkShippedSkill, r as resolvePkgDir, t as getShippedSkills } from "../_chunks/prepare.mjs";
|
|
2
3
|
import "../_chunks/sanitize.mjs";
|
|
3
|
-
import { _ as
|
|
4
|
+
import { _ as writeToRepoCache, a as hasShippedDocs, c as linkPkg, d as listCached, f as listReferenceFiles, g as writeToCache, h as writeSections, i as getPkgKeyFiles, l as linkPkgNamed, m as readCachedSection, n as clearCache, o as isCached, p as readCachedDocs, r as ensureCacheDir, s as linkCachedDir, t as clearAllCache, u as linkRepoCachedDir } from "../_chunks/cache.mjs";
|
|
4
5
|
export { CACHE_DIR, REFERENCES_DIR, REPOS_DIR, clearAllCache, clearCache, ensureCacheDir, getCacheDir, getCacheKey, getPackageDbPath, getPkgKeyFiles, getRepoCacheDir, getShippedSkills, getVersionKey, hasShippedDocs, isCached, linkCachedDir, linkPkg, linkPkgNamed, linkRepoCachedDir, linkShippedSkill, listCached, listReferenceFiles, readCachedDocs, readCachedSection, resolvePkgDir, writeSections, writeToCache, writeToRepoCache };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
//#region src/cli-entry.ts
|
|
3
|
+
/**
|
|
4
|
+
* CLI entry point. Intercepts `skilld prepare` to run the fast path (~45ms)
|
|
5
|
+
* before the full CLI loads (~200ms of module imports).
|
|
6
|
+
*/
|
|
7
|
+
await (process.argv[2] === "prepare" && process.argv.length <= 3 ? import("./prepare.mjs") : import("./cli.mjs"));
|
|
8
|
+
//#endregion
|
|
9
|
+
export {};
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=cli-entry.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-entry.mjs","names":[],"sources":["../src/cli-entry.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point. Intercepts `skilld prepare` to run the fast path (~45ms)\n * before the full CLI loads (~200ms of module imports).\n */\n\n// eslint-disable-next-line antfu/no-top-level-await\nawait import(process.argv[2] === 'prepare' && process.argv.length <= 3\n ? './prepare.ts'\n : './cli.ts',\n)\n"],"mappings":";;;;;;AAOA,OAAa,QAAQ,KAAK,OAAO,aAAa,QAAQ,KAAK,UAAU,IAAA,OACjE,mBAAA,OACA"}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { c as getOAuthProviderList, i as getAvailableModels, l as loginOAuthProvider, o as getModelName, t as detectImportedPackages, u as logoutOAuthProvider } from "./_chunks/agent.mjs";
|
|
3
3
|
import { i as getPackageDbPath, o as getCacheDir, t as CACHE_DIR } from "./_chunks/config.mjs";
|
|
4
|
+
import "./_chunks/prepare.mjs";
|
|
4
5
|
import "./_chunks/sanitize.mjs";
|
|
5
6
|
import "./_chunks/cache.mjs";
|
|
6
7
|
import "./_chunks/yaml.mjs";
|
|
@@ -9,13 +10,14 @@ import { n as getSharedSkillsDir, o as semverGt, r as mapInsert } from "./_chunk
|
|
|
9
10
|
import { r as fetchNpmRegistryMeta, t as fetchLatestVersion } from "./_chunks/sources.mjs";
|
|
10
11
|
import { a as targets, i as getAgentVersion, r as detectTargetAgent, t as detectInstalledAgents } from "./_chunks/detect.mjs";
|
|
11
12
|
import { o as unlinkSkillFromAgents } from "./_chunks/prompts.mjs";
|
|
12
|
-
import {
|
|
13
|
+
import { D as hasCompletedWizard, M as updateConfig, O as hasConfig, S as version, T as defaultFeatures, _ as relativeTime, a as formatStatus, b as sharedArgs, c as getRepoHint, d as introLine, f as isInteractive, g as promptForAgent, h as pickModel, k as readConfig, m as menuLoop, n as NO_MODELS_MESSAGE, o as getInstalledGenerators, p as isRunningInsideAgent, r as OAUTH_NOTE, u as guard, v as requireInteractive, x as suggestPrepareHook, y as resolveAgent } from "./_chunks/cli-helpers.mjs";
|
|
13
14
|
import { a as removeLockEntry, n as parsePackages } from "./_chunks/lockfile.mjs";
|
|
14
15
|
import { i as iterateSkills, n as getSkillsDir, r as isOutdated, t as getProjectState } from "./_chunks/skills.mjs";
|
|
15
16
|
import { c as timeAgo, i as formatSource, l as timedSpinner } from "./_chunks/formatting.mjs";
|
|
17
|
+
import { t as runWizard } from "./_chunks/wizard.mjs";
|
|
18
|
+
import "./_chunks/core.mjs";
|
|
16
19
|
import { join, resolve } from "pathe";
|
|
17
20
|
import { existsSync, readFileSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
18
|
-
import { execSync } from "node:child_process";
|
|
19
21
|
import pLimit from "p-limit";
|
|
20
22
|
import * as p from "@clack/prompts";
|
|
21
23
|
import { defineCommand, runMain } from "citty";
|
|
@@ -513,184 +515,6 @@ const infoCommandDef = defineCommand({
|
|
|
513
515
|
}
|
|
514
516
|
});
|
|
515
517
|
//#endregion
|
|
516
|
-
//#region src/commands/wizard.ts
|
|
517
|
-
function hasGhCli() {
|
|
518
|
-
if (process.env.SKILLD_NO_GH) return false;
|
|
519
|
-
try {
|
|
520
|
-
execSync("gh --version", { stdio: "ignore" });
|
|
521
|
-
return true;
|
|
522
|
-
} catch {
|
|
523
|
-
return false;
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
async function runWizard(opts = {}) {
|
|
527
|
-
if (!isInteractive()) return false;
|
|
528
|
-
const agentLabel = opts.agent ? targets[opts.agent].displayName : null;
|
|
529
|
-
const skillsDir = opts.agent ? targets[opts.agent].skillsDir : ".claude/skills";
|
|
530
|
-
const agentLine = agentLabel ? `\n\x1B[90mTarget agent: ${agentLabel}\x1B[0m` : "";
|
|
531
|
-
p.note(`Your AI agent reads docs from its training data - but APIs change,
|
|
532
|
-
versions drift, and patterns go stale. Skilld fixes this.
|
|
533
|
-
|
|
534
|
-
It generates a [1mSKILL.md[0m - a markdown reference card built from
|
|
535
|
-
the [1mactual docs, issues, and release notes[0m for the exact
|
|
536
|
-
package versions in your project. Your agent reads this file
|
|
537
|
-
every session - no hallucinated APIs.
|
|
538
|
-
|
|
539
|
-
[1mHow it works:[0m
|
|
540
|
-
1. Fetch docs, issues, and types for your packages
|
|
541
|
-
2. Optionally compress with an LLM into a concise cheat sheet
|
|
542
|
-
|
|
543
|
-
\x1B[90mExample: \`skilld add vue\` creates ${skillsDir}/vue-skilld/SKILL.md\nYour agent then knows the right APIs, gotchas, and patterns\nfor your exact version.\x1B[0m${agentLine}`, "Welcome to skilld");
|
|
544
|
-
const ghInstalled = hasGhCli();
|
|
545
|
-
if (ghInstalled) p.log.success("GitHub CLI detected — will use it to pull issues and discussions.");
|
|
546
|
-
else p.log.info("\x1B[90mGitHub CLI not installed — issues and discussions disabled.\n Install later to enable: \x1B[36mhttps://cli.github.com\x1B[0m");
|
|
547
|
-
const selected = await p.multiselect({
|
|
548
|
-
message: "What data sources should skills include?",
|
|
549
|
-
options: [
|
|
550
|
-
{
|
|
551
|
-
label: "Local search",
|
|
552
|
-
value: "search",
|
|
553
|
-
hint: "query engine for `skilld search` across all skill docs"
|
|
554
|
-
},
|
|
555
|
-
{
|
|
556
|
-
label: "Release notes",
|
|
557
|
-
value: "releases",
|
|
558
|
-
hint: "changelogs and migration notes per version"
|
|
559
|
-
},
|
|
560
|
-
{
|
|
561
|
-
label: "GitHub issues",
|
|
562
|
-
value: "issues",
|
|
563
|
-
hint: "common bugs, workarounds, and solutions",
|
|
564
|
-
disabled: !ghInstalled
|
|
565
|
-
},
|
|
566
|
-
{
|
|
567
|
-
label: "GitHub discussions",
|
|
568
|
-
value: "discussions",
|
|
569
|
-
hint: "community Q&A and usage examples",
|
|
570
|
-
disabled: !ghInstalled
|
|
571
|
-
}
|
|
572
|
-
],
|
|
573
|
-
initialValues: [...Object.entries(defaultFeatures).filter(([, v]) => v).map(([k]) => k), ...ghInstalled ? ["issues", "discussions"] : []],
|
|
574
|
-
required: false
|
|
575
|
-
});
|
|
576
|
-
if (p.isCancel(selected)) {
|
|
577
|
-
p.cancel("Setup cancelled");
|
|
578
|
-
return false;
|
|
579
|
-
}
|
|
580
|
-
const features = {
|
|
581
|
-
search: selected.includes("search"),
|
|
582
|
-
issues: selected.includes("issues"),
|
|
583
|
-
discussions: selected.includes("discussions"),
|
|
584
|
-
releases: selected.includes("releases")
|
|
585
|
-
};
|
|
586
|
-
p.note("An LLM can optionally summarize raw docs into a focused reference\nhighlighting best practices, gotchas, and migrations.\n\n\x1B[1mWithout LLM:\x1B[0m ~2 KB skill with package metadata, types, and links\n\x1B[1mWith LLM:\x1B[0m ~5 KB skill with curated gotchas, patterns, and migration notes\n\n\x1B[1mThis is a one-time build step\x1B[0m - it generates the SKILL.md, then your\ncoding agent reads the result every session. Can be a different model.\n\n\x1B[90mWorks with API keys, existing subscriptions (Claude Pro, ChatGPT Plus,\nCopilot, Gemini) via OAuth, or CLI tools (claude, gemini, codex).\x1B[0m", "Enhancement model (optional)");
|
|
587
|
-
let modelId;
|
|
588
|
-
let skippedEnhancement = false;
|
|
589
|
-
let oauthJustConnected = false;
|
|
590
|
-
while (true) {
|
|
591
|
-
const allModels = process.env.SKILLD_NO_AGENTS ? [] : await getAvailableModels();
|
|
592
|
-
if (allModels.length === 0) p.log.warn(NO_MODELS_MESSAGE);
|
|
593
|
-
else if (oauthJustConnected) p.log.step(`${allModels.length} models now available. Select one below.`);
|
|
594
|
-
else {
|
|
595
|
-
const providers = /* @__PURE__ */ new Set();
|
|
596
|
-
for (const m of allModels) {
|
|
597
|
-
const vendor = m.vendorGroup ?? m.providerName;
|
|
598
|
-
if (!m.id.startsWith("pi:")) providers.add(`${vendor} via CLI`);
|
|
599
|
-
else if (m.hint?.includes("API key")) providers.add(`${vendor} via API key`);
|
|
600
|
-
else if (m.hint?.includes("OAuth")) providers.add(`${vendor} via OAuth`);
|
|
601
|
-
}
|
|
602
|
-
if (providers.size > 0) p.log.success(`Found: ${[...providers].join(", ")}`);
|
|
603
|
-
}
|
|
604
|
-
const choice = await pickModel(allModels, {
|
|
605
|
-
before: allModels.length > 0 ? [{
|
|
606
|
-
label: "Auto",
|
|
607
|
-
value: "_auto",
|
|
608
|
-
hint: "picks best available model from connected providers"
|
|
609
|
-
}] : [],
|
|
610
|
-
after: [{
|
|
611
|
-
label: "Connect OAuth provider...",
|
|
612
|
-
value: "_connect",
|
|
613
|
-
hint: "use existing Claude Pro, ChatGPT Plus, etc."
|
|
614
|
-
}, {
|
|
615
|
-
label: "Skip enhancement",
|
|
616
|
-
value: "_skip",
|
|
617
|
-
hint: "base skill with docs, issues, and types - add LLM later via `skilld config`"
|
|
618
|
-
}]
|
|
619
|
-
});
|
|
620
|
-
if (choice === null) {
|
|
621
|
-
p.cancel("Setup cancelled");
|
|
622
|
-
return false;
|
|
623
|
-
}
|
|
624
|
-
if (choice === "_connect") {
|
|
625
|
-
await wizardConnectProvider();
|
|
626
|
-
oauthJustConnected = true;
|
|
627
|
-
continue;
|
|
628
|
-
}
|
|
629
|
-
if (choice === "_skip") {
|
|
630
|
-
skippedEnhancement = true;
|
|
631
|
-
break;
|
|
632
|
-
}
|
|
633
|
-
if (choice === "_auto") break;
|
|
634
|
-
modelId = choice;
|
|
635
|
-
break;
|
|
636
|
-
}
|
|
637
|
-
updateConfig({
|
|
638
|
-
features,
|
|
639
|
-
...modelId ? {
|
|
640
|
-
model: modelId,
|
|
641
|
-
skipLlm: false
|
|
642
|
-
} : {
|
|
643
|
-
model: void 0,
|
|
644
|
-
skipLlm: skippedEnhancement
|
|
645
|
-
}
|
|
646
|
-
});
|
|
647
|
-
const modelSummary = modelId ? getModelName(modelId) : skippedEnhancement ? "none (raw docs)" : "auto";
|
|
648
|
-
const featureList = Object.entries(features).filter(([, v]) => v).map(([k]) => k).join(", ") || "none";
|
|
649
|
-
p.log.success(`Model: ${modelSummary} · Features: ${featureList}`);
|
|
650
|
-
if (opts.showOutro !== false) p.note("Run \x1B[36mskilld add <pkg>\x1B[0m to generate skills for specific packages\nRun \x1B[36mskilld\x1B[0m to scan your project and pick packages interactively\nRun \x1B[36mskilld config\x1B[0m to change settings later", "Setup complete");
|
|
651
|
-
return true;
|
|
652
|
-
}
|
|
653
|
-
async function wizardConnectProvider() {
|
|
654
|
-
p.note(OAUTH_NOTE, "How OAuth works");
|
|
655
|
-
const providers = getOAuthProviderList();
|
|
656
|
-
const provider = await p.select({
|
|
657
|
-
message: "Connect provider",
|
|
658
|
-
options: providers.map((pr) => ({
|
|
659
|
-
label: pr.name,
|
|
660
|
-
value: pr.id,
|
|
661
|
-
hint: pr.loggedIn ? "connected" : void 0
|
|
662
|
-
}))
|
|
663
|
-
});
|
|
664
|
-
if (p.isCancel(provider)) return;
|
|
665
|
-
const spinner = p.spinner();
|
|
666
|
-
spinner.start("Connecting...");
|
|
667
|
-
const success = await loginOAuthProvider(provider, {
|
|
668
|
-
onAuth: (url, instructions) => {
|
|
669
|
-
spinner.stop("Open this URL in your browser:");
|
|
670
|
-
p.log.info(` \x1B[36m${url}\x1B[0m`);
|
|
671
|
-
if (instructions) p.log.info(` \x1B[90m${instructions}\x1B[0m`);
|
|
672
|
-
spinner.start("Waiting for authentication...");
|
|
673
|
-
},
|
|
674
|
-
onPrompt: async (message, placeholder) => {
|
|
675
|
-
const value = await p.text({
|
|
676
|
-
message,
|
|
677
|
-
placeholder
|
|
678
|
-
});
|
|
679
|
-
if (p.isCancel(value)) return "";
|
|
680
|
-
return value;
|
|
681
|
-
},
|
|
682
|
-
onProgress: (msg) => p.log.step(msg)
|
|
683
|
-
}).catch((err) => {
|
|
684
|
-
spinner.stop(`Login failed: ${err.message}`);
|
|
685
|
-
return false;
|
|
686
|
-
});
|
|
687
|
-
spinner.stop();
|
|
688
|
-
if (success) {
|
|
689
|
-
const name = providers.find((pr) => pr.id === provider)?.name ?? provider;
|
|
690
|
-
p.log.success(`Connected to ${name}`);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
//#endregion
|
|
694
518
|
//#region src/cli.ts
|
|
695
519
|
const _emit = process.emit;
|
|
696
520
|
process.emit = (event, ...args) => event === "warning" && args[0]?.name === "ExperimentalWarning" && args[0]?.message?.includes("SQLite") ? false : _emit.apply(process, [event, ...args]);
|
|
@@ -808,15 +632,15 @@ runMain(defineCommand({
|
|
|
808
632
|
},
|
|
809
633
|
args: { agent: sharedArgs.agent },
|
|
810
634
|
subCommands: {
|
|
811
|
-
add: () => import("./_chunks/
|
|
812
|
-
eject: () => import("./_chunks/
|
|
813
|
-
update: () => import("./_chunks/
|
|
635
|
+
add: () => import("./_chunks/sync2.mjs").then((m) => m.addCommandDef),
|
|
636
|
+
eject: () => import("./_chunks/sync2.mjs").then((m) => m.ejectCommandDef),
|
|
637
|
+
update: () => import("./_chunks/sync2.mjs").then((m) => m.updateCommandDef),
|
|
814
638
|
info: () => infoCommandDef,
|
|
815
639
|
list: () => import("./_chunks/list.mjs").then((m) => m.listCommandDef),
|
|
816
640
|
config: () => configCommandDef,
|
|
817
641
|
remove: () => removeCommandDef,
|
|
818
642
|
install: () => import("./_chunks/install.mjs").then((m) => m.installCommandDef),
|
|
819
|
-
prepare: () => import("./_chunks/
|
|
643
|
+
prepare: () => import("./_chunks/prepare2.mjs").then((m) => m.prepareCommandDef),
|
|
820
644
|
uninstall: () => import("./_chunks/uninstall.mjs").then((m) => m.uninstallCommandDef),
|
|
821
645
|
search: () => import("./_chunks/search.mjs").then((m) => m.searchCommandDef),
|
|
822
646
|
cache: () => import("./_chunks/cache2.mjs").then((m) => m.cacheCommandDef),
|
|
@@ -1057,7 +881,7 @@ runMain(defineCommand({
|
|
|
1057
881
|
selected = choice;
|
|
1058
882
|
}
|
|
1059
883
|
const wizardConfig = readConfig();
|
|
1060
|
-
const { syncCommand } = await import("./_chunks/
|
|
884
|
+
const { syncCommand } = await import("./_chunks/sync2.mjs");
|
|
1061
885
|
await syncCommand(state, {
|
|
1062
886
|
packages: selected,
|
|
1063
887
|
global: false,
|
|
@@ -1283,7 +1107,7 @@ runMain(defineCommand({
|
|
|
1283
1107
|
if (choice.length === 0) return;
|
|
1284
1108
|
selected = choice;
|
|
1285
1109
|
}
|
|
1286
|
-
const { syncCommand: sync } = await import("./_chunks/
|
|
1110
|
+
const { syncCommand: sync } = await import("./_chunks/sync2.mjs");
|
|
1287
1111
|
await sync(state, {
|
|
1288
1112
|
packages: selected,
|
|
1289
1113
|
global: false,
|
|
@@ -1308,7 +1132,7 @@ runMain(defineCommand({
|
|
|
1308
1132
|
initialValues: state.outdated.map((s) => s.packageName || s.name)
|
|
1309
1133
|
}));
|
|
1310
1134
|
if (selected.length === 0) return;
|
|
1311
|
-
const { syncCommand: syncUpdate } = await import("./_chunks/
|
|
1135
|
+
const { syncCommand: syncUpdate } = await import("./_chunks/sync2.mjs");
|
|
1312
1136
|
await syncUpdate(state, {
|
|
1313
1137
|
packages: selected,
|
|
1314
1138
|
global: false,
|
|
@@ -1359,6 +1183,6 @@ runMain(defineCommand({
|
|
|
1359
1183
|
}
|
|
1360
1184
|
}));
|
|
1361
1185
|
//#endregion
|
|
1362
|
-
export {
|
|
1186
|
+
export {};
|
|
1363
1187
|
|
|
1364
1188
|
//# sourceMappingURL=cli.mjs.map
|