{"version":3,"file":"source-l77aIDwD.mjs","names":[],"sources":["../src/source.ts"],"sourcesContent":["import { access, mkdtemp, readdir, readFile, rm, stat } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { basename, dirname, isAbsolute, join, resolve } from 'node:path'\nimport { glob } from 'tinyglobby'\nimport type { ResolvedPiPackage, ResourceInventory } from './types.js'\n\ntype PiManifest = Partial<Record<'extensions' | 'skills' | 'prompts' | 'themes', string[]>>\n\nasync function exists(path: string): Promise<boolean> {\n  try {\n    await access(path)\n    return true\n  } catch {\n    return false\n  }\n}\n\nfunction stringArray(value: unknown): string[] | undefined {\n  return Array.isArray(value) && value.every(item => typeof item === 'string') ? value : undefined\n}\n\nfunction piManifest(packageJson: Record<string, unknown>): PiManifest | undefined {\n  const raw = packageJson.pi\n  if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) return undefined\n  const record = raw as Record<string, unknown>\n  const extensions = stringArray(record.extensions)\n  const skills = stringArray(record.skills)\n  const prompts = stringArray(record.prompts)\n  const themes = stringArray(record.themes)\n  return {\n    ...(extensions !== undefined ? { extensions } : {}),\n    ...(skills !== undefined ? { skills } : {}),\n    ...(prompts !== undefined ? { prompts } : {}),\n    ...(themes !== undefined ? { themes } : {}),\n  }\n}\n\nconst DEFAULT_PATTERNS: Record<keyof ResourceInventory, string[]> = {\n  extensions: ['extensions/**/*.{ts,tsx,js,jsx,mts,mjs,cts,cjs}'],\n  skills: ['skills/**/*'],\n  prompts: ['prompts/*.md'],\n  themes: ['themes/*.json'],\n}\n\nconst FILE_PATTERNS: Record<keyof ResourceInventory, string> = {\n  extensions: '**/*.{ts,tsx,js,jsx,mts,mjs,cts,cjs}',\n  skills: '**/*',\n  prompts: '**/*.md',\n  themes: '**/*.json',\n}\n\n// Pi's own loader tolerates resource paths that do not resolve (existsSync\n// filtering); mirror that leniency for patterns escaping the package root:\n// skip the pattern with a warning instead of refusing the whole package.\n// Files outside the package are still never globbed or copied.\nfunction safePattern(pattern: string): string | undefined {\n  const normalized = pattern.replaceAll('\\\\', '/')\n  const positive = normalized.startsWith('!') ? normalized.slice(1) : normalized\n  if (isAbsolute(positive) || positive.split('/').includes('..')) {\n    console.warn(`pi2dsh: skipping resource pattern that escapes the package root (Pi itself would not resolve it either at install layout): ${JSON.stringify(pattern)}`)\n    return undefined\n  }\n  return normalized\n}\n\nasync function patternsFor(\n  rootDir: string,\n  kind: keyof ResourceInventory,\n  configured: string[] | undefined,\n): Promise<string[]> {\n  if (configured === undefined) return DEFAULT_PATTERNS[kind]\n  const output: string[] = []\n  for (const raw of configured) {\n    const pattern = safePattern(raw)\n    if (pattern === undefined) continue\n    if (pattern.startsWith('!')) {\n      output.push(pattern)\n      continue\n    }\n    const absolute = resolve(rootDir, pattern)\n    try {\n      const info = await stat(absolute)\n      output.push(info.isDirectory() ? `${pattern.replace(/\\/$/u, '')}/${FILE_PATTERNS[kind]}` : pattern)\n    } catch {\n      output.push(pattern)\n    }\n  }\n  return output\n}\n\n// Pi's extension discovery for a DIRECTORY entry (coding-agent\n// src/core/package-manager.ts resolveExtensionEntries/collectAutoExtensionEntries\n// @6f707eb36064e82af9c1320a7634f4dfad21049b; logic unchanged, minus the\n// .gitignore/.piignore filter): a directory that carries its own\n// package.json `pi.extensions` or an index.ts/index.js IS one entry set;\n// otherwise its direct *.ts/*.js files are entries and each subdirectory\n// contributes only through that same rule. No recursion beyond one level —\n// a package's `internal/` helpers (no index) are shared modules, not entries.\n// The old `dir/**/*.ts` glob loaded every helper as an extension and logged\n// \"has no default factory function\" for each (pi-code: 40 of 64 files).\nasync function resolveExtensionEntries(dir: string): Promise<string[] | null> {\n  const packageJsonPath = join(dir, 'package.json')\n  if (await exists(packageJsonPath)) {\n    try {\n      const manifest = piManifest(JSON.parse(await readFile(packageJsonPath, 'utf8')) as Record<string, unknown>)\n      if (manifest?.extensions !== undefined && manifest.extensions.length > 0) {\n        const entries: string[] = []\n        for (const extPath of manifest.extensions) {\n          const resolved = resolve(dir, extPath)\n          if (await exists(resolved)) entries.push(resolved)\n        }\n        if (entries.length > 0) return entries\n      }\n    } catch {\n      // An unreadable nested manifest falls through to the index rule, as Pi does.\n    }\n  }\n  for (const index of ['index.ts', 'index.js']) {\n    const candidate = join(dir, index)\n    if (await exists(candidate)) return [candidate]\n  }\n  return null\n}\n\nasync function collectAutoExtensionEntries(dir: string): Promise<string[]> {\n  if (!await exists(dir)) return []\n  const rootEntries = await resolveExtensionEntries(dir)\n  if (rootEntries !== null) return rootEntries\n  const entries: string[] = []\n  for (const entry of await readdir(dir, { withFileTypes: true })) {\n    if (entry.name.startsWith('.') || entry.name === 'node_modules') continue\n    const fullPath = join(dir, entry.name)\n    let isDir = entry.isDirectory()\n    let isFile = entry.isFile()\n    if (entry.isSymbolicLink()) {\n      try {\n        const info = await stat(fullPath)\n        isDir = info.isDirectory()\n        isFile = info.isFile()\n      } catch {\n        continue\n      }\n    }\n    if (isFile && (entry.name.endsWith('.ts') || entry.name.endsWith('.js'))) entries.push(fullPath)\n    else if (isDir) {\n      const resolved = await resolveExtensionEntries(fullPath)\n      if (resolved !== null) entries.push(...resolved)\n    }\n  }\n  return entries\n}\n\nasync function discoverExtensions(rootDir: string, configured: string[] | undefined): Promise<string[]> {\n  // Pi: no manifest → the package's `extensions/` directory under the auto\n  // rule; a manifest → each entry is a file (as is) or a directory (auto rule).\n  // Patterns Pi would not understand (globs, negations) keep the glob path.\n  const entries = configured === undefined ? ['extensions'] : configured\n  const output = new Set<string>()\n  const globPatterns: string[] = []\n  for (const raw of entries) {\n    const pattern = safePattern(raw)\n    if (pattern === undefined) continue\n    if (pattern.startsWith('!') || /[*?[\\]{}]/u.test(pattern)) {\n      globPatterns.push(pattern)\n      continue\n    }\n    const absolute = resolve(rootDir, pattern)\n    try {\n      const info = await stat(absolute)\n      if (info.isDirectory()) for (const entry of await collectAutoExtensionEntries(absolute)) output.add(entry)\n      else output.add(absolute)\n    } catch {\n      // Pi skips manifest entries that do not resolve.\n    }\n  }\n  if (globPatterns.length > 0) {\n    const matches = await glob(globPatterns, { cwd: rootDir, absolute: true, onlyFiles: true, dot: false, followSymbolicLinks: false })\n    for (const match of matches) output.add(match)\n  }\n  return [...output].sort()\n}\n\nasync function discoverResources(rootDir: string, packageJson: Record<string, unknown>): Promise<ResourceInventory> {\n  const manifest = piManifest(packageJson)\n  const discover = async (kind: keyof ResourceInventory): Promise<string[]> => {\n    const patterns = await patternsFor(rootDir, kind, manifest?.[kind])\n    const matches = await glob(patterns, {\n      cwd: rootDir,\n      absolute: true,\n      onlyFiles: true,\n      dot: false,\n      followSymbolicLinks: false,\n    })\n    return matches.sort()\n  }\n  return {\n    extensions: await discoverExtensions(rootDir, manifest?.extensions),\n    skills: await discover('skills'),\n    prompts: await discover('prompts'),\n    themes: await discover('themes'),\n  }\n}\n\nfunction packageIdentity(packageJson: Record<string, unknown>, source: string, fallbackName: string) {\n  return {\n    name: typeof packageJson.name === 'string' ? packageJson.name : fallbackName,\n    version: typeof packageJson.version === 'string' ? packageJson.version : '0.0.0-local',\n    source,\n  }\n}\n\nasync function readPackageJson(rootDir: string): Promise<Record<string, unknown>> {\n  const text = await readFile(join(rootDir, 'package.json'), 'utf8')\n  const parsed: unknown = JSON.parse(text)\n  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n    throw new Error('package.json must contain an object')\n  }\n  return parsed as Record<string, unknown>\n}\n\nexport async function resolvePiPackage(source: string, cwd = process.cwd()): Promise<ResolvedPiPackage> {\n  const localCandidate = resolve(cwd, source.replace(/^file:/u, ''))\n  const local = source.startsWith('.')\n    || source.startsWith('/')\n    || source.startsWith('file:')\n    || await exists(localCandidate)\n  let rootDir: string\n  let temporary = false\n  let packageJson: Record<string, unknown>\n\n  if (local) {\n    const requested = localCandidate\n    const info = await stat(requested)\n    if (info.isFile()) {\n      rootDir = dirname(requested)\n      const packagePath = join(rootDir, 'package.json')\n      packageJson = await exists(packagePath)\n        ? await readPackageJson(rootDir)\n        : { name: basename(requested).replace(/\\.[^.]+$/u, ''), pi: { extensions: [basename(requested)] } }\n    } else {\n      rootDir = requested\n      packageJson = await readPackageJson(rootDir)\n    }\n  } else {\n    rootDir = await mkdtemp(join(tmpdir(), 'pi2dsh-source-'))\n    temporary = true\n    try {\n      // Lazy: only npm-spec resolution needs the registry client. Host\n      // bundles resolve installed directories and never load pacote.\n      const { default: pacote } = await import('pacote')\n      await pacote.extract(source, rootDir)\n      packageJson = await readPackageJson(rootDir)\n    } catch (error) {\n      await rm(rootDir, { recursive: true, force: true })\n      throw error\n    }\n  }\n\n  const resources = await discoverResources(rootDir, packageJson)\n  const identity = packageIdentity(packageJson, source, basename(rootDir))\n  return {\n    rootDir,\n    temporary,\n    identity,\n    packageJson,\n    resources,\n    async dispose() {\n      if (temporary) await rm(rootDir, { recursive: true, force: true })\n    },\n  }\n}\n"],"mappings":"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"}