skilld 1.7.4 → 2.0.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.
Files changed (156) hide show
  1. package/dist/_chunks/add.mjs +66 -0
  2. package/dist/_chunks/add.mjs.map +1 -0
  3. package/dist/_chunks/agent-prompt.mjs +88 -0
  4. package/dist/_chunks/agent-prompt.mjs.map +1 -0
  5. package/dist/_chunks/agent.mjs +81 -57
  6. package/dist/_chunks/agent.mjs.map +1 -1
  7. package/dist/_chunks/args.mjs +42 -0
  8. package/dist/_chunks/args.mjs.map +1 -0
  9. package/dist/_chunks/assemble.mjs +10 -7
  10. package/dist/_chunks/assemble.mjs.map +1 -1
  11. package/dist/_chunks/author.mjs +33 -17
  12. package/dist/_chunks/author.mjs.map +1 -1
  13. package/dist/_chunks/cache.mjs +143 -183
  14. package/dist/_chunks/cache.mjs.map +1 -1
  15. package/dist/_chunks/cache2.mjs +7 -6
  16. package/dist/_chunks/cache2.mjs.map +1 -1
  17. package/dist/_chunks/client.mjs +117 -0
  18. package/dist/_chunks/client.mjs.map +1 -0
  19. package/dist/_chunks/core.mjs +5 -5
  20. package/dist/_chunks/detect.mjs +53 -43
  21. package/dist/_chunks/detect.mjs.map +1 -1
  22. package/dist/_chunks/eject.mjs +69 -0
  23. package/dist/_chunks/eject.mjs.map +1 -0
  24. package/dist/_chunks/embedding-cache2.mjs +1 -1
  25. package/dist/_chunks/env.mjs +19 -0
  26. package/dist/_chunks/env.mjs.map +1 -0
  27. package/dist/_chunks/install-many.mjs +376 -0
  28. package/dist/_chunks/install-many.mjs.map +1 -0
  29. package/dist/_chunks/install.mjs +81 -326
  30. package/dist/_chunks/install.mjs.map +1 -1
  31. package/dist/_chunks/intro.mjs +63 -0
  32. package/dist/_chunks/intro.mjs.map +1 -0
  33. package/dist/_chunks/list.mjs +2 -2
  34. package/dist/_chunks/list.mjs.map +1 -1
  35. package/dist/_chunks/lockfile.mjs +3 -2
  36. package/dist/_chunks/lockfile.mjs.map +1 -1
  37. package/dist/_chunks/login.mjs +233 -0
  38. package/dist/_chunks/login.mjs.map +1 -0
  39. package/dist/_chunks/logout.mjs +27 -0
  40. package/dist/_chunks/logout.mjs.map +1 -0
  41. package/dist/_chunks/map.mjs +11 -0
  42. package/dist/_chunks/map.mjs.map +1 -0
  43. package/dist/_chunks/markdown.mjs +79 -54
  44. package/dist/_chunks/markdown.mjs.map +1 -1
  45. package/dist/_chunks/menu.mjs +33 -0
  46. package/dist/_chunks/menu.mjs.map +1 -0
  47. package/dist/_chunks/model-picker.mjs +61 -0
  48. package/dist/_chunks/model-picker.mjs.map +1 -0
  49. package/dist/_chunks/monorepo.mjs +4 -2
  50. package/dist/_chunks/monorepo.mjs.map +1 -1
  51. package/dist/_chunks/package-json.mjs.map +1 -1
  52. package/dist/_chunks/paths.mjs +3 -5
  53. package/dist/_chunks/paths.mjs.map +1 -1
  54. package/dist/_chunks/{sync-pipeline.mjs → pipeline.mjs} +346 -313
  55. package/dist/_chunks/pipeline.mjs.map +1 -0
  56. package/dist/_chunks/pool2.mjs +1 -1
  57. package/dist/_chunks/portable.mjs +151 -0
  58. package/dist/_chunks/portable.mjs.map +1 -0
  59. package/dist/_chunks/prepare-hook.mjs +2 -0
  60. package/dist/_chunks/prepare-hook2.mjs +61 -0
  61. package/dist/_chunks/prepare-hook2.mjs.map +1 -0
  62. package/dist/_chunks/prepare.mjs +47 -3
  63. package/dist/_chunks/prepare.mjs.map +1 -1
  64. package/dist/_chunks/prepare2.mjs +7 -6
  65. package/dist/_chunks/prepare2.mjs.map +1 -1
  66. package/dist/_chunks/prompts.mjs +484 -74
  67. package/dist/_chunks/prompts.mjs.map +1 -1
  68. package/dist/_chunks/pull.mjs +219 -0
  69. package/dist/_chunks/pull.mjs.map +1 -0
  70. package/dist/_chunks/regex.mjs +19 -0
  71. package/dist/_chunks/regex.mjs.map +1 -0
  72. package/dist/_chunks/retriv.mjs +2 -171
  73. package/dist/_chunks/retriv2.mjs +159 -0
  74. package/dist/_chunks/retriv2.mjs.map +1 -0
  75. package/dist/_chunks/sanitize.mjs +12 -9
  76. package/dist/_chunks/sanitize.mjs.map +1 -1
  77. package/dist/_chunks/search-helpers.mjs +8 -6
  78. package/dist/_chunks/search-helpers.mjs.map +1 -1
  79. package/dist/_chunks/search-interactive.mjs +23 -20
  80. package/dist/_chunks/search-interactive.mjs.map +1 -1
  81. package/dist/_chunks/search.mjs +3 -3
  82. package/dist/_chunks/search.mjs.map +1 -1
  83. package/dist/_chunks/semver.mjs +2755 -1
  84. package/dist/_chunks/semver.mjs.map +1 -1
  85. package/dist/_chunks/skill-installer2.mjs +10 -11
  86. package/dist/_chunks/skill-installer2.mjs.map +1 -1
  87. package/dist/_chunks/skills.mjs +6 -7
  88. package/dist/_chunks/skills.mjs.map +1 -1
  89. package/dist/_chunks/store.mjs +107 -0
  90. package/dist/_chunks/store.mjs.map +1 -0
  91. package/dist/_chunks/sync.mjs +411 -910
  92. package/dist/_chunks/sync.mjs.map +1 -1
  93. package/dist/_chunks/sync2.mjs +2 -5
  94. package/dist/_chunks/telemetry.mjs +26 -0
  95. package/dist/_chunks/telemetry.mjs.map +1 -0
  96. package/dist/_chunks/uninstall.mjs +12 -9
  97. package/dist/_chunks/uninstall.mjs.map +1 -1
  98. package/dist/_chunks/update.mjs +171 -0
  99. package/dist/_chunks/update.mjs.map +1 -0
  100. package/dist/_chunks/upload.mjs +3 -3
  101. package/dist/_chunks/validate.mjs +1 -1
  102. package/dist/_chunks/version.mjs +16 -17
  103. package/dist/_chunks/version.mjs.map +1 -1
  104. package/dist/_chunks/whoami.mjs +21 -0
  105. package/dist/_chunks/whoami.mjs.map +1 -0
  106. package/dist/_chunks/wizard.mjs +2 -190
  107. package/dist/_chunks/wizard2.mjs +200 -0
  108. package/dist/_chunks/wizard2.mjs.map +1 -0
  109. package/dist/cli.mjs +72 -53
  110. package/dist/cli.mjs.map +1 -1
  111. package/dist/prepare.mjs +4 -3
  112. package/dist/prepare.mjs.map +1 -1
  113. package/dist/retriv/worker.d.mts +5 -1
  114. package/dist/retriv/worker.d.mts.map +1 -1
  115. package/dist/retriv/worker.mjs +1 -1
  116. package/package.json +19 -28
  117. package/dist/_chunks/author-group.mjs +0 -17
  118. package/dist/_chunks/author-group.mjs.map +0 -1
  119. package/dist/_chunks/cli-helpers.mjs +0 -335
  120. package/dist/_chunks/cli-helpers.mjs.map +0 -1
  121. package/dist/_chunks/cli-helpers2.mjs +0 -2
  122. package/dist/_chunks/index.d.mts +0 -344
  123. package/dist/_chunks/index.d.mts.map +0 -1
  124. package/dist/_chunks/index2.d.mts +0 -279
  125. package/dist/_chunks/index2.d.mts.map +0 -1
  126. package/dist/_chunks/index3.d.mts +0 -44
  127. package/dist/_chunks/index3.d.mts.map +0 -1
  128. package/dist/_chunks/index4.d.mts +0 -553
  129. package/dist/_chunks/index4.d.mts.map +0 -1
  130. package/dist/_chunks/package-registry.mjs +0 -465
  131. package/dist/_chunks/package-registry.mjs.map +0 -1
  132. package/dist/_chunks/retriv.mjs.map +0 -1
  133. package/dist/_chunks/setup.mjs +0 -17
  134. package/dist/_chunks/setup.mjs.map +0 -1
  135. package/dist/_chunks/sources.mjs +0 -2654
  136. package/dist/_chunks/sources.mjs.map +0 -1
  137. package/dist/_chunks/sync-pipeline.mjs.map +0 -1
  138. package/dist/_chunks/sync-registry.mjs +0 -65
  139. package/dist/_chunks/sync-registry.mjs.map +0 -1
  140. package/dist/_chunks/types.d.mts +0 -76
  141. package/dist/_chunks/types.d.mts.map +0 -1
  142. package/dist/_chunks/types2.d.mts +0 -88
  143. package/dist/_chunks/types2.d.mts.map +0 -1
  144. package/dist/_chunks/wizard.mjs.map +0 -1
  145. package/dist/agent/index.d.mts +0 -2
  146. package/dist/agent/index.mjs +0 -4
  147. package/dist/cache/index.d.mts +0 -2
  148. package/dist/cache/index.mjs +0 -5
  149. package/dist/index.d.mts +0 -6
  150. package/dist/index.mjs +0 -6
  151. package/dist/retriv/index.d.mts +0 -3
  152. package/dist/retriv/index.mjs +0 -2
  153. package/dist/sources/index.d.mts +0 -3
  154. package/dist/sources/index.mjs +0 -3
  155. package/dist/types.d.mts +0 -4
  156. package/dist/types.mjs +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"sync.mjs","names":["resolvePath","agents","_exhaustive"],"sources":["../../src/telemetry.ts","../../src/commands/sync-resolvers.ts","../../src/commands/sync-runner.ts","../../src/commands/sync-ui-clack.ts","../../src/commands/sync-git.ts","../../src/commands/sync-merge.ts","../../src/commands/sync-ui-parallel.ts","../../src/commands/sync-parallel.ts","../../src/commands/sync.ts"],"sourcesContent":["/**\n * Anonymous telemetry — fire-and-forget GET to add-skill.vercel.sh/t\n *\n * Opt-out: set DISABLE_TELEMETRY=1 or DO_NOT_TRACK=1\n * Auto-disabled in CI environments.\n */\n\nimport { isCI } from 'std-env'\n\nconst TELEMETRY_URL = 'https://add-skill.vercel.sh/t'\nconst SKILLS_VERSION = '1.3.9'\n\ninterface InstallTelemetryData {\n event: 'install'\n source: string\n skills: string\n agents: string\n global?: '1'\n skillFiles?: string\n sourceType?: string\n}\n\ninterface RemoveTelemetryData {\n event: 'remove'\n source?: string\n skills: string\n agents: string\n global?: '1'\n sourceType?: string\n}\n\ntype TelemetryData\n = | InstallTelemetryData\n | RemoveTelemetryData\n\nfunction isEnabled(): boolean {\n return !process.env.DISABLE_TELEMETRY && !process.env.DO_NOT_TRACK\n}\n\nexport function track(data: TelemetryData): void {\n if (!isEnabled())\n return\n\n try {\n const params = new URLSearchParams()\n\n params.set('v', SKILLS_VERSION)\n\n if (isCI)\n params.set('ci', '1')\n\n for (const [key, value] of Object.entries(data)) {\n if (value !== undefined && value !== null)\n params.set(key, String(value))\n }\n\n // Fire and forget\n fetch(`${TELEMETRY_URL}?${params.toString()}`).catch(() => {})\n }\n catch {\n // Telemetry should never break the CLI\n }\n}\n","/**\n * `PackageResolver` implementations for the unified sync runner.\n *\n * Each resolver turns a spec string into a `ResolvedSpec` (or `UnresolvedSpec`\n * with attempts / shipped fallback). The resolver owns source-specific\n * concerns (npm vs crate vs github metadata fetching, version negotiation),\n * so the runner stays source-agnostic.\n */\n\nimport type { PackageResolver, ResolverResult } from './sync-runner.ts'\nimport { handleShippedSkills } from '../agent/skill-installer.ts'\nimport { resolveGitHubRepo } from '../sources/github.ts'\nimport { resolvePackageOrCrate } from '../sources/index.ts'\n\n/**\n * npm + crate resolver. Wraps `resolvePackageOrCrate` and falls back to\n * shipped-skill detection when no docs are found.\n *\n * Returns:\n * - `ResolvedSpec` on success\n * - `UnresolvedSpec` with `shipped` populated when docs are missing but the\n * package ships its own SKILL.md (caller short-circuits)\n * - `UnresolvedSpec` with attempts only on hard failure\n */\nexport const npmResolver: PackageResolver = async (spec, opts) => {\n const resolution = await resolvePackageOrCrate(spec, {\n cwd: opts.cwd,\n onProgress: msg => opts.onProgress(`${spec}: ${msg}`),\n })\n const { isCrate, packageName, identityPackageName, storagePackageName, requestedTag, localVersion, attempts, registryVersion } = resolution\n\n if (!resolution.resolved) {\n const result: ResolverResult = {\n identityName: identityPackageName,\n attempts,\n registryVersion,\n }\n // Even without docs, the package may ship its own skills.\n if (!isCrate) {\n const shippedVersion = localVersion || registryVersion || 'latest'\n const shipped = handleShippedSkills(packageName, shippedVersion, opts.cwd, opts.agent, opts.global)\n if (shipped)\n result.shipped = shipped.shipped\n }\n return result\n }\n\n const resolved = resolution.resolved\n const version = isCrate\n ? (resolved.version || requestedTag || 'latest')\n : (localVersion || resolved.version || 'latest')\n\n return {\n identityName: identityPackageName,\n storageName: storagePackageName,\n version,\n resolved,\n kind: isCrate ? 'crate' : 'npm',\n requestedTag,\n localVersion,\n }\n}\n\n/**\n * GitHub-repo resolver. Used when `gh:owner/repo` has no pre-authored skills\n * and we fall back to generating one from the repo's docs.\n *\n * `spec` is `${owner}/${repo}`. Identity / storage names use `${owner}-${repo}`\n * to match the on-disk skill dir naming.\n */\nexport function createGithubResolver(owner: string, repo: string): PackageResolver {\n return async (_spec, opts) => {\n const resolved = await resolveGitHubRepo(owner, repo, msg => opts.onProgress(msg))\n if (!resolved) {\n return {\n identityName: `${owner}-${repo}`,\n attempts: [{ source: 'github-meta', status: 'not-found', message: `Could not find docs for ${owner}/${repo}` }],\n }\n }\n const repoUrl = `https://github.com/${owner}/${repo}`\n const name = `${owner}-${repo}`\n return {\n identityName: name,\n storageName: name,\n version: resolved.version || 'main',\n // Inject repoUrl so downstream `parseGitHubRepoSlug(resolved.repoUrl)`\n // and the generated SKILL.md frontmatter both have it.\n resolved: { ...resolved, repoUrl },\n kind: 'github',\n }\n }\n}\n","/**\n * Unified sync pipeline.\n *\n * `runBaseSync` and `runEnhancePhase` own the shared skeleton for every sync\n * frontend (sync, sync-parallel, sync-git). Frontends supply:\n * - a `PackageResolver` — how to turn a spec string into a ResolvedSpec\n * - a `SyncUi` — how to surface progress (clack vs logUpdate)\n *\n * Eject mode is threaded through both phases via `RunBaseConfig.eject` /\n * `RunEnhanceConfig.eject`. When set, the runner skips the lockfile +\n * agent-linking steps and emits the `./references/` portable path layout.\n */\n\nimport type { AgentType, SkillSection, StreamProgress } from '../agent/index.ts'\nimport type { SkillContext } from '../agent/skill-builder.ts'\nimport type { SkillInfo } from '../core/lockfile.ts'\nimport type { ResolveAttempt, ResolvedPackage } from '../sources/index.ts'\nimport type { LlmConfig, UpdateContext } from './llm-prompts.ts'\nimport { existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { join, relative, resolve as resolvePath } from 'pathe'\nimport { computeSkillDirName, getModelLabel, linkSkillToAgents, sanitizeName } from '../agent/index.ts'\nimport { applyCachedSections, runSkillEnhancement, writeBaseSkill, writePromptFiles } from '../agent/skill-builder.ts'\nimport { ensureProjectFiles, handleShippedSkills, installSkill, linkShippedToAgents, resolveBaseDir } from '../agent/skill-installer.ts'\nimport { createReferenceCache } from '../cache/index.ts'\nimport { getActiveFeatures } from '../core/config.ts'\nimport { todayIsoDate } from '../core/formatting.ts'\nimport { findSkillDirByPackage, parsePackageNames, readLock } from '../core/lockfile.ts'\nimport { parseFrontmatter } from '../core/markdown.ts'\nimport { getSharedSkillsDir } from '../core/paths.ts'\nimport { fetchPkgDist, isPrerelease, parseGitHubRepoSlug } from '../sources/index.ts'\nimport { buildSkillContext, fetchAndCacheResources, prepareSkillReferences } from './sync-pipeline.ts'\n\nconst RATE_LIMIT_RE = /\\b429\\b|rate.?limit|exhausted.*capacity|quota.*reset/i\n\n/**\n * Frontend-agnostic progress surface. Sequential frontends typically wire\n * these to clack `taskLog`/`spinner`; parallel frontends update a state map\n * and re-render via `logUpdate`.\n */\nexport interface SyncUi {\n /** Resolution started for `spec`. */\n resolveStart: (spec: string) => void\n /** Resolver progress message (e.g. cascade step). */\n resolveProgress: (msg: string) => void\n /** Resolution succeeded. */\n resolveDone: (version: string, opts: { cached: boolean, force?: boolean }) => void\n /** Resolution failed (no docs, not shipped). Frontend may still prompt for suggestions. */\n resolveFailed: (identityName: string) => void\n\n downloadingDist: () => void\n\n /** Resource fetching: lifecycle + per-source progress. */\n fetchStart: () => void\n fetchProgress: (msg: string) => void\n fetchDone: (parts: string[], cached: boolean) => void\n\n /** Search index lifecycle (only invoked when `features.search`). */\n indexStart: () => void\n indexProgress: (msg: string) => void\n indexDone: () => void\n\n /** Non-fatal warning (e.g. partial fetch failure). */\n warn: (msg: string) => void\n\n /** Base SKILL.md written. */\n baseDone: (relPath: string, mode: 'add' | 'update') => void\n\n /** All sections served from LLM cache; LLM call skipped. */\n sectionsCached: () => void\n\n /** LLM optimization started. */\n llmStart: (modelLabel: string) => void\n llmProgress: (progress: StreamProgress) => void\n llmDone: (info: {\n usage?: { totalTokens: number }\n cost?: number\n debugLogsDir?: string\n error?: string\n warnings?: string[]\n }) => void\n llmFailed: (error: string, opts: { rateLimited: boolean }) => void\n\n /** A shipped (in-package) SKILL.md was linked instead of generated. */\n shippedInstalled: (skillName: string, relPath: string) => void\n}\n\n/** Spec resolved into the facts every runner step needs. */\nexport interface ResolvedSpec {\n /** Identity for display + lockfile (`@scope/pkg`). */\n identityName: string\n /** Storage / cache key (often == identity for npm; differs for crates). */\n storageName: string\n version: string\n resolved: ResolvedPackage\n /** Source kind — controls dist download and shipped-skill probing. */\n kind: 'npm' | 'crate' | 'github'\n /** Tag the user requested via `pkg@tag` (used to gate prerelease warning). */\n requestedTag?: string\n /** Local node_modules version, when present (gates prerelease warning). */\n localVersion?: string\n}\n\n/** Resolution failure: caller decides whether to suggest, retry, or abort. */\nexport interface UnresolvedSpec {\n identityName: string\n /** Shipped skill registered as a fallback when no docs were resolvable. */\n shipped?: { skillName: string, skillDir: string }[]\n attempts: ResolveAttempt[]\n registryVersion?: string\n}\n\nexport type ResolverResult = ResolvedSpec | UnresolvedSpec\n\nexport interface ResolverOpts {\n cwd: string\n agent: AgentType\n global: boolean\n onProgress: (msg: string) => void\n}\n\nexport type PackageResolver = (spec: string, opts: ResolverOpts) => Promise<ResolverResult>\n\n/** Result of `runBaseSync` — discriminated so the frontend knows what to do next. */\nexport type BaseSyncResult\n = | { kind: 'shipped' }\n | { kind: 'unresolved', unresolved: UnresolvedSpec }\n | { kind: 'merge-needed', state: MergeNeededState }\n | { kind: 'ready', state: ReadyState }\n\n/**\n * Returned when the target skill dir already holds a different primary\n * package — the runner stops before fetching/caching so the frontend can run\n * its merge-specific writeGeneratedSkillMd flow with both packages.\n */\nexport interface MergeNeededState {\n identityName: string\n storageName: string\n version: string\n resolved: ResolvedPackage\n baseDir: string\n skillDir: string\n skillDirName: string\n existingLock: SkillInfo\n}\n\nexport interface ReadyState {\n ctx: SkillContext\n skillDir: string\n skillDirName: string\n baseDir: string\n updateCtx?: UpdateContext\n /** True when every requested section is already in the LLM cache. */\n allSectionsCached: boolean\n /** Identity name (for outro / telemetry). */\n identityName: string\n /** Storage / cache key (needed for eject's `ejectReferences` cleanup). */\n storageName: string\n version: string\n docsType: 'llms.txt' | 'readme' | 'docs'\n repoInfo?: { owner: string, repo: string }\n}\n\nexport interface RunBaseConfig {\n agent: AgentType\n global: boolean\n mode?: 'add' | 'update'\n force?: boolean\n /** Skip building search index / embeddings even when configured. */\n noSearch?: boolean\n /** Override skill directory name (only honored on add). */\n name?: string\n /** Lower-bound date for release/issue/discussion collection. */\n from?: string\n /**\n * Eject mode:\n * - `false` / undefined → write under agent baseDir, link, lock\n * - `true` → write under `<cwd>/skills/<name>` (portable)\n * - `string` → write under `<resolve(cwd, string)>/<name>`\n * When set, lockfile + agent-linking + named-pkg symlink are skipped.\n */\n eject?: boolean | string\n}\n\n/** Phase 1: resolve → fetch → cache → install → write base SKILL.md. */\nexport async function runBaseSync(\n spec: string,\n config: RunBaseConfig,\n ui: SyncUi,\n resolver: PackageResolver,\n cwd: string,\n defaultSections: SkillSection[],\n): Promise<BaseSyncResult> {\n ui.resolveStart(spec)\n\n const resolverResult = await resolver(spec, {\n cwd,\n agent: config.agent,\n global: config.global,\n onProgress: msg => ui.resolveProgress(msg),\n })\n\n if (!('resolved' in resolverResult)) {\n if (resolverResult.shipped && resolverResult.shipped.length > 0) {\n for (const s of resolverResult.shipped)\n ui.shippedInstalled(s.skillName, relative(cwd, s.skillDir))\n return { kind: 'shipped' }\n }\n ui.resolveFailed(resolverResult.identityName)\n return { kind: 'unresolved', unresolved: resolverResult }\n }\n\n const { identityName, storageName, version, resolved, kind, requestedTag, localVersion } = resolverResult\n const cache = createReferenceCache(storageName, version)\n\n if (config.force)\n cache.clearForce()\n\n const useCache = cache.has()\n\n // Download npm dist when not in node_modules (crates have no dist).\n if (kind !== 'crate' && !existsSync(join(cwd, 'node_modules', identityName))) {\n ui.downloadingDist()\n await fetchPkgDist(identityName, version)\n }\n\n // Shipped skills: short-circuit before cache/LLM.\n if (kind !== 'crate') {\n const shipped = handleShippedSkills(identityName, version, cwd, config.agent, config.global)\n if (shipped) {\n linkShippedToAgents(shipped.shipped, cwd, config.agent, config.global)\n for (const s of shipped.shipped)\n ui.shippedInstalled(s.skillName, relative(cwd, s.skillDir))\n return { kind: 'shipped' }\n }\n }\n\n ui.resolveDone(version, { cached: useCache, force: config.force })\n\n // Prerelease nudge: if user didn't pin and we resolved to stable latest,\n // surface that a newer next/beta/alpha tag exists they could opt into.\n if (kind === 'npm' && !localVersion && !requestedTag && !isPrerelease(version)) {\n const nextTag = resolved.distTags?.next ?? resolved.distTags?.beta ?? resolved.distTags?.alpha\n if (nextTag && (!resolved.releasedAt || !nextTag.releasedAt || nextTag.releasedAt > resolved.releasedAt))\n ui.warn(`No local dependency found — using latest stable (${version}). Prerelease ${nextTag.version} available: skilld add ${identityName}@beta`)\n }\n\n cache.ensure()\n\n const isEject = !!config.eject\n const baseDir = resolveBaseDir(cwd, config.agent, config.global)\n let skillDirName = config.name ? sanitizeName(config.name) : computeSkillDirName(storageName)\n if (config.mode === 'update' && !config.name && !isEject) {\n const lock = readLock(baseDir)\n const found = lock ? findSkillDirByPackage(lock, identityName) : null\n if (found)\n skillDirName = found\n }\n // Eject path lives under the user's working tree; lockfile lives under baseDir.\n const skillDir = isEject\n ? typeof config.eject === 'string'\n ? join(resolvePath(cwd, config.eject), skillDirName)\n : join(cwd, 'skills', skillDirName)\n : join(baseDir, skillDirName)\n mkdirSync(skillDir, { recursive: true })\n\n // Capture pre-update context before lockfile gets overwritten.\n // Eject mode never reads/writes the lockfile, so skip merge detection too.\n const existingLock = isEject ? undefined : readLock(baseDir)?.skills[skillDirName]\n // Merge: skill dir already holds a different primary package — defer to\n // the frontend, which owns the merge SKILL.md regen.\n if (existingLock && existingLock.packageName && existingLock.packageName !== identityName) {\n return {\n kind: 'merge-needed',\n state: {\n identityName,\n storageName,\n version,\n resolved,\n baseDir,\n skillDir,\n skillDirName,\n existingLock,\n },\n }\n }\n const updateCtx: UpdateContext | undefined = config.mode === 'update' && existingLock\n ? {\n oldVersion: existingLock.version,\n newVersion: version,\n syncedAt: existingLock.syncedAt,\n wasEnhanced: (() => {\n const skillMdPath = join(skillDir, 'SKILL.md')\n if (!existsSync(skillMdPath))\n return false\n const fm = parseFrontmatter(readFileSync(skillMdPath, 'utf-8'))\n return !!fm.generated_by\n })(),\n }\n : undefined\n\n const features = getActiveFeatures(config.noSearch ? { search: false } : undefined)\n\n ui.fetchStart()\n const resources = await fetchAndCacheResources({\n packageName: storageName,\n resolved,\n version,\n useCache,\n features,\n from: config.from,\n onProgress: msg => ui.fetchProgress(msg),\n })\n const parts: string[] = []\n if (resources.docsToIndex.length > 0) {\n const docCount = resources.docsToIndex.filter(d => d.metadata?.type === 'doc').length\n if (docCount > 0)\n parts.push(`${docCount} docs`)\n }\n if (resources.hasIssues)\n parts.push('issues')\n if (resources.hasDiscussions)\n parts.push('discussions')\n if (resources.hasReleases)\n parts.push('releases')\n ui.fetchDone(parts, resources.usedCache)\n for (const w of resources.warnings)\n ui.warn(w)\n\n if (features.search)\n ui.indexStart()\n const prepared = await prepareSkillReferences({\n packageName: storageName,\n version,\n cwd,\n skillDir,\n resources,\n features,\n baseDir,\n onIndexProgress: msg => ui.indexProgress(msg),\n })\n if (features.search)\n ui.indexDone()\n\n // Eject mode skips per-pkg symlink + lockfile + agent-linking. The lockfile\n // is also where we read merged-package state from; eject keeps just `[name]`.\n if (!isEject) {\n const repoSlug = parseGitHubRepoSlug(resolved.repoUrl)\n cache.linkPkgNamed(skillDir, cwd)\n const lock: SkillInfo = {\n packageName: identityName,\n version,\n repo: repoSlug,\n source: resources.docSource,\n syncedAt: todayIsoDate(),\n generator: 'skilld',\n }\n installSkill({\n cwd,\n agent: config.agent,\n global: config.global,\n baseDir,\n skillDirName,\n lock,\n dedupePackageName: identityName,\n skipLinkAgents: true,\n })\n }\n\n const updatedLock = isEject ? undefined : readLock(baseDir)?.skills[skillDirName]\n const allPackages = parsePackageNames(updatedLock?.packages)\n\n const ctx = buildSkillContext({\n packageName: identityName,\n cachePackageName: storageName,\n version,\n skillDir,\n skillDirName,\n resources,\n prepared,\n resolved,\n packages: allPackages,\n features,\n })\n\n const baseSkillMd = writeBaseSkill(ctx, { eject: isEject })\n ctx.overheadLines = baseSkillMd.split('\\n').length\n ui.baseDone(relative(cwd, skillDir), config.mode === 'update' ? 'update' : 'add')\n\n const allSectionsCached = !config.force && applyCachedSections(ctx, defaultSections, { eject: isEject })\n if (allSectionsCached)\n ui.sectionsCached()\n\n return {\n kind: 'ready',\n state: {\n ctx,\n skillDir,\n skillDirName,\n baseDir,\n updateCtx,\n allSectionsCached,\n identityName,\n storageName,\n version,\n docsType: resources.docsType,\n repoInfo: resources.repoInfo,\n },\n }\n}\n\nexport interface RunEnhanceConfig {\n agent: AgentType\n global: boolean\n force?: boolean\n debug?: boolean\n /** Same flag as RunBaseConfig.eject; passed again so cleanup runs at the right step. */\n eject?: boolean | string\n}\n\n/**\n * Phase 2: enhance with LLM (or write prompt files), then finalize.\n * In eject mode, finalization is `clearSkillInternalDir` + `ejectReferences`.\n * Otherwise it's `linkSkillToAgents` + `ensureProjectFiles`.\n */\nexport async function runEnhancePhase(\n state: ReadyState,\n llmConfig: LlmConfig | null,\n config: RunEnhanceConfig,\n ui: SyncUi,\n cwd: string,\n): Promise<void> {\n const isEject = !!config.eject\n\n if (llmConfig?.promptOnly) {\n writePromptFiles(\n { ...state.ctx, packageName: state.ctx.cachePackageName ?? state.ctx.packageName, cachePackageName: undefined },\n { sections: llmConfig.sections, customPrompt: llmConfig.customPrompt },\n )\n }\n else if (llmConfig) {\n await enhanceWithUi(state.ctx, llmConfig, { ...config, eject: isEject }, ui)\n }\n\n if (isEject) {\n const cache = createReferenceCache(state.storageName, state.version)\n if (!config.debug)\n cache.clearSkillInternal(state.skillDir)\n cache.eject(state.skillDir, cwd, state.docsType, {\n features: state.ctx.features ?? getActiveFeatures(),\n repoInfo: state.repoInfo,\n })\n return\n }\n\n const shared: string | false = config.global ? false : (getSharedSkillsDir(cwd) ?? false)\n if (shared)\n linkSkillToAgents(state.skillDirName, shared, cwd, config.agent)\n\n await ensureProjectFiles({ cwd, agent: config.agent, global: config.global, shared })\n}\n\nasync function enhanceWithUi(\n ctx: SkillContext,\n llmConfig: LlmConfig,\n config: RunEnhanceConfig,\n ui: SyncUi,\n): Promise<void> {\n ui.llmStart(getModelLabel(llmConfig.model))\n const result = await runSkillEnhancement(\n ctx,\n {\n model: llmConfig.model,\n force: config.force,\n debug: config.debug,\n sections: llmConfig.sections,\n customPrompt: llmConfig.customPrompt,\n eject: !!config.eject,\n },\n progress => ui.llmProgress(progress),\n )\n\n if (result.wasOptimized) {\n ui.llmDone({\n usage: result.usage ? { totalTokens: result.usage.totalTokens } : undefined,\n cost: result.cost,\n debugLogsDir: result.debugLogsDir,\n error: result.error,\n warnings: result.warnings,\n })\n }\n else {\n ui.llmFailed(result.error ?? '', { rateLimited: !!result.error && RATE_LIMIT_RE.test(result.error) })\n }\n}\n\n// Re-exports so call sites can pull `OptimizeModel`/`CustomPrompt` from one\n// place when wiring frontends.\nexport type { CustomPrompt, OptimizeModel, SkillSection } from '../agent/index.ts'\n","/**\n * Sequential clack-based `SyncUi` strategy. Used by single-package sync flows\n * (sync-single, sync-git docs fallback). Composes:\n * - `timedSpinner` for the resolve / fetch / index phases\n * - `taskLog` for the LLM enhancement phase (multi-line stream)\n * - `p.log.*` for status messages\n */\n\nimport type { StreamProgress } from '../agent/index.ts'\nimport type { SyncUi } from './sync-runner.ts'\nimport * as p from '@clack/prompts'\nimport { relative } from 'pathe'\nimport { timedSpinner } from '../core/formatting.ts'\n\nexport interface ClackUiOptions {\n /** Used to resolve `debugLogsDir` against — typically `process.cwd()`. */\n cwd: string\n}\n\n/**\n * Build a sequential UI bound to a fresh spinner/taskLog set. Each call\n * returns a new UI; do not share between concurrent syncs.\n */\nexport function createClackUi({ cwd }: ClackUiOptions): SyncUi {\n // Spinner is reused across resolve → fetch → index phases. We create it\n // lazily on first use and stop it at each phase boundary.\n let spinner: ReturnType<typeof timedSpinner> | null = null\n let resourceSpinner: ReturnType<typeof timedSpinner> | null = null\n let indexSpinner: ReturnType<typeof timedSpinner> | null = null\n let llmLog: ReturnType<typeof p.taskLog> | null = null\n let currentSpec = ''\n\n return {\n resolveStart(spec) {\n currentSpec = spec\n spinner = timedSpinner()\n spinner.start(`Resolving ${spec}`)\n },\n resolveProgress(msg) {\n spinner?.message(msg)\n },\n resolveDone(version, opts) {\n const suffix = opts.force ? ' (force)' : opts.cached ? ' (cached)' : ''\n spinner?.stop(`Resolved ${currentSpec}@${version}${suffix}`)\n spinner = null\n },\n resolveFailed(identityName) {\n spinner?.stop(`Could not find docs for: ${identityName}`)\n spinner = null\n },\n downloadingDist() {\n spinner?.message('Downloading dist')\n },\n fetchStart() {\n resourceSpinner = timedSpinner()\n resourceSpinner.start('Finding resources')\n },\n fetchProgress(msg) {\n resourceSpinner?.message(msg)\n },\n fetchDone(parts, cached) {\n const summary = parts.length > 0 ? parts.join(', ') : 'resources'\n resourceSpinner?.stop(cached ? `Loaded ${summary} (cached)` : `Fetched ${summary}`)\n resourceSpinner = null\n },\n indexStart() {\n indexSpinner = timedSpinner()\n indexSpinner.start('Creating search index')\n },\n indexProgress(msg) {\n indexSpinner?.message(msg)\n },\n indexDone() {\n indexSpinner?.stop('Search index ready')\n indexSpinner = null\n },\n warn(msg) {\n p.log.warn(`\\x1B[33m${msg}\\x1B[0m`)\n },\n baseDone(relPath, mode) {\n p.log.success(mode === 'update' ? `Updated skill: ${relPath}` : `Created base skill: ${relPath}`)\n },\n sectionsCached() {\n p.log.success('Applied cached SKILL.md sections')\n },\n llmStart(modelLabel) {\n p.log.step(modelLabel)\n llmLog = p.taskLog({ title: `Agent exploring ${currentSpec}`, limit: 3 })\n },\n llmProgress(progress: StreamProgress) {\n if (!llmLog)\n return\n // Mirror the line format `enhanceSkillWithLLM` previously used: prefer\n // the chunk text when it's a hint marker `[...]`, otherwise show model.\n const sectionPrefix = progress.section ? `[${progress.section}] ` : ''\n const line = progress.chunk.startsWith('[') ? `${sectionPrefix}${progress.chunk}` : `${sectionPrefix}${progress.chunk}`\n llmLog.message(line)\n },\n llmDone(info) {\n if (!llmLog)\n return\n const parts: string[] = []\n if (info.usage)\n parts.push(`${Math.round(info.usage.totalTokens / 1000)}k tokens`)\n if (info.cost)\n parts.push(`$${info.cost.toFixed(2)}`)\n const suffix = parts.length > 0 ? ` (${parts.join(', ')})` : ''\n llmLog.success(`Generated best practices${suffix}`)\n llmLog = null\n if (info.debugLogsDir)\n p.log.info(`Debug logs: ${relative(cwd, info.debugLogsDir)}`)\n if (info.error)\n p.log.warn(`\\x1B[33mPartial failure: ${info.error}\\x1B[0m`)\n if (info.warnings) {\n for (const w of info.warnings)\n p.log.warn(`\\x1B[33m${w}\\x1B[0m`)\n }\n },\n llmFailed(error, opts) {\n if (!llmLog)\n return\n if (opts.rateLimited)\n llmLog.error(`Rate limited by LLM provider. Try again shortly or use a different model via \\`skilld config\\``)\n else\n llmLog.error(`Enhancement failed${error ? `: ${error}` : ''}`)\n llmLog = null\n },\n shippedInstalled(skillName, relPath) {\n p.log.success(`Using published SKILL.md: ${skillName} → ${relPath}`)\n },\n }\n}\n","/**\n * Git skill sync — install pre-authored skills from git repos,\n * or generate skills from repo docs when no pre-authored skills exist.\n */\n\nimport type { AgentType, OptimizeModel } from '../agent/index.ts'\nimport type { GitSkillSource } from '../sources/git-skills.ts'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { dirname, join, relative } from 'pathe'\nimport { agents, writeSkillMd } from '../agent/index.ts'\nimport { installSkill } from '../agent/skill-installer.ts'\nimport { CACHE_DIR } from '../cache/index.ts'\nimport { readConfig } from '../core/config.ts'\nimport { timedSpinner, todayIsoDate } from '../core/formatting.ts'\nimport { sanitizeMarkdown } from '../core/sanitize.ts'\nimport { shutdownWorker } from '../retriv/pool.ts'\nimport { fetchGitSkills } from '../sources/git-skills.ts'\nimport { track } from '../telemetry.ts'\nimport { DEFAULT_SECTIONS, selectLlmConfig } from './llm-prompts.ts'\nimport { createGithubResolver } from './sync-resolvers.ts'\nimport { runBaseSync, runEnhancePhase } from './sync-runner.ts'\nimport { createClackUi } from './sync-ui-clack.ts'\n\nexport interface GitSyncOptions {\n source: GitSkillSource\n global: boolean\n agent: AgentType\n yes: boolean\n model?: OptimizeModel\n force?: boolean\n debug?: boolean\n from?: string\n /** Filter to specific skill names (comma-separated via --skill flag) */\n skillFilter?: string[]\n}\n\nexport async function syncGitSkills(opts: GitSyncOptions): Promise<void> {\n const { source, agent, global: isGlobal, yes } = opts\n const cwd = process.cwd()\n const agentConfig = agents[agent]\n const baseDir = isGlobal\n ? join(CACHE_DIR, 'skills')\n : join(cwd, agentConfig.skillsDir)\n\n const label = source.type === 'local'\n ? source.localPath!\n : `${source.owner}/${source.repo}`\n\n const spin = timedSpinner()\n spin.start(`Fetching skills from ${label}`)\n\n const { skills } = await fetchGitSkills(source, msg => spin.message(msg))\n\n if (skills.length === 0) {\n // No pre-authored skills — fall back to generating from repo docs (GitHub only)\n if (source.type === 'github' && source.owner && source.repo) {\n spin.stop(`No pre-authored skills in ${label}, generating from repo docs...`)\n return syncGitHubRepo(opts)\n }\n spin.stop(`No skills found in ${label}`)\n return\n }\n\n spin.stop(`Found ${skills.length} skill(s) in ${label}`)\n\n // Select skills to install\n let selected = skills\n\n if (opts.skillFilter?.length) {\n // --skill flag: filter to matching names (strip -skilld suffix for comparison)\n const filterSet = new Set(opts.skillFilter.map(s => s.toLowerCase().replace(/-skilld$/, '')))\n selected = skills.filter(s => filterSet.has(s.name.toLowerCase().replace(/-skilld$/, '')))\n if (selected.length === 0) {\n p.log.warn(`No skills matched: ${opts.skillFilter.join(', ')}`)\n p.log.message(`Available: ${skills.map(s => s.name).join(', ')}`)\n return\n }\n }\n else if (source.skillPath) {\n // Direct path: auto-select the matched skill\n selected = skills\n }\n else if (skills.length > 1 && !yes) {\n const choices = await p.autocompleteMultiselect({\n message: `Select skills to install from ${label}`,\n options: skills.map(s => ({\n label: s.name.replace(/-skilld$/, ''),\n value: s.name,\n hint: s.description || s.path,\n })),\n initialValues: [],\n })\n\n if (p.isCancel(choices))\n return\n\n const selectedNames = new Set(choices)\n selected = skills.filter(s => selectedNames.has(s.name))\n if (selected.length === 0)\n return\n }\n\n // Install each selected skill\n mkdirSync(baseDir, { recursive: true })\n\n for (const skill of selected) {\n const skillDir = join(baseDir, skill.name)\n mkdirSync(skillDir, { recursive: true })\n\n // Sanitize and write SKILL.md\n writeSkillMd(skillDir, sanitizeMarkdown(skill.content))\n\n // Write supporting files directly in skill dir (not under .skilld/)\n // so SKILL.md relative paths like ./references/docs/guide.md resolve correctly\n if (skill.files.length > 0) {\n for (const f of skill.files) {\n const filePath = join(skillDir, f.path)\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, f.content)\n }\n }\n\n const sourceType = source.type === 'local' ? 'local' : source.type\n installSkill({\n cwd,\n agent,\n global: isGlobal,\n baseDir,\n skillDirName: skill.name,\n lock: {\n source: sourceType,\n repo: source.type === 'local' ? source.localPath : `${source.owner}/${source.repo}`,\n path: skill.path || undefined,\n ref: source.ref || 'main',\n syncedAt: todayIsoDate(),\n generator: 'external',\n },\n skipLinkAgents: true,\n })\n }\n\n // Track telemetry (skip local sources)\n if (source.type !== 'local' && source.owner && source.repo) {\n track({\n event: 'install',\n source: `${source.owner}/${source.repo}`,\n skills: selected.map(s => s.name).join(','),\n agents: agent,\n ...(isGlobal && { global: '1' as const }),\n sourceType: source.type,\n })\n }\n\n for (const skill of selected) {\n const skillRel = relative(cwd, join(baseDir, skill.name))\n const fileLines = ['SKILL.md', ...skill.files.map(f => f.path)]\n .map(f => ` \\x1B[90m└\\x1B[0m ${f}`)\n .join('\\n')\n p.log.success(`Installed \\x1B[36m${skill.name}\\x1B[0m \\x1B[90m→ ${skillRel}\\x1B[0m\\n${fileLines}`)\n }\n}\n\n/**\n * Generate a skill from a GitHub repo's docs (no npm package required).\n * Routes through the unified runner with a `createGithubResolver` so the\n * fetch / cache / install / LLM cycle is shared with npm flows.\n */\nasync function syncGitHubRepo(opts: GitSyncOptions): Promise<void> {\n const { source, agent, global: isGlobal, yes } = opts\n const owner = source.owner!\n const repo = source.repo!\n const cwd = process.cwd()\n const ui = createClackUi({ cwd })\n const spec = `${owner}/${repo}`\n\n const result = await runBaseSync(\n spec,\n {\n agent,\n global: isGlobal,\n force: opts.force,\n from: opts.from,\n },\n ui,\n createGithubResolver(owner, repo),\n cwd,\n DEFAULT_SECTIONS,\n )\n\n if (result.kind !== 'ready')\n return\n\n const { state } = result\n const globalConfig = readConfig()\n let llmConfig: import('./llm-prompts.ts').LlmConfig | null = null\n if (!state.allSectionsCached && !globalConfig.skipLlm && (!yes || opts.model))\n llmConfig = await selectLlmConfig(opts.model)\n\n await runEnhancePhase(\n state,\n llmConfig,\n { agent, global: isGlobal, force: opts.force, debug: opts.debug },\n ui,\n cwd,\n )\n\n await shutdownWorker()\n\n track({\n event: 'install',\n source: spec,\n skills: state.skillDirName,\n agents: agent,\n ...(isGlobal && { global: '1' as const }),\n sourceType: 'github-generated',\n })\n\n p.outro(`Synced ${spec} to ${relative(cwd, state.skillDir)}`)\n}\n","/**\n * Merge mode — when a skill dir already holds a different primary package,\n * `runBaseSync` returns `merge-needed` and the frontend regenerates SKILL.md\n * combining the existing primary with the new package. Sequential only.\n */\n\nimport type { AgentType } from '../agent/index.ts'\nimport type { MergeNeededState } from './sync-runner.ts'\nimport { existsSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { linkSkillToAgents, writeGeneratedSkillMd } from '../agent/index.ts'\nimport { installSkill } from '../agent/skill-installer.ts'\nimport { createReferenceCache } from '../cache/index.ts'\nimport { getActiveFeatures } from '../core/config.ts'\nimport { todayIsoDate } from '../core/formatting.ts'\nimport { parsePackageNames, readLock } from '../core/lockfile.ts'\nimport { getSharedSkillsDir, skillRefsSection } from '../core/paths.ts'\nimport { toStoragePackageName } from '../core/prefix.ts'\nimport { parseGitHubRepoSlug } from '../sources/index.ts'\nimport { findRelatedSkills } from './sync-pipeline.ts'\n\nexport interface MergeConfig {\n agent: AgentType\n global: boolean\n}\n\nexport async function handleMerge(\n state: MergeNeededState,\n config: MergeConfig,\n cwd: string,\n): Promise<void> {\n const { identityName, storageName, version, resolved, baseDir, skillDir, skillDirName, existingLock } = state\n\n p.log.step(`Merging ${identityName} into ${skillDirName}`)\n const cache = createReferenceCache(storageName, version)\n cache.linkPkgNamed(skillDir, cwd)\n\n const repoSlug = parseGitHubRepoSlug(resolved.repoUrl)\n installSkill({\n cwd,\n agent: config.agent,\n global: config.global,\n baseDir,\n skillDirName,\n lock: {\n packageName: identityName,\n version,\n repo: repoSlug,\n source: existingLock.source,\n syncedAt: todayIsoDate(),\n generator: 'skilld',\n },\n skipLinkAgents: true,\n })\n\n const updatedLock = readLock(baseDir)?.skills[skillDirName]\n const allPackages = parsePackageNames(updatedLock?.packages)\n const relatedSkills = await findRelatedSkills(storageName, baseDir)\n const existingStorageName = toStoragePackageName(existingLock.packageName!)\n const existingCache = createReferenceCache(existingStorageName, existingLock.version)\n const pkgFiles = existingCache.keyFiles(cwd)\n const shippedDocs = existingCache.hasShipped(cwd)\n\n const features = getActiveFeatures()\n writeGeneratedSkillMd(skillDir, {\n name: existingLock.packageName!,\n version: existingLock.version,\n relatedSkills,\n hasIssues: features.issues && existsSync(skillRefsSection(skillDir, 'issues')),\n hasDiscussions: features.discussions && existsSync(skillRefsSection(skillDir, 'discussions')),\n hasReleases: features.releases && existsSync(skillRefsSection(skillDir, 'releases')),\n docsType: (existingLock.source?.includes('llms.txt') ? 'llms.txt' : 'docs') as 'llms.txt' | 'readme' | 'docs',\n hasShippedDocs: shippedDocs,\n pkgFiles,\n dirName: skillDirName,\n packages: allPackages,\n features,\n })\n\n const sharedDir = !config.global && getSharedSkillsDir(cwd)\n if (sharedDir)\n linkSkillToAgents(skillDirName, sharedDir, cwd, config.agent)\n\n p.outro(`Merged ${identityName} into ${skillDirName}`)\n}\n","/**\n * Parallel `SyncUi` strategy. Many packages render concurrently into a\n * single `logUpdate` table. Each package gets its own `SyncUi` instance\n * bound to its slot in a shared state map; the runner doesn't know it's\n * one of N — it just calls UI methods, which mutate state and re-render.\n *\n * Status taxonomy:\n * pending → resolving → downloading → embedding → done\n * ↘ exploring/thinking/generating (LLM)\n * ↘ error\n */\n\nimport type { SyncUi } from './sync-runner.ts'\nimport logUpdate from 'log-update'\nimport { formatDuration } from '../core/formatting.ts'\n\nexport type PackageStatus = 'pending' | 'resolving' | 'downloading' | 'embedding' | 'exploring' | 'thinking' | 'generating' | 'done' | 'error'\n\nexport interface PackageState {\n name: string\n status: PackageStatus\n message: string\n version?: string\n streamPreview?: string\n startedAt?: number\n completedAt?: number\n}\n\nconst STATUS_ICONS: Record<PackageStatus, string> = {\n pending: '○',\n resolving: '◐',\n downloading: '◒',\n embedding: '◓',\n exploring: '◔',\n thinking: '◔',\n generating: '◑',\n done: '✓',\n error: '✗',\n}\n\nconst STATUS_COLORS: Record<PackageStatus, string> = {\n pending: '\\x1B[90m',\n resolving: '\\x1B[36m',\n downloading: '\\x1B[36m',\n embedding: '\\x1B[36m',\n exploring: '\\x1B[34m',\n thinking: '\\x1B[35m',\n generating: '\\x1B[33m',\n done: '\\x1B[32m',\n error: '\\x1B[31m',\n}\n\nexport interface ParallelRender {\n states: Map<string, PackageState>\n /** Header verb — \"Syncing\" / \"Updating\". */\n verb: string\n /** Total packages (so progress shows \"k/N done\"). */\n total: number\n}\n\n/** Render the entire packages table in one logUpdate frame. */\nexport function renderParallel(r: ParallelRender): void {\n const maxNameLen = Math.max(...[...r.states.keys()].map(n => n.length), 20)\n const lines = [...r.states.values()].map((s) => {\n const icon = STATUS_ICONS[s.status]\n const color = STATUS_COLORS[s.status]\n const reset = '\\x1B[0m'\n const dim = '\\x1B[90m'\n const name = s.name.padEnd(maxNameLen)\n const version = s.version ? `${dim}${s.version}${reset} ` : ''\n const elapsed = (s.status === 'done' || s.status === 'error') && s.startedAt && s.completedAt\n ? ` ${dim}(${formatDuration(s.completedAt - s.startedAt)})${reset}`\n : ''\n const preview = s.streamPreview ? ` ${dim}${s.streamPreview}${reset}` : ''\n return ` ${color}${icon}${reset} ${name} ${version}${s.message}${elapsed}${preview}`\n })\n\n const doneCount = [...r.states.values()].filter(s => s.status === 'done').length\n const errorCount = [...r.states.values()].filter(s => s.status === 'error').length\n const header = `\\x1B[1m${r.verb} ${r.total} packages\\x1B[0m (${doneCount} done${errorCount > 0 ? `, ${errorCount} failed` : ''})\\n`\n\n logUpdate(header + lines.join('\\n'))\n}\n\n/**\n * Build a `SyncUi` bound to one package's slot. UI methods mutate that slot\n * and trigger a full re-render via `render`.\n */\nexport function createParallelUi(name: string, render: ParallelRender, version?: string): SyncUi {\n const state = render.states.get(name)\n if (!state)\n throw new Error(`createParallelUi: no state slot for \"${name}\"`)\n\n function update(status: PackageStatus, message: string, ver?: string): void {\n if (!state!.startedAt && status !== 'pending')\n state!.startedAt = performance.now()\n if ((status === 'done' || status === 'error') && !state!.completedAt)\n state!.completedAt = performance.now()\n state!.status = status\n state!.message = message\n state!.streamPreview = undefined\n if (ver)\n state!.version = ver\n renderParallel(render)\n }\n\n if (version)\n state.version = version\n\n return {\n resolveStart() {\n update('resolving', 'Resolving...')\n },\n resolveProgress(msg) {\n update('resolving', msg)\n },\n resolveDone(ver, opts) {\n // Parallel UI doesn't print a per-step \"Resolved\" line — the version\n // chip on the row already conveys it. Move into the next phase\n // immediately, mirroring `useCache` vs fresh-fetch labels.\n update('downloading', opts.cached ? 'Using cache' : opts.force ? 'Re-fetching docs...' : 'Fetching docs...', ver)\n },\n resolveFailed(_identityName) {\n // No-op; the runner returns `unresolved` and the frontend will set\n // an `error` state with the actual reason.\n },\n downloadingDist() {\n update('downloading', 'Downloading dist...')\n },\n fetchStart() {\n // Already in 'downloading' status from resolveDone; no transition.\n },\n fetchProgress(msg) {\n update('downloading', msg)\n },\n fetchDone(_parts, _cached) {\n update('downloading', 'Linking references...')\n },\n indexStart() {\n update('embedding', 'Indexing docs')\n },\n indexProgress(msg) {\n update('embedding', msg)\n },\n indexDone() {\n // Stay in 'embedding' until the base-skill write moves us to 'done'.\n },\n warn(_msg) {\n // Warnings are surfaced after the parallel render completes (frontend\n // collects from resources.warnings).\n },\n baseDone(_relPath, mode) {\n update('done', mode === 'update' ? 'Skill updated' : 'Base skill created')\n },\n sectionsCached() {\n // Frontend logs the aggregate \"Applied cached for X, Y, Z\" line.\n },\n llmStart(modelLabel) {\n update('generating', modelLabel)\n },\n llmProgress(progress) {\n const isReasoning = progress.type === 'reasoning'\n const status: PackageStatus = isReasoning ? 'exploring' : 'generating'\n const sectionPrefix = progress.section ? `[${progress.section}] ` : ''\n const label = progress.chunk.startsWith('[') ? `${sectionPrefix}${progress.chunk}` : `${sectionPrefix}${progress.chunk}`\n update(status, label)\n },\n llmDone(_info) {\n update('done', 'Skill optimized')\n },\n llmFailed(error, _opts) {\n update('error', error)\n },\n shippedInstalled(_skillName, _relPath) {\n update('done', 'Published SKILL.md')\n },\n }\n}\n","/**\n * Parallel sync orchestrator. Two phased waves:\n * 1. base sync per pkg (pLimited) — fetch, cache, write base SKILL.md\n * 2. LLM enhancement per pkg (pLimited) — single combined `selectLlmConfig`\n * prompt drives all pkgs in this wave\n *\n * Both waves use `runBaseSync` / `runEnhancePhase` from sync-runner; the\n * frontend just supplies a parallel `SyncUi` and orchestrates the pLimit.\n */\n\nimport type { AgentType, OptimizeModel } from '../agent/index.ts'\nimport type { ReadyState, RunBaseConfig } from './sync-runner.ts'\nimport type { PackageState, ParallelRender } from './sync-ui-parallel.ts'\nimport * as p from '@clack/prompts'\nimport logUpdate from 'log-update'\nimport pLimit from 'p-limit'\nimport { getModelLabel } from '../agent/index.ts'\nimport { ensureProjectFiles } from '../agent/skill-installer.ts'\nimport { ensureCacheDir, getVersionKey } from '../cache/index.ts'\nimport { readConfig } from '../core/config.ts'\nimport { semverDiff } from '../core/semver.ts'\nimport { shutdownWorker } from '../retriv/pool.ts'\nimport { parsePackageSpec, searchNpmPackages } from '../sources/index.ts'\nimport { DEFAULT_SECTIONS, resolveAutoModel, selectLlmConfig } from './llm-prompts.ts'\nimport { npmResolver } from './sync-resolvers.ts'\nimport { runBaseSync, runEnhancePhase } from './sync-runner.ts'\nimport { createParallelUi, renderParallel } from './sync-ui-parallel.ts'\n\nexport interface ParallelSyncConfig {\n packages: string[]\n global: boolean\n agent: AgentType\n model?: OptimizeModel\n yes?: boolean\n force?: boolean\n debug?: boolean\n concurrency?: number\n mode?: 'add' | 'update'\n}\n\n/** Bump-type ordering for combining update contexts across packages. */\nconst DIFF_RANK: Record<string, number> = {\n major: 5,\n premajor: 4,\n minor: 3,\n preminor: 2,\n patch: 1,\n prepatch: 1,\n prerelease: 0,\n}\n\nexport async function syncPackagesParallel(config: ParallelSyncConfig): Promise<void> {\n const { packages, concurrency = 5 } = config\n const cwd = process.cwd()\n\n const states = new Map<string, PackageState>()\n for (const spec of packages)\n states.set(spec, { name: spec, status: 'pending', message: 'Waiting...' })\n\n const render: ParallelRender = {\n states,\n verb: config.mode === 'update' ? 'Updating' : 'Syncing',\n total: packages.length,\n }\n\n ensureCacheDir()\n renderParallel(render)\n\n const limit = pLimit(concurrency)\n const baseConfig: RunBaseConfig = {\n agent: config.agent,\n global: config.global,\n mode: config.mode,\n force: config.force,\n }\n\n // ── Wave 1: base sync per pkg ──\n const baseResults = await Promise.allSettled(\n packages.map(spec =>\n limit(async () => {\n const { name } = parsePackageSpec(spec)\n const ui = createParallelUi(name, render)\n return runBaseSync(spec, baseConfig, ui, npmResolver, cwd, DEFAULT_SECTIONS)\n }),\n ),\n )\n\n logUpdate.done()\n\n const ready: Array<{ spec: string, state: ReadyState }> = []\n const shippedCount: string[] = []\n const errors: Array<{ spec: string, reason: string }> = []\n const aggregatedWarnings: string[] = []\n\n for (let i = 0; i < baseResults.length; i++) {\n const spec = packages[i]!\n const r = baseResults[i]!\n if (r.status === 'rejected') {\n const err = r.reason\n const reason = err instanceof Error ? err.message : String(err)\n const slot = states.get(spec)\n if (slot)\n slot.status = 'error'\n errors.push({ spec, reason })\n continue\n }\n const result = r.value\n if (result.kind === 'shipped') {\n shippedCount.push(spec)\n continue\n }\n if (result.kind === 'unresolved') {\n const npmAttempt = result.unresolved.attempts.find(a => a.source === 'npm')\n let reason: string\n if (npmAttempt?.status === 'not-found') {\n const suggestions = await searchNpmPackages(result.unresolved.identityName, 3)\n const hint = suggestions.length > 0 ? ` (try: ${suggestions.map(s => s.name).join(', ')})` : ''\n reason = (npmAttempt.message || 'Not on npm') + hint\n }\n else {\n const failed = result.unresolved.attempts.filter(a => a.status !== 'success')\n reason = failed.map(a => a.message || a.source).join('; ') || 'No docs found'\n }\n const slot = states.get(spec)\n if (slot) {\n slot.status = 'error'\n slot.message = reason\n }\n errors.push({ spec, reason })\n continue\n }\n if (result.kind === 'merge-needed') {\n // Merge requires interactive context; surface and skip.\n errors.push({ spec, reason: `Skill dir already holds ${result.state.existingLock.packageName} — run sequentially to merge` })\n continue\n }\n ready.push({ spec, state: result.state })\n }\n\n renderParallel(render)\n logUpdate.done()\n\n const pastVerb = config.mode === 'update' ? 'Updated' : 'Created'\n p.log.success(`${pastVerb} ${ready.length} base skills${shippedCount.length > 0 ? ` (${shippedCount.length} shipped)` : ''}`)\n\n for (const w of aggregatedWarnings)\n p.log.warn(`\\x1B[33m${w}\\x1B[0m`)\n for (const { spec, reason } of errors)\n p.log.error(` ${spec}: ${reason}`)\n\n // Pre-cached pkgs skip the LLM ask. `runBaseSync` already wrote the cached\n // SKILL.md and surfaced `allSectionsCached` on the ReadyState.\n const cachedPkgs: string[] = []\n const uncached: typeof ready = []\n for (const r of ready) {\n if (r.state.allSectionsCached)\n cachedPkgs.push(r.spec)\n else\n uncached.push(r)\n }\n if (cachedPkgs.length > 0)\n p.log.success(`Applied cached SKILL.md sections for ${cachedPkgs.join(', ')}`)\n\n // ── Wave 2: LLM enhancement ──\n const globalConfig = readConfig()\n const resolvedModel = await resolveAutoModel(config.model, config.yes)\n const shouldAskLlm = uncached.length > 0 && !globalConfig.skipLlm && !(config.yes && !resolvedModel)\n\n if (shouldAskLlm) {\n const updateCtx = config.mode === 'update' ? aggregateUpdateCtx(uncached) : undefined\n const llmConfig = await selectLlmConfig(resolvedModel, undefined, updateCtx)\n\n if (llmConfig?.promptOnly) {\n // Reset slots so the prompt-only path renders cleanly per pkg.\n for (const r of uncached) {\n const slot = states.get(r.spec)\n if (slot) {\n slot.status = 'done'\n slot.message = 'Prompts written'\n }\n }\n renderParallel(render)\n // Phase 2 in promptOnly mode is a synchronous file-writes loop — no\n // need for parallelism. Reuse the same enhance phase via runEnhancePhase\n // (which dispatches to writePromptFiles when promptOnly is set).\n for (const r of uncached) {\n const ui = createParallelUi(r.spec, render, getVersionKey(r.state.version))\n await runEnhancePhase(r.state, llmConfig, {\n agent: config.agent,\n global: config.global,\n force: config.force,\n debug: config.debug,\n }, ui, cwd)\n }\n }\n else if (llmConfig) {\n p.log.step(getModelLabel(llmConfig.model))\n // Reset slots for the LLM phase so progress restarts visually.\n for (const r of uncached) {\n states.set(r.spec, { name: r.spec, status: 'pending', message: 'Waiting...', version: getVersionKey(r.state.version) })\n }\n renderParallel(render)\n\n const llmResults = await Promise.allSettled(\n uncached.map(r =>\n limit(async () => {\n const ui = createParallelUi(r.spec, render, getVersionKey(r.state.version))\n await runEnhancePhase(r.state, llmConfig, {\n agent: config.agent,\n global: config.global,\n force: config.force,\n debug: config.debug,\n }, ui, cwd)\n }),\n ),\n )\n\n logUpdate.done()\n const llmSucceeded = llmResults.filter(x => x.status === 'fulfilled').length\n p.log.success(`Enhanced ${llmSucceeded}/${uncached.length} skills with LLM`)\n }\n }\n else {\n // No LLM ask but we still need to link agents + ensure project files for\n // each ready pkg. `runEnhancePhase(state, null, ...)` does exactly that.\n for (const r of ready) {\n const ui = createParallelUi(r.spec, render, getVersionKey(r.state.version))\n await runEnhancePhase(r.state, null, {\n agent: config.agent,\n global: config.global,\n force: config.force,\n debug: config.debug,\n }, ui, cwd)\n }\n }\n\n await ensureProjectFiles({ cwd, agent: config.agent, global: config.global })\n\n await shutdownWorker()\n\n p.outro(`${pastVerb} ${ready.length}/${packages.length} packages`)\n\n const { suggestPrepareHook } = await import('../cli-helpers.ts')\n try {\n await suggestPrepareHook(cwd)\n }\n catch (err) {\n p.log.warn(`Failed to suggest prepare hook: ${err instanceof Error ? err.message : String(err)}`)\n }\n}\n\n/**\n * Combine per-package update contexts into a single aggregate for the LLM\n * config prompt. Picks the highest-rank bump, the earliest syncedAt, and\n * `allEnhanced` only when every pkg was previously LLM-enhanced.\n */\nfunction aggregateUpdateCtx(ready: Array<{ state: ReadyState }>): import('./llm-prompts.ts').UpdateContext {\n let maxDiff = ''\n let allEnhanced = true\n let anySyncedAt: string | undefined\n for (const r of ready) {\n const u = r.state.updateCtx\n if (!u?.wasEnhanced)\n allEnhanced = false\n if (u?.syncedAt && (!anySyncedAt || u.syncedAt < anySyncedAt))\n anySyncedAt = u.syncedAt\n if (u?.oldVersion && u.newVersion) {\n const diff = semverDiff(u.oldVersion, u.newVersion)\n if (diff && (DIFF_RANK[diff] ?? 0) > (DIFF_RANK[maxDiff] ?? -1))\n maxDiff = diff\n }\n }\n const first = ready[0]?.state.updateCtx\n return {\n oldVersion: ready.length === 1 ? first?.oldVersion : undefined,\n newVersion: ready.length === 1 ? first?.newVersion : undefined,\n syncedAt: anySyncedAt,\n wasEnhanced: allEnhanced,\n bumpType: maxDiff || undefined,\n }\n}\n","import type { AgentType, OptimizeModel, SkillSection } from '../agent/index.ts'\nimport type { ProjectState } from '../core/skills.ts'\nimport type { GitSkillSource } from '../sources/git-skills.ts'\nimport type { ResolveAttempt } from '../sources/index.ts'\nimport type { RunBaseConfig } from './sync-runner.ts'\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { defineCommand } from 'citty'\nimport { join, relative, resolve } from 'pathe'\nimport {\n buildAllSectionPrompts,\n computeSkillDirName,\n detectImportedPackages,\n portabilizePrompt,\n SECTION_OUTPUT_FILES,\n writeGeneratedSkillMd,\n} from '../agent/index.ts'\nimport { ensureGitignore, ensureProjectFiles, installSkill, resolveBaseDir } from '../agent/skill-installer.ts'\nimport {\n createReferenceCache,\n listReferenceFiles,\n} from '../cache/index.ts'\nimport { getInstalledGenerators, introLine, isInteractive, promptForAgent, resolveAgent, sharedArgs, suggestPrepareHook } from '../cli-helpers.ts'\nimport { getActiveFeatures, hasCompletedWizard, readConfig } from '../core/config.ts'\nimport { timedSpinner, todayIsoDate } from '../core/formatting.ts'\nimport { writeLock } from '../core/lockfile.ts'\nimport { isCrateSpec, parseSkillInput, resolveSkillName } from '../core/prefix.ts'\nimport { getProjectState } from '../core/skills.ts'\nimport { shutdownWorker } from '../retriv/pool.ts'\nimport {\n fetchPkgDist,\n parseGitHubRepoSlug,\n resolvePackageOrCrate,\n searchNpmPackages,\n} from '../sources/index.ts'\nimport { DEFAULT_SECTIONS, resolveAutoModel, selectLlmConfig } from './llm-prompts.ts'\nimport { syncGitSkills } from './sync-git.ts'\nimport { handleMerge } from './sync-merge.ts'\nimport { syncPackagesParallel } from './sync-parallel.ts'\nimport {\n fetchAndCacheResources,\n prepareSkillReferences,\n} from './sync-pipeline.ts'\nimport { npmResolver } from './sync-resolvers.ts'\nimport { runBaseSync, runEnhancePhase } from './sync-runner.ts'\nimport { createClackUi } from './sync-ui-clack.ts'\nimport { runWizard } from './wizard.ts'\n\n// Re-export for external consumers\nexport { enhanceSkillWithLLM, writePromptFiles } from '../agent/skill-builder.ts'\nexport type { EnhanceRunOptions, PromptRunOptions, SkillContext } from '../agent/skill-builder.ts'\nexport { ensureAgentInstructions, ensureGitignore, SKILLD_MARKER_END, SKILLD_MARKER_START } from '../agent/skill-installer.ts'\nexport { isCrateSpec } from '../core/prefix.ts'\nexport { DEFAULT_SECTIONS, selectLlmConfig, selectModel, selectSkillSections } from './llm-prompts.ts'\n\nconst RESOLVE_SOURCE_LABELS: Record<string, string> = {\n 'npm': 'npm registry',\n 'github-docs': 'GitHub versioned docs',\n 'github-meta': 'GitHub metadata',\n 'github-search': 'GitHub search',\n 'readme': 'README fallback',\n 'llms.txt': 'llms.txt convention',\n 'crawl': 'website crawl',\n 'local': 'local node_modules',\n}\n\nfunction showResolveAttempts(attempts: ResolveAttempt[]): void {\n if (attempts.length === 0)\n return\n\n p.log.message('\\x1B[90mDoc resolution:\\x1B[0m')\n for (const attempt of attempts) {\n const icon = attempt.status === 'success' ? '\\x1B[32m✓\\x1B[0m' : '\\x1B[90m✗\\x1B[0m'\n const label = RESOLVE_SOURCE_LABELS[attempt.source] ?? attempt.source\n const source = `\\x1B[90m${label}\\x1B[0m`\n const msg = attempt.message ? ` \\x1B[90m— ${attempt.message}\\x1B[0m` : ''\n p.log.message(` ${icon} ${source}${msg}`)\n }\n}\n\nexport type { LlmConfig, UpdateContext } from './llm-prompts.ts'\n\nexport interface SyncOptions {\n packages?: string[]\n global: boolean\n agent: AgentType\n model?: OptimizeModel\n yes: boolean\n force?: boolean\n debug?: boolean\n mode?: 'add' | 'update'\n /** Eject mode: copy references as real files instead of symlinking */\n eject?: boolean | string\n /** Override the computed skill directory name */\n name?: string\n /** Lower-bound date for release/issue/discussion collection (ISO date, e.g. \"2025-07-01\") */\n from?: string\n /** Skip search index / embeddings generation */\n noSearch?: boolean\n}\n\nexport async function syncCommand(state: ProjectState, opts: SyncOptions): Promise<void> {\n // If packages specified, sync those\n if (opts.packages && opts.packages.length > 0) {\n const crateSpecs = opts.packages.filter(isCrateSpec)\n const npmSpecs = opts.packages.filter(p => !isCrateSpec(p))\n\n // npm packages: parallel if >1, serial if 1\n if (npmSpecs.length > 1) {\n await syncPackagesParallel({\n packages: npmSpecs,\n global: opts.global,\n agent: opts.agent,\n model: opts.model,\n yes: opts.yes,\n force: opts.force,\n debug: opts.debug,\n mode: opts.mode,\n })\n }\n else if (npmSpecs.length === 1) {\n await syncSinglePackage(npmSpecs[0]!, opts)\n }\n\n // Crates: serialize (respect crates.io rate limits)\n for (const spec of crateSpecs)\n await syncSinglePackage(spec, opts)\n\n return\n }\n\n // Otherwise show picker, pre-selecting missing/outdated\n const packages = await interactivePicker(state)\n if (!packages || packages.length === 0) {\n p.outro('No packages selected')\n return\n }\n\n // Use parallel sync for multiple packages\n if (packages.length > 1) {\n return syncPackagesParallel({\n packages,\n global: opts.global,\n agent: opts.agent,\n model: opts.model,\n yes: opts.yes,\n force: opts.force,\n debug: opts.debug,\n mode: opts.mode,\n })\n }\n\n // Single package - use original flow\n await syncSinglePackage(packages[0]!, opts)\n}\n\nasync function interactivePicker(state: ProjectState): Promise<string[] | null> {\n const spin = timedSpinner()\n spin.start('Detecting imports...')\n\n const cwd = process.cwd()\n const { packages: detected, error } = await detectImportedPackages(cwd)\n const declaredMap = state.deps\n\n if (error || detected.length === 0) {\n spin.stop(error ? `Detection failed: ${error}` : 'No imports detected')\n if (declaredMap.size === 0) {\n p.log.warn('No dependencies found')\n return null\n }\n // Fallback to package.json\n return pickFromList(Array.from(declaredMap.entries(), ([name, version]) => ({\n name,\n version: maskPatch(version),\n count: 0,\n inPkgJson: true,\n })), state)\n }\n\n spin.stop(`Loaded ${detected.length} project skills`)\n\n const packages = detected.map(pkg => ({\n name: pkg.name,\n version: declaredMap.get(pkg.name),\n count: pkg.count,\n inPkgJson: declaredMap.has(pkg.name),\n }))\n\n return pickFromList(packages, state)\n}\n\nfunction maskPatch(version: string | undefined): string | undefined {\n if (!version)\n return undefined\n const parts = version.split('.')\n if (parts.length >= 3) {\n parts[2] = 'x'\n return parts.slice(0, 3).join('.')\n }\n return version\n}\n\nasync function pickFromList(\n packages: Array<{ name: string, version?: string, count: number, inPkgJson: boolean }>,\n state: ProjectState,\n): Promise<string[] | null> {\n // Pre-select missing and outdated\n const missingSet = new Set(state.missing)\n const outdatedSet = new Set(state.outdated.map(s => s.name))\n\n const options = packages.map(pkg => ({\n label: pkg.inPkgJson ? `${pkg.name} ★` : pkg.name,\n value: pkg.name,\n hint: [\n maskPatch(pkg.version),\n pkg.count > 0 ? `${pkg.count} imports` : null,\n ].filter(Boolean).join(' · ') || undefined,\n }))\n\n const initialValues = packages\n .filter(pkg => missingSet.has(pkg.name) || outdatedSet.has(pkg.name))\n .map(pkg => pkg.name)\n\n const selected = await p.multiselect({\n message: 'Select packages to sync',\n options,\n required: false,\n initialValues,\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Cancelled')\n return null\n }\n\n return selected as string[]\n}\n\ninterface SyncConfig {\n global: boolean\n agent: AgentType\n model?: OptimizeModel\n yes: boolean\n force?: boolean\n debug?: boolean\n mode?: 'add' | 'update'\n eject?: boolean | string\n name?: string\n from?: string\n noSearch?: boolean\n}\n\n/**\n * Sequential sync via the unified runner. Handles npm/crate, add/update mode,\n * eject mode, merge, shipped skills, and \"did-you-mean\" suggestions.\n */\nasync function runSimpleSync(packageSpec: string, config: SyncConfig): Promise<void> {\n const cwd = process.cwd()\n const ui = createClackUi({ cwd })\n const isEject = !!config.eject\n\n const baseConfig: RunBaseConfig = {\n agent: config.agent,\n global: config.global,\n mode: config.mode,\n force: config.force,\n noSearch: config.noSearch,\n name: config.name,\n from: config.from,\n eject: config.eject,\n }\n\n const result = await runBaseSync(packageSpec, baseConfig, ui, npmResolver, cwd, DEFAULT_SECTIONS)\n\n if (result.kind === 'shipped') {\n p.outro(`Synced ${packageSpec}`)\n return\n }\n\n if (result.kind === 'unresolved') {\n const { unresolved } = result\n // Suggestion picker: only meaningful for npm specs (not crates).\n if (!isCrateSpec(packageSpec)) {\n const suggestions = await searchNpmPackages(unresolved.identityName)\n if (suggestions.length > 0) {\n showResolveAttempts(unresolved.attempts)\n const selected = await p.select({\n message: 'Did you mean one of these?',\n options: [\n ...suggestions.map(s => ({ label: s.name, value: s.name, hint: s.description })),\n { label: 'None of these', value: '_none_' as const },\n ],\n })\n if (!p.isCancel(selected) && selected !== '_none_')\n return syncSinglePackage(selected as string, config)\n return\n }\n }\n showResolveAttempts(unresolved.attempts)\n return\n }\n\n if (result.kind === 'merge-needed') {\n await handleMerge(result.state, { agent: config.agent, global: config.global }, cwd)\n return\n }\n\n // result.kind === 'ready'\n const { state } = result\n const globalConfig = readConfig()\n const resolvedModel = await resolveAutoModel(config.model, config.yes)\n\n let llmConfig: import('./llm-prompts.ts').LlmConfig | null = null\n if (!state.allSectionsCached && !globalConfig.skipLlm && !(config.yes && !resolvedModel))\n llmConfig = await selectLlmConfig(resolvedModel, undefined, state.updateCtx)\n\n await runEnhancePhase(\n state,\n llmConfig,\n { agent: config.agent, global: config.global, force: config.force, debug: config.debug, eject: config.eject },\n ui,\n cwd,\n )\n\n await shutdownWorker()\n const ejectMsg = isEject ? ' (ejected)' : ''\n const relDir = relative(cwd, state.skillDir)\n p.outro(config.mode === 'update'\n ? `Updated ${state.identityName}${ejectMsg}`\n : `Synced ${state.identityName} → ${relDir}${ejectMsg}`)\n\n try {\n await suggestPrepareHook(cwd)\n }\n catch (err) {\n p.log.warn(`Failed to suggest prepare hook: ${err instanceof Error ? err.message : String(err)}`)\n }\n}\n\nasync function syncSinglePackage(packageSpec: string, config: SyncConfig): Promise<void> {\n if (isCrateSpec(packageSpec) && !packageSpec.slice('crate:'.length).trim()) {\n p.log.error('Invalid crate spec. Use format: crate:<name>')\n return\n }\n return runSimpleSync(packageSpec, config)\n}\n\n// ── Citty command definitions (lazy-loaded by cli.ts) ──\n\nexport const addCommandDef = defineCommand({\n meta: { name: 'add', description: 'Install skills (npm:<pkg>, crate:<name>, gh:<owner/repo>, @<curator>)' },\n args: {\n package: {\n type: 'positional',\n description: 'Package(s) to sync (space/comma-separated; npm:<pkg>, crate:<name>, or owner/repo)',\n required: true,\n },\n skill: {\n type: 'string',\n alias: 's',\n description: 'Select specific skills from a git repo (comma-separated)',\n valueHint: 'name',\n },\n ...sharedArgs,\n },\n async run({ args }) {\n const cwd = process.cwd()\n let agent: AgentType | 'none' | null = resolveAgent(args.agent)\n if (!agent) {\n agent = await promptForAgent()\n if (!agent)\n return\n }\n\n // Collect raw inputs (don't split URLs on slashes/spaces yet)\n const rawInputs = [...new Set(\n [args.package, ...((args as any)._ || [])]\n .map((s: string) => s.trim())\n .filter(Boolean),\n )]\n\n // No-agent mode: export portable prompts\n if (agent === 'none') {\n const packages = [...new Set(rawInputs.flatMap(s => s.split(/[,\\s]+/)).map(s => s.trim()).filter(Boolean))]\n for (const pkg of packages)\n await exportPortablePrompts(pkg, { force: args.force, agent: 'none' })\n return\n }\n\n // First-time setup — configure features + LLM model\n if (!hasCompletedWizard())\n await runWizard({ agent })\n\n // Classify inputs via prefix parser\n const parsedSources = rawInputs.map(parseSkillInput)\n const gitSources: GitSkillSource[] = []\n const npmEntries: Array<{ name: string, spec: string }> = []\n const crateSpecs: string[] = []\n const unsupported: string[] = []\n\n for (const source of parsedSources) {\n switch (source.type) {\n case 'git':\n gitSources.push(source.source)\n break\n case 'npm':\n npmEntries.push({ name: source.package, spec: source.tag ? `${source.package}@${source.tag}` : source.package })\n break\n case 'crate':\n crateSpecs.push(source.version ? `crate:${source.package}@${source.version}` : `crate:${source.package}`)\n break\n case 'bare':\n p.log.warn(`Bare names are deprecated. Use \\x1B[36mnpm:${source.package}\\x1B[0m instead.`)\n npmEntries.push({ name: source.package, spec: source.tag ? `${source.package}@${source.tag}` : source.package })\n break\n case 'curator':\n unsupported.push(`@${source.handle} (curator)`)\n break\n case 'collection':\n unsupported.push(`@${source.handle}/${source.name} (collection)`)\n break\n default: {\n const _exhaustive: never = source\n throw new Error(`Unhandled SkillSource type: ${JSON.stringify(_exhaustive)}`)\n }\n }\n }\n\n if (unsupported.length > 0) {\n p.log.error(`Curator and collection installs are not yet available:\\n ${unsupported.join('\\n ')}\\n\\nFollow https://skilld.dev for launch updates.`)\n process.exitCode = 1\n if (gitSources.length === 0 && npmEntries.length === 0 && crateSpecs.length === 0)\n return\n }\n\n // Handle git sources\n if (gitSources.length > 0) {\n for (const source of gitSources) {\n const skillFilter = args.skill ? args.skill.split(/[,\\s]+/).map((s: string) => s.trim()).filter(Boolean) : undefined\n await syncGitSkills({ source, global: args.global, agent, yes: args.yes, model: args.model as OptimizeModel | undefined, force: args.force, debug: args.debug, skillFilter })\n }\n }\n\n // Handle npm packages: registry first, then fallback to doc generation\n if (npmEntries.length > 0) {\n const { syncRegistrySkill } = await import('./sync-registry.ts')\n const seen = new Set<string>()\n const dedupedEntries = npmEntries.filter((e) => {\n if (seen.has(e.name))\n return false\n seen.add(e.name)\n return true\n })\n\n // Try registry for each package, collect misses for fallback\n const fallbackPackages: string[] = []\n for (const entry of dedupedEntries) {\n const result = await syncRegistrySkill({ packageName: entry.name, agent, cwd })\n if (result) {\n p.log.success(`Installed \\x1B[36m${result.name}\\x1B[0m from registry`)\n }\n else {\n fallbackPackages.push(entry.spec)\n }\n }\n\n // Fallback: generate from docs for packages not in registry\n if (fallbackPackages.length > 0) {\n const state = await getProjectState(cwd)\n p.intro(introLine({ state, agentId: agent || undefined }))\n await syncCommand(state, {\n packages: [...fallbackPackages, ...crateSpecs],\n global: args.global,\n agent,\n model: args.model as OptimizeModel | undefined,\n yes: args.yes,\n force: args.force,\n debug: args.debug,\n })\n return\n }\n }\n\n // Crates without any npm packages: route straight to syncCommand\n if (crateSpecs.length > 0) {\n const state = await getProjectState(cwd)\n p.intro(introLine({ state, agentId: agent || undefined }))\n await syncCommand(state, {\n packages: crateSpecs,\n global: args.global,\n agent,\n model: args.model as OptimizeModel | undefined,\n yes: args.yes,\n force: args.force,\n debug: args.debug,\n })\n }\n },\n})\n\nexport const ejectCommandDef = defineCommand({\n meta: { name: 'eject', description: 'Eject skill with references as real files (portable, no symlinks)' },\n args: {\n package: {\n type: 'positional',\n description: 'Package to eject',\n required: true,\n },\n name: {\n type: 'string',\n alias: 'n',\n description: 'Custom skill directory name (default: derived from package)',\n },\n out: {\n type: 'string',\n alias: 'o',\n description: 'Output directory path override',\n },\n from: {\n type: 'string',\n description: 'Collect releases/issues/discussions from this date onward (YYYY-MM-DD)',\n },\n search: {\n type: 'boolean',\n description: 'Build search index / embeddings (use --no-search to skip)',\n default: true,\n },\n ...sharedArgs,\n },\n async run({ args }) {\n const cwd = process.cwd()\n // Eject skips agent detection — output goes to ./skills/<name> by default\n const resolved = resolveAgent(args.agent)\n const agent: AgentType = resolved && resolved !== 'none' ? resolved : 'claude-code'\n\n if (!hasCompletedWizard())\n await runWizard({ agent })\n\n const state = await getProjectState(cwd)\n p.intro(introLine({ state, agentId: agent || undefined }))\n return syncCommand(state, {\n packages: [args.package],\n global: args.global,\n agent,\n model: args.model as OptimizeModel | undefined,\n yes: args.yes,\n force: args.force,\n debug: args.debug,\n eject: args.out || true,\n name: args.name,\n from: args.from,\n noSearch: !args.search,\n })\n },\n})\n\nexport const updateCommandDef = defineCommand({\n meta: { name: 'update', description: 'Update outdated skills' },\n args: {\n package: {\n type: 'positional',\n description: 'Package(s) to update (space or comma-separated). Without args, syncs all outdated.',\n required: false,\n },\n background: {\n type: 'boolean',\n alias: 'b',\n description: 'Run in background (detached process, non-interactive)',\n default: false,\n },\n ...sharedArgs,\n },\n async run({ args }) {\n const cwd = process.cwd()\n\n // Background mode: spawn detached `skilld update` and exit immediately\n if (args.background) {\n const { spawn } = await import('node:child_process')\n const updateArgs = ['update', ...(args.package ? [args.package] : []), ...(args.agent ? ['--agent', args.agent] : []), ...(args.model ? ['--model', args.model as string] : [])]\n const child = spawn(process.execPath, [process.argv[1]!, ...updateArgs], {\n cwd,\n detached: true,\n stdio: 'ignore',\n }) as import('node:child_process').ChildProcess\n child.unref()\n return\n }\n\n const silent = !isInteractive()\n\n let agent = resolveAgent(args.agent)\n if (!agent) {\n agent = await promptForAgent()\n if (!agent)\n return\n }\n\n // No-agent mode: re-export portable prompts for outdated packages\n if (agent === 'none') {\n const state = await getProjectState(cwd)\n const packages = args.package\n ? Array.from(\n new Set([args.package, ...((args as any)._ || [])].flatMap(s => s.split(/[,\\s]+/)).map(s => s.trim()).filter(Boolean)),\n s => resolveSkillName(s),\n ).filter((s): s is string => s !== null)\n : state.outdated.map(s => s.packageName || s.name)\n if (packages.length === 0) {\n if (!silent)\n p.log.success('All skills up to date')\n return\n }\n for (const pkg of packages)\n await exportPortablePrompts(pkg, { force: args.force, agent: 'none' })\n return\n }\n\n const config = readConfig()\n const state = await getProjectState(cwd)\n\n if (!silent) {\n const generators = getInstalledGenerators()\n p.intro(introLine({ state, generators, modelId: config.model, agentId: config.agent || agent || undefined }))\n }\n\n // Specific packages (strip npm:/gh: prefixes)\n if (args.package) {\n const raw = [...new Set([args.package, ...((args as any)._ || [])].flatMap(s => s.split(/[,\\s]+/)).map(s => s.trim()).filter(Boolean))]\n const packages: string[] = []\n for (const r of raw) {\n const name = resolveSkillName(r)\n if (!name) {\n p.log.warn(`Cannot update \\x1B[36m${r}\\x1B[0m: curator/collection inputs are not addressable here.`)\n continue\n }\n packages.push(name)\n }\n if (packages.length === 0)\n return\n return syncCommand(state, {\n packages,\n global: args.global,\n agent,\n model: (args.model as OptimizeModel | undefined) || (silent ? config.model : undefined),\n yes: args.yes || silent,\n force: args.force,\n debug: args.debug,\n mode: 'update',\n })\n }\n\n // No args: sync all outdated + all crate skills.\n // Crates have no package.json entry to pin against, so state.outdated never\n // includes them. Bulk update re-resolves each against crates.io; if the version\n // hasn't changed the cache short-circuits fetching.\n const crateSpecs = state.skills\n .map(s => s.info?.packageName)\n .filter((name): name is string => !!name && name.startsWith('crate:'))\n if (state.outdated.length === 0 && crateSpecs.length === 0) {\n p.log.success('All skills up to date')\n return\n }\n\n const packages = [\n ...state.outdated.map(s => s.packageName || s.name),\n ...crateSpecs,\n ]\n return syncCommand(state, {\n packages,\n global: args.global,\n agent,\n model: (args.model as OptimizeModel | undefined) || (silent ? config.model : undefined),\n yes: args.yes || silent,\n force: args.force,\n debug: args.debug,\n mode: 'update',\n })\n },\n})\n\n// ── Portable prompt export (no-agent mode) ─────────────────────\n\nexport async function exportPortablePrompts(packageSpec: string, opts: {\n out?: string\n sections?: SkillSection[]\n force?: boolean\n agent?: AgentType | 'none'\n}): Promise<void> {\n const sections = opts.sections ?? DEFAULT_SECTIONS\n\n const spin = timedSpinner()\n spin.start(`Resolving ${packageSpec}`)\n const cwd = process.cwd()\n\n const { packageName, localVersion, resolved } = await resolvePackageOrCrate(packageSpec, {\n cwd,\n onProgress: label => spin.message(`${packageSpec}: ${label}`),\n })\n\n if (!resolved) {\n spin.stop(`Could not find docs for: ${packageSpec}`)\n return\n }\n\n const version = localVersion || resolved.version || 'latest'\n const cache = createReferenceCache(packageName, version)\n const useCache = !opts.force && cache.has()\n\n // Download npm dist if not in node_modules\n if (!existsSync(join(cwd, 'node_modules', packageName))) {\n spin.message(`Downloading ${packageName}@${version} dist`)\n await fetchPkgDist(packageName, version)\n }\n\n spin.stop(`Resolved ${packageName}@${useCache ? cache.versionKey : version}`)\n cache.ensure()\n\n const skillDirName = computeSkillDirName(packageName)\n const features = getActiveFeatures()\n\n // Resolve skill dir — detect agent unless explicitly 'none'\n const agent: AgentType | null = opts.agent === 'none'\n ? null\n : opts.agent ?? (await import('../agent/detect.ts').then(m => m.detectTargetAgent()))\n const baseDir = agent\n ? resolveBaseDir(cwd, agent, false)\n : join(cwd, '.claude', 'skills') // fallback when no agent detected\n const skillDir = opts.out ? resolve(cwd, opts.out) : join(baseDir, skillDirName)\n\n // Warn if output files already exist (user may have pending work)\n if (existsSync(skillDir) && !opts.force) {\n const existing = Object.values(SECTION_OUTPUT_FILES).filter(f => existsSync(join(skillDir, f)))\n if (existing.length > 0)\n p.log.warn(`Overwriting existing output files in ${relative(cwd, skillDir)}: ${existing.join(', ')}`)\n }\n mkdirSync(skillDir, { recursive: true })\n\n // Fetch & cache resources\n const resSpin = timedSpinner()\n resSpin.start('Fetching resources')\n const resources = await fetchAndCacheResources({\n packageName,\n resolved,\n version,\n useCache,\n features,\n onProgress: msg => resSpin.message(msg),\n })\n resSpin.stop('Resources ready')\n for (const w of resources.warnings)\n p.log.warn(`\\x1B[33m${w}\\x1B[0m`)\n\n const prepared = await prepareSkillReferences({\n packageName,\n version,\n cwd,\n skillDir,\n resources,\n features,\n baseDir: join(skillDir, '..'),\n })\n const { hasChangelog, shippedDocs, pkgFiles, relatedSkills } = prepared\n const docFiles = listReferenceFiles(skillDir)\n\n // Build prompts\n const prompts = buildAllSectionPrompts({\n packageName,\n skillDir,\n version,\n hasIssues: resources.hasIssues,\n hasDiscussions: resources.hasDiscussions,\n hasReleases: resources.hasReleases,\n hasChangelog,\n docFiles,\n docsType: resources.docsType,\n hasShippedDocs: shippedDocs,\n pkgFiles,\n features,\n sections,\n })\n\n cache.eject(skillDir, cwd, resources.docsType, { features, repoInfo: resources.repoInfo })\n cache.clearSkillInternal(skillDir)\n\n // Write portable prompts\n for (const [section, prompt] of prompts) {\n const portable = portabilizePrompt(prompt, section)\n writeFileSync(join(skillDir, `PROMPT_${section}.md`), portable)\n }\n\n // Generate SKILL.md (ejected — uses ./references/ paths)\n writeGeneratedSkillMd(skillDir, {\n name: packageName,\n version,\n releasedAt: resolved.releasedAt,\n description: resolved.description,\n\n distTags: resolved.distTags,\n relatedSkills,\n hasIssues: resources.hasIssues,\n hasDiscussions: resources.hasDiscussions,\n hasReleases: resources.hasReleases,\n hasChangelog,\n docsType: resources.docsType,\n hasShippedDocs: shippedDocs,\n pkgFiles,\n repoUrl: resolved.repoUrl,\n features,\n eject: true,\n })\n\n const repoSlug = parseGitHubRepoSlug(resolved.repoUrl)\n if (agent) {\n const { shared } = installSkill({\n cwd,\n agent,\n global: false,\n baseDir,\n skillDirName,\n lock: {\n packageName,\n version,\n repo: repoSlug,\n source: resources.docSource,\n syncedAt: todayIsoDate(),\n generator: 'skilld',\n },\n })\n await ensureProjectFiles({ cwd, agent, global: false, shared })\n }\n else {\n // No agent — write lockfile but skip agent linking; ensure gitignore for fallback dir\n writeLock(baseDir, skillDirName, {\n packageName,\n version,\n repo: repoSlug,\n source: resources.docSource,\n syncedAt: todayIsoDate(),\n generator: 'skilld',\n })\n await ensureGitignore('.claude/skills', cwd, false)\n }\n\n const relDir = relative(cwd, skillDir)\n const sectionList = [...prompts.keys()]\n p.log.success(`Skill installed to ${relDir}`)\n\n // Show agent prompt the user can copy-paste\n const promptFiles = sectionList.map(s => `PROMPT_${s}.md`).join(', ')\n const outputFileList = sectionList.map(s => SECTION_OUTPUT_FILES[s]).join(', ')\n p.log.info(`Have your agent enhance the skill. Give it this prompt:\\n\\x1B[2m\\x1B[3m Read each prompt file (${promptFiles}) in ${relDir}/, read the\\n referenced files, then write your output to the matching file (${outputFileList}).\\n When done, run: skilld assemble\\x1B[0m`)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sync.mjs","names":["resolvePath"],"sources":["../../src/commands/sync/resolvers.ts","../../src/commands/sync/phases.ts","../../src/commands/sync/run.ts","../../src/commands/sync/ui/clack.ts","../../src/commands/sync/ui/parallel.ts","../../src/commands/sync-parallel.ts","../../src/commands/sync/merge.ts","../../src/commands/sync.ts"],"sourcesContent":["/**\n * `PackageResolver` implementations: turn a spec into a `ResolvedSpec` (or\n * `UnresolvedSpec` with attempts / shipped fallback).\n */\n\nimport type { AgentType } from '../../agent/index.ts'\nimport type { ResolverOpts, ResolverResult } from './phases.ts'\nimport { handleShippedSkills } from '../../agent/skill-installer.ts'\nimport { resolveGitHubRepo } from '../../sources/github.ts'\nimport { resolvePackageOrCrate } from '../../sources/index.ts'\n\nexport type PackageResolver = (spec: string, opts: ResolverOpts) => Promise<ResolverResult>\n\nexport const npmResolver: PackageResolver = async (spec, opts) => {\n const resolution = await resolvePackageOrCrate(spec, {\n cwd: opts.cwd,\n onProgress: msg => opts.onProgress(`${spec}: ${msg}`),\n })\n const { isCrate, packageName, identityPackageName, storagePackageName, requestedTag, localVersion, attempts, registryVersion } = resolution\n\n if (!resolution.resolved) {\n const result: ResolverResult = {\n identityName: identityPackageName,\n attempts,\n registryVersion,\n }\n if (!isCrate) {\n const shippedVersion = localVersion || registryVersion || 'latest'\n const shipped = handleShippedSkills(packageName, shippedVersion, opts.cwd, opts.agent, opts.global)\n if (shipped)\n result.shipped = shipped.shipped\n }\n return result\n }\n\n const resolved = resolution.resolved\n const version = isCrate\n ? (resolved.version || requestedTag || 'latest')\n : (localVersion || resolved.version || 'latest')\n\n return {\n identityName: identityPackageName,\n storageName: storagePackageName,\n version,\n resolved,\n kind: isCrate ? 'crate' : 'npm',\n requestedTag,\n localVersion,\n }\n}\n\nexport function createGithubResolver(owner: string, repo: string): PackageResolver {\n return async (_spec, opts) => {\n const resolved = await resolveGitHubRepo(owner, repo, msg => opts.onProgress(msg))\n if (!resolved) {\n return {\n identityName: `${owner}-${repo}`,\n attempts: [{ source: 'github-meta', status: 'not-found', message: `Could not find docs for ${owner}/${repo}` }],\n }\n }\n const repoUrl = `https://github.com/${owner}/${repo}`\n const name = `${owner}-${repo}`\n return {\n identityName: name,\n storageName: name,\n version: resolved.version || 'main',\n resolved: { ...resolved, repoUrl },\n kind: 'github',\n }\n }\n}\n\nexport type { AgentType }\n","/**\n * Internal phase functions: `runBaseSync` (resolve → fetch → cache → write base\n * SKILL.md) and `runEnhancePhase` (LLM optimization → finalize). Both emit\n * hookable events instead of calling a UI surface directly.\n */\n\nimport type { Hookable } from 'hookable'\nimport type { AgentType, SkillSection } from '../../agent/index.ts'\nimport type { SkillContext } from '../../agent/skill-builder.ts'\nimport type { SkillInfo } from '../../core/lockfile.ts'\nimport type { ResolveAttempt, ResolvedPackage } from '../../sources/index.ts'\nimport type { LlmConfig, UpdateContext } from '../llm-prompts.ts'\nimport type { PackageResolver } from './resolvers.ts'\nimport type { SyncHooks } from './run.ts'\nimport { existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { join, relative, resolve as resolvePath } from 'pathe'\nimport { computeSkillDirName, getModelLabel, linkSkillToAgents, sanitizeName } from '../../agent/index.ts'\nimport { applyCachedSections, runSkillEnhancement, writeBaseSkill, writePromptFiles } from '../../agent/skill-builder.ts'\nimport { ensureProjectFiles, handleShippedSkills, installSkill, linkShippedToAgents, resolveBaseDir } from '../../agent/skill-installer.ts'\nimport { createReferenceCache } from '../../cache/index.ts'\nimport { getActiveFeatures } from '../../core/config.ts'\nimport { todayIsoDate } from '../../core/formatting.ts'\nimport { findSkillDirByPackage, parsePackageNames, readLock } from '../../core/lockfile.ts'\nimport { parseFrontmatter } from '../../core/markdown.ts'\nimport { getSharedSkillsDir } from '../../core/paths.ts'\nimport { parseGitHubRepoSlug } from '../../core/url.ts'\nimport { fetchPkgDist, isPrerelease } from '../../sources/index.ts'\nimport { buildSkillContext, fetchAndCacheResources, prepareSkillReferences } from './pipeline.ts'\n\nconst RATE_LIMIT_RE = /\\b429\\b|rate.?limit|exhausted.*capacity|quota.*reset/i\n\n/** Spec resolved into the facts every runner step needs. */\nexport interface ResolvedSpec {\n identityName: string\n storageName: string\n version: string\n resolved: ResolvedPackage\n kind: 'npm' | 'crate' | 'github'\n requestedTag?: string\n localVersion?: string\n}\n\n/** Resolution failure: caller decides whether to suggest, retry, or abort. */\nexport interface UnresolvedSpec {\n identityName: string\n shipped?: { skillName: string, skillDir: string }[]\n attempts: ResolveAttempt[]\n registryVersion?: string\n}\n\nexport type ResolverResult = ResolvedSpec | UnresolvedSpec\n\nexport interface ResolverOpts {\n cwd: string\n agent: AgentType\n global: boolean\n onProgress: (msg: string) => void\n}\n\n/** Result of `runBaseSync`. */\nexport type BaseSyncResult\n = | { kind: 'shipped' }\n | { kind: 'unresolved', unresolved: UnresolvedSpec }\n | { kind: 'merge-needed', state: MergeNeededState }\n | { kind: 'ready', state: ReadyState }\n\nexport interface MergeNeededState {\n identityName: string\n storageName: string\n version: string\n resolved: ResolvedPackage\n baseDir: string\n skillDir: string\n skillDirName: string\n existingLock: SkillInfo\n}\n\nexport interface ReadyState {\n ctx: SkillContext\n skillDir: string\n skillDirName: string\n baseDir: string\n updateCtx?: UpdateContext\n allSectionsCached: boolean\n identityName: string\n storageName: string\n version: string\n docsType: 'llms.txt' | 'readme' | 'docs'\n repoInfo?: { owner: string, repo: string }\n}\n\nexport interface RunBaseConfig {\n agent: AgentType\n global: boolean\n mode?: 'add' | 'update'\n force?: boolean\n noSearch?: boolean\n name?: string\n from?: string\n eject?: boolean | string\n}\n\n/** Phase 1: resolve → fetch → cache → install → write base SKILL.md. */\nexport async function runBaseSync(\n spec: string,\n config: RunBaseConfig,\n hooks: Hookable<SyncHooks>,\n resolver: PackageResolver,\n cwd: string,\n defaultSections: SkillSection[],\n): Promise<BaseSyncResult> {\n await hooks.callHook('resolve:start', { spec })\n\n const resolverResult = await resolver(spec, {\n cwd,\n agent: config.agent,\n global: config.global,\n onProgress: msg => hooks.callHook('resolve:progress', { spec, message: msg }),\n })\n\n if (!('resolved' in resolverResult)) {\n if (resolverResult.shipped && resolverResult.shipped.length > 0) {\n for (const s of resolverResult.shipped)\n await hooks.callHook('shipped:installed', { spec, skillName: s.skillName, skillDir: s.skillDir })\n return { kind: 'shipped' }\n }\n await hooks.callHook('resolve:failed', { spec, identityName: resolverResult.identityName, attempts: resolverResult.attempts })\n return { kind: 'unresolved', unresolved: resolverResult }\n }\n\n const { identityName, storageName, version, resolved, kind, requestedTag, localVersion } = resolverResult\n const cache = createReferenceCache(storageName, version)\n\n if (config.force)\n cache.clearForce()\n\n const useCache = cache.has()\n\n if (kind !== 'crate' && !existsSync(join(cwd, 'node_modules', identityName))) {\n await hooks.callHook('dist:downloading', { spec })\n await fetchPkgDist(identityName, version)\n }\n\n if (kind !== 'crate') {\n const shipped = handleShippedSkills(identityName, version, cwd, config.agent, config.global)\n if (shipped) {\n linkShippedToAgents(shipped.shipped, cwd, config.agent, config.global)\n for (const s of shipped.shipped)\n await hooks.callHook('shipped:installed', { spec, skillName: s.skillName, skillDir: s.skillDir })\n return { kind: 'shipped' }\n }\n }\n\n await hooks.callHook('resolve:done', { spec, version, cached: useCache, force: config.force })\n\n if (kind === 'npm' && !localVersion && !requestedTag && !isPrerelease(version)) {\n const nextTag = resolved.distTags?.next ?? resolved.distTags?.beta ?? resolved.distTags?.alpha\n if (nextTag && (!resolved.releasedAt || !nextTag.releasedAt || nextTag.releasedAt > resolved.releasedAt))\n await hooks.callHook('warn', { spec, message: `No local dependency found — using latest stable (${version}). Prerelease ${nextTag.version} available: skilld add ${identityName}@beta` })\n }\n\n cache.ensure()\n\n const isEject = !!config.eject\n const baseDir = resolveBaseDir(cwd, config.agent, config.global)\n let skillDirName = config.name ? sanitizeName(config.name) : computeSkillDirName(storageName)\n if (config.mode === 'update' && !config.name && !isEject) {\n const lock = readLock(baseDir)\n const found = lock ? findSkillDirByPackage(lock, identityName) : null\n if (found)\n skillDirName = found\n }\n const skillDir = isEject\n ? typeof config.eject === 'string'\n ? join(resolvePath(cwd, config.eject), skillDirName)\n : join(cwd, 'skills', skillDirName)\n : join(baseDir, skillDirName)\n mkdirSync(skillDir, { recursive: true })\n\n const existingLock = isEject ? undefined : readLock(baseDir)?.skills[skillDirName]\n if (existingLock && existingLock.packageName && existingLock.packageName !== identityName) {\n return {\n kind: 'merge-needed',\n state: {\n identityName,\n storageName,\n version,\n resolved,\n baseDir,\n skillDir,\n skillDirName,\n existingLock,\n },\n }\n }\n const updateCtx: UpdateContext | undefined = config.mode === 'update' && existingLock\n ? {\n oldVersion: existingLock.version,\n newVersion: version,\n syncedAt: existingLock.syncedAt,\n wasEnhanced: (() => {\n const skillMdPath = join(skillDir, 'SKILL.md')\n if (!existsSync(skillMdPath))\n return false\n const fm = parseFrontmatter(readFileSync(skillMdPath, 'utf-8'))\n return !!fm.generated_by\n })(),\n }\n : undefined\n\n const features = getActiveFeatures(config.noSearch ? { search: false } : undefined)\n\n await hooks.callHook('fetch:start', { spec })\n const resources = await fetchAndCacheResources({\n packageName: storageName,\n resolved,\n version,\n useCache,\n features,\n from: config.from,\n onProgress: msg => hooks.callHook('fetch:progress', { spec, message: msg }),\n })\n const parts: string[] = []\n if (resources.docsToIndex.length > 0) {\n const docCount = resources.docsToIndex.filter(d => d.metadata?.type === 'doc').length\n if (docCount > 0)\n parts.push(`${docCount} docs`)\n }\n if (resources.hasIssues)\n parts.push('issues')\n if (resources.hasDiscussions)\n parts.push('discussions')\n if (resources.hasReleases)\n parts.push('releases')\n await hooks.callHook('fetch:done', { spec, parts, cached: resources.usedCache })\n for (const w of resources.warnings)\n await hooks.callHook('warn', { spec, message: w })\n\n if (features.search)\n await hooks.callHook('index:start', { spec })\n const prepared = await prepareSkillReferences({\n packageName: storageName,\n version,\n cwd,\n skillDir,\n resources,\n features,\n baseDir,\n onIndexProgress: msg => hooks.callHook('index:progress', { spec, message: msg }),\n })\n if (features.search)\n await hooks.callHook('index:done', { spec })\n\n if (!isEject) {\n const repoSlug = parseGitHubRepoSlug(resolved.repoUrl)\n cache.linkPkgNamed(skillDir, cwd)\n const lock: SkillInfo = {\n packageName: identityName,\n version,\n repo: repoSlug,\n source: resources.docSource,\n syncedAt: todayIsoDate(),\n generator: 'skilld',\n }\n installSkill({\n cwd,\n agent: config.agent,\n global: config.global,\n baseDir,\n skillDirName,\n lock,\n dedupePackageName: identityName,\n skipLinkAgents: true,\n })\n }\n\n const updatedLock = isEject ? undefined : readLock(baseDir)?.skills[skillDirName]\n const allPackages = parsePackageNames(updatedLock?.packages)\n\n const ctx = buildSkillContext({\n packageName: identityName,\n cachePackageName: storageName,\n version,\n skillDir,\n skillDirName,\n resources,\n prepared,\n resolved,\n packages: allPackages,\n features,\n })\n\n const baseSkillMd = writeBaseSkill(ctx, { eject: isEject })\n ctx.overheadLines = baseSkillMd.split('\\n').length\n await hooks.callHook('base:done', { spec, skillDir: relative(cwd, skillDir), mode: config.mode === 'update' ? 'update' : 'add' })\n\n const allSectionsCached = !config.force && applyCachedSections(ctx, defaultSections, { eject: isEject })\n if (allSectionsCached)\n await hooks.callHook('sections:cached', { spec })\n\n return {\n kind: 'ready',\n state: {\n ctx,\n skillDir,\n skillDirName,\n baseDir,\n updateCtx,\n allSectionsCached,\n identityName,\n storageName,\n version,\n docsType: resources.docsType,\n repoInfo: resources.repoInfo,\n },\n }\n}\n\nexport interface RunEnhanceConfig {\n agent: AgentType\n global: boolean\n force?: boolean\n debug?: boolean\n eject?: boolean | string\n}\n\n/** Phase 2: enhance with LLM (or write prompt files), then finalize. */\nexport async function runEnhancePhase(\n state: ReadyState,\n llmConfig: LlmConfig | null,\n config: RunEnhanceConfig,\n hooks: Hookable<SyncHooks>,\n cwd: string,\n): Promise<void> {\n const isEject = !!config.eject\n const spec = state.identityName\n\n if (llmConfig?.promptOnly) {\n writePromptFiles(\n { ...state.ctx, packageName: state.ctx.cachePackageName ?? state.ctx.packageName, cachePackageName: undefined },\n { sections: llmConfig.sections, customPrompt: llmConfig.customPrompt },\n )\n }\n else if (llmConfig) {\n await enhanceWithHooks(state.ctx, llmConfig, { ...config, eject: isEject }, hooks, spec)\n }\n\n if (isEject) {\n const cache = createReferenceCache(state.storageName, state.version)\n if (!config.debug)\n cache.clearSkillInternal(state.skillDir)\n cache.eject(state.skillDir, cwd, state.docsType, {\n features: state.ctx.features ?? getActiveFeatures(),\n repoInfo: state.repoInfo,\n })\n return\n }\n\n const shared: string | false = config.global ? false : (getSharedSkillsDir(cwd) ?? false)\n if (shared)\n linkSkillToAgents(state.skillDirName, shared, cwd, config.agent)\n\n await ensureProjectFiles({ cwd, agent: config.agent, global: config.global, shared })\n}\n\nasync function enhanceWithHooks(\n ctx: SkillContext,\n llmConfig: LlmConfig,\n config: RunEnhanceConfig,\n hooks: Hookable<SyncHooks>,\n spec: string,\n): Promise<void> {\n await hooks.callHook('enhance:start', { spec, modelLabel: getModelLabel(llmConfig.model) })\n const result = await runSkillEnhancement(\n ctx,\n {\n model: llmConfig.model,\n force: config.force,\n debug: config.debug,\n sections: llmConfig.sections,\n customPrompt: llmConfig.customPrompt,\n eject: !!config.eject,\n },\n progress => hooks.callHook('enhance:progress', { spec, progress }),\n )\n\n if (result.wasOptimized) {\n await hooks.callHook('enhance:done', {\n spec,\n usage: result.usage ? { totalTokens: result.usage.totalTokens } : undefined,\n cost: result.cost,\n debugLogsDir: result.debugLogsDir,\n error: result.error,\n warnings: result.warnings,\n })\n }\n else {\n await hooks.callHook('enhance:failed', {\n spec,\n error: result.error ?? '',\n rateLimited: !!result.error && RATE_LIMIT_RE.test(result.error),\n })\n }\n}\n\nexport type { CustomPrompt, OptimizeModel, SkillSection } from '../../agent/index.ts'\n","/**\n * Unified sync run factory.\n *\n * Owns orchestration for sync flows. Frontends supply:\n * - a `PackageResolver` (npm/crate/github)\n * - hook bindings (UI surfaces: clack, parallel logUpdate, etc.)\n *\n * Hooks fire for every observable phase: resolve, fetch, index, base,\n * sections-cached, enhance, shipped, warn. Each payload carries `spec`\n * so a single hook bus handles concurrent specs.\n */\n\nimport type { Hookable } from 'hookable'\nimport type { OptimizeModel, SkillSection, StreamProgress } from '../../agent/index.ts'\nimport type { ResolveAttempt } from '../../sources/index.ts'\nimport type { LlmConfig } from '../llm-prompts.ts'\nimport type { ReadyState } from './phases.ts'\nimport type { PackageResolver } from './resolvers.ts'\nimport { createHooks } from 'hookable'\nimport pLimit from 'p-limit'\nimport { runBaseSync, runEnhancePhase } from './phases.ts'\n\nexport interface EnhanceDoneInfo {\n usage?: { totalTokens: number }\n cost?: number\n debugLogsDir?: string\n error?: string\n warnings?: string[]\n}\n\nexport interface SyncHooks {\n 'resolve:start': (info: { spec: string }) => void\n 'resolve:progress': (info: { spec: string, message: string }) => void\n 'resolve:done': (info: { spec: string, version: string, cached: boolean, force?: boolean }) => void\n 'resolve:failed': (info: { spec: string, identityName: string, attempts: ResolveAttempt[] }) => void\n 'dist:downloading': (info: { spec: string }) => void\n 'fetch:start': (info: { spec: string }) => void\n 'fetch:progress': (info: { spec: string, message: string }) => void\n 'fetch:done': (info: { spec: string, parts: string[], cached: boolean }) => void\n 'index:start': (info: { spec: string }) => void\n 'index:progress': (info: { spec: string, message: string }) => void\n 'index:done': (info: { spec: string }) => void\n 'base:done': (info: { spec: string, skillDir: string, mode: 'add' | 'update' }) => void\n 'sections:cached': (info: { spec: string }) => void\n 'enhance:start': (info: { spec: string, modelLabel: string }) => void\n 'enhance:progress': (info: { spec: string, progress: StreamProgress }) => void\n 'enhance:done': (info: { spec: string } & EnhanceDoneInfo) => void\n 'enhance:failed': (info: { spec: string, error: string, rateLimited: boolean }) => void\n 'shipped:installed': (info: { spec: string, skillName: string, skillDir: string }) => void\n 'warn': (info: { spec?: string, message: string }) => void\n}\n\nexport interface CreateSyncRunOptions {\n cwd: string\n resolver: PackageResolver\n agent: import('../../agent/index.ts').AgentType\n global: boolean\n mode?: 'add' | 'update'\n force?: boolean\n noSearch?: boolean\n name?: string\n from?: string\n debug?: boolean\n eject?: boolean | string\n defaultSections: SkillSection[]\n /**\n * LLM config resolver. Called once when the first ready state arrives\n * (sequential) or once for the whole batch (parallel) with the\n * aggregated update context. Return `null` to skip enhancement.\n */\n resolveLlmConfig?: (info: { ready: ReadonlyArray<{ spec: string, state: ReadyState }> }) => Promise<LlmConfig | null> | LlmConfig | null\n /**\n * Called when a merge-needed state is hit. Sequential frontends supply\n * a handler that regenerates SKILL.md; parallel frontends pass undefined\n * and the run reports the spec as an error.\n */\n onMergeNeeded?: (state: import('./phases.ts').MergeNeededState) => Promise<void>\n}\n\nexport type RunOutcome\n = | { kind: 'shipped', spec: string }\n | { kind: 'unresolved', spec: string, identityName: string, attempts: ResolveAttempt[] }\n | { kind: 'merged', spec: string }\n | { kind: 'ready', spec: string, state: ReadyState }\n | { kind: 'enhanced', spec: string, state: ReadyState }\n | { kind: 'error', spec: string, reason: string }\n\nexport interface SyncRun {\n hooks: Hookable<SyncHooks>\n /** Phase 1 only: resolve + fetch + write base skill. Returns outcome (no enhance). */\n runBase: (spec: string) => Promise<RunOutcome>\n /** Phase 2: enhance via LLM and finalize. */\n runEnhance: (state: ReadyState, llmConfig: LlmConfig | null) => Promise<void>\n /** Full pipeline for a single spec: base + (per-spec llm prompt) + enhance. */\n run: (spec: string) => Promise<RunOutcome>\n /** Parallel base sync over many specs; returns per-spec outcomes. */\n runMany: (specs: string[], opts?: { concurrency?: number }) => Promise<RunOutcome[]>\n}\n\nexport function createSyncRun(opts: CreateSyncRunOptions): SyncRun {\n const hooks = createHooks<SyncHooks>()\n\n async function runBase(spec: string): Promise<RunOutcome> {\n const result = await runBaseSync(\n spec,\n {\n agent: opts.agent,\n global: opts.global,\n mode: opts.mode,\n force: opts.force,\n noSearch: opts.noSearch,\n name: opts.name,\n from: opts.from,\n eject: opts.eject,\n },\n hooks,\n opts.resolver,\n opts.cwd,\n opts.defaultSections,\n )\n\n if (result.kind === 'shipped')\n return { kind: 'shipped', spec }\n if (result.kind === 'unresolved') {\n return {\n kind: 'unresolved',\n spec,\n identityName: result.unresolved.identityName,\n attempts: result.unresolved.attempts,\n }\n }\n if (result.kind === 'merge-needed') {\n if (opts.onMergeNeeded) {\n await opts.onMergeNeeded(result.state)\n return { kind: 'merged', spec }\n }\n return {\n kind: 'error',\n spec,\n reason: `Skill dir already holds ${result.state.existingLock.packageName} — run sequentially to merge`,\n }\n }\n return { kind: 'ready', spec, state: result.state }\n }\n\n async function runEnhance(state: ReadyState, llmConfig: LlmConfig | null): Promise<void> {\n await runEnhancePhase(\n state,\n llmConfig,\n {\n agent: opts.agent,\n global: opts.global,\n force: opts.force,\n debug: opts.debug,\n eject: opts.eject,\n },\n hooks,\n opts.cwd,\n )\n }\n\n async function run(spec: string): Promise<RunOutcome> {\n const base = await runBase(spec)\n if (base.kind !== 'ready')\n return base\n\n let llmConfig: LlmConfig | null = null\n if (!base.state.allSectionsCached && opts.resolveLlmConfig)\n llmConfig = await opts.resolveLlmConfig({ ready: [{ spec, state: base.state }] }) ?? null\n\n await runEnhance(base.state, llmConfig)\n return { kind: 'enhanced', spec, state: base.state }\n }\n\n async function runMany(specs: string[], runOpts?: { concurrency?: number }): Promise<RunOutcome[]> {\n const limit = pLimit(runOpts?.concurrency ?? 5)\n const results = await Promise.allSettled(specs.map(spec => limit(() => runBase(spec))))\n return results.map((r, i): RunOutcome =>\n r.status === 'fulfilled'\n ? r.value\n : { kind: 'error', spec: specs[i]!, reason: r.reason instanceof Error ? r.reason.message : String(r.reason) },\n )\n }\n\n return { hooks, runBase, runEnhance, run, runMany }\n}\n\nexport type { OptimizeModel }\n","/**\n * Sequential clack-based UI binder. Subscribes a fresh spinner/taskLog set\n * to the sync hook bus. Used by single-package sync flows.\n */\n\nimport type { Hookable } from 'hookable'\nimport type { SyncHooks } from '../run.ts'\nimport { styleText } from 'node:util'\nimport * as p from '@clack/prompts'\nimport { relative } from 'pathe'\nimport { timedSpinner } from '../../../core/formatting.ts'\n\nexport interface ClackUiOptions {\n cwd: string\n}\n\nexport function bindClackUi(hooks: Hookable<SyncHooks>, { cwd }: ClackUiOptions): void {\n let spinner: ReturnType<typeof timedSpinner> | null = null\n let resourceSpinner: ReturnType<typeof timedSpinner> | null = null\n let indexSpinner: ReturnType<typeof timedSpinner> | null = null\n let llmLog: ReturnType<typeof p.taskLog> | null = null\n let currentSpec = ''\n\n hooks.hook('resolve:start', ({ spec }) => {\n currentSpec = spec\n spinner = timedSpinner()\n spinner.start(`Resolving ${spec}`)\n })\n hooks.hook('resolve:progress', ({ message }) => {\n spinner?.message(message)\n })\n hooks.hook('resolve:done', ({ version, cached, force }) => {\n const suffix = force ? ' (force)' : cached ? ' (cached)' : ''\n spinner?.stop(`Resolved ${currentSpec}@${version}${suffix}`)\n spinner = null\n })\n hooks.hook('resolve:failed', ({ identityName }) => {\n spinner?.stop(`Could not find docs for: ${identityName}`)\n spinner = null\n })\n hooks.hook('dist:downloading', () => {\n spinner?.message('Downloading dist')\n })\n hooks.hook('fetch:start', () => {\n resourceSpinner = timedSpinner()\n resourceSpinner.start('Finding resources')\n })\n hooks.hook('fetch:progress', ({ message }) => {\n resourceSpinner?.message(message)\n })\n hooks.hook('fetch:done', ({ parts, cached }) => {\n const summary = parts.length > 0 ? parts.join(', ') : 'resources'\n resourceSpinner?.stop(cached ? `Loaded ${summary} (cached)` : `Fetched ${summary}`)\n resourceSpinner = null\n })\n hooks.hook('index:start', () => {\n indexSpinner = timedSpinner()\n indexSpinner.start('Creating search index')\n })\n hooks.hook('index:progress', ({ message }) => {\n indexSpinner?.message(message)\n })\n hooks.hook('index:done', () => {\n indexSpinner?.stop('Search index ready')\n indexSpinner = null\n })\n hooks.hook('warn', ({ message }) => {\n p.log.warn(styleText('yellow', message))\n })\n hooks.hook('base:done', ({ skillDir, mode }) => {\n p.log.success(mode === 'update' ? `Updated skill: ${skillDir}` : `Created base skill: ${skillDir}`)\n })\n hooks.hook('sections:cached', () => {\n p.log.success('Applied cached SKILL.md sections')\n })\n hooks.hook('enhance:start', ({ spec, modelLabel }) => {\n currentSpec = spec\n p.log.step(modelLabel)\n llmLog = p.taskLog({ title: `Agent exploring ${spec}`, limit: 3 })\n })\n hooks.hook('enhance:progress', ({ progress }) => {\n if (!llmLog)\n return\n const sectionPrefix = progress.section ? `[${progress.section}] ` : ''\n const line = `${sectionPrefix}${progress.chunk}`\n llmLog.message(line)\n })\n hooks.hook('enhance:done', (info) => {\n if (!llmLog)\n return\n const parts: string[] = []\n if (info.usage)\n parts.push(`${Math.round(info.usage.totalTokens / 1000)}k tokens`)\n if (info.cost)\n parts.push(`$${info.cost.toFixed(2)}`)\n const suffix = parts.length > 0 ? ` (${parts.join(', ')})` : ''\n llmLog.success(`Generated best practices${suffix}`)\n llmLog = null\n if (info.debugLogsDir)\n p.log.info(`Debug logs: ${relative(cwd, info.debugLogsDir)}`)\n if (info.error)\n p.log.warn(styleText('yellow', `Partial failure: ${info.error}`))\n if (info.warnings) {\n for (const w of info.warnings)\n p.log.warn(styleText('yellow', w))\n }\n })\n hooks.hook('enhance:failed', ({ error, rateLimited }) => {\n if (!llmLog)\n return\n if (rateLimited)\n llmLog.error(`Rate limited by LLM provider. Try again shortly or use a different model via \\`skilld config\\``)\n else\n llmLog.error(`Enhancement failed${error ? `: ${error}` : ''}`)\n llmLog = null\n })\n hooks.hook('shipped:installed', ({ skillName, skillDir }) => {\n p.log.success(`Using published SKILL.md: ${skillName} → ${relative(cwd, skillDir)}`)\n })\n}\n","/**\n * Parallel logUpdate UI binder. Subscribes to a shared state map (keyed by\n * spec) and re-renders the full table on each event.\n */\n\nimport type { Hookable } from 'hookable'\nimport type { SyncHooks } from '../run.ts'\nimport { styleText } from 'node:util'\nimport logUpdate from 'log-update'\nimport { formatDuration } from '../../../core/formatting.ts'\n\nexport type PackageStatus = 'pending' | 'resolving' | 'downloading' | 'embedding' | 'exploring' | 'thinking' | 'generating' | 'done' | 'error'\n\nexport interface PackageState {\n name: string\n status: PackageStatus\n message: string\n version?: string\n streamPreview?: string\n startedAt?: number\n completedAt?: number\n}\n\nconst STATUS_ICONS: Record<PackageStatus, string> = {\n pending: '○',\n resolving: '◐',\n downloading: '◒',\n embedding: '◓',\n exploring: '◔',\n thinking: '◔',\n generating: '◑',\n done: '✓',\n error: '✗',\n}\n\ntype StyleColor = Parameters<typeof styleText>[0]\nconst STATUS_COLORS: Record<PackageStatus, StyleColor> = {\n pending: 'gray',\n resolving: 'cyan',\n downloading: 'cyan',\n embedding: 'cyan',\n exploring: 'blue',\n thinking: 'magenta',\n generating: 'yellow',\n done: 'green',\n error: 'red',\n}\n\nexport interface ParallelRender {\n states: Map<string, PackageState>\n verb: string\n total: number\n}\n\nexport function renderParallel(r: ParallelRender): void {\n const maxNameLen = Math.max(...[...r.states.keys()].map(n => n.length), 20)\n const lines = [...r.states.values()].map((s) => {\n const icon = styleText(STATUS_COLORS[s.status], STATUS_ICONS[s.status])\n const name = s.name.padEnd(maxNameLen)\n const version = s.version ? `${styleText('gray', s.version)} ` : ''\n const elapsed = (s.status === 'done' || s.status === 'error') && s.startedAt && s.completedAt\n ? ` ${styleText('gray', `(${formatDuration(s.completedAt - s.startedAt)})`)}`\n : ''\n const preview = s.streamPreview ? ` ${styleText('gray', s.streamPreview)}` : ''\n return ` ${icon} ${name} ${version}${s.message}${elapsed}${preview}`\n })\n\n const doneCount = [...r.states.values()].filter(s => s.status === 'done').length\n const errorCount = [...r.states.values()].filter(s => s.status === 'error').length\n const header = `${styleText('bold', `${r.verb} ${r.total} packages`)} (${doneCount} done${errorCount > 0 ? `, ${errorCount} failed` : ''})\\n`\n\n logUpdate(header + lines.join('\\n'))\n}\n\n/**\n * Subscribe the parallel renderer to the hook bus. Each event mutates the\n * slot for `spec` and triggers a full re-render.\n */\nexport function bindParallelUi(hooks: Hookable<SyncHooks>, render: ParallelRender): void {\n function update(spec: string, status: PackageStatus, message: string, ver?: string): void {\n const state = render.states.get(spec)\n if (!state)\n return\n if (!state.startedAt && status !== 'pending')\n state.startedAt = performance.now()\n if ((status === 'done' || status === 'error') && !state.completedAt)\n state.completedAt = performance.now()\n state.status = status\n state.message = message\n state.streamPreview = undefined\n if (ver)\n state.version = ver\n renderParallel(render)\n }\n\n hooks.hook('resolve:start', ({ spec }) => update(spec, 'resolving', 'Resolving...'))\n hooks.hook('resolve:progress', ({ spec, message }) => update(spec, 'resolving', message))\n hooks.hook('resolve:done', ({ spec, version, cached, force }) => {\n update(spec, 'downloading', cached ? 'Using cache' : force ? 'Re-fetching docs...' : 'Fetching docs...', version)\n })\n hooks.hook('resolve:failed', () => {\n // No-op: frontend sets error with reason via outcome\n })\n hooks.hook('dist:downloading', ({ spec }) => update(spec, 'downloading', 'Downloading dist...'))\n hooks.hook('fetch:start', () => {\n // Already in 'downloading'\n })\n hooks.hook('fetch:progress', ({ spec, message }) => update(spec, 'downloading', message))\n hooks.hook('fetch:done', ({ spec }) => update(spec, 'downloading', 'Linking references...'))\n hooks.hook('index:start', ({ spec }) => update(spec, 'embedding', 'Indexing docs'))\n hooks.hook('index:progress', ({ spec, message }) => update(spec, 'embedding', message))\n hooks.hook('index:done', () => {\n // Stay embedding until base:done\n })\n hooks.hook('warn', () => {\n // Warnings surfaced after parallel render completes\n })\n hooks.hook('base:done', ({ spec, mode }) => {\n update(spec, 'done', mode === 'update' ? 'Skill updated' : 'Base skill created')\n })\n hooks.hook('sections:cached', () => {\n // Frontend logs aggregate \"Applied cached...\" line\n })\n hooks.hook('enhance:start', ({ spec, modelLabel }) => update(spec, 'generating', modelLabel))\n hooks.hook('enhance:progress', ({ spec, progress }) => {\n const isReasoning = progress.type === 'reasoning'\n const status: PackageStatus = isReasoning ? 'exploring' : 'generating'\n const sectionPrefix = progress.section ? `[${progress.section}] ` : ''\n update(spec, status, `${sectionPrefix}${progress.chunk}`)\n })\n hooks.hook('enhance:done', ({ spec }) => update(spec, 'done', 'Skill optimized'))\n hooks.hook('enhance:failed', ({ spec, error }) => update(spec, 'error', error))\n hooks.hook('shipped:installed', ({ spec }) => update(spec, 'done', 'Published SKILL.md'))\n}\n","/**\n * Parallel sync orchestrator. Two phased waves:\n * 1. base sync per pkg (pLimited) — fetch, cache, write base SKILL.md\n * 2. LLM enhancement per pkg (pLimited)\n *\n * Both waves use `createSyncRun()` with a parallel UI binder. State map is\n * keyed by raw spec to match hook payloads.\n */\n\nimport type { AgentType, OptimizeModel } from '../agent/index.ts'\nimport type { ReadyState } from './sync/phases.ts'\nimport type { PackageState, ParallelRender } from './sync/ui/parallel.ts'\nimport { styleText } from 'node:util'\nimport * as p from '@clack/prompts'\nimport logUpdate from 'log-update'\nimport pLimit from 'p-limit'\nimport { getModelLabel } from '../agent/index.ts'\nimport { ensureProjectFiles } from '../agent/skill-installer.ts'\nimport { ensureCacheDir, getVersionKey } from '../cache/index.ts'\nimport { readConfig } from '../core/config.ts'\nimport { semverDiff } from '../core/semver.ts'\nimport { parsePackageSpec } from '../core/url.ts'\nimport { shutdownWorker } from '../retriv/pool.ts'\nimport { searchNpmPackages } from '../sources/index.ts'\nimport { DEFAULT_SECTIONS, resolveAutoModel, selectLlmConfig } from './llm-prompts.ts'\nimport { npmResolver } from './sync/resolvers.ts'\nimport { createSyncRun } from './sync/run.ts'\nimport { bindParallelUi, renderParallel } from './sync/ui/parallel.ts'\n\nexport interface ParallelSyncConfig {\n packages: string[]\n global: boolean\n agent: AgentType\n model?: OptimizeModel\n yes?: boolean\n force?: boolean\n debug?: boolean\n concurrency?: number\n mode?: 'add' | 'update'\n}\n\nconst DIFF_RANK: Record<string, number> = {\n major: 5,\n premajor: 4,\n minor: 3,\n preminor: 2,\n patch: 1,\n prepatch: 1,\n prerelease: 0,\n}\n\nexport async function syncPackagesParallel(config: ParallelSyncConfig): Promise<void> {\n const { packages, concurrency = 5 } = config\n const cwd = process.cwd()\n\n // State map keyed by display name (matches the original behavior where\n // parsePackageSpec(spec).name was used as the slot key).\n const states = new Map<string, PackageState>()\n const specToName = new Map<string, string>()\n for (const spec of packages) {\n const { name } = parsePackageSpec(spec)\n specToName.set(spec, name)\n states.set(spec, { name, status: 'pending', message: 'Waiting...' })\n }\n\n const render: ParallelRender = {\n states,\n verb: config.mode === 'update' ? 'Updating' : 'Syncing',\n total: packages.length,\n }\n\n ensureCacheDir()\n renderParallel(render)\n\n const run = createSyncRun({\n cwd,\n resolver: npmResolver,\n agent: config.agent,\n global: config.global,\n mode: config.mode,\n force: config.force,\n debug: config.debug,\n defaultSections: DEFAULT_SECTIONS,\n })\n bindParallelUi(run.hooks, render)\n\n // ── Wave 1: base sync per pkg ──\n const limit = pLimit(concurrency)\n const baseResults = await Promise.allSettled(\n packages.map(spec => limit(() => run.runBase(spec))),\n )\n\n logUpdate.done()\n\n const ready: Array<{ spec: string, state: ReadyState }> = []\n const shippedCount: string[] = []\n const errors: Array<{ spec: string, reason: string }> = []\n const aggregatedWarnings: string[] = []\n\n for (let i = 0; i < baseResults.length; i++) {\n const spec = packages[i]!\n const r = baseResults[i]!\n if (r.status === 'rejected') {\n const err = r.reason\n const reason = err instanceof Error ? err.message : String(err)\n const slot = states.get(spec)\n if (slot)\n slot.status = 'error'\n errors.push({ spec, reason })\n continue\n }\n const result = r.value\n if (result.kind === 'shipped') {\n shippedCount.push(spec)\n continue\n }\n if (result.kind === 'unresolved') {\n const npmAttempt = result.attempts.find(a => a.source === 'npm')\n let reason: string\n if (npmAttempt?.status === 'not-found') {\n const suggestions = await searchNpmPackages(result.identityName, 3)\n const hint = suggestions.length > 0 ? ` (try: ${suggestions.map(s => s.name).join(', ')})` : ''\n reason = (npmAttempt.message || 'Not on npm') + hint\n }\n else {\n const failed = result.attempts.filter(a => a.status !== 'success')\n reason = failed.map(a => a.message || a.source).join('; ') || 'No docs found'\n }\n const slot = states.get(spec)\n if (slot) {\n slot.status = 'error'\n slot.message = reason\n }\n errors.push({ spec, reason })\n continue\n }\n if (result.kind === 'error') {\n errors.push({ spec, reason: result.reason })\n continue\n }\n if (result.kind === 'ready')\n ready.push({ spec, state: result.state })\n }\n\n renderParallel(render)\n logUpdate.done()\n\n const pastVerb = config.mode === 'update' ? 'Updated' : 'Created'\n p.log.success(`${pastVerb} ${ready.length} base skills${shippedCount.length > 0 ? ` (${shippedCount.length} shipped)` : ''}`)\n\n for (const w of aggregatedWarnings)\n p.log.warn(styleText('yellow', w))\n for (const { spec, reason } of errors)\n p.log.error(` ${spec}: ${reason}`)\n\n const cachedPkgs: string[] = []\n const uncached: typeof ready = []\n for (const r of ready) {\n if (r.state.allSectionsCached)\n cachedPkgs.push(r.spec)\n else\n uncached.push(r)\n }\n if (cachedPkgs.length > 0)\n p.log.success(`Applied cached SKILL.md sections for ${cachedPkgs.join(', ')}`)\n\n // ── Wave 2: LLM enhancement ──\n const globalConfig = readConfig()\n const resolvedModel = await resolveAutoModel(config.model, config.yes)\n const shouldAskLlm = uncached.length > 0 && !globalConfig.skipLlm && !(config.yes && !resolvedModel)\n\n if (shouldAskLlm) {\n const updateCtx = config.mode === 'update' ? aggregateUpdateCtx(uncached) : undefined\n const llmConfig = await selectLlmConfig(resolvedModel, undefined, updateCtx)\n\n if (llmConfig?.promptOnly) {\n for (const r of uncached) {\n const slot = states.get(r.spec)\n if (slot) {\n slot.status = 'done'\n slot.message = 'Prompts written'\n }\n }\n renderParallel(render)\n for (const r of uncached)\n await run.runEnhance(r.state, llmConfig)\n }\n else if (llmConfig) {\n p.log.step(getModelLabel(llmConfig.model))\n for (const r of uncached) {\n const displayName = specToName.get(r.spec) ?? r.spec\n states.set(r.spec, { name: displayName, status: 'pending', message: 'Waiting...', version: getVersionKey(r.state.version) })\n }\n renderParallel(render)\n\n const llmResults = await Promise.allSettled(\n uncached.map(r => limit(() => run.runEnhance(r.state, llmConfig))),\n )\n\n logUpdate.done()\n const llmSucceeded = llmResults.filter(x => x.status === 'fulfilled').length\n p.log.success(`Enhanced ${llmSucceeded}/${uncached.length} skills with LLM`)\n }\n }\n else {\n for (const r of ready)\n await run.runEnhance(r.state, null)\n }\n\n await ensureProjectFiles({ cwd, agent: config.agent, global: config.global })\n\n await shutdownWorker()\n\n p.outro(`${pastVerb} ${ready.length}/${packages.length} packages`)\n\n const { suggestPrepareHook } = await import('../cli/prepare-hook.ts')\n try {\n await suggestPrepareHook(cwd)\n }\n catch (err) {\n p.log.warn(`Failed to suggest prepare hook: ${err instanceof Error ? err.message : String(err)}`)\n }\n}\n\nfunction aggregateUpdateCtx(ready: Array<{ state: ReadyState }>): import('./llm-prompts.ts').UpdateContext {\n let maxDiff = ''\n let allEnhanced = true\n let anySyncedAt: string | undefined\n for (const r of ready) {\n const u = r.state.updateCtx\n if (!u?.wasEnhanced)\n allEnhanced = false\n if (u?.syncedAt && (!anySyncedAt || u.syncedAt < anySyncedAt))\n anySyncedAt = u.syncedAt\n if (u?.oldVersion && u.newVersion) {\n const diff = semverDiff(u.oldVersion, u.newVersion)\n if (diff && (DIFF_RANK[diff] ?? 0) > (DIFF_RANK[maxDiff] ?? -1))\n maxDiff = diff\n }\n }\n const first = ready[0]?.state.updateCtx\n return {\n oldVersion: ready.length === 1 ? first?.oldVersion : undefined,\n newVersion: ready.length === 1 ? first?.newVersion : undefined,\n syncedAt: anySyncedAt,\n wasEnhanced: allEnhanced,\n bumpType: maxDiff || undefined,\n }\n}\n","/**\n * Merge mode — when a skill dir already holds a different primary package,\n * runBaseSync returns `merge-needed` and we regenerate SKILL.md combining\n * the existing primary with the new package. Sequential only.\n */\n\nimport type { AgentType } from '../../agent/index.ts'\nimport type { MergeNeededState } from './phases.ts'\nimport { existsSync } from 'node:fs'\nimport * as p from '@clack/prompts'\nimport { linkSkillToAgents, writeGeneratedSkillMd } from '../../agent/index.ts'\nimport { installSkill } from '../../agent/skill-installer.ts'\nimport { createReferenceCache } from '../../cache/index.ts'\nimport { getActiveFeatures } from '../../core/config.ts'\nimport { todayIsoDate } from '../../core/formatting.ts'\nimport { parsePackageNames, readLock } from '../../core/lockfile.ts'\nimport { getSharedSkillsDir, skillRefsSection } from '../../core/paths.ts'\nimport { toStoragePackageName } from '../../core/prefix.ts'\nimport { parseGitHubRepoSlug } from '../../core/url.ts'\nimport { findRelatedSkills } from './pipeline.ts'\n\nexport interface MergeConfig {\n agent: AgentType\n global: boolean\n}\n\nexport async function handleMerge(\n state: MergeNeededState,\n config: MergeConfig,\n cwd: string,\n): Promise<void> {\n const { identityName, storageName, version, resolved, baseDir, skillDir, skillDirName, existingLock } = state\n\n p.log.step(`Merging ${identityName} into ${skillDirName}`)\n const cache = createReferenceCache(storageName, version)\n cache.linkPkgNamed(skillDir, cwd)\n\n const repoSlug = parseGitHubRepoSlug(resolved.repoUrl)\n installSkill({\n cwd,\n agent: config.agent,\n global: config.global,\n baseDir,\n skillDirName,\n lock: {\n packageName: identityName,\n version,\n repo: repoSlug,\n source: existingLock.source,\n syncedAt: todayIsoDate(),\n generator: 'skilld',\n },\n skipLinkAgents: true,\n })\n\n const updatedLock = readLock(baseDir)?.skills[skillDirName]\n const allPackages = parsePackageNames(updatedLock?.packages)\n const relatedSkills = await findRelatedSkills(storageName, baseDir)\n const existingStorageName = toStoragePackageName(existingLock.packageName!)\n const existingCache = createReferenceCache(existingStorageName, existingLock.version)\n const pkgFiles = existingCache.keyFiles(cwd)\n const shippedDocs = existingCache.hasShipped(cwd)\n\n const features = getActiveFeatures()\n writeGeneratedSkillMd(skillDir, {\n name: existingLock.packageName!,\n version: existingLock.version,\n relatedSkills,\n hasIssues: features.issues && existsSync(skillRefsSection(skillDir, 'issues')),\n hasDiscussions: features.discussions && existsSync(skillRefsSection(skillDir, 'discussions')),\n hasReleases: features.releases && existsSync(skillRefsSection(skillDir, 'releases')),\n docsType: (existingLock.source?.includes('llms.txt') ? 'llms.txt' : 'docs') as 'llms.txt' | 'readme' | 'docs',\n hasShippedDocs: shippedDocs,\n pkgFiles,\n dirName: skillDirName,\n packages: allPackages,\n features,\n })\n\n const sharedDir = !config.global && getSharedSkillsDir(cwd)\n if (sharedDir)\n linkSkillToAgents(skillDirName, sharedDir, cwd, config.agent)\n\n p.outro(`Merged ${identityName} into ${skillDirName}`)\n}\n","import type { AgentType, OptimizeModel } from '../agent/index.ts'\nimport type { ProjectState } from '../core/skills.ts'\nimport type { ResolveAttempt } from '../sources/index.ts'\nimport { styleText } from 'node:util'\nimport * as p from '@clack/prompts'\nimport { relative } from 'pathe'\nimport { detectImportedPackages } from '../agent/index.ts'\nimport { suggestPrepareHook } from '../cli/prepare-hook.ts'\nimport { readConfig } from '../core/config.ts'\nimport { timedSpinner } from '../core/formatting.ts'\nimport { isCrateSpec } from '../core/prefix.ts'\nimport { shutdownWorker } from '../retriv/pool.ts'\nimport { searchNpmPackages } from '../sources/index.ts'\nimport { DEFAULT_SECTIONS, resolveAutoModel, selectLlmConfig } from './llm-prompts.ts'\nimport { syncPackagesParallel } from './sync-parallel.ts'\nimport { handleMerge } from './sync/merge.ts'\nimport { npmResolver } from './sync/resolvers.ts'\nimport { createSyncRun } from './sync/run.ts'\nimport { bindClackUi } from './sync/ui/clack.ts'\n\nconst RESOLVE_SOURCE_LABELS: Record<string, string> = {\n 'npm': 'npm registry',\n 'github-docs': 'GitHub versioned docs',\n 'github-meta': 'GitHub metadata',\n 'github-search': 'GitHub search',\n 'readme': 'README fallback',\n 'llms.txt': 'llms.txt convention',\n 'crawl': 'website crawl',\n 'local': 'local node_modules',\n}\n\nfunction showResolveAttempts(attempts: ResolveAttempt[]): void {\n if (attempts.length === 0)\n return\n\n p.log.message(styleText('gray', 'Doc resolution:'))\n for (const attempt of attempts) {\n const icon = attempt.status === 'success' ? styleText('green', '✓') : styleText('gray', '✗')\n const label = RESOLVE_SOURCE_LABELS[attempt.source] ?? attempt.source\n const source = styleText('gray', label)\n const msg = attempt.message ? ` ${styleText('gray', `— ${attempt.message}`)}` : ''\n p.log.message(` ${icon} ${source}${msg}`)\n }\n}\n\nexport interface SyncOptions {\n packages?: string[]\n global: boolean\n agent: AgentType\n model?: OptimizeModel\n yes: boolean\n force?: boolean\n debug?: boolean\n mode?: 'add' | 'update'\n eject?: boolean | string\n name?: string\n from?: string\n noSearch?: boolean\n}\n\nexport async function syncCommand(state: ProjectState, opts: SyncOptions): Promise<void> {\n if (opts.packages && opts.packages.length > 0) {\n const crateSpecs = opts.packages.filter(isCrateSpec)\n const npmSpecs = opts.packages.filter(p => !isCrateSpec(p))\n\n if (npmSpecs.length > 1) {\n await syncPackagesParallel({\n packages: npmSpecs,\n global: opts.global,\n agent: opts.agent,\n model: opts.model,\n yes: opts.yes,\n force: opts.force,\n debug: opts.debug,\n mode: opts.mode,\n })\n }\n else if (npmSpecs.length === 1) {\n await syncSinglePackage(npmSpecs[0]!, opts)\n }\n\n for (const spec of crateSpecs)\n await syncSinglePackage(spec, opts)\n\n return\n }\n\n const packages = await interactivePicker(state)\n if (!packages || packages.length === 0) {\n p.outro('No packages selected')\n return\n }\n\n if (packages.length > 1) {\n return syncPackagesParallel({\n packages,\n global: opts.global,\n agent: opts.agent,\n model: opts.model,\n yes: opts.yes,\n force: opts.force,\n debug: opts.debug,\n mode: opts.mode,\n })\n }\n\n await syncSinglePackage(packages[0]!, opts)\n}\n\nasync function interactivePicker(state: ProjectState): Promise<string[] | null> {\n const spin = timedSpinner()\n spin.start('Detecting imports...')\n\n const cwd = process.cwd()\n const { packages: detected, error } = await detectImportedPackages(cwd)\n const declaredMap = state.deps\n\n if (error || detected.length === 0) {\n spin.stop(error ? `Detection failed: ${error}` : 'No imports detected')\n if (declaredMap.size === 0) {\n p.log.warn('No dependencies found')\n return null\n }\n return pickFromList(Array.from(declaredMap.entries(), ([name, version]) => ({\n name,\n version: maskPatch(version),\n count: 0,\n inPkgJson: true,\n })), state)\n }\n\n spin.stop(`Loaded ${detected.length} project skills`)\n\n const packages = detected.map(pkg => ({\n name: pkg.name,\n version: declaredMap.get(pkg.name),\n count: pkg.count,\n inPkgJson: declaredMap.has(pkg.name),\n }))\n\n return pickFromList(packages, state)\n}\n\nfunction maskPatch(version: string | undefined): string | undefined {\n if (!version)\n return undefined\n const parts = version.split('.')\n if (parts.length >= 3) {\n parts[2] = 'x'\n return parts.slice(0, 3).join('.')\n }\n return version\n}\n\nasync function pickFromList(\n packages: Array<{ name: string, version?: string, count: number, inPkgJson: boolean }>,\n state: ProjectState,\n): Promise<string[] | null> {\n const missingSet = new Set(state.missing)\n const outdatedSet = new Set(state.outdated.map(s => s.name))\n\n const options = packages.map(pkg => ({\n label: pkg.inPkgJson ? `${pkg.name} ★` : pkg.name,\n value: pkg.name,\n hint: [\n maskPatch(pkg.version),\n pkg.count > 0 ? `${pkg.count} imports` : null,\n ].filter(Boolean).join(' · ') || undefined,\n }))\n\n const initialValues = packages\n .filter(pkg => missingSet.has(pkg.name) || outdatedSet.has(pkg.name))\n .map(pkg => pkg.name)\n\n const selected = await p.multiselect({\n message: 'Select packages to sync',\n options,\n required: false,\n initialValues,\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Cancelled')\n return null\n }\n\n return selected as string[]\n}\n\ninterface SyncConfig {\n global: boolean\n agent: AgentType\n model?: OptimizeModel\n yes: boolean\n force?: boolean\n debug?: boolean\n mode?: 'add' | 'update'\n eject?: boolean | string\n name?: string\n from?: string\n noSearch?: boolean\n}\n\nasync function runSimpleSync(packageSpec: string, config: SyncConfig): Promise<void> {\n const cwd = process.cwd()\n const isEject = !!config.eject\n\n const run = createSyncRun({\n cwd,\n resolver: npmResolver,\n agent: config.agent,\n global: config.global,\n mode: config.mode,\n force: config.force,\n noSearch: config.noSearch,\n name: config.name,\n from: config.from,\n debug: config.debug,\n eject: config.eject,\n defaultSections: DEFAULT_SECTIONS,\n onMergeNeeded: state => handleMerge(state, { agent: config.agent, global: config.global }, cwd),\n })\n bindClackUi(run.hooks, { cwd })\n\n const base = await run.runBase(packageSpec)\n\n if (base.kind === 'shipped') {\n p.outro(`Synced ${packageSpec}`)\n return\n }\n\n if (base.kind === 'unresolved') {\n if (!isCrateSpec(packageSpec)) {\n const suggestions = await searchNpmPackages(base.identityName)\n if (suggestions.length > 0) {\n showResolveAttempts(base.attempts)\n const selected = await p.select({\n message: 'Did you mean one of these?',\n options: [\n ...suggestions.map(s => ({ label: s.name, value: s.name, hint: s.description })),\n { label: 'None of these', value: '_none_' as const },\n ],\n })\n if (!p.isCancel(selected) && selected !== '_none_')\n return syncSinglePackage(selected as string, config)\n return\n }\n }\n showResolveAttempts(base.attempts)\n return\n }\n\n if (base.kind === 'merged' || base.kind === 'error')\n return\n\n // base.kind === 'ready'\n const { state } = base\n const globalConfig = readConfig()\n const resolvedModel = await resolveAutoModel(config.model, config.yes)\n\n let llmConfig: import('./llm-prompts.ts').LlmConfig | null = null\n if (!state.allSectionsCached && !globalConfig.skipLlm && !(config.yes && !resolvedModel))\n llmConfig = await selectLlmConfig(resolvedModel, undefined, state.updateCtx)\n\n await run.runEnhance(state, llmConfig)\n\n await shutdownWorker()\n const ejectMsg = isEject ? ' (ejected)' : ''\n const relDir = relative(cwd, state.skillDir)\n p.outro(config.mode === 'update'\n ? `Updated ${state.identityName}${ejectMsg}`\n : `Synced ${state.identityName} → ${relDir}${ejectMsg}`)\n\n try {\n await suggestPrepareHook(cwd)\n }\n catch (err) {\n p.log.warn(`Failed to suggest prepare hook: ${err instanceof Error ? err.message : String(err)}`)\n }\n}\n\nasync function syncSinglePackage(packageSpec: string, config: SyncConfig): Promise<void> {\n if (isCrateSpec(packageSpec) && !packageSpec.slice('crate:'.length).trim()) {\n p.log.error('Invalid crate spec. Use format: crate:<name>')\n return\n }\n return runSimpleSync(packageSpec, config)\n}\n"],"mappings":"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"}
@@ -1,5 +1,2 @@
1
- import "./sources.mjs";
2
- import "./skill-installer2.mjs";
3
- import "./sync-pipeline.mjs";
4
- import { a as updateCommandDef, i as syncCommand, n as ejectCommandDef, t as addCommandDef } from "./sync.mjs";
5
- export { addCommandDef, ejectCommandDef, syncCommand, updateCommandDef };
1
+ import { t as syncCommand } from "./sync.mjs";
2
+ export { syncCommand };
@@ -0,0 +1,26 @@
1
+ import { t as version } from "./version.mjs";
2
+ import { i as getRegistryBase } from "./client.mjs";
3
+ import { isCI } from "std-env";
4
+ function isEnabled() {
5
+ if (process.env.SKILLD_TELEMETRY === "0") return false;
6
+ if (process.env.DISABLE_TELEMETRY || process.env.DO_NOT_TRACK) return false;
7
+ return true;
8
+ }
9
+ function track(payload) {
10
+ if (!isEnabled()) return;
11
+ const body = {
12
+ ...payload,
13
+ cliVersion: version
14
+ };
15
+ fetch(`${getRegistryBase()}/events/cli`, {
16
+ method: "POST",
17
+ headers: { "content-type": "application/json" },
18
+ body: JSON.stringify({
19
+ ...body,
20
+ ...isCI && { ci: true }
21
+ })
22
+ }).catch(() => {});
23
+ }
24
+ export { track as t };
25
+
26
+ //# sourceMappingURL=telemetry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.mjs","names":[],"sources":["../../src/telemetry.ts"],"sourcesContent":["/**\n * Anonymous telemetry → `POST <registry>/events/cli`. Fire-and-forget; never\n * throws into a caller, never blocks shutdown.\n *\n * Opt-out: `SKILLD_TELEMETRY=0`, `DISABLE_TELEMETRY=1`, or `DO_NOT_TRACK=1`.\n * Auto-disabled in CI.\n *\n * Wire shape: `CliEventInput` from `skilld-protocol/wire`. CLI-level callers\n * use the `TelemetryPayload` alias (which omits `cliVersion` — `track` fills\n * it from the bundled CLI version).\n */\n\nimport type { TelemetryEvent, TelemetrySurface } from 'skilld-protocol/constants'\nimport type { CliEventInput } from 'skilld-protocol/wire'\nimport { isCI } from 'std-env'\nimport { getRegistryBase } from './registry/client.ts'\nimport { version } from './version.ts'\n\nexport type { TelemetryEvent, TelemetrySurface }\n\nexport type TelemetryPayload = Omit<CliEventInput, 'cliVersion'>\n\nfunction isEnabled(): boolean {\n if (process.env.SKILLD_TELEMETRY === '0')\n return false\n if (process.env.DISABLE_TELEMETRY || process.env.DO_NOT_TRACK)\n return false\n return true\n}\n\nexport function track(payload: TelemetryPayload): void {\n if (!isEnabled())\n return\n\n const body: CliEventInput = {\n ...payload,\n cliVersion: version,\n }\n\n fetch(`${getRegistryBase()}/events/cli`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ ...body, ...(isCI && { ci: true }) }),\n }).catch(() => {})\n}\n"],"mappings":";;;AAsBA,SAAS,YAAqB;CAC5B,IAAI,QAAQ,IAAI,qBAAqB,KACnC,OAAO;CACT,IAAI,QAAQ,IAAI,qBAAqB,QAAQ,IAAI,cAC/C,OAAO;CACT,OAAO;;AAGT,SAAgB,MAAM,SAAiC;CACrD,IAAI,CAAC,WAAW,EACd;CAEF,MAAM,OAAsB;EAC1B,GAAG;EACH,YAAY;EACb;CAED,MAAM,GAAG,iBAAiB,CAAC,cAAc;EACvC,QAAQ;EACR,SAAS,EAAE,gBAAgB,oBAAoB;EAC/C,MAAM,KAAK,UAAU;GAAE,GAAG;GAAM,GAAI,QAAQ,EAAE,IAAI,MAAM;GAAG,CAAC;EAC7D,CAAC,CAAC,YAAY,GAAG"}
@@ -1,16 +1,19 @@
1
- import { c as SHARED_SKILLS_DIR, t as CACHE_DIR } from "./paths.mjs";
2
- import { I as unregisterProject, j as getRegisteredProjects } from "./cache.mjs";
3
- import { X as mapInsert } from "./sources.mjs";
4
1
  import { a as targets } from "./detect.mjs";
5
2
  import "./agent.mjs";
6
- import { p as isInteractive, x as sharedArgs } from "./cli-helpers.mjs";
3
+ import { l as SHARED_SKILLS_DIR, n as CACHE_DIR } from "./paths.mjs";
4
+ import { c as getRegisteredProjects, p as unregisterProject } from "./cache.mjs";
5
+ import { t as isInteractive } from "./env.mjs";
6
+ import { t as sharedArgs } from "./args.mjs";
7
+ import { t as mapInsert } from "./map.mjs";
7
8
  import { c as readLock } from "./lockfile.mjs";
8
9
  import { n as SKILLD_MARKER_START, t as SKILLD_MARKER_END } from "./skill-installer2.mjs";
9
- import "./sync.mjs";
10
10
  import { existsSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
11
- import { join } from "pathe";
11
+ import { styleText } from "node:util";
12
12
  import * as p from "@clack/prompts";
13
13
  import { defineCommand } from "citty";
14
+ import { join } from "pathe";
15
+ const STATIC_REGEX_1 = /\n+$/;
16
+ const STATIC_REGEX_2 = /^\n+/;
14
17
  function removeAgentInstructions(agent, projectPath) {
15
18
  const agentConfig = targets[agent];
16
19
  if (!agentConfig.instructionFile) return false;
@@ -32,8 +35,8 @@ function removeMarkerBlock(filePath) {
32
35
  if (startIdx === -1) return false;
33
36
  const endIdx = content.indexOf(SKILLD_MARKER_END, startIdx);
34
37
  if (endIdx === -1) return false;
35
- const before = content.slice(0, startIdx).replace(/\n+$/, "");
36
- const after = content.slice(endIdx + SKILLD_MARKER_END.length).replace(/^\n+/, "");
38
+ const before = content.slice(0, startIdx).replace(STATIC_REGEX_1, "");
39
+ const after = content.slice(endIdx + SKILLD_MARKER_END.length).replace(STATIC_REGEX_2, "");
37
40
  const updated = before + (before && after ? "\n" : "") + after;
38
41
  if (updated.trim() === "") rmSync(filePath);
39
42
  else writeFileSync(filePath, updated.endsWith("\n") ? updated : `${updated}\n`);
@@ -194,7 +197,7 @@ const uninstallCommandDef = defineCommand({
194
197
  },
195
198
  args: { ...sharedArgs },
196
199
  async run({ args }) {
197
- p.intro(`\x1B[1m\x1B[35mskilld\x1B[0m uninstall`);
200
+ p.intro(`${styleText(["bold", "magenta"], "skilld")} uninstall`);
198
201
  return uninstallCommand({
199
202
  scope: args.global ? "all" : void 0,
200
203
  agent: args.agent,