skilld 1.2.2 → 1.3.0
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/README.md +21 -20
- package/dist/_chunks/agent.mjs +471 -17
- package/dist/_chunks/agent.mjs.map +1 -1
- package/dist/_chunks/assemble.mjs +2 -2
- package/dist/_chunks/assemble.mjs.map +1 -1
- package/dist/_chunks/cache.mjs +8 -2
- package/dist/_chunks/cache.mjs.map +1 -1
- package/dist/_chunks/cache2.mjs +2 -2
- package/dist/_chunks/cache2.mjs.map +1 -1
- package/dist/_chunks/cli-helpers.mjs +421 -0
- package/dist/_chunks/cli-helpers.mjs.map +1 -0
- package/dist/_chunks/detect.mjs +51 -22
- package/dist/_chunks/detect.mjs.map +1 -1
- package/dist/_chunks/detect2.mjs +2 -0
- package/dist/_chunks/embedding-cache.mjs +13 -4
- package/dist/_chunks/embedding-cache.mjs.map +1 -1
- package/dist/_chunks/formatting.mjs +1 -286
- package/dist/_chunks/formatting.mjs.map +1 -1
- package/dist/_chunks/index.d.mts.map +1 -1
- package/dist/_chunks/index2.d.mts.map +1 -1
- package/dist/_chunks/install.mjs +6 -4
- package/dist/_chunks/install.mjs.map +1 -1
- package/dist/_chunks/list.mjs +3 -2
- package/dist/_chunks/list.mjs.map +1 -1
- package/dist/_chunks/pool.mjs +3 -2
- package/dist/_chunks/pool.mjs.map +1 -1
- package/dist/_chunks/prompts.mjs +38 -4
- package/dist/_chunks/prompts.mjs.map +1 -1
- package/dist/_chunks/sanitize.mjs +7 -0
- package/dist/_chunks/sanitize.mjs.map +1 -1
- package/dist/_chunks/search-interactive.mjs +3 -2
- package/dist/_chunks/search-interactive.mjs.map +1 -1
- package/dist/_chunks/search.mjs +4 -3
- package/dist/_chunks/search.mjs.map +1 -1
- package/dist/_chunks/setup.mjs +27 -0
- package/dist/_chunks/setup.mjs.map +1 -0
- package/dist/_chunks/shared.mjs +6 -2
- package/dist/_chunks/shared.mjs.map +1 -1
- package/dist/_chunks/skills.mjs +1 -1
- package/dist/_chunks/sources.mjs +8 -8
- package/dist/_chunks/sources.mjs.map +1 -1
- package/dist/_chunks/sync.mjs +390 -108
- package/dist/_chunks/sync.mjs.map +1 -1
- package/dist/_chunks/uninstall.mjs +16 -2
- package/dist/_chunks/uninstall.mjs.map +1 -1
- package/dist/agent/index.d.mts +22 -4
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +3 -3
- package/dist/cli.mjs +619 -328
- package/dist/cli.mjs.map +1 -1
- package/dist/retriv/index.d.mts +18 -3
- package/dist/retriv/index.d.mts.map +1 -1
- package/dist/retriv/index.mjs +30 -1
- package/dist/retriv/index.mjs.map +1 -1
- package/dist/retriv/worker.d.mts +2 -0
- package/dist/retriv/worker.d.mts.map +1 -1
- package/dist/retriv/worker.mjs +1 -0
- package/dist/retriv/worker.mjs.map +1 -1
- package/dist/sources/index.mjs +1 -1
- package/package.json +9 -8
- package/dist/_chunks/chunk.mjs +0 -15
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":["agents","skilldVersion","agents"],"sources":["../src/commands/config.ts","../src/commands/remove.ts","../src/commands/status.ts","../src/commands/wizard.ts","../src/cli.ts"],"sourcesContent":["import type { FeaturesConfig } from '../core/config.ts'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { agents, getAvailableModels } from '../agent/index.ts'\nimport { getInstalledGenerators, introLine, requireInteractive } from '../cli-helpers.ts'\nimport { defaultFeatures, readConfig, updateConfig } from '../core/config.ts'\nimport { getProjectState } from '../core/skills.ts'\n\nexport async function configCommand(): Promise<void> {\n const config = readConfig()\n\n const features = config.features ?? defaultFeatures\n const enabledCount = Object.values(features).filter(Boolean).length\n\n const action = await p.select({\n message: 'Settings',\n options: [\n { label: 'Change features', value: 'features', hint: `${enabledCount}/4 enabled` },\n { label: 'Change model', value: 'model', hint: config.model || 'auto' },\n { label: 'Change agent', value: 'agent', hint: config.agent || 'auto-detect' },\n ],\n })\n\n if (p.isCancel(action)) {\n p.cancel('Cancelled')\n return\n }\n\n switch (action) {\n case 'features': {\n const featureOptions = [\n { label: 'Semantic + token search', value: 'search' as const, hint: 'local query engine to cut token costs and speed up grep' },\n { label: 'Release notes', value: 'releases' as const, hint: 'track changelogs for installed packages' },\n { label: 'GitHub issues', value: 'issues' as const, hint: 'surface common problems and solutions' },\n { label: 'GitHub discussions', value: 'discussions' as const, hint: 'include Q&A and community knowledge' },\n ] as const\n\n const selected = await p.multiselect({\n message: 'Enable features',\n options: featureOptions.map(f => ({\n label: f.label,\n value: f.value,\n hint: f.hint,\n })),\n initialValues: Object.entries(features)\n .filter(([, v]) => v)\n .map(([k]) => k) as Array<keyof FeaturesConfig>,\n required: false,\n })\n\n if (p.isCancel(selected))\n return\n\n const updated: FeaturesConfig = {\n search: selected.includes('search'),\n issues: selected.includes('issues'),\n discussions: selected.includes('discussions'),\n releases: selected.includes('releases'),\n }\n updateConfig({ features: updated })\n p.log.success(`Features updated: ${selected.length} enabled`)\n break\n }\n\n case 'model': {\n const available = await getAvailableModels()\n if (available.length === 0) {\n p.log.warn('No LLM CLIs found')\n return\n }\n\n const model = await p.select({\n message: 'Select default model',\n options: [\n { label: 'Auto (prompt each time)', value: '' },\n ...available.map(m => ({\n label: m.recommended ? `${m.name} (Recommended)` : m.name,\n value: m.id,\n hint: m.hint,\n })),\n ],\n initialValue: config.model || '',\n })\n\n if (p.isCancel(model))\n return\n\n updateConfig({ model: (model || undefined) as typeof config.model })\n p.log.success(model ? `Default model set to ${model}` : 'Model will be prompted each time')\n break\n }\n\n case 'agent': {\n const agentChoice = await p.select({\n message: 'Select default agent',\n options: [\n { label: 'Auto-detect', value: '' },\n ...Object.entries(agents).map(([id, a]) => ({\n label: a.displayName,\n value: id,\n hint: a.skillsDir,\n })),\n ],\n initialValue: config.agent || '',\n })\n\n if (p.isCancel(agentChoice))\n return\n\n updateConfig({ agent: agentChoice || undefined })\n p.log.success(agentChoice ? `Default agent set to ${agentChoice}` : 'Agent will be auto-detected')\n break\n }\n }\n}\n\nexport const configCommandDef = defineCommand({\n meta: { name: 'config', description: 'Edit settings' },\n args: {},\n async run() {\n requireInteractive('config')\n const cwd = process.cwd()\n const state = await getProjectState(cwd)\n const generators = getInstalledGenerators()\n const config = readConfig()\n p.intro(introLine({ state, generators, modelId: config.model }))\n return configCommand()\n },\n})\n","import type { AgentType } from '../agent/index.ts'\nimport type { ProjectState, SkillEntry } from '../core/skills.ts'\nimport { existsSync, rmSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { unlinkSkillFromAgents } from '../agent/index.ts'\nimport { getInstalledGenerators, introLine, isInteractive, promptForAgent, resolveAgent, sharedArgs } from '../cli-helpers.ts'\nimport { readConfig } from '../core/config.ts'\nimport { removeLockEntry } from '../core/lockfile.ts'\nimport { getSharedSkillsDir } from '../core/shared.ts'\nimport { getProjectState, getSkillsDir, iterateSkills } from '../core/skills.ts'\n\nexport interface RemoveOptions {\n packages?: string[]\n global: boolean\n agent: AgentType\n yes: boolean\n}\n\nexport async function removeCommand(state: ProjectState, opts: RemoveOptions): Promise<void> {\n // Get skills from the appropriate scope\n const scope = opts.global ? 'global' : 'local'\n const allSkills = [...iterateSkills({ scope })]\n\n // Non-interactive without packages → error\n if (!isInteractive() && !opts.packages) {\n console.error('Error: `skilld remove` requires package names in non-interactive mode.\\n Usage: skilld remove <package...>')\n process.exit(1)\n }\n\n // Get skills to choose from\n const skills = opts.packages\n ? allSkills.filter(s => opts.packages!.includes(s.name))\n : await pickSkillsToRemove(allSkills, scope)\n\n if (!skills || skills.length === 0) {\n p.log.info('No skills selected')\n return\n }\n\n // Confirm deletion (skip in non-interactive)\n if (!opts.yes && isInteractive()) {\n const confirmed = await p.confirm({\n message: `Remove ${skills.length} skill(s)? ${skills.map(s => s.name).join(', ')}`,\n })\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel('Cancelled')\n return\n }\n }\n\n // Delete each skill\n const cwd = process.cwd()\n const shared = getSharedSkillsDir(cwd)\n for (const skill of skills) {\n const skillsDir = getSkillsDir(skill.agent, skill.scope)\n\n if (existsSync(skill.dir)) {\n rmSync(skill.dir, { recursive: true, force: true })\n removeLockEntry(skillsDir, skill.name)\n // Clean up per-agent symlinks when removing from shared dir\n if (shared && skill.scope === 'local')\n unlinkSkillFromAgents(skill.name, cwd, opts.agent)\n p.log.success(`Removed ${skill.name}`)\n }\n else {\n p.log.warn(`${skill.name} not found`)\n }\n }\n\n p.outro(`Removed ${skills.length} skill(s)`)\n}\n\nasync function pickSkillsToRemove(skills: SkillEntry[], scope: 'local' | 'global'): Promise<SkillEntry[] | null> {\n if (skills.length === 0) {\n p.log.warn(`No ${scope} skills installed`)\n return null\n }\n\n const options = skills.map(skill => ({\n label: skill.name,\n value: skill.name,\n hint: skill.info?.version ? `@${skill.info.version}` : undefined,\n }))\n\n const selected = await p.multiselect({\n message: 'Select skills to remove',\n options,\n required: false,\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Cancelled')\n return null\n }\n\n const selectedSet = new Set(selected as string[])\n return skills.filter(s => selectedSet.has(s.name))\n}\n\nexport const removeCommandDef = defineCommand({\n meta: { name: 'remove', description: 'Remove installed skills' },\n args: {\n package: {\n type: 'positional',\n description: 'Package(s) to remove (space-separated)',\n required: false,\n },\n ...sharedArgs,\n },\n async run({ args }) {\n const cwd = process.cwd()\n let agent = resolveAgent(args.agent)\n if (!agent || agent === 'none') {\n if (agent === 'none')\n return\n const picked = await promptForAgent()\n if (!picked || picked === 'none')\n return\n agent = picked\n }\n\n const state = await getProjectState(cwd)\n const generators = getInstalledGenerators()\n const config = readConfig()\n const scope = args.global ? 'global' : 'project'\n const intro = { state, generators, modelId: config.model }\n p.intro(`${introLine(intro)} · remove (${scope})`)\n\n // Collect packages from positional args\n const packages = args.package\n ? [...new Set([args.package, ...((args as any)._ || [])].map((s: string) => s.trim()).filter(Boolean))]\n : undefined\n\n return removeCommand(state, {\n packages,\n global: args.global,\n agent,\n yes: args.yes,\n })\n },\n})\n","import type { AgentType } from '../agent/index.ts'\nimport type { SkillInfo } from '../core/lockfile.ts'\nimport { existsSync, readdirSync, statSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { join } from 'pathe'\nimport { agents, getAgentVersion } from '../agent/index.ts'\nimport { CACHE_DIR, getPackageDbPath } from '../cache/index.ts'\nimport { getCacheDir } from '../cache/version.ts'\nimport { sharedArgs } from '../cli-helpers.ts'\nimport { defaultFeatures, hasConfig, readConfig } from '../core/config.ts'\nimport { formatSource, timeAgo } from '../core/formatting.ts'\nimport { parsePackages } from '../core/lockfile.ts'\nimport { getSharedSkillsDir, mapInsert } from '../core/shared.ts'\n\nimport { iterateSkills } from '../core/skills.ts'\nimport { version as skilldVersion } from '../version.ts'\n\nexport interface StatusOptions {\n global?: boolean\n}\n\ninterface TrackedPackage {\n name: string\n info: SkillInfo\n agents: Set<AgentType>\n scope: 'local' | 'global'\n}\n\nfunction countDocs(packageName: string, version?: string): number {\n if (!version)\n return 0\n const cacheDir = getCacheDir(packageName, version)\n if (!existsSync(cacheDir))\n return 0\n let count = 0\n const walk = (dir: string, depth = 0) => {\n if (depth > 3)\n return\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.name === 'search.db')\n continue\n if (entry.isDirectory())\n walk(join(dir, entry.name), depth + 1)\n else if (entry.name.endsWith('.md') || entry.name.endsWith('.mdx'))\n count++\n }\n }\n catch {}\n }\n walk(cacheDir)\n return count\n}\n\nasync function countEmbeddings(packageName: string, version?: string): Promise<number | null> {\n if (!version)\n return null\n const dbPath = getPackageDbPath(packageName, version)\n if (!existsSync(dbPath))\n return null\n try {\n const { DatabaseSync } = await import('node:sqlite')\n const db = new DatabaseSync(dbPath, { open: true, readOnly: true })\n try {\n const row = db.prepare('SELECT count(*) as cnt FROM vector_metadata').get() as { cnt: number } | undefined\n return row?.cnt ?? null\n }\n finally {\n db.close()\n }\n }\n catch {\n return null\n }\n}\n\nfunction countRefDocs(skillDir: string): number {\n const refsDir = join(skillDir, '.skilld')\n if (!existsSync(refsDir))\n return 0\n let count = 0\n const walk = (dir: string, depth = 0) => {\n if (depth > 3)\n return\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory() || entry.isSymbolicLink()) {\n try {\n const stat = statSync(join(dir, entry.name))\n if (stat.isDirectory())\n walk(join(dir, entry.name), depth + 1)\n }\n catch { continue }\n }\n else if (entry.name.endsWith('.md') || entry.name.endsWith('.mdx')) {\n count++\n }\n }\n }\n catch {}\n }\n walk(refsDir)\n return count\n}\n\n// dim helper\nconst dim = (s: string) => `\\x1B[90m${s}\\x1B[0m`\nconst bold = (s: string) => `\\x1B[1m${s}\\x1B[0m`\nconst green = (s: string) => `\\x1B[32m${s}\\x1B[0m`\n\nfunction getLastSynced(): string | null {\n let latest: Date | null = null\n for (const skill of iterateSkills()) {\n if (skill.info?.syncedAt) {\n const d = new Date(skill.info.syncedAt)\n if (!latest || d > latest)\n latest = d\n }\n }\n if (!latest)\n return null\n return timeAgo(latest.toISOString())\n}\n\nfunction buildConfigLines(): string[] {\n const config = readConfig()\n const lines: string[] = []\n\n lines.push(`Version v${skilldVersion}`)\n const lastSynced = getLastSynced()\n if (lastSynced)\n lines.push(`Synced ${dim(lastSynced)}`)\n const shared = getSharedSkillsDir()\n if (shared)\n lines.push(`Shared ${dim(shared)}`)\n lines.push(`Config ${dim(join(CACHE_DIR, 'config.yaml'))}${hasConfig() ? '' : dim(' (not created)')}`)\n lines.push(`Cache ${dim(CACHE_DIR)}`)\n\n const withCli = Object.entries(agents).filter(([_, a]) => a.cli) as [AgentType, typeof agents[AgentType]][]\n const installed: string[] = []\n for (const [id, agent] of withCli) {\n const ver = getAgentVersion(id)\n if (ver)\n installed.push(`${agent.displayName} v${ver}`)\n }\n if (installed.length > 0)\n lines.push(`Agents ${installed.join(', ')}`)\n\n if (config.model)\n lines.push(`Model ${config.model}`)\n\n const features = { ...defaultFeatures, ...config.features }\n const parts = Object.entries(features).map(([k, v]) => `${k}: ${v ? green('on') : dim('off')}`)\n lines.push(`Features ${parts.join(', ')}`)\n\n if (config.projects?.length)\n lines.push(`Projects ${config.projects.length} registered`)\n\n return lines\n}\n\nexport async function statusCommand(opts: StatusOptions = {}): Promise<void> {\n const allSkills = [...iterateSkills({ scope: opts.global ? 'global' : 'all' })]\n\n // Config section\n p.log.step(bold('Skilld Config'))\n p.log.message(buildConfigLines().join('\\n'))\n\n if (allSkills.length === 0) {\n p.log.step(bold('Skills'))\n p.log.message(`${dim('(none)')}\\n\\nRun ${bold('skilld add <package>')} to install skills`)\n return\n }\n\n // Deduplicate by package identity, grouped by scope\n const localPkgs = new Map<string, TrackedPackage>()\n const globalPkgs = new Map<string, TrackedPackage>()\n\n for (const skill of allSkills) {\n const key = skill.info?.packageName || skill.name\n const map = skill.scope === 'local' ? localPkgs : globalPkgs\n\n const entry = mapInsert(map, key, () => ({\n name: skill.name,\n info: skill.info || {},\n agents: new Set<AgentType>(),\n scope: skill.scope,\n }))\n entry.agents.add(skill.agent)\n }\n\n const buildPackageLines = async (pkgs: Map<string, TrackedPackage>): Promise<string[]> => {\n const lines: string[] = []\n for (const [, pkg] of pkgs) {\n const { info } = pkg\n const isShipped = info.source === 'shipped'\n const icon = isShipped ? '▶' : '◆'\n\n const pkgsList = parsePackages(info.packages)\n const nameDisplay = pkgsList.length > 1\n ? `${pkg.name} ${dim(`(${pkgsList.map(p => p.name).join(', ')})`)}`\n : pkg.name\n const parts = [`${icon} ${bold(nameDisplay)}`]\n if (info.version)\n parts.push(dim(info.version))\n const source = formatSource(info.source)\n if (source && source !== 'shipped')\n parts.push(dim(source))\n\n lines.push(parts.join(' '))\n\n const meta: string[] = []\n const pkgName = info.packageName || pkg.name\n const docs = countDocs(pkgName, info.version) || countRefDocs(join(\n pkg.scope === 'global'\n ? agents[pkg.agents.values().next().value!].globalSkillsDir!\n : join(process.cwd(), agents[pkg.agents.values().next().value!].skillsDir),\n pkg.name,\n ))\n if (docs > 0)\n meta.push(`${docs} docs`)\n\n const embeddings = await countEmbeddings(pkgName, info.version)\n if (embeddings !== null)\n meta.push(`${embeddings} chunks`)\n\n const ago = timeAgo(info.syncedAt)\n if (ago)\n meta.push(`synced ${ago}`)\n\n if (pkg.agents.size > 0) {\n const agentNames = Array.from(pkg.agents, a => agents[a].displayName)\n meta.push(agentNames.join(', '))\n }\n\n if (meta.length > 0)\n lines.push(` ${dim(meta.join(' · '))}`)\n }\n return lines\n }\n\n if (!opts.global && localPkgs.size > 0) {\n p.log.step(`${bold('Local')} (project)`)\n p.log.message((await buildPackageLines(localPkgs)).join('\\n'))\n }\n\n if (globalPkgs.size > 0) {\n p.log.step(bold('Global'))\n p.log.message((await buildPackageLines(globalPkgs)).join('\\n'))\n }\n\n if (!opts.global && localPkgs.size === 0) {\n p.log.step(`${bold('Local')} (project)`)\n p.log.message(dim('(none)'))\n }\n\n const total = localPkgs.size + globalPkgs.size\n p.log.info(`${total} package${total !== 1 ? 's' : ''}`)\n}\n\nexport const infoCommandDef = defineCommand({\n meta: { name: 'info', description: 'Show skill info and config' },\n args: {\n global: sharedArgs.global,\n },\n run({ args }) {\n return statusCommand({ global: args.global })\n },\n})\n","import type { FeaturesConfig } from '../core/config.ts'\nimport { execSync } from 'node:child_process'\nimport * as p from '@clack/prompts'\nimport { getAvailableModels } from '../agent/index.ts'\nimport { isInteractive } 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 async function runWizard(): Promise<void> {\n if (!isInteractive())\n return\n\n p.note(\n 'Skilld gives your AI agent skill knowledge on your NPM\\n'\n + 'dependencies gathered from versioned docs, source code\\n'\n + 'and GitHub issues.',\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.warn(\n 'GitHub CLI not found. Install it to enable issues/discussions:\\n'\n + ' \\x1B[36mhttps://cli.github.com\\x1B[0m',\n )\n }\n\n // Feature toggles\n const selected = await p.multiselect({\n message: 'Which features would you like to enable?',\n options: [\n { label: 'Semantic + token search', value: 'search' as const, hint: 'local query engine to cut token costs and speed up grep' },\n { label: 'Release notes', value: 'releases' as const, hint: 'track changelogs for installed packages' },\n { label: 'GitHub issues', value: 'issues' as const, hint: 'surface common problems and solutions', disabled: !ghInstalled },\n { label: 'GitHub discussions', value: 'discussions' as const, hint: 'include Q&A and community knowledge', 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 process.exit(0)\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 // LLM optimization — optional, model selection is independent of target agent\n const allModels = process.env.SKILLD_NO_AGENTS ? [] : await getAvailableModels()\n let modelId: string | undefined\n\n if (allModels.length > 0) {\n p.note(\n 'Skills work without an LLM, but one can rewrite your\\n'\n + 'SKILL.md files with best practices and better structure.\\n'\n + '\\x1B[90mThis is separate from the agent where skills are installed —\\n'\n + 'the target agent is auto-detected from your project files.\\x1B[0m',\n 'Optional: LLM optimization',\n )\n\n const modelChoice = await p.select({\n message: 'Model for generating SKILL.md',\n options: [\n { label: 'Skip', value: '', hint: 'use raw docs, no LLM needed' },\n ...allModels.map(m => ({\n label: m.recommended ? `${m.name} (Recommended)` : m.name,\n value: m.id,\n hint: `${m.agentName} · ${m.hint}`,\n })),\n ],\n })\n\n if (p.isCancel(modelChoice)) {\n p.cancel('Setup cancelled')\n process.exit(0)\n }\n\n modelId = (modelChoice as string) || undefined\n }\n else {\n p.log.warn(\n 'No supported LLM CLIs detected (claude, gemini, codex).\\n'\n + ' Skills will still work, but won\\'t be LLM-optimized.',\n )\n const proceed = await p.confirm({\n message: 'Continue without LLM optimization?',\n initialValue: true,\n })\n if (p.isCancel(proceed) || !proceed) {\n p.cancel('Setup cancelled')\n process.exit(0)\n }\n }\n\n updateConfig({\n features,\n ...(modelId ? { model: modelId as any } : { skipLlm: true }),\n })\n\n p.outro('Thanks, you\\'re all set! Change config anytime with `skilld config`.')\n}\n","#!/usr/bin/env node\nimport type { PackageUsage } from './agent/detect-imports.ts'\nimport type { AgentType } from './agent/index.ts'\nimport { existsSync, readFileSync, realpathSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand, runMain } from 'citty'\nimport pLimit from 'p-limit'\nimport { join, resolve } from 'pathe'\nimport { detectImportedPackages } from './agent/index.ts'\nimport { formatStatus, getRepoHint, isInteractive, promptForAgent, relativeTime, resolveAgent, sharedArgs } from './cli-helpers.ts'\nimport { configCommand, configCommandDef } from './commands/config.ts'\nimport { removeCommand, removeCommandDef } from './commands/remove.ts'\nimport { infoCommandDef, statusCommand } from './commands/status.ts'\nimport { runWizard } from './commands/wizard.ts'\nimport { timedSpinner } from './core/formatting.ts'\nimport { getProjectState, hasCompletedWizard, isOutdated, readConfig, semverGt } from './core/index.ts'\nimport { fetchLatestVersion, fetchNpmRegistryMeta } from './sources/index.ts'\n\nimport { version } from './version.ts'\n\n// Suppress node:sqlite ExperimentalWarning (loaded lazily by retriv)\nconst _emit = process.emit\nprocess.emit = (event: string, ...args: any[]) =>\n event === 'warning' && args[0]?.name === 'ExperimentalWarning' && args[0]?.message?.includes('SQLite')\n ? false\n : _emit.apply(process, [event, ...args])\n\n// ── Brand animation ──\n\nconst NOISE_CHARS = '⣿⡿⣷⣾⣽⣻⢿⡷⣯⣟⡾⣵⣳⢾⡽⣞⡷⣝⢯'\n\n// Seed hue from cwd so each project gets a consistent color\nfunction djb2(s: string): number {\n let h = 5381\n for (let i = 0; i < s.length; i++)\n h = ((h << 5) + h + s.charCodeAt(i)) >>> 0\n return h\n}\n\nfunction hueToChannel(p: number, q: number, t: number): number {\n const t1 = t < 0 ? t + 1 : t > 1 ? t - 1 : t\n if (t1 < 1 / 6)\n return p + (q - p) * 6 * t1\n if (t1 < 1 / 2)\n return q\n if (t1 < 2 / 3)\n return p + (q - p) * (2 / 3 - t1) * 6\n return p\n}\n\nfunction hsl(h: number, s: number, l: number): [number, number, number] {\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s\n const p = 2 * l - q\n return [\n Math.round(hueToChannel(p, q, h + 1 / 3) * 255),\n Math.round(hueToChannel(p, q, h) * 255),\n Math.round(hueToChannel(p, q, h - 1 / 3) * 255),\n ]\n}\n\nconst BRAND_HUE = (djb2(process.cwd()) % 360) / 360\n\n// density 0 = random sparse braille, density 1 = ⣿ (all dots filled)\nfunction noiseChar(brightness: number, density = 0): string {\n if (brightness < 0.08)\n return ' '\n const b = Math.min(brightness, 1)\n const ch = Math.random() < density ? '⣿' : NOISE_CHARS[Math.floor(Math.random() * NOISE_CHARS.length)]\n const [r, g, bl] = hsl(BRAND_HUE, 0.4 + b * 0.15, 0.35 + b * 0.25)\n return `\\x1B[38;2;${r};${g};${bl}m${ch}`\n}\n\nfunction noiseLine(len: number, brightnessFn: (x: number) => number, density = 0): string {\n let s = ''\n for (let i = 0; i < len; i++)\n s += noiseChar(brightnessFn(i), density)\n return `${s}\\x1B[0m`\n}\n\nfunction brandFrame(t: number, floor = 0, density = 0): string {\n const cx = 5\n const cy = 1\n const brightness = (x: number, y: number) => {\n const d = Math.sqrt((x - cx) ** 2 + ((y - cy) * 3) ** 2)\n let val = 0\n for (let ring = 0; ring < 3; ring++) {\n const rt = t - ring * 0.5\n if (rt <= 0)\n continue\n const front = rt * 4\n const proximity = Math.abs(d - front)\n val += Math.exp(-proximity * proximity * 0.8) * Math.exp(-rt * 0.4)\n }\n const base = Math.max(0, (t - 1.5) * 0.3) * (Math.random() * 0.3 + 0.1)\n return Math.min(1, Math.max(floor, val + base))\n }\n return [\n noiseLine(10, x => brightness(x, 0), density),\n `${noiseLine(2, x => brightness(x, 1), density)} %NAME% ${noiseLine(2, x => brightness(x + 8, 1), density)} %VER%`,\n noiseLine(10, x => brightness(x, 2), density),\n ].join('\\n')\n}\n\nasync function brandLoader<T>(work: () => Promise<T>, minMs = 1500): Promise<T> {\n if (process.env.SKILLD_EFFECT === 'none')\n return work()\n\n const logUpdate = (await import('log-update')).default\n const name = '\\x1B[1m\\x1B[38;2;255;255;255mskilld\\x1B[0m'\n const ver = `\\x1B[2mv${version}\\x1B[0m`\n const status = '\\x1B[2mSetting up your environment\\x1B[0m'\n const start = Date.now()\n\n const sub = (raw: string) => raw.replace('%NAME%', name).replace('%VER%', ver)\n\n let done = false\n const result = Promise.all([\n work(),\n new Promise<void>(r => setTimeout(r, minMs)),\n ]).then(([v]) => {\n done = true\n return v\n })\n\n // Main animation — ripple with status text\n // eslint-disable-next-line no-unmodified-loop-condition -- modified async in .then()\n while (!done) {\n const t = (Date.now() - start) / 1000\n logUpdate(`\\n ${sub(brandFrame(t))}\\n\\n ${status}`)\n await new Promise(r => setTimeout(r, 60))\n }\n\n // Fill outro — ramp floor + density so all dots fill in\n const outroMs = 500\n const outroStart = Date.now()\n const tFinal = (outroStart - start) / 1000\n while (Date.now() - outroStart < outroMs) {\n const p = (Date.now() - outroStart) / outroMs\n const eased = p * p\n logUpdate(`\\n ${sub(brandFrame(tFinal + p * 0.5, eased * 0.9, eased))}\\n`)\n await new Promise(r => setTimeout(r, 40))\n }\n\n // Final frame — all pixels ⣿, full brightness\n logUpdate(`\\n ${sub(brandFrame(tFinal + 1, 0.9, 1))}\\n`)\n logUpdate.done()\n return result\n}\n\n// ── Subcommands (lazy-loaded) ──\n\nconst SUBCOMMAND_NAMES = ['add', 'eject', 'update', 'info', 'list', 'config', 'remove', 'install', 'uninstall', 'search', 'cache', 'validate', 'assemble']\n\n// ── Main command ──\n\nconst main = defineCommand({\n meta: {\n name: 'skilld',\n version,\n description: 'Sync package documentation for agentic use',\n },\n args: {\n agent: sharedArgs.agent,\n },\n subCommands: {\n add: () => import('./commands/sync.ts').then(m => m.addCommandDef),\n eject: () => import('./commands/sync.ts').then(m => m.ejectCommandDef),\n update: () => import('./commands/sync.ts').then(m => m.updateCommandDef),\n info: () => infoCommandDef,\n list: () => import('./commands/list.ts').then(m => m.listCommandDef),\n config: () => configCommandDef,\n remove: () => removeCommandDef,\n install: () => import('./commands/install.ts').then(m => m.installCommandDef),\n uninstall: () => import('./commands/uninstall.ts').then(m => m.uninstallCommandDef),\n search: () => import('./commands/search.ts').then(m => m.searchCommandDef),\n cache: () => import('./commands/cache.ts').then(m => m.cacheCommandDef),\n validate: () => import('./commands/validate.ts').then(m => m.validateCommandDef),\n assemble: () => import('./commands/assemble.ts').then(m => m.assembleCommandDef),\n },\n async run({ args }) {\n // Guard: citty always calls parent run() after subcommand dispatch.\n // If a subcommand was invoked, bail out here.\n const firstArg = process.argv[2]\n if (firstArg && !firstArg.startsWith('-') && SUBCOMMAND_NAMES.includes(firstArg))\n return\n\n const cwd = process.cwd()\n\n // Bare `skilld` — interactive menu (requires TTY)\n if (!isInteractive()) {\n const state = await getProjectState(cwd)\n const status = formatStatus(state.synced.length, state.outdated.length)\n console.log(`skilld v${version} · ${status}`)\n return\n }\n\n let currentAgent: AgentType | 'none' | null = resolveAgent(args.agent)\n\n if (!currentAgent) {\n currentAgent = await promptForAgent()\n if (!currentAgent)\n return\n }\n\n // No-agent mode: skip interactive menu, just offer `skilld add <pkg>` usage\n if (currentAgent === 'none') {\n p.log.info('No agent selected. Use `skilld add <pkg>` to export portable prompts.')\n return\n }\n\n // After this point, agent is guaranteed to be a real AgentType\n const agent: AgentType = currentAgent\n\n // Animate brand while bootstrapping + check for updates\n const { state, selfUpdate } = await brandLoader(async () => {\n const config = readConfig()\n const state = await getProjectState(cwd)\n\n // Run self-update check + unmatched skills NPM check in parallel\n let selfUpdate = null as { latest: string, releasedAt?: string } | null\n const tasks: Promise<void>[] = []\n\n // Check if skilld itself has a newer version (skip for npx/dlx/bunx)\n const isEphemeral = process.env.npm_command === 'exec'\n if (!isEphemeral) {\n tasks.push(\n fetchNpmRegistryMeta('skilld', version).then((meta) => {\n const latestTag = meta.distTags?.latest\n if (latestTag && semverGt(latestTag.version, version))\n selfUpdate = { latest: latestTag.version, releasedAt: latestTag.releasedAt }\n }).catch(() => {}),\n )\n }\n\n // For skills not in local deps, check NPM for version updates\n if (state.unmatched.length > 0) {\n const limit = pLimit(5)\n tasks.push(\n Promise.all(state.unmatched.map(skill => limit(async () => {\n const pkgName = skill.info?.packageName || skill.name\n const latest = await fetchLatestVersion(pkgName)\n if (latest && isOutdated(skill, latest)) {\n state.outdated.push({ ...skill, packageName: pkgName, latestVersion: latest })\n }\n else if (latest) {\n state.synced.push({ ...skill, packageName: pkgName, latestVersion: latest })\n }\n }))).then(() => {}),\n )\n }\n\n await Promise.all(tasks)\n return { config, state, selfUpdate }\n })\n\n // Show self-update notification\n if (selfUpdate) {\n const released = selfUpdate.releasedAt ? `\\x1B[90m · ${relativeTime(new Date(selfUpdate.releasedAt))}\\x1B[0m` : ''\n const binPath = realpathSync(process.argv[1])\n const isLocal = binPath.startsWith(resolve(cwd, 'node_modules'))\n const flag = isLocal ? '' : ' -g'\n const cmd = `npx nypm add${flag} skilld@${selfUpdate.latest}`\n p.note(\n `\\x1B[90m${version}\\x1B[0m → \\x1B[1m\\x1B[32m${selfUpdate.latest}\\x1B[0m${released}\\n\\x1B[36m${cmd}\\x1B[0m`,\n '\\x1B[33mUpdate available\\x1B[0m',\n )\n }\n\n // First time setup - no skills yet\n if (state.skills.length === 0) {\n if (!hasCompletedWizard()) {\n await runWizard()\n }\n\n // Transition to project setup\n const pkgJsonPath = join(cwd, 'package.json')\n const hasPkgJson = existsSync(pkgJsonPath)\n const projectName = hasPkgJson\n ? JSON.parse(readFileSync(pkgJsonPath, 'utf-8')).name\n : undefined\n const projectLabel = projectName\n ? `Generating skills for \\x1B[36m${projectName}\\x1B[0m`\n : 'Generating skills for current directory'\n p.log.step(projectLabel)\n\n if (!hasPkgJson) {\n p.log.warn('No package.json found — enter package names manually or run inside a project')\n }\n\n p.log.info('Tip: Only generate skills for packages your agent struggles with.\\n The fewer skills, the more context you have for everything else :)')\n\n // Initial setup loop — allow user to go back\n let setupComplete = false\n while (!setupComplete) {\n const source = hasPkgJson\n ? await p.select({\n message: 'How should I find packages?',\n options: [\n { label: 'Scan source files', value: 'imports', hint: 'Find actually used imports' },\n { label: 'Use package.json', value: 'deps', hint: `All ${state.deps.size} dependencies` },\n { label: 'Enter manually', value: 'manual' },\n ],\n })\n : 'manual' as const\n\n if (p.isCancel(source)) {\n p.cancel('Setup cancelled')\n return\n }\n\n // Get packages based on source\n let selected: string[]\n\n if (source === 'manual') {\n const input = await p.text({\n message: 'Enter package names (space or comma-separated)',\n placeholder: 'vue nuxt pinia',\n })\n if (p.isCancel(input)) {\n if (!hasPkgJson) {\n p.cancel('Setup cancelled')\n return\n }\n continue\n }\n if (!input) {\n p.log.warn('No packages entered')\n continue\n }\n selected = input.split(/[,\\s]+/).map(s => s.trim()).filter(Boolean)\n if (selected.length === 0) {\n p.log.warn('No valid packages entered')\n continue\n }\n }\n else {\n let usages: PackageUsage[]\n if (source === 'imports') {\n const spinner = timedSpinner()\n spinner.start('Scanning imports...')\n const result = await detectImportedPackages(cwd)\n\n if (result.packages.length === 0) {\n spinner.stop('No imports found, falling back to package.json')\n usages = Array.from(state.deps.keys(), name => ({ name, count: 0 }))\n }\n else {\n const depSet = new Set(state.deps.keys())\n usages = result.packages.filter(pkg => depSet.has(pkg.name) || pkg.source === 'preset')\n\n if (usages.length === 0) {\n spinner.stop(`Found ${result.packages.length} imported packages but none match dependencies`)\n usages = result.packages\n }\n else {\n spinner.stop(`Found ${usages.length} imported packages`)\n }\n }\n }\n else {\n usages = Array.from(state.deps.keys(), name => ({ name, count: 0 }))\n }\n\n // Let user select which packages\n const packages = usages.map(u => u.name)\n if (packages.length === 0) {\n p.log.warn('No packages found')\n continue\n }\n const sourceMap = new Map(usages.map(u => [u.name, u.source]))\n const maxLen = Math.max(...packages.map(n => n.length))\n const choice = await p.multiselect({\n message: `Select packages (${packages.length} found)`,\n options: packages.map((name) => {\n const ver = state.deps.get(name)?.replace(/^[\\^~>=<]/, '') || ''\n const repo = getRepoHint(name, cwd)\n const hint = sourceMap.get(name) === 'preset' ? 'nuxt module' : undefined\n const pad = ' '.repeat(maxLen - name.length + 2)\n const meta = [ver, hint, repo].filter(Boolean).join(' ')\n return { label: meta ? `${name}${pad}\\x1B[90m${meta}\\x1B[39m` : name, value: name }\n }),\n initialValues: packages,\n })\n\n if (p.isCancel(choice)) {\n continue\n }\n if (choice.length === 0) {\n p.log.warn('No packages selected')\n continue\n }\n selected = choice\n }\n\n // syncCommand will ask about LLM after generating base skills\n const { syncCommand } = await import('./commands/sync.ts')\n await syncCommand(state, {\n packages: selected,\n global: false,\n agent,\n yes: false,\n })\n setupComplete = true\n }\n return\n }\n\n // Has skills - show status + interactive menu\n const status = formatStatus(state.synced.length, state.outdated.length)\n p.log.info(status)\n\n // Menu loop — Escape in sub-actions returns to menu\n\n while (true) {\n type ActionValue = 'install' | 'update' | 'remove' | 'search' | 'info' | 'config'\n const options: Array<{ label: string, value: ActionValue, hint?: string }> = []\n\n options.push({ label: 'Add new skills', value: 'install' })\n if (state.outdated.length > 0) {\n options.push({ label: 'Update skills', value: 'update', hint: `\\x1B[33m${state.outdated.length} outdated\\x1B[0m` })\n }\n options.push(\n { label: 'Remove skills', value: 'remove' },\n { label: 'Search docs', value: 'search' },\n { label: 'Info', value: 'info' },\n { label: 'Configure', value: 'config' },\n )\n\n const action = await p.select({\n message: 'What would you like to do?',\n options,\n })\n\n if (p.isCancel(action)) {\n p.cancel('Cancelled')\n return\n }\n\n switch (action) {\n case 'install': {\n const installedNames = new Set(state.skills.map(s => s.packageName || s.name))\n const uninstalledDeps = [...state.deps.keys()].filter(d => !installedNames.has(d))\n const allDepsInstalled = uninstalledDeps.length === 0\n const hasPkgJsonMenu = existsSync(join(cwd, 'package.json'))\n\n const source = hasPkgJsonMenu\n ? await p.select({\n message: 'How should I find packages?',\n options: [\n { label: 'Scan source files', value: 'imports' as const, hint: allDepsInstalled ? 'all installed' : 'find actually used imports', disabled: allDepsInstalled },\n { label: 'Use package.json', value: 'deps' as const, hint: allDepsInstalled ? 'all installed' : `${uninstalledDeps.length} uninstalled`, disabled: allDepsInstalled },\n { label: 'Enter manually', value: 'manual' as const },\n ],\n })\n : 'manual' as const\n\n if (p.isCancel(source))\n continue\n\n let selected: string[]\n\n if (source === 'manual') {\n const input = await p.text({\n message: 'Enter package names (space or comma-separated)',\n placeholder: 'vue nuxt pinia',\n })\n if (p.isCancel(input) || !input)\n continue\n selected = input.split(/[,\\s]+/).map(s => s.trim()).filter(Boolean)\n if (selected.length === 0)\n continue\n }\n else {\n let usages: PackageUsage[]\n if (source === 'imports') {\n const spinner = timedSpinner()\n spinner.start('Scanning imports...')\n const result = await detectImportedPackages(cwd)\n\n if (result.packages.length === 0) {\n spinner.stop('No imports found, falling back to package.json')\n usages = uninstalledDeps.map(name => ({ name, count: 0 }))\n }\n else {\n const depSet = new Set(state.deps.keys())\n usages = result.packages\n .filter(pkg => depSet.has(pkg.name) || pkg.source === 'preset')\n .filter(pkg => !installedNames.has(pkg.name))\n\n if (usages.length === 0) {\n spinner.stop('All detected imports already have skills')\n continue\n }\n else {\n spinner.stop(`Found ${usages.length} imported packages`)\n }\n }\n }\n else {\n usages = uninstalledDeps.map(name => ({ name, count: 0 }))\n }\n\n const packages = usages.map(u => u.name)\n if (packages.length === 0) {\n p.log.warn('No packages found')\n continue\n }\n const sourceMap = new Map(usages.map(u => [u.name, u.source]))\n const maxLen = Math.max(...packages.map(n => n.length))\n const choice = await p.multiselect({\n message: `Select packages (${packages.length} found)`,\n options: packages.map((name) => {\n const ver = state.deps.get(name)?.replace(/^[\\^~>=<]/, '') || ''\n const repo = getRepoHint(name, cwd)\n const hint = sourceMap.get(name) === 'preset' ? 'nuxt module' : undefined\n const pad = ' '.repeat(maxLen - name.length + 2)\n const meta = [ver, hint, repo].filter(Boolean).join(' ')\n return { label: meta ? `${name}${pad}\\x1B[90m${meta}\\x1B[39m` : name, value: name }\n }),\n initialValues: packages,\n })\n\n if (p.isCancel(choice) || choice.length === 0)\n continue\n selected = choice\n }\n\n const { syncCommand: sync } = await import('./commands/sync.ts')\n return sync(state, {\n packages: selected,\n global: false,\n agent,\n yes: false,\n })\n }\n case 'update': {\n if (state.outdated.length === 0) {\n p.log.success('All skills up to date')\n return\n }\n const selected = await p.multiselect({\n message: 'Select packages to update',\n options: state.outdated.map(s => ({\n label: s.name,\n value: s.packageName || s.name,\n hint: `${s.info?.version ?? 'unknown'} → ${s.latestVersion}`,\n })),\n initialValues: state.outdated.map(s => s.packageName || s.name),\n })\n if (p.isCancel(selected) || selected.length === 0)\n continue\n const { syncCommand: syncUpdate } = await import('./commands/sync.ts')\n return syncUpdate(state, {\n packages: selected,\n global: false,\n agent,\n yes: false,\n })\n }\n case 'remove':\n await removeCommand(state, {\n global: false,\n agent,\n yes: false,\n })\n continue\n case 'search': {\n const { interactiveSearch } = await import('./commands/search-interactive.ts')\n await interactiveSearch()\n continue\n }\n case 'info':\n await statusCommand({ global: false })\n continue\n case 'config':\n await configCommand()\n continue\n }\n }\n },\n})\n\nrunMain(main)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":["agents","skilldVersion","agents","agents","agents"],"sources":["../src/commands/config.ts","../src/commands/remove.ts","../src/commands/status.ts","../src/commands/wizard.ts","../src/cli.ts"],"sourcesContent":["import type { OptimizeModel } from '../agent/index.ts'\nimport type { FeaturesConfig } from '../core/config.ts'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { getOAuthProviderList, loginOAuthProvider, logoutOAuthProvider } from '../agent/clis/pi-ai.ts'\nimport { agents, detectTargetAgent, getAvailableModels, getModelName } from '../agent/index.ts'\nimport { guard, introLine, menuLoop, NO_MODELS_MESSAGE, OAUTH_NOTE, pickModel, requireInteractive } from '../cli-helpers.ts'\nimport { defaultFeatures, readConfig, updateConfig } from '../core/config.ts'\nimport { getProjectState } from '../core/skills.ts'\n\nexport async function configCommand(): Promise<void> {\n const initConfig = readConfig()\n const agentId = initConfig.agent || detectTargetAgent() || undefined\n const cyan = (s: string) => `\\x1B[36m${s}\\x1B[90m`\n const modelLabel = initConfig.skipLlm\n ? 'skip'\n : initConfig.model\n ? cyan(getModelName(initConfig.model))\n : 'auto'\n const agentLabel = agentId && agents[agentId as keyof typeof agents]\n ? cyan(agents[agentId as keyof typeof agents].displayName)\n : 'auto-detect'\n p.note(`\\x1B[90mFetch docs → Enhance with ${modelLabel} → Install to ${agentLabel}\\x1B[0m`, 'How skilld works')\n\n await menuLoop({\n message: 'Settings',\n options: () => {\n const config = readConfig()\n const features = config.features ?? defaultFeatures\n const enabledCount = Object.values(features).filter(Boolean).length\n const modelHint = config.skipLlm\n ? 'disabled'\n : config.model\n ? getModelName(config.model)\n : 'auto'\n const connectedOAuth = getOAuthProviderList().filter(pr => pr.loggedIn).length\n const oauthHint = connectedOAuth > 0 ? `${connectedOAuth} connected` : 'none'\n return [\n { label: 'Data sources', value: 'features', hint: `${enabledCount}/4 enabled · issues, releases, search, discussions` },\n { label: 'OAuth providers', value: 'oauth', hint: `${oauthHint} · pi-ai direct API` },\n { label: 'Enhancement model', value: 'model', hint: `${modelHint} · rewrites SKILL.md with best practices` },\n { label: 'Target agent', value: 'agent', hint: `${config.agent || 'auto-detect'} · where skills are installed` },\n ]\n },\n onSelect: async (action) => {\n switch (action) {\n case 'features': {\n const config = readConfig()\n const features = config.features ?? defaultFeatures\n const selected = guard(await p.multiselect({\n message: 'Data sources',\n options: [\n { label: 'Semantic + token search', value: 'search' as const, hint: 'local query engine to cut token costs and speed up grep' },\n { label: 'Release notes', value: 'releases' as const, hint: 'track changelogs for installed packages' },\n { label: 'GitHub issues', value: 'issues' as const, hint: 'surface common problems and solutions' },\n { label: 'GitHub discussions', value: 'discussions' as const, hint: 'include Q&A and community knowledge' },\n ],\n initialValues: Object.entries(features)\n .filter(([, v]) => v)\n .map(([k]) => k) as Array<keyof FeaturesConfig>,\n required: false,\n }))\n updateConfig({\n features: {\n search: selected.includes('search'),\n issues: selected.includes('issues'),\n discussions: selected.includes('discussions'),\n releases: selected.includes('releases'),\n },\n })\n p.log.success(`Data sources updated: ${selected.length} enabled`)\n break\n }\n\n case 'oauth': {\n await configureOAuth()\n break\n }\n\n case 'model': {\n await configureModel()\n break\n }\n\n case 'agent': {\n const config = readConfig()\n const agentChoice = guard(await p.select({\n message: 'Target agent — where should skills be installed?',\n options: [\n { label: 'Auto-detect', value: '' },\n ...Object.entries(agents).map(([id, a]) => ({\n label: a.displayName,\n value: id,\n hint: a.skillsDir,\n })),\n ],\n initialValue: config.agent || '',\n }))\n updateConfig({ agent: agentChoice || undefined })\n p.log.success(agentChoice ? `Target agent set to ${agentChoice}` : 'Target agent will be auto-detected')\n break\n }\n }\n },\n })\n}\n\nasync function configureOAuth(): Promise<void> {\n p.note(OAUTH_NOTE, 'How OAuth works')\n\n await menuLoop({\n message: 'OAuth providers',\n options: () => {\n const providers = getOAuthProviderList()\n return providers.map(pr => ({\n label: pr.name,\n value: pr.id,\n hint: pr.loggedIn ? '\\x1B[32mconnected\\x1B[0m' : 'not connected',\n }))\n },\n onSelect: async (providerId) => {\n const providers = getOAuthProviderList()\n const pr = providers.find(p2 => p2.id === providerId)\n if (!pr)\n return\n\n if (pr.loggedIn) {\n const action = guard(await p.select({\n message: pr.name,\n options: [\n { label: 'Disconnect', value: 'disconnect' },\n { label: 'Back', value: 'back' },\n ],\n }))\n if (action === 'disconnect') {\n logoutOAuthProvider(providerId as string)\n p.log.success(`Disconnected from ${pr.name}`)\n }\n return\n }\n\n const spinner = p.spinner()\n spinner.start('Connecting...')\n\n const success = await loginOAuthProvider(providerId 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 if (success)\n p.log.success(`Connected to ${pr.name}`)\n },\n })\n}\n\n// ── Model selection ──────────────────────────────────────────────────\n\nasync function configureModel(): Promise<void> {\n // Loop so user can connect OAuth and come back to pick a model\n while (true) {\n const available = await getAvailableModels()\n\n if (available.length === 0)\n p.log.warn(NO_MODELS_MESSAGE)\n\n const choice = await pickModel(available, {\n before: available.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' },\n ],\n })\n\n if (!choice)\n return\n\n if (choice === '_connect') {\n await configureOAuth()\n continue\n }\n\n if (choice === '_skip') {\n updateConfig({ model: undefined, skipLlm: true })\n p.log.success('Enhancement disabled - skills will use raw docs only')\n }\n else if (choice === '_auto') {\n updateConfig({ model: undefined, skipLlm: false })\n p.log.success('Enhancement model will be auto-selected')\n }\n else {\n updateConfig({ model: choice as OptimizeModel, skipLlm: false })\n p.log.success(`Enhancement model set to ${getModelName(choice as OptimizeModel)}`)\n }\n return\n }\n}\n\nexport const configCommandDef = defineCommand({\n meta: { name: 'config', description: 'Edit settings' },\n args: {},\n async run() {\n requireInteractive('config')\n const cwd = process.cwd()\n const state = await getProjectState(cwd)\n p.intro(introLine({ state }))\n return configCommand()\n },\n})\n","import type { AgentType } from '../agent/index.ts'\nimport type { ProjectState, SkillEntry } from '../core/skills.ts'\nimport { existsSync, rmSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { unlinkSkillFromAgents } from '../agent/index.ts'\nimport { getInstalledGenerators, introLine, isInteractive, promptForAgent, resolveAgent, sharedArgs } from '../cli-helpers.ts'\nimport { readConfig } from '../core/config.ts'\nimport { removeLockEntry } from '../core/lockfile.ts'\nimport { getSharedSkillsDir } from '../core/shared.ts'\nimport { getProjectState, getSkillsDir, iterateSkills } from '../core/skills.ts'\n\nexport interface RemoveOptions {\n packages?: string[]\n global: boolean\n agent: AgentType\n yes: boolean\n}\n\nexport async function removeCommand(state: ProjectState, opts: RemoveOptions): Promise<void> {\n // Get skills from the appropriate scope\n const scope = opts.global ? 'global' : 'local'\n const allSkills = [...iterateSkills({ scope })]\n\n // Non-interactive without packages → error\n if (!isInteractive() && !opts.packages) {\n console.error('Error: `skilld remove` requires package names in non-interactive mode.\\n Usage: skilld remove <package...>')\n process.exit(1)\n }\n\n // Get skills to choose from\n const skills = opts.packages\n ? allSkills.filter(s => opts.packages!.includes(s.name))\n : await pickSkillsToRemove(allSkills, scope)\n\n if (!skills || skills.length === 0) {\n p.log.info('No skills selected')\n return\n }\n\n // Confirm deletion (skip in non-interactive)\n if (!opts.yes && isInteractive()) {\n const confirmed = await p.confirm({\n message: `Remove ${skills.length} skill(s)? ${skills.map(s => s.name).join(', ')}`,\n })\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel('Cancelled')\n return\n }\n }\n\n // Delete each skill\n const cwd = process.cwd()\n const shared = getSharedSkillsDir(cwd)\n for (const skill of skills) {\n const skillsDir = getSkillsDir(skill.agent, skill.scope)\n\n if (existsSync(skill.dir)) {\n rmSync(skill.dir, { recursive: true, force: true })\n removeLockEntry(skillsDir, skill.name)\n // Clean up per-agent symlinks when removing from shared dir\n if (shared && skill.scope === 'local')\n unlinkSkillFromAgents(skill.name, cwd, opts.agent)\n p.log.success(`Removed ${skill.name}`)\n }\n else {\n p.log.warn(`${skill.name} not found`)\n }\n }\n\n p.outro(`Removed ${skills.length} skill(s)`)\n}\n\nasync function pickSkillsToRemove(skills: SkillEntry[], scope: 'local' | 'global'): Promise<SkillEntry[] | null> {\n if (skills.length === 0) {\n p.log.warn(`No ${scope} skills installed`)\n return null\n }\n\n const options = skills.map(skill => ({\n label: skill.name,\n value: skill.name,\n hint: skill.info?.version ? `@${skill.info.version}` : undefined,\n }))\n\n const selected = await p.multiselect({\n message: 'Select skills to remove',\n options,\n required: false,\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Cancelled')\n return null\n }\n\n const selectedSet = new Set(selected as string[])\n return skills.filter(s => selectedSet.has(s.name))\n}\n\nexport const removeCommandDef = defineCommand({\n meta: { name: 'remove', description: 'Remove installed skills' },\n args: {\n package: {\n type: 'positional',\n description: 'Package(s) to remove (space-separated)',\n required: false,\n },\n ...sharedArgs,\n },\n async run({ args }) {\n const cwd = process.cwd()\n let agent = resolveAgent(args.agent)\n if (!agent || agent === 'none') {\n if (agent === 'none')\n return\n const picked = await promptForAgent()\n if (!picked || picked === 'none')\n return\n agent = picked\n }\n\n const state = await getProjectState(cwd)\n const generators = getInstalledGenerators()\n const config = readConfig()\n const scope = args.global ? 'global' : 'project'\n const intro = { state, generators, modelId: config.model, agentId: agent || config.agent || undefined }\n p.intro(`${introLine(intro)} · remove (${scope})`)\n\n // Collect packages from positional args\n const packages = args.package\n ? [...new Set([args.package, ...((args as any)._ || [])].map((s: string) => s.trim()).filter(Boolean))]\n : undefined\n\n return removeCommand(state, {\n packages,\n global: args.global,\n agent,\n yes: args.yes,\n })\n },\n})\n","import type { AgentType } from '../agent/index.ts'\nimport type { SkillInfo } from '../core/lockfile.ts'\nimport { existsSync, readdirSync, statSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { join } from 'pathe'\nimport { agents, getAgentVersion } from '../agent/index.ts'\nimport { CACHE_DIR, getPackageDbPath } from '../cache/index.ts'\nimport { getCacheDir } from '../cache/version.ts'\nimport { sharedArgs } from '../cli-helpers.ts'\nimport { defaultFeatures, hasConfig, readConfig } from '../core/config.ts'\nimport { formatSource, timeAgo } from '../core/formatting.ts'\nimport { parsePackages } from '../core/lockfile.ts'\nimport { getSharedSkillsDir, mapInsert } from '../core/shared.ts'\n\nimport { iterateSkills } from '../core/skills.ts'\nimport { version as skilldVersion } from '../version.ts'\n\nexport interface StatusOptions {\n global?: boolean\n}\n\ninterface TrackedPackage {\n name: string\n info: SkillInfo\n agents: Set<AgentType>\n scope: 'local' | 'global'\n}\n\nfunction countDocs(packageName: string, version?: string): number {\n if (!version)\n return 0\n const cacheDir = getCacheDir(packageName, version)\n if (!existsSync(cacheDir))\n return 0\n let count = 0\n const walk = (dir: string, depth = 0) => {\n if (depth > 3)\n return\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.name === 'search.db')\n continue\n if (entry.isDirectory())\n walk(join(dir, entry.name), depth + 1)\n else if (entry.name.endsWith('.md') || entry.name.endsWith('.mdx'))\n count++\n }\n }\n catch {}\n }\n walk(cacheDir)\n return count\n}\n\nasync function countEmbeddings(packageName: string, version?: string): Promise<number | null> {\n if (!version)\n return null\n const dbPath = getPackageDbPath(packageName, version)\n if (!existsSync(dbPath))\n return null\n try {\n const { DatabaseSync } = await import('node:sqlite')\n const db = new DatabaseSync(dbPath, { open: true, readOnly: true })\n try {\n const row = db.prepare('SELECT count(*) as cnt FROM vector_metadata').get() as { cnt: number } | undefined\n return row?.cnt ?? null\n }\n finally {\n db.close()\n }\n }\n catch {\n return null\n }\n}\n\nfunction countRefDocs(skillDir: string): number {\n const refsDir = join(skillDir, '.skilld')\n if (!existsSync(refsDir))\n return 0\n let count = 0\n const walk = (dir: string, depth = 0) => {\n if (depth > 3)\n return\n try {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory() || entry.isSymbolicLink()) {\n try {\n const stat = statSync(join(dir, entry.name))\n if (stat.isDirectory())\n walk(join(dir, entry.name), depth + 1)\n }\n catch { continue }\n }\n else if (entry.name.endsWith('.md') || entry.name.endsWith('.mdx')) {\n count++\n }\n }\n }\n catch {}\n }\n walk(refsDir)\n return count\n}\n\n// dim helper\nconst dim = (s: string) => `\\x1B[90m${s}\\x1B[0m`\nconst bold = (s: string) => `\\x1B[1m${s}\\x1B[0m`\nconst green = (s: string) => `\\x1B[32m${s}\\x1B[0m`\n\nfunction getLastSynced(): string | null {\n let latest: Date | null = null\n for (const skill of iterateSkills()) {\n if (skill.info?.syncedAt) {\n const d = new Date(skill.info.syncedAt)\n if (!latest || d > latest)\n latest = d\n }\n }\n if (!latest)\n return null\n return timeAgo(latest.toISOString())\n}\n\nfunction buildConfigLines(): string[] {\n const config = readConfig()\n const lines: string[] = []\n\n lines.push(`Version v${skilldVersion}`)\n const lastSynced = getLastSynced()\n if (lastSynced)\n lines.push(`Synced ${dim(lastSynced)}`)\n const shared = getSharedSkillsDir()\n if (shared)\n lines.push(`Shared ${dim(shared)}`)\n lines.push(`Config ${dim(join(CACHE_DIR, 'config.yaml'))}${hasConfig() ? '' : dim(' (not created)')}`)\n lines.push(`Cache ${dim(CACHE_DIR)}`)\n\n const withCli = Object.entries(agents).filter(([_, a]) => a.cli) as [AgentType, typeof agents[AgentType]][]\n const installed: string[] = []\n for (const [id, agent] of withCli) {\n const ver = getAgentVersion(id)\n if (ver)\n installed.push(`${agent.displayName} v${ver}`)\n }\n if (installed.length > 0)\n lines.push(`Agents ${installed.join(', ')}`)\n\n if (config.model)\n lines.push(`Model ${config.model}`)\n\n const features = { ...defaultFeatures, ...config.features }\n const parts = Object.entries(features).map(([k, v]) => `${k}: ${v ? green('on') : dim('off')}`)\n lines.push(`Features ${parts.join(', ')}`)\n\n if (config.projects?.length)\n lines.push(`Projects ${config.projects.length} registered`)\n\n return lines\n}\n\nexport async function statusCommand(opts: StatusOptions = {}): Promise<void> {\n const allSkills = [...iterateSkills({ scope: opts.global ? 'global' : 'all' })]\n\n // Config section\n p.log.step(bold('Skilld Config'))\n p.log.message(buildConfigLines().join('\\n'))\n\n if (allSkills.length === 0) {\n p.log.step(bold('Skills'))\n p.log.message(`${dim('(none)')}\\n\\nRun ${bold('skilld add <package>')} to install skills`)\n return\n }\n\n // Deduplicate by package identity, grouped by scope\n const localPkgs = new Map<string, TrackedPackage>()\n const globalPkgs = new Map<string, TrackedPackage>()\n\n for (const skill of allSkills) {\n const key = skill.info?.packageName || skill.name\n const map = skill.scope === 'local' ? localPkgs : globalPkgs\n\n const entry = mapInsert(map, key, () => ({\n name: skill.name,\n info: skill.info || {},\n agents: new Set<AgentType>(),\n scope: skill.scope,\n }))\n entry.agents.add(skill.agent)\n }\n\n const buildPackageLines = async (pkgs: Map<string, TrackedPackage>): Promise<string[]> => {\n const lines: string[] = []\n for (const [, pkg] of pkgs) {\n const { info } = pkg\n const isShipped = info.source === 'shipped'\n const icon = isShipped ? '▶' : '◆'\n\n const pkgsList = parsePackages(info.packages)\n const nameDisplay = pkgsList.length > 1\n ? `${pkg.name} ${dim(`(${pkgsList.map(p => p.name).join(', ')})`)}`\n : pkg.name\n const parts = [`${icon} ${bold(nameDisplay)}`]\n if (info.version)\n parts.push(dim(info.version))\n const source = formatSource(info.source)\n if (source && source !== 'shipped')\n parts.push(dim(source))\n\n lines.push(parts.join(' '))\n\n const meta: string[] = []\n const pkgName = info.packageName || pkg.name\n const docs = countDocs(pkgName, info.version) || countRefDocs(join(\n pkg.scope === 'global'\n ? agents[pkg.agents.values().next().value!].globalSkillsDir!\n : join(process.cwd(), agents[pkg.agents.values().next().value!].skillsDir),\n pkg.name,\n ))\n if (docs > 0)\n meta.push(`${docs} docs`)\n\n const embeddings = await countEmbeddings(pkgName, info.version)\n if (embeddings !== null)\n meta.push(`${embeddings} chunks`)\n\n const ago = timeAgo(info.syncedAt)\n if (ago)\n meta.push(`synced ${ago}`)\n\n if (pkg.agents.size > 0) {\n const agentNames = Array.from(pkg.agents, a => agents[a].displayName)\n meta.push(agentNames.join(', '))\n }\n\n if (meta.length > 0)\n lines.push(` ${dim(meta.join(' · '))}`)\n }\n return lines\n }\n\n if (!opts.global && localPkgs.size > 0) {\n p.log.step(`${bold('Local')} (project)`)\n p.log.message((await buildPackageLines(localPkgs)).join('\\n'))\n }\n\n if (globalPkgs.size > 0) {\n p.log.step(bold('Global'))\n p.log.message((await buildPackageLines(globalPkgs)).join('\\n'))\n }\n\n if (!opts.global && localPkgs.size === 0) {\n p.log.step(`${bold('Local')} (project)`)\n p.log.message(dim('(none)'))\n }\n\n const total = localPkgs.size + globalPkgs.size\n p.log.info(`${total} package${total !== 1 ? 's' : ''}`)\n}\n\nexport const infoCommandDef = defineCommand({\n meta: { name: 'info', description: 'Show skill info and config' },\n args: {\n global: sharedArgs.global,\n },\n run({ args }) {\n return statusCommand({ global: args.global })\n },\n})\n","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","#!/usr/bin/env node\nimport type { PackageUsage } from './agent/detect-imports.ts'\nimport type { AgentType } from './agent/index.ts'\nimport { existsSync, readFileSync, realpathSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand, runMain } from 'citty'\nimport pLimit from 'p-limit'\nimport { join, resolve } from 'pathe'\nimport { agents, detectImportedPackages, detectInstalledAgents } from './agent/index.ts'\nimport { formatStatus, getRepoHint, guard, isInteractive, isRunningInsideAgent, menuLoop, promptForAgent, relativeTime, resolveAgent, sharedArgs } from './cli-helpers.ts'\nimport { configCommand, configCommandDef } from './commands/config.ts'\nimport { removeCommand, removeCommandDef } from './commands/remove.ts'\nimport { infoCommandDef, statusCommand } from './commands/status.ts'\nimport { runWizard } from './commands/wizard.ts'\nimport { timedSpinner } from './core/formatting.ts'\nimport { getProjectState, hasCompletedWizard, isOutdated, readConfig, semverGt } from './core/index.ts'\nimport { iterateSkills } from './core/skills.ts'\nimport { fetchLatestVersion, fetchNpmRegistryMeta } from './sources/index.ts'\n\nimport { version } from './version.ts'\n\n// Suppress node:sqlite ExperimentalWarning (loaded lazily by retriv)\nconst _emit = process.emit\nprocess.emit = (event: string, ...args: any[]) =>\n event === 'warning' && args[0]?.name === 'ExperimentalWarning' && args[0]?.message?.includes('SQLite')\n ? false\n : _emit.apply(process, [event, ...args])\n\n// ── Brand animation ──\n\nconst NOISE_CHARS = '⣿⡿⣷⣾⣽⣻⢿⡷⣯⣟⡾⣵⣳⢾⡽⣞⡷⣝⢯'\n\n// Seed hue from cwd so each project gets a consistent color\nfunction djb2(s: string): number {\n let h = 5381\n for (let i = 0; i < s.length; i++)\n h = ((h << 5) + h + s.charCodeAt(i)) >>> 0\n return h\n}\n\nfunction hueToChannel(p: number, q: number, t: number): number {\n const t1 = t < 0 ? t + 1 : t > 1 ? t - 1 : t\n if (t1 < 1 / 6)\n return p + (q - p) * 6 * t1\n if (t1 < 1 / 2)\n return q\n if (t1 < 2 / 3)\n return p + (q - p) * (2 / 3 - t1) * 6\n return p\n}\n\nfunction hsl(h: number, s: number, l: number): [number, number, number] {\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s\n const p = 2 * l - q\n return [\n Math.round(hueToChannel(p, q, h + 1 / 3) * 255),\n Math.round(hueToChannel(p, q, h) * 255),\n Math.round(hueToChannel(p, q, h - 1 / 3) * 255),\n ]\n}\n\nconst BRAND_HUE = (djb2(process.cwd()) % 360) / 360\n\n// density 0 = random sparse braille, density 1 = ⣿ (all dots filled)\nfunction noiseChar(brightness: number, density = 0): string {\n if (brightness < 0.08)\n return ' '\n const b = Math.min(brightness, 1)\n const ch = Math.random() < density ? '⣿' : NOISE_CHARS[Math.floor(Math.random() * NOISE_CHARS.length)]\n const [r, g, bl] = hsl(BRAND_HUE, 0.4 + b * 0.15, 0.35 + b * 0.25)\n return `\\x1B[38;2;${r};${g};${bl}m${ch}`\n}\n\nfunction noiseLine(len: number, brightnessFn: (x: number) => number, density = 0): string {\n let s = ''\n for (let i = 0; i < len; i++)\n s += noiseChar(brightnessFn(i), density)\n return `${s}\\x1B[0m`\n}\n\nfunction brandFrame(t: number, floor = 0, density = 0): string {\n const cx = 5\n const cy = 1\n const brightness = (x: number, y: number) => {\n const d = Math.sqrt((x - cx) ** 2 + ((y - cy) * 3) ** 2)\n let val = 0\n for (let ring = 0; ring < 3; ring++) {\n const rt = t - ring * 0.5\n if (rt <= 0)\n continue\n const front = rt * 4\n const proximity = Math.abs(d - front)\n val += Math.exp(-proximity * proximity * 0.8) * Math.exp(-rt * 0.4)\n }\n const base = Math.max(0, (t - 1.5) * 0.3) * (Math.random() * 0.3 + 0.1)\n return Math.min(1, Math.max(floor, val + base))\n }\n return [\n noiseLine(10, x => brightness(x, 0), density),\n `${noiseLine(2, x => brightness(x, 1), density)} %NAME% ${noiseLine(2, x => brightness(x + 8, 1), density)} %VER%`,\n noiseLine(10, x => brightness(x, 2), density),\n ].join('\\n')\n}\n\nasync function brandLoader<T>(work: () => Promise<T>, minMs = 1500): Promise<T> {\n if (process.env.SKILLD_EFFECT === 'none')\n return work()\n\n const logUpdate = (await import('log-update')).default\n const name = '\\x1B[1m\\x1B[38;2;255;255;255mskilld\\x1B[0m'\n const ver = `\\x1B[2mv${version}\\x1B[0m`\n const status = '\\x1B[2mSetting up your environment\\x1B[0m'\n const start = Date.now()\n\n const sub = (raw: string) => raw.replace('%NAME%', name).replace('%VER%', ver)\n\n let done = false\n const result = Promise.all([\n work(),\n new Promise<void>(r => setTimeout(r, minMs)),\n ]).then(([v]) => {\n done = true\n return v\n })\n\n // Main animation — ripple with status text\n // eslint-disable-next-line no-unmodified-loop-condition -- modified async in .then()\n while (!done) {\n const t = (Date.now() - start) / 1000\n logUpdate(`\\n ${sub(brandFrame(t))}\\n\\n ${status}`)\n await new Promise(r => setTimeout(r, 60))\n }\n\n // Fill outro — ramp floor + density so all dots fill in\n const outroMs = 500\n const outroStart = Date.now()\n const tFinal = (outroStart - start) / 1000\n while (Date.now() - outroStart < outroMs) {\n const p = (Date.now() - outroStart) / outroMs\n const eased = p * p\n logUpdate(`\\n ${sub(brandFrame(tFinal + p * 0.5, eased * 0.9, eased))}\\n`)\n await new Promise(r => setTimeout(r, 40))\n }\n\n // Final frame — all pixels ⣿, full brightness\n logUpdate(`\\n ${sub(brandFrame(tFinal + 1, 0.9, 1))}\\n`)\n logUpdate.done()\n return result\n}\n\n// ── Subcommands (lazy-loaded) ──\n\nconst SUBCOMMAND_NAMES = ['add', 'eject', 'update', 'info', 'list', 'config', 'remove', 'install', 'uninstall', 'search', 'cache', 'validate', 'assemble', 'setup']\n\n// ── Main command ──\n\nconst main = defineCommand({\n meta: {\n name: 'skilld',\n version,\n description: 'Sync package documentation for agentic use',\n },\n args: {\n agent: sharedArgs.agent,\n },\n subCommands: {\n add: () => import('./commands/sync.ts').then(m => m.addCommandDef),\n eject: () => import('./commands/sync.ts').then(m => m.ejectCommandDef),\n update: () => import('./commands/sync.ts').then(m => m.updateCommandDef),\n info: () => infoCommandDef,\n list: () => import('./commands/list.ts').then(m => m.listCommandDef),\n config: () => configCommandDef,\n remove: () => removeCommandDef,\n install: () => import('./commands/install.ts').then(m => m.installCommandDef),\n uninstall: () => import('./commands/uninstall.ts').then(m => m.uninstallCommandDef),\n search: () => import('./commands/search.ts').then(m => m.searchCommandDef),\n cache: () => import('./commands/cache.ts').then(m => m.cacheCommandDef),\n validate: () => import('./commands/validate.ts').then(m => m.validateCommandDef),\n assemble: () => import('./commands/assemble.ts').then(m => m.assembleCommandDef),\n setup: () => import('./commands/setup.ts').then(m => m.setupCommandDef),\n },\n async run({ args }) {\n // Guard: citty always calls parent run() after subcommand dispatch.\n // If a subcommand was invoked, bail out here.\n const firstArg = process.argv[2]\n if (firstArg && !firstArg.startsWith('-') && SUBCOMMAND_NAMES.includes(firstArg))\n return\n\n const cwd = process.cwd()\n\n // Bare `skilld` — interactive menu (requires TTY)\n if (!isInteractive()) {\n const state = await getProjectState(cwd)\n const status = formatStatus(state.synced.length, state.outdated.length)\n console.log(`skilld v${version} · ${status}`)\n if (isRunningInsideAgent())\n console.log('Interactive wizard requires a standalone terminal (detected agent session).\\nUse `skilld add <pkg>` to add skills non-interactively, or run `npx skilld` in a separate terminal.')\n return\n }\n\n let currentAgent: AgentType | 'none' | null = resolveAgent(args.agent)\n\n if (!currentAgent) {\n currentAgent = await promptForAgent()\n if (!currentAgent)\n return\n }\n\n // No-agent mode: run wizard, then guide them\n if (currentAgent === 'none') {\n if (!hasCompletedWizard()) {\n if (!await runWizard())\n return\n }\n p.log.info(\n 'No agent selected - skills export as portable PROMPT_*.md files.\\n'\n + ' Run \\x1B[36mskilld add <pkg>\\x1B[0m to generate prompts for any package.\\n'\n + ' Run \\x1B[36mskilld config\\x1B[0m to set a target agent later.',\n )\n return\n }\n\n // After this point, agent is guaranteed to be a real AgentType\n const agent: AgentType = currentAgent\n\n // Animate brand while bootstrapping + check for updates\n let { state, selfUpdate } = await brandLoader(async () => {\n const config = readConfig()\n const state = await getProjectState(cwd)\n\n // Run self-update check + unmatched skills NPM check in parallel\n let selfUpdate = null as { latest: string, releasedAt?: string } | null\n const tasks: Promise<void>[] = []\n\n // Check if skilld itself has a newer version (skip for npx/dlx/bunx)\n const isEphemeral = process.env.npm_command === 'exec'\n if (!isEphemeral) {\n tasks.push(\n fetchNpmRegistryMeta('skilld', version).then((meta) => {\n const latestTag = meta.distTags?.latest\n if (latestTag && semverGt(latestTag.version, version))\n selfUpdate = { latest: latestTag.version, releasedAt: latestTag.releasedAt }\n }).catch(() => {}),\n )\n }\n\n // For skills not in local deps, check NPM for version updates\n if (state.unmatched.length > 0) {\n const limit = pLimit(5)\n tasks.push(\n Promise.all(state.unmatched.map(skill => limit(async () => {\n const pkgName = skill.info?.packageName || skill.name\n const latest = await fetchLatestVersion(pkgName)\n if (latest && isOutdated(skill, latest)) {\n state.outdated.push({ ...skill, packageName: pkgName, latestVersion: latest })\n }\n else if (latest) {\n state.synced.push({ ...skill, packageName: pkgName, latestVersion: latest })\n }\n }))).then(() => {}),\n )\n }\n\n await Promise.all(tasks)\n return { config, state, selfUpdate }\n })\n\n // Show self-update notification\n if (selfUpdate) {\n const released = selfUpdate.releasedAt ? `\\x1B[90m · ${relativeTime(new Date(selfUpdate.releasedAt))}\\x1B[0m` : ''\n const binPath = realpathSync(process.argv[1])\n const isLocal = binPath.startsWith(resolve(cwd, 'node_modules'))\n const flag = isLocal ? '' : ' -g'\n const cmd = `npx nypm add${flag} skilld@${selfUpdate.latest}`\n p.note(\n `\\x1B[90m${version}\\x1B[0m → \\x1B[1m\\x1B[32m${selfUpdate.latest}\\x1B[0m${released}\\n\\x1B[36m${cmd}\\x1B[0m`,\n '\\x1B[33mUpdate available\\x1B[0m',\n )\n }\n\n // First time setup or returning with no skills (e.g. cancelled last time)\n if (state.skills.length === 0) {\n if (!hasCompletedWizard()) {\n if (!await runWizard({ agent, showOutro: false }))\n return\n }\n else {\n p.log.step('No skills installed yet - pick some packages to get started.')\n }\n\n // Transition to project setup\n const pkgJsonPath = join(cwd, 'package.json')\n const hasPkgJson = existsSync(pkgJsonPath)\n const projectName = hasPkgJson\n ? JSON.parse(readFileSync(pkgJsonPath, 'utf-8')).name\n : undefined\n const projectLabel = projectName\n ? `Generating skills for \\x1B[36m${projectName}\\x1B[0m`\n : 'Generating skills for current directory'\n p.log.step(projectLabel)\n\n if (!hasPkgJson) {\n p.log.warn('No package.json found - enter npm package names manually.\\n For best results, run skilld inside a JS/TS project directory.')\n }\n\n p.log.info('Tip: Add skills for packages with complex APIs or frequent breaking changes - not every dependency needs one.')\n\n // Initial setup loop — allow user to go back\n let setupComplete = false\n while (!setupComplete) {\n const source = hasPkgJson\n ? await p.select({\n message: 'How should I find packages?',\n options: [\n { label: 'Scan source files', value: 'imports', hint: 'find actually used imports' },\n { label: 'Use package.json', value: 'deps', hint: `all ${state.deps.size} dependencies` },\n { label: 'Enter manually', value: 'manual' },\n { label: 'Skip for now', value: 'skip', hint: 'add skills later with `skilld add <pkg>`' },\n ],\n })\n : 'manual' as const\n\n if (p.isCancel(source)) {\n p.cancel('Setup cancelled')\n return\n }\n\n if (source === 'skip') {\n p.log.info('Run \\x1B[36mskilld add <pkg>\\x1B[0m or \\x1B[36mskilld\\x1B[0m anytime to add skills.')\n return\n }\n\n // Get packages based on source\n let selected: string[]\n\n if (source === 'manual') {\n const input = await p.text({\n message: 'Enter package names (space or comma-separated)',\n placeholder: 'vue nuxt pinia',\n })\n if (p.isCancel(input)) {\n if (!hasPkgJson) {\n p.cancel('Setup cancelled')\n return\n }\n continue\n }\n if (!input) {\n p.log.warn('No packages entered')\n continue\n }\n selected = input.split(/[,\\s]+/).map(s => s.trim()).filter(Boolean)\n if (selected.length === 0) {\n p.log.warn('No valid packages entered')\n continue\n }\n }\n else {\n let usages: PackageUsage[]\n if (source === 'imports') {\n const spinner = timedSpinner()\n spinner.start('Scanning imports...')\n const result = await detectImportedPackages(cwd)\n\n if (result.packages.length === 0) {\n spinner.stop('No imports found, falling back to package.json')\n usages = Array.from(state.deps.keys(), name => ({ name, count: 0 }))\n }\n else {\n const depSet = new Set(state.deps.keys())\n usages = result.packages.filter(pkg => depSet.has(pkg.name) || pkg.source === 'preset')\n\n if (usages.length === 0) {\n spinner.stop(`Found ${result.packages.length} imported packages but none match dependencies`)\n usages = result.packages\n }\n else {\n spinner.stop(`Found ${usages.length} imported packages`)\n }\n }\n }\n else {\n usages = Array.from(state.deps.keys(), name => ({ name, count: 0 }))\n }\n\n // Let user select which packages\n const packages = usages.map(u => u.name)\n if (packages.length === 0) {\n p.log.warn('No packages found')\n continue\n }\n const sourceMap = new Map(usages.map(u => [u.name, u.source]))\n const maxLen = Math.max(...packages.map(n => n.length))\n // Pre-select frameworks and presets (most likely to benefit from skills)\n const preselect = packages.filter((name) => {\n if (sourceMap.get(name) === 'preset')\n return true\n // Common frameworks with complex/changing APIs\n const frameworks = new Set(['vue', 'nuxt', 'react', 'next', 'svelte', '@sveltejs/kit', 'astro', 'solid-js', 'angular', 'typescript', 'vite', 'vitest'])\n return frameworks.has(name)\n })\n\n const choice = await p.multiselect({\n message: `Select packages (${packages.length} found)`,\n options: packages.map((name) => {\n const ver = state.deps.get(name)?.replace(/^[\\^~>=<]/, '') || ''\n const repo = getRepoHint(name, cwd)\n const hint = sourceMap.get(name) === 'preset' ? 'nuxt module' : undefined\n const pad = ' '.repeat(maxLen - name.length + 2)\n const meta = [ver, hint, repo].filter(Boolean).join(' ')\n return { label: meta ? `${name}${pad}\\x1B[90m${meta}\\x1B[39m` : name, value: name }\n }),\n initialValues: preselect,\n })\n\n if (p.isCancel(choice)) {\n continue\n }\n if (choice.length === 0) {\n p.log.warn('No packages selected')\n continue\n }\n selected = choice\n }\n\n // Pass wizard-configured model so sync doesn't re-prompt.\n // Wizard already handled model selection - yes:true auto-resolves.\n const wizardConfig = readConfig()\n const { syncCommand } = await import('./commands/sync.ts')\n await syncCommand(state, {\n packages: selected,\n global: false,\n agent,\n model: wizardConfig.model as import('./agent/index.ts').OptimizeModel | undefined,\n yes: !wizardConfig.skipLlm,\n })\n setupComplete = true\n }\n\n // Show SKILL.md preview and verification for newly generated skills\n const postState = await getProjectState(cwd)\n const previewSkill = postState.skills[0]\n if (previewSkill) {\n const previewPath = join(cwd, agents[agent].skillsDir, previewSkill.name, 'SKILL.md')\n if (existsSync(previewPath)) {\n const previewContent = readFileSync(previewPath, 'utf-8')\n // eslint-disable-next-line no-control-regex, regexp/no-obscure-range\n const previewLines = previewContent.split('\\n').slice(0, 20).join('\\n').replace(/\\x1B\\[[0-?]*[ -/]*[@-~]/g, '').replace(/\\x1B\\].*?(?:\\x07|\\x1B\\\\)/g, '')\n const fileSize = (Buffer.byteLength(previewContent) / 1024).toFixed(1)\n p.note(\n `\\x1B[90m${previewLines}\\n...\\x1B[0m`,\n `${agents[agent].skillsDir}/${previewSkill.name}/SKILL.md (${fileSize} KB)`,\n )\n }\n }\n\n // First-run guidance with agent-specific verification tips\n const agentName = agents[agent].displayName\n const agentInstalled = detectInstalledAgents().includes(agent)\n const verifyTips: Record<string, string> = {\n 'claude-code': 'Start a new Claude Code session - skills load automatically.\\nOr type /skill-name to invoke a specific skill.',\n 'cursor': 'Restart Cursor to pick up new skills.\\nSkills appear in Settings > Cursor Rules.',\n 'github-copilot': 'Restart your editor to pick up new skills.\\nCopilot discovers skills from .github/skills/ at startup.',\n 'gemini-cli': 'Start a new Gemini CLI session.\\nVerify with /skills list.',\n 'codex': 'Start a new Codex session.\\nSkills in .agents/skills/ are discovered at startup.',\n 'windsurf': 'Restart Windsurf to pick up new skills.\\nSkills auto-invoke when their description matches your prompt.',\n 'cline': 'Restart your editor. Cline reads skill descriptions at startup.\\nFull content loads on-demand when the agent invokes use_skill.',\n 'goose': 'Start a new Goose session.\\nSkills are discovered automatically at startup.',\n 'amp': 'Start a new Amp session.\\nReads skill descriptions at startup, full content on invocation.',\n 'opencode': 'Start a new OpenCode session.\\nSkills are discovered automatically at startup.',\n 'roo': 'Restart your editor. Roo reads skill descriptions at startup.',\n }\n const verifyLine = agentInstalled\n ? (verifyTips[agent] ?? '')\n : `Skills are ready in ${agents[agent].skillsDir}/.\\n\\x1B[90m${agentName} was not detected on this machine.\\nInstall it to use these skills, or run \\`skilld config\\` to change agents.\\x1B[0m`\n\n // Build a \"try it\" suggestion that tests skill-specific knowledge\n const firstPkg = previewSkill?.info?.packageName || previewSkill?.name\n const trySuggestion = firstPkg\n ? `\\n\\n\\x1B[36mTry it:\\x1B[0m ask your agent \"What are the gotchas or breaking changes in ${firstPkg}?\"`\n : ''\n\n p.note(\n `${verifyLine}${trySuggestion}\\n\\n`\n + `Run \\x1B[36mskilld info\\x1B[0m to see installed skills.\\n`\n + `Run \\x1B[36mskilld\\x1B[0m again to add more, update, or search.`,\n `${agentName} - next steps`,\n )\n\n // Team advice: suggest prepare hook + lockfile\n if (hasPkgJson) {\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'))\n const hasHook = pkgJson.scripts?.prepare?.includes('skilld')\n if (!hasHook) {\n const prepareCmd = pkgJson.scripts?.prepare\n ? `${pkgJson.scripts.prepare} && skilld update -b`\n : 'skilld update -b'\n p.log.info(\n `\\x1B[90mKeep skills fresh by adding to package.json scripts:\\n`\n + ` \\x1B[36m\"prepare\": \"${prepareCmd}\"\\x1B[0m\\n`\n + ` \\x1B[90mRefreshes docs on install. Run \\`skilld update\\` to regenerate LLM enhancements.\\n`\n + ` Commit skilld-lock.yaml so teammates can run \\`skilld install\\`.\\x1B[0m`,\n )\n }\n }\n return\n }\n\n // Has skills - show status + interactive menu\n const status = formatStatus(state.synced.length, state.outdated.length)\n p.log.info(status)\n\n const refreshState = async () => {\n state = await getProjectState(cwd)\n }\n\n // Main menu — Escape in sub-actions returns to menu via guard()\n await menuLoop({\n message: 'What would you like to do?',\n options: () => {\n const opts: Array<{ label: string, value: string, hint?: string }> = []\n opts.push({ label: 'Add new skills', value: 'install' })\n if (state.outdated.length > 0) {\n opts.push({ label: 'Update skills', value: 'update', hint: `\\x1B[33m${state.outdated.length} outdated\\x1B[0m` })\n }\n opts.push(\n { label: 'Remove skills', value: 'remove' },\n { label: 'Search docs', value: 'search' },\n { label: 'Info', value: 'info' },\n { label: 'Configure', value: 'config' },\n )\n return opts\n },\n onSelect: async (action) => {\n switch (action) {\n case 'install': {\n const installedNames = new Set([\n ...state.synced.map(s => s.packageName),\n ...state.outdated.map(s => s.packageName),\n ].filter(Boolean) as string[])\n const uninstalledDeps = [...state.deps.keys()].filter(d => !installedNames.has(d))\n const allDepsInstalled = uninstalledDeps.length === 0\n const hasPkgJsonMenu = existsSync(join(cwd, 'package.json'))\n\n const source = hasPkgJsonMenu\n ? guard(await p.select({\n message: 'How should I find packages?',\n options: [\n { label: 'Scan source files', value: 'imports' as const, hint: allDepsInstalled ? 'all installed' : 'find actually used imports', disabled: allDepsInstalled },\n { label: 'Use package.json', value: 'deps' as const, hint: allDepsInstalled ? 'all installed' : `${uninstalledDeps.length} uninstalled`, disabled: allDepsInstalled },\n { label: 'Enter manually', value: 'manual' as const },\n ],\n }))\n : 'manual' as const\n\n let selected: string[]\n\n if (source === 'manual') {\n const input = guard(await p.text({\n message: 'Enter package names (space or comma-separated)',\n placeholder: 'vue nuxt pinia',\n }))\n if (!input)\n return\n selected = input.split(/[,\\s]+/).map(s => s.trim()).filter(Boolean)\n if (selected.length === 0)\n return\n }\n else {\n let usages: PackageUsage[]\n if (source === 'imports') {\n const spinner = timedSpinner()\n spinner.start('Scanning imports...')\n const result = await detectImportedPackages(cwd)\n\n if (result.packages.length === 0) {\n spinner.stop('No imports found, falling back to package.json')\n usages = uninstalledDeps.map(name => ({ name, count: 0 }))\n }\n else {\n const depSet = new Set(state.deps.keys())\n const matched = result.packages\n .filter(pkg => depSet.has(pkg.name) || pkg.source === 'preset')\n const alreadyInstalled = matched.filter(pkg => installedNames.has(pkg.name))\n usages = matched.filter(pkg => !installedNames.has(pkg.name))\n\n if (usages.length === 0) {\n spinner.stop('All detected imports already have skills')\n return\n }\n else {\n spinner.stop(`Found ${matched.length} imported packages`)\n if (alreadyInstalled.length > 0) {\n p.log.info(`${alreadyInstalled.length} already have skills installed`)\n }\n }\n }\n }\n else {\n usages = uninstalledDeps.map(name => ({ name, count: 0 }))\n }\n\n const packages = usages.map(u => u.name)\n if (packages.length === 0) {\n p.log.warn('No packages found')\n return\n }\n const usageMap = new Map(usages.map(u => [u.name, u]))\n const sourceMap = new Map(usages.map(u => [u.name, u.source]))\n const frameworks = new Set(['vue', 'nuxt', 'react', 'next', 'svelte', '@sveltejs/kit', 'astro', 'solid-js', 'angular', 'typescript', 'vite', 'vitest'])\n const maxLen = Math.max(...packages.map(n => n.length))\n const choice = guard(await p.multiselect({\n message: `Select packages your agent struggles with or that are new to you (${packages.length} found)`,\n options: packages.map((name) => {\n const ver = state.deps.get(name)?.replace(/^[\\^~>=<]/, '') || ''\n const repo = getRepoHint(name, cwd)\n const src = sourceMap.get(name)\n const hint = src === 'preset'\n ? 'nuxt module'\n : frameworks.has(name)\n ? 'framework'\n : (usageMap.get(name)?.count ?? 0) >= 5\n ? `${usageMap.get(name)!.count} imports`\n : undefined\n const pad = ' '.repeat(maxLen - name.length + 2)\n const meta = [ver, hint, repo].filter(Boolean).join(' ')\n return { label: meta ? `${name}${pad}\\x1B[90m${meta}\\x1B[39m` : name, value: name }\n }),\n initialValues: [],\n }))\n\n if (choice.length === 0)\n return\n selected = choice\n }\n\n const { syncCommand: sync } = await import('./commands/sync.ts')\n await sync(state, {\n packages: selected,\n global: false,\n agent,\n yes: false,\n })\n await refreshState()\n return true\n }\n case 'update': {\n if (state.outdated.length === 0) {\n p.log.success('All skills up to date')\n return true\n }\n const selected = guard(await p.multiselect({\n message: 'Select packages to update',\n options: state.outdated.map(s => ({\n label: s.name,\n value: s.packageName || s.name,\n hint: `${s.info?.version ?? 'unknown'} → ${s.latestVersion}`,\n })),\n initialValues: state.outdated.map(s => s.packageName || s.name),\n }))\n if (selected.length === 0)\n return\n const { syncCommand: syncUpdate } = await import('./commands/sync.ts')\n await syncUpdate(state, {\n packages: selected,\n global: false,\n agent,\n yes: false,\n mode: 'update',\n })\n await refreshState()\n return true\n }\n case 'remove': {\n // Check if global skills exist to offer scope choice\n const globalSkills = [...iterateSkills({ scope: 'global' })]\n let removeGlobal = false\n if (globalSkills.length > 0) {\n const scope = guard(await p.select({\n message: 'Which skills?',\n options: [\n { label: 'Project skills', value: 'local' as const },\n { label: 'Global skills', value: 'global' as const, hint: `${globalSkills.length} installed` },\n ],\n }))\n removeGlobal = scope === 'global'\n }\n await removeCommand(state, {\n global: removeGlobal,\n agent,\n yes: false,\n })\n await refreshState()\n break\n }\n case 'search': {\n const { interactiveSearch } = await import('./commands/search-interactive.ts')\n await interactiveSearch()\n break\n }\n case 'info':\n await statusCommand({ global: false })\n break\n case 'config':\n await configCommand()\n await refreshState()\n break\n }\n },\n })\n },\n})\n\nrunMain(main)\n"],"mappings":"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"}
|
package/dist/retriv/index.d.mts
CHANGED
|
@@ -13,12 +13,27 @@ declare function getDb(config: Pick<IndexConfig, 'dbPath'>): Promise<retriv.Sear
|
|
|
13
13
|
* Index documents in-process (no worker thread).
|
|
14
14
|
* Preferred for tests and environments where worker_threads is unreliable.
|
|
15
15
|
*/
|
|
16
|
-
declare function createIndexDirect(documents: Document[], config: IndexConfig
|
|
16
|
+
declare function createIndexDirect(documents: Document[], config: IndexConfig & {
|
|
17
|
+
removeIds?: string[];
|
|
18
|
+
}): Promise<void>;
|
|
17
19
|
/**
|
|
18
20
|
* Index documents in a background worker thread.
|
|
19
21
|
* Falls back to direct indexing if worker fails to spawn.
|
|
20
22
|
*/
|
|
21
|
-
declare function createIndex(documents: Document[], config: IndexConfig
|
|
23
|
+
declare function createIndex(documents: Document[], config: IndexConfig & {
|
|
24
|
+
removeIds?: string[];
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* List all raw document IDs in an existing index.
|
|
28
|
+
* Returns chunk IDs (e.g. "doc-id#chunk-0") for chunked docs.
|
|
29
|
+
* Queries sqlite directly to bypass createRetriv's parent-ID deduplication,
|
|
30
|
+
* so callers can use these IDs for exact removal and parent-ID grouping.
|
|
31
|
+
*/
|
|
32
|
+
declare function listIndexIds(config: Pick<IndexConfig, 'dbPath'>): Promise<string[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Remove documents by ID from an existing index.
|
|
35
|
+
*/
|
|
36
|
+
declare function removeFromIndex(ids: string[], config: Pick<IndexConfig, 'dbPath'>): Promise<void>;
|
|
22
37
|
declare function search(query: string, config: IndexConfig, options?: SearchOptions): Promise<SearchResult[]>;
|
|
23
38
|
/**
|
|
24
39
|
* Search and return formatted snippets
|
|
@@ -28,5 +43,5 @@ declare function openPool(dbPaths: string[]): Promise<Map<string, RetrivInstance
|
|
|
28
43
|
declare function searchPooled(query: string, pool: Map<string, RetrivInstance>, options?: SearchOptions): Promise<SearchSnippet[]>;
|
|
29
44
|
declare function closePool(pool: Map<string, RetrivInstance>): Promise<void>;
|
|
30
45
|
//#endregion
|
|
31
|
-
export { type ChunkEntity, type Document, type IndexConfig, type IndexPhase, type IndexProgress, SearchDepsUnavailableError, type SearchFilter, type SearchOptions, type SearchResult, type SearchSnippet, closePool, createIndex, createIndexDirect, getDb, openPool, search, searchPooled, searchSnippets };
|
|
46
|
+
export { type ChunkEntity, type Document, type IndexConfig, type IndexPhase, type IndexProgress, SearchDepsUnavailableError, type SearchFilter, type SearchOptions, type SearchResult, type SearchSnippet, closePool, createIndex, createIndexDirect, getDb, listIndexIds, openPool, removeFromIndex, search, searchPooled, searchSnippets };
|
|
32
47
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/retriv/index.ts"],"mappings":";;;;KAKK,cAAA,GAAiB,OAAA,CAAQ,UAAA,QAAkB,KAAA;AAAA,cAEnC,0BAAA,SAAmC,KAAA;cAClC,KAAA;AAAA;AAAA,iBAQQ,KAAA,CAAM,MAAA,EAAQ,IAAA,CAAK,WAAA,cAAsB,OAAA,CAAvB,MAAA,CAAuB,cAAA;;;;;;;iBAuCzC,iBAAA,CACpB,SAAA,EAAW,QAAA,IACX,MAAA,EAAQ,WAAA,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/retriv/index.ts"],"mappings":";;;;KAKK,cAAA,GAAiB,OAAA,CAAQ,UAAA,QAAkB,KAAA;AAAA,cAEnC,0BAAA,SAAmC,KAAA;cAClC,KAAA;AAAA;AAAA,iBAQQ,KAAA,CAAM,MAAA,EAAQ,IAAA,CAAK,WAAA,cAAsB,OAAA,CAAvB,MAAA,CAAuB,cAAA;;;;;;;iBAuCzC,iBAAA,CACpB,SAAA,EAAW,QAAA,IACX,MAAA,EAAQ,WAAA;EAAgB,SAAA;AAAA,IACvB,OAAA;;AAnDH;;;iBA+DsB,WAAA,CACpB,SAAA,EAAW,QAAA,IACX,MAAA,EAAQ,WAAA;EAAgB,SAAA;AAAA,IACvB,OAAA;;;;AAzDH;;;iBAqEsB,YAAA,CACpB,MAAA,EAAQ,IAAA,CAAK,WAAA,cACZ,OAAA;;;;iBAiBmB,eAAA,CACpB,GAAA,YACA,MAAA,EAAQ,IAAA,CAAK,WAAA,cACZ,OAAA;AAAA,iBAQmB,MAAA,CACpB,KAAA,UACA,MAAA,EAAQ,WAAA,EACR,OAAA,GAAS,aAAA,GACR,OAAA,CAAQ,YAAA;;;;iBAqBW,cAAA,CACpB,KAAA,UACA,MAAA,EAAQ,WAAA,EACR,OAAA,GAAS,aAAA,GACR,OAAA,CAAQ,aAAA;AAAA,iBA2BW,QAAA,CAAS,OAAA,aAAoB,OAAA,CAAQ,GAAA,SAAY,cAAA;AAAA,iBASjD,YAAA,CACpB,KAAA,UACA,IAAA,EAAM,GAAA,SAAY,cAAA,GAClB,OAAA,GAAS,aAAA,GACR,OAAA,CAAQ,aAAA;AAAA,iBAkCW,SAAA,CAAU,IAAA,EAAM,GAAA,SAAY,cAAA,IAAkB,OAAA"}
|
package/dist/retriv/index.mjs
CHANGED
|
@@ -39,6 +39,7 @@ async function getDb(config) {
|
|
|
39
39
|
*/
|
|
40
40
|
async function createIndexDirect(documents, config) {
|
|
41
41
|
const db = await getDb(config);
|
|
42
|
+
if (config.removeIds?.length) await db.remove?.(config.removeIds);
|
|
42
43
|
await db.index(documents, { onProgress: config.onProgress });
|
|
43
44
|
await db.close?.();
|
|
44
45
|
}
|
|
@@ -50,6 +51,34 @@ async function createIndex(documents, config) {
|
|
|
50
51
|
const { createIndexInWorker } = await import("../_chunks/pool.mjs").then((n) => n.t);
|
|
51
52
|
return createIndexInWorker(documents, config);
|
|
52
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* List all raw document IDs in an existing index.
|
|
56
|
+
* Returns chunk IDs (e.g. "doc-id#chunk-0") for chunked docs.
|
|
57
|
+
* Queries sqlite directly to bypass createRetriv's parent-ID deduplication,
|
|
58
|
+
* so callers can use these IDs for exact removal and parent-ID grouping.
|
|
59
|
+
*/
|
|
60
|
+
async function listIndexIds(config) {
|
|
61
|
+
const nodeSqlite = globalThis.process?.getBuiltinModule?.("node:sqlite");
|
|
62
|
+
if (!nodeSqlite) return [];
|
|
63
|
+
const db = new nodeSqlite.DatabaseSync(config.dbPath, {
|
|
64
|
+
open: true,
|
|
65
|
+
readOnly: true
|
|
66
|
+
});
|
|
67
|
+
try {
|
|
68
|
+
return db.prepare("SELECT id FROM documents_meta").all().map((r) => r.id);
|
|
69
|
+
} finally {
|
|
70
|
+
db.close();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Remove documents by ID from an existing index.
|
|
75
|
+
*/
|
|
76
|
+
async function removeFromIndex(ids, config) {
|
|
77
|
+
if (ids.length === 0) return;
|
|
78
|
+
const db = await getDb(config);
|
|
79
|
+
await db.remove?.(ids);
|
|
80
|
+
await db.close?.();
|
|
81
|
+
}
|
|
53
82
|
async function search(query, config, options = {}) {
|
|
54
83
|
const { limit = 10, filter } = options;
|
|
55
84
|
const db = await getDb(config);
|
|
@@ -139,6 +168,6 @@ async function closePool(pool) {
|
|
|
139
168
|
pool.clear();
|
|
140
169
|
}
|
|
141
170
|
//#endregion
|
|
142
|
-
export { SearchDepsUnavailableError, closePool, createIndex, createIndexDirect, getDb, openPool, search, searchPooled, searchSnippets };
|
|
171
|
+
export { SearchDepsUnavailableError, closePool, createIndex, createIndexDirect, getDb, listIndexIds, openPool, removeFromIndex, search, searchPooled, searchSnippets };
|
|
143
172
|
|
|
144
173
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/retriv/index.ts"],"sourcesContent":["import type { ChunkEntity, Document, IndexConfig, IndexPhase, IndexProgress, SearchFilter, SearchOptions, SearchResult, SearchSnippet } from './types.ts'\nimport { stripFrontmatter } from '../core/markdown.ts'\n\nexport type { ChunkEntity, Document, IndexConfig, IndexPhase, IndexProgress, SearchFilter, SearchOptions, SearchResult, SearchSnippet }\n\ntype RetrivInstance = Awaited<ReturnType<typeof getDb>>\n\nexport class SearchDepsUnavailableError extends Error {\n constructor(cause: unknown) {\n super('Search dependencies unavailable (sqlite-vec or retriv not installed). Search indexing skipped.')\n this.name = 'SearchDepsUnavailableError'\n this.cause = cause\n }\n}\n\n// Dynamic imports: retriv/chunkers/auto eagerly loads typescript which may not be installed (e.g. npx)\nexport async function getDb(config: Pick<IndexConfig, 'dbPath'>) {\n let createRetriv, autoChunker, sqliteMod, sqliteVec, transformersJs, cachedEmbeddings\n try {\n ;([\n { createRetriv },\n { autoChunker },\n sqliteMod,\n sqliteVec,\n { transformersJs },\n { cachedEmbeddings },\n ] = await Promise.all([\n import('retriv'),\n import('retriv/chunkers/auto'),\n import('retriv/db/sqlite'),\n import('sqlite-vec'),\n import('retriv/embeddings/transformers-js'),\n import('./embedding-cache.ts'),\n ]))\n }\n catch (err: any) {\n if (err?.code === 'ERR_MODULE_NOT_FOUND')\n throw new SearchDepsUnavailableError(err)\n throw err\n }\n const embeddings = await cachedEmbeddings(transformersJs())\n return createRetriv({\n driver: sqliteMod.default({\n path: config.dbPath,\n embeddings,\n sqliteVec,\n }),\n chunking: autoChunker(),\n })\n}\n\n/**\n * Index documents in-process (no worker thread).\n * Preferred for tests and environments where worker_threads is unreliable.\n */\nexport async function createIndexDirect(\n documents: Document[],\n config: IndexConfig,\n): Promise<void> {\n const db = await getDb(config)\n await db.index(documents, { onProgress: config.onProgress })\n await db.close?.()\n}\n\n/**\n * Index documents in a background worker thread.\n * Falls back to direct indexing if worker fails to spawn.\n */\nexport async function createIndex(\n documents: Document[],\n config: IndexConfig,\n): Promise<void> {\n // Dynamic import justified: search/searchSnippets shouldn't pull in worker_threads\n const { createIndexInWorker } = await import('./pool.ts')\n return createIndexInWorker(documents, config)\n}\n\nexport async function search(\n query: string,\n config: IndexConfig,\n options: SearchOptions = {},\n): Promise<SearchResult[]> {\n const { limit = 10, filter } = options\n const db = await getDb(config)\n const results = await db.search(query, { limit, filter, returnContent: true, returnMetadata: true, returnMeta: true })\n await db.close?.()\n\n return results.map(r => ({\n id: r.id,\n content: r.content ?? '',\n score: r.score,\n metadata: r.metadata ?? {},\n highlights: r._meta?.highlights ?? [],\n lineRange: r._chunk?.lineRange,\n entities: r._chunk?.entities,\n scope: r._chunk?.scope,\n }))\n}\n\n/**\n * Search and return formatted snippets\n */\nexport async function searchSnippets(\n query: string,\n config: IndexConfig,\n options: SearchOptions = {},\n): Promise<SearchSnippet[]> {\n const results = await search(query, config, options)\n return toSnippets(results)\n}\n\nfunction toSnippets(results: SearchResult[]): SearchSnippet[] {\n return results.map((r) => {\n const content = stripFrontmatter(r.content)\n const source = r.metadata.source || r.id\n const lines = content.split('\\n').length\n\n return {\n package: r.metadata.package || 'unknown',\n source,\n lineStart: r.lineRange?.[0] ?? 1,\n lineEnd: r.lineRange?.[1] ?? lines,\n content,\n score: r.score,\n highlights: r.highlights,\n entities: r.entities,\n scope: r.scope,\n }\n })\n}\n\n// ── Pooled DB access for interactive search ──\n\nexport async function openPool(dbPaths: string[]): Promise<Map<string, RetrivInstance>> {\n const pool = new Map<string, RetrivInstance>()\n await Promise.all(dbPaths.map(async (dbPath) => {\n const db = await getDb({ dbPath })\n pool.set(dbPath, db)\n }))\n return pool\n}\n\nexport async function searchPooled(\n query: string,\n pool: Map<string, RetrivInstance>,\n options: SearchOptions = {},\n): Promise<SearchSnippet[]> {\n const { limit = 10, filter } = options\n const fetchLimit = limit * 2 // Over-fetch to compensate for dedup\n const allResults = await Promise.all(\n Array.from(pool.values(), async (db) => {\n const results = await db.search(query, { limit: fetchLimit, filter, returnContent: true, returnMetadata: true, returnMeta: true })\n return results.map(r => ({\n id: r.id,\n content: r.content ?? '',\n score: r.score,\n metadata: r.metadata ?? {},\n highlights: r._meta?.highlights ?? [],\n lineRange: r._chunk?.lineRange as [number, number] | undefined,\n entities: r._chunk?.entities,\n scope: r._chunk?.scope,\n }))\n }),\n )\n // Deduplicate by source+lineRange (overlapping chunks from same doc)\n const seen = new Set<string>()\n const merged = allResults.flat()\n .sort((a, b) => b.score - a.score)\n .filter((r) => {\n const lr = r.lineRange\n const key = `${r.metadata.source || r.id}:${lr?.[0]}-${lr?.[1]}`\n if (seen.has(key))\n return false\n seen.add(key)\n return true\n })\n .slice(0, limit)\n return toSnippets(merged)\n}\n\nexport async function closePool(pool: Map<string, RetrivInstance>): Promise<void> {\n await Promise.all(Array.from(pool.values(), db => db.close?.()))\n pool.clear()\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/retriv/index.ts"],"sourcesContent":["import type { ChunkEntity, Document, IndexConfig, IndexPhase, IndexProgress, SearchFilter, SearchOptions, SearchResult, SearchSnippet } from './types.ts'\nimport { stripFrontmatter } from '../core/markdown.ts'\n\nexport type { ChunkEntity, Document, IndexConfig, IndexPhase, IndexProgress, SearchFilter, SearchOptions, SearchResult, SearchSnippet }\n\ntype RetrivInstance = Awaited<ReturnType<typeof getDb>>\n\nexport class SearchDepsUnavailableError extends Error {\n constructor(cause: unknown) {\n super('Search dependencies unavailable (sqlite-vec or retriv not installed). Search indexing skipped.')\n this.name = 'SearchDepsUnavailableError'\n this.cause = cause\n }\n}\n\n// Dynamic imports: retriv/chunkers/auto eagerly loads typescript which may not be installed (e.g. npx)\nexport async function getDb(config: Pick<IndexConfig, 'dbPath'>) {\n let createRetriv, autoChunker, sqliteMod, sqliteVec, transformersJs, cachedEmbeddings\n try {\n ;([\n { createRetriv },\n { autoChunker },\n sqliteMod,\n sqliteVec,\n { transformersJs },\n { cachedEmbeddings },\n ] = await Promise.all([\n import('retriv'),\n import('retriv/chunkers/auto'),\n import('retriv/db/sqlite'),\n import('sqlite-vec'),\n import('retriv/embeddings/transformers-js'),\n import('./embedding-cache.ts'),\n ]))\n }\n catch (err: any) {\n if (err?.code === 'ERR_MODULE_NOT_FOUND')\n throw new SearchDepsUnavailableError(err)\n throw err\n }\n const embeddings = await cachedEmbeddings(transformersJs())\n return createRetriv({\n driver: sqliteMod.default({\n path: config.dbPath,\n embeddings,\n sqliteVec,\n }),\n chunking: autoChunker(),\n })\n}\n\n/**\n * Index documents in-process (no worker thread).\n * Preferred for tests and environments where worker_threads is unreliable.\n */\nexport async function createIndexDirect(\n documents: Document[],\n config: IndexConfig & { removeIds?: string[] },\n): Promise<void> {\n const db = await getDb(config)\n if (config.removeIds?.length)\n await db.remove?.(config.removeIds)\n await db.index(documents, { onProgress: config.onProgress })\n await db.close?.()\n}\n\n/**\n * Index documents in a background worker thread.\n * Falls back to direct indexing if worker fails to spawn.\n */\nexport async function createIndex(\n documents: Document[],\n config: IndexConfig & { removeIds?: string[] },\n): Promise<void> {\n // Dynamic import justified: search/searchSnippets shouldn't pull in worker_threads\n const { createIndexInWorker } = await import('./pool.ts')\n return createIndexInWorker(documents, config)\n}\n\n/**\n * List all raw document IDs in an existing index.\n * Returns chunk IDs (e.g. \"doc-id#chunk-0\") for chunked docs.\n * Queries sqlite directly to bypass createRetriv's parent-ID deduplication,\n * so callers can use these IDs for exact removal and parent-ID grouping.\n */\nexport async function listIndexIds(\n config: Pick<IndexConfig, 'dbPath'>,\n): Promise<string[]> {\n const nodeSqlite = globalThis.process?.getBuiltinModule?.('node:sqlite') as typeof import('node:sqlite') | undefined\n if (!nodeSqlite)\n return []\n const db = new nodeSqlite.DatabaseSync(config.dbPath, { open: true, readOnly: true })\n try {\n const rows = db.prepare('SELECT id FROM documents_meta').all() as Array<{ id: string }>\n return rows.map(r => r.id)\n }\n finally {\n db.close()\n }\n}\n\n/**\n * Remove documents by ID from an existing index.\n */\nexport async function removeFromIndex(\n ids: string[],\n config: Pick<IndexConfig, 'dbPath'>,\n): Promise<void> {\n if (ids.length === 0)\n return\n const db = await getDb(config)\n await db.remove?.(ids)\n await db.close?.()\n}\n\nexport async function search(\n query: string,\n config: IndexConfig,\n options: SearchOptions = {},\n): Promise<SearchResult[]> {\n const { limit = 10, filter } = options\n const db = await getDb(config)\n const results = await db.search(query, { limit, filter, returnContent: true, returnMetadata: true, returnMeta: true })\n await db.close?.()\n\n return results.map(r => ({\n id: r.id,\n content: r.content ?? '',\n score: r.score,\n metadata: r.metadata ?? {},\n highlights: r._meta?.highlights ?? [],\n lineRange: r._chunk?.lineRange,\n entities: r._chunk?.entities,\n scope: r._chunk?.scope,\n }))\n}\n\n/**\n * Search and return formatted snippets\n */\nexport async function searchSnippets(\n query: string,\n config: IndexConfig,\n options: SearchOptions = {},\n): Promise<SearchSnippet[]> {\n const results = await search(query, config, options)\n return toSnippets(results)\n}\n\nfunction toSnippets(results: SearchResult[]): SearchSnippet[] {\n return results.map((r) => {\n const content = stripFrontmatter(r.content)\n const source = r.metadata.source || r.id\n const lines = content.split('\\n').length\n\n return {\n package: r.metadata.package || 'unknown',\n source,\n lineStart: r.lineRange?.[0] ?? 1,\n lineEnd: r.lineRange?.[1] ?? lines,\n content,\n score: r.score,\n highlights: r.highlights,\n entities: r.entities,\n scope: r.scope,\n }\n })\n}\n\n// ── Pooled DB access for interactive search ──\n\nexport async function openPool(dbPaths: string[]): Promise<Map<string, RetrivInstance>> {\n const pool = new Map<string, RetrivInstance>()\n await Promise.all(dbPaths.map(async (dbPath) => {\n const db = await getDb({ dbPath })\n pool.set(dbPath, db)\n }))\n return pool\n}\n\nexport async function searchPooled(\n query: string,\n pool: Map<string, RetrivInstance>,\n options: SearchOptions = {},\n): Promise<SearchSnippet[]> {\n const { limit = 10, filter } = options\n const fetchLimit = limit * 2 // Over-fetch to compensate for dedup\n const allResults = await Promise.all(\n Array.from(pool.values(), async (db) => {\n const results = await db.search(query, { limit: fetchLimit, filter, returnContent: true, returnMetadata: true, returnMeta: true })\n return results.map(r => ({\n id: r.id,\n content: r.content ?? '',\n score: r.score,\n metadata: r.metadata ?? {},\n highlights: r._meta?.highlights ?? [],\n lineRange: r._chunk?.lineRange as [number, number] | undefined,\n entities: r._chunk?.entities,\n scope: r._chunk?.scope,\n }))\n }),\n )\n // Deduplicate by source+lineRange (overlapping chunks from same doc)\n const seen = new Set<string>()\n const merged = allResults.flat()\n .sort((a, b) => b.score - a.score)\n .filter((r) => {\n const lr = r.lineRange\n const key = `${r.metadata.source || r.id}:${lr?.[0]}-${lr?.[1]}`\n if (seen.has(key))\n return false\n seen.add(key)\n return true\n })\n .slice(0, limit)\n return toSnippets(merged)\n}\n\nexport async function closePool(pool: Map<string, RetrivInstance>): Promise<void> {\n await Promise.all(Array.from(pool.values(), db => db.close?.()))\n pool.clear()\n}\n"],"mappings":"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"}
|
package/dist/retriv/worker.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.mts","names":[],"sources":["../../src/retriv/worker.ts"],"mappings":";;;UAGiB,kBAAA;EACf,IAAA;EACA,EAAA;EACA,SAAA,EAAW,QAAA;EACX,MAAA;AAAA;AAAA,UAGe,qBAAA;EACf,IAAA;AAAA;AAAA,KAGU,aAAA,GAAgB,kBAAA,GAAqB,qBAAA;AAAA,UAEhC,sBAAA;EACf,IAAA;EACA,EAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA;AAAA;AAAA,UAGe,kBAAA;EACf,IAAA;EACA,EAAA;AAAA;AAAA,UAGe,mBAAA;EACf,IAAA;EACA,EAAA;EACA,OAAA;AAAA;AAAA,KAGU,cAAA,GAAiB,sBAAA,GAAyB,kBAAA,GAAqB,mBAAA"}
|
|
1
|
+
{"version":3,"file":"worker.d.mts","names":[],"sources":["../../src/retriv/worker.ts"],"mappings":";;;UAGiB,kBAAA;EACf,IAAA;EACA,EAAA;EACA,SAAA,EAAW,QAAA;EACX,MAAA;EADyB;EAGzB,SAAA;AAAA;AAAA,UAGe,qBAAA;EACf,IAAA;AAAA;AAAA,KAGU,aAAA,GAAgB,kBAAA,GAAqB,qBAAA;AAAA,UAEhC,sBAAA;EACf,IAAA;EACA,EAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA;AAAA;AAAA,UAGe,kBAAA;EACf,IAAA;EACA,EAAA;AAAA;AAAA,UAGe,mBAAA;EACf,IAAA;EACA,EAAA;EACA,OAAA;AAAA;AAAA,KAGU,cAAA,GAAiB,sBAAA,GAAyB,kBAAA,GAAqB,mBAAA"}
|
package/dist/retriv/worker.mjs
CHANGED
|
@@ -19,6 +19,7 @@ if (parentPort) parentPort.on("message", async (msg) => {
|
|
|
19
19
|
};
|
|
20
20
|
const { getDb } = await import("./index.mjs");
|
|
21
21
|
const db = await getDb(config);
|
|
22
|
+
if (msg.removeIds?.length) await db.remove?.(msg.removeIds);
|
|
22
23
|
await db.index(documents, { onProgress: config.onProgress });
|
|
23
24
|
await db.close?.();
|
|
24
25
|
parentPort.postMessage({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.mjs","names":[],"sources":["../../src/retriv/worker.ts"],"sourcesContent":["import type { IndexConfig, Document as RetrivDocument } from './types.ts'\nimport { parentPort } from 'node:worker_threads'\n\nexport interface WorkerIndexMessage {\n type: 'index'\n id: number\n documents: RetrivDocument[]\n dbPath: string\n}\n\nexport interface WorkerShutdownMessage {\n type: 'shutdown'\n}\n\nexport type WorkerMessage = WorkerIndexMessage | WorkerShutdownMessage\n\nexport interface WorkerProgressResponse {\n type: 'progress'\n id: number\n phase: string\n current: number\n total: number\n}\n\nexport interface WorkerDoneResponse {\n type: 'done'\n id: number\n}\n\nexport interface WorkerErrorResponse {\n type: 'error'\n id: number\n message: string\n}\n\nexport type WorkerResponse = WorkerProgressResponse | WorkerDoneResponse | WorkerErrorResponse\n\nif (parentPort) {\n parentPort.on('message', async (msg: WorkerMessage) => {\n if (msg.type === 'shutdown') {\n process.exit(0)\n }\n\n if (msg.type === 'index') {\n const { id, documents, dbPath } = msg\n\n try {\n const config: IndexConfig = {\n dbPath,\n onProgress: ({ phase, current, total }) => {\n parentPort!.postMessage({ type: 'progress', id, phase, current, total } satisfies WorkerProgressResponse)\n },\n }\n\n const { getDb } = await import('./index.ts')\n const db = await getDb(config)\n await db.index(documents, { onProgress: config.onProgress })\n await db.close?.()\n\n parentPort!.postMessage({ type: 'done', id } satisfies WorkerDoneResponse)\n }\n catch (err) {\n parentPort!.postMessage({\n type: 'error',\n id,\n message: err instanceof Error ? err.message : String(err),\n } satisfies WorkerErrorResponse)\n }\n }\n })\n}\n"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"worker.mjs","names":[],"sources":["../../src/retriv/worker.ts"],"sourcesContent":["import type { IndexConfig, Document as RetrivDocument } from './types.ts'\nimport { parentPort } from 'node:worker_threads'\n\nexport interface WorkerIndexMessage {\n type: 'index'\n id: number\n documents: RetrivDocument[]\n dbPath: string\n /** Exact IDs (including chunk IDs) to remove before indexing */\n removeIds?: string[]\n}\n\nexport interface WorkerShutdownMessage {\n type: 'shutdown'\n}\n\nexport type WorkerMessage = WorkerIndexMessage | WorkerShutdownMessage\n\nexport interface WorkerProgressResponse {\n type: 'progress'\n id: number\n phase: string\n current: number\n total: number\n}\n\nexport interface WorkerDoneResponse {\n type: 'done'\n id: number\n}\n\nexport interface WorkerErrorResponse {\n type: 'error'\n id: number\n message: string\n}\n\nexport type WorkerResponse = WorkerProgressResponse | WorkerDoneResponse | WorkerErrorResponse\n\nif (parentPort) {\n parentPort.on('message', async (msg: WorkerMessage) => {\n if (msg.type === 'shutdown') {\n process.exit(0)\n }\n\n if (msg.type === 'index') {\n const { id, documents, dbPath } = msg\n\n try {\n const config: IndexConfig = {\n dbPath,\n onProgress: ({ phase, current, total }) => {\n parentPort!.postMessage({ type: 'progress', id, phase, current, total } satisfies WorkerProgressResponse)\n },\n }\n\n const { getDb } = await import('./index.ts')\n const db = await getDb(config)\n if (msg.removeIds?.length)\n await db.remove?.(msg.removeIds)\n await db.index(documents, { onProgress: config.onProgress })\n await db.close?.()\n\n parentPort!.postMessage({ type: 'done', id } satisfies WorkerDoneResponse)\n }\n catch (err) {\n parentPort!.postMessage({\n type: 'error',\n id,\n message: err instanceof Error ? err.message : String(err),\n } satisfies WorkerErrorResponse)\n }\n }\n })\n}\n"],"mappings":";;AAuCA,IAAI,WACF,YAAW,GAAG,WAAW,OAAO,QAAuB;AACrD,KAAI,IAAI,SAAS,WACf,SAAQ,KAAK,EAAE;AAGjB,KAAI,IAAI,SAAS,SAAS;EACxB,MAAM,EAAE,IAAI,WAAW,WAAW;AAElC,MAAI;GACF,MAAM,SAAsB;IAC1B;IACA,aAAa,EAAE,OAAO,SAAS,YAAY;AACzC,gBAAY,YAAY;MAAE,MAAM;MAAY;MAAI;MAAO;MAAS;MAAO,CAAkC;;IAE5G;GAED,MAAM,EAAE,UAAU,MAAM,OAAO;GAC/B,MAAM,KAAK,MAAM,MAAM,OAAO;AAC9B,OAAI,IAAI,WAAW,OACjB,OAAM,GAAG,SAAS,IAAI,UAAU;AAClC,SAAM,GAAG,MAAM,WAAW,EAAE,YAAY,OAAO,YAAY,CAAC;AAC5D,SAAM,GAAG,SAAS;AAElB,cAAY,YAAY;IAAE,MAAM;IAAQ;IAAI,CAA8B;WAErE,KAAK;AACV,cAAY,YAAY;IACtB,MAAM;IACN;IACA,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAA;IACtD,CAA+B;;;EAGpC"}
|
package/dist/sources/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "../_chunks/config.mjs";
|
|
2
2
|
import "../_chunks/yaml.mjs";
|
|
3
3
|
import "../_chunks/markdown.mjs";
|
|
4
|
-
import { c as
|
|
4
|
+
import { c as getBlogPreset, d as getFilePatterns, g as getRepoKeyForPackage, h as getRepoEntry, l as getCrawlUrl, m as getRelatedPackages, p as getPrereleaseChangelogRef, u as getDocOverride } from "../_chunks/shared.mjs";
|
|
5
5
|
import { $ as isGitHubRepoUrl, A as parseGitSkillInput, B as isGhAvailable, C as downloadLlmsDocs, D as normalizeLlmsLinks, E as fetchLlmsUrl, F as formatDiscussionAsMarkdown, G as fetchReleaseNotes, H as toCrawlPattern, I as generateDiscussionIndex, J as parseSemver, K as generateReleaseIndex, L as fetchGitHubIssues, M as resolveEntryFiles, N as generateDocsIndex, O as parseMarkdownLinks, P as fetchGitHubDiscussions, Q as fetchText, R as formatIssueAsMarkdown, S as validateGitDocsWithLlms, T as fetchLlmsTxt, U as fetchBlogReleases, V as fetchCrawledDocs, W as compareSemver, X as extractBranchHint, Y as $fetch, Z as fetchGitHubRaw, _ as fetchReadme, a as getInstalledSkillVersion, b as isShallowGitDocs, c as readLocalPackageInfo, d as resolvePackageDocs, et as normalizeRepoUrl, f as resolvePackageDocsWithAttempts, g as fetchGitHubRepoMeta, h as fetchGitDocs, i as fetchPkgDist, j as parseSkillFrontmatterName, k as fetchGitSkills, l as resolveInstalledVersion, m as MIN_GIT_DOCS, n as fetchNpmPackage, nt as parsePackageSpec, o as parseVersionSpecifier, p as searchNpmPackages, q as isPrerelease, r as fetchNpmRegistryMeta, rt as verifyUrl, s as readLocalDependencies, t as fetchLatestVersion, tt as parseGitHubUrl, u as resolveLocalPackageDocs, v as fetchReadmeContent, w as extractSections, x as resolveGitHubRepo, y as filterFrameworkDocs, z as generateIssueIndex } from "../_chunks/sources.mjs";
|
|
6
6
|
export { $fetch, MIN_GIT_DOCS, compareSemver, downloadLlmsDocs, extractBranchHint, extractSections, fetchBlogReleases, fetchCrawledDocs, fetchGitDocs, fetchGitHubDiscussions, fetchGitHubIssues, fetchGitHubRaw, fetchGitHubRepoMeta, fetchGitSkills, fetchLatestVersion, fetchLlmsTxt, fetchLlmsUrl, fetchNpmPackage, fetchNpmRegistryMeta, fetchPkgDist, fetchReadme, fetchReadmeContent, fetchReleaseNotes, fetchText, filterFrameworkDocs, formatDiscussionAsMarkdown, formatIssueAsMarkdown, generateDiscussionIndex, generateDocsIndex, generateIssueIndex, generateReleaseIndex, getBlogPreset, getCrawlUrl, getDocOverride, getFilePatterns, getInstalledSkillVersion, getPrereleaseChangelogRef, getRelatedPackages, getRepoEntry, getRepoKeyForPackage, isGhAvailable, isGitHubRepoUrl, isPrerelease, isShallowGitDocs, normalizeLlmsLinks, normalizeRepoUrl, parseGitHubUrl, parseGitSkillInput, parseMarkdownLinks, parsePackageSpec, parseSemver, parseSkillFrontmatterName, parseVersionSpecifier, readLocalDependencies, readLocalPackageInfo, resolveEntryFiles, resolveGitHubRepo, resolveInstalledVersion, resolveLocalPackageDocs, resolvePackageDocs, resolvePackageDocsWithAttempts, searchNpmPackages, toCrawlPattern, validateGitDocsWithLlms, verifyUrl };
|