lockdelta 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -57,7 +57,7 @@ function parseDenoLock(content) {
57
57
  const { name, version } = splitSpecifier(specifier);
58
58
  const resultKey = key === "jsr" ? `jsr:${name}` : name;
59
59
  if (name && version && !result[resultKey]) {
60
- result[resultKey] = version;
60
+ result[resultKey] = { version };
61
61
  }
62
62
  }
63
63
  }
@@ -136,7 +136,7 @@ function parseBunLock(content) {
136
136
  if (typeof nameAtVersion !== "string") continue;
137
137
  const version = extractVersion(nameAtVersion);
138
138
  if (!version || version.startsWith("workspace:")) continue;
139
- result[name] = version;
139
+ result[name] = { version };
140
140
  }
141
141
  return result;
142
142
  }
@@ -171,7 +171,10 @@ function parseV2Packages(packages) {
171
171
  const name = key.slice("node_modules/".length);
172
172
  const pkgVersion = pkg.version;
173
173
  if (pkgVersion && !result[name]) {
174
- result[name] = pkgVersion;
174
+ const entry = { version: pkgVersion };
175
+ const registryUrl = resolvedToOrigin(pkg.resolved);
176
+ if (registryUrl !== void 0) entry.registryUrl = registryUrl;
177
+ result[name] = entry;
175
178
  }
176
179
  }
177
180
  return result;
@@ -179,7 +182,10 @@ function parseV2Packages(packages) {
179
182
  function parseV1Dependencies(deps, result = {}) {
180
183
  for (const [name, pkg] of Object.entries(deps)) {
181
184
  if (pkg.version && !result[name]) {
182
- result[name] = pkg.version;
185
+ const entry = { version: pkg.version };
186
+ const registryUrl = resolvedToOrigin(pkg.resolved);
187
+ if (registryUrl !== void 0) entry.registryUrl = registryUrl;
188
+ result[name] = entry;
183
189
  }
184
190
  if (pkg.dependencies) {
185
191
  parseV1Dependencies(pkg.dependencies, result);
@@ -187,6 +193,14 @@ function parseV1Dependencies(deps, result = {}) {
187
193
  }
188
194
  return result;
189
195
  }
196
+ function resolvedToOrigin(resolved) {
197
+ if (!resolved) return void 0;
198
+ try {
199
+ return new URL(resolved).origin;
200
+ } catch {
201
+ return void 0;
202
+ }
203
+ }
190
204
 
191
205
  // src/ecosystems/javascript/parsers/pnpm.ts
192
206
  import { parse as parseYaml } from "yaml";
@@ -206,7 +220,7 @@ function parseLockfileVersion(v) {
206
220
  }
207
221
  function parsePnpmV9(packages) {
208
222
  const result = {};
209
- for (const key of Object.keys(packages)) {
223
+ for (const [key, value] of Object.entries(packages)) {
210
224
  let name;
211
225
  let version;
212
226
  if (key.startsWith("@")) {
@@ -222,14 +236,18 @@ function parsePnpmV9(packages) {
222
236
  }
223
237
  version = stripVersionSuffix(version);
224
238
  if (name && version && !result[name]) {
225
- result[name] = version;
239
+ const entry = { version };
240
+ const pkg = value;
241
+ const registryUrl = pkg?.resolution?.tarball ? resolvedToOrigin2(pkg.resolution.tarball) : void 0;
242
+ if (registryUrl !== void 0) entry.registryUrl = registryUrl;
243
+ result[name] = entry;
226
244
  }
227
245
  }
228
246
  return result;
229
247
  }
230
248
  function parsePnpmLegacy(packages) {
231
249
  const result = {};
232
- for (const key of Object.keys(packages)) {
250
+ for (const [key, value] of Object.entries(packages)) {
233
251
  const cleaned = key.startsWith("/") ? key.slice(1) : key;
234
252
  let name;
235
253
  let version;
@@ -260,7 +278,11 @@ function parsePnpmLegacy(packages) {
260
278
  }
261
279
  version = stripVersionSuffix(version);
262
280
  if (name && version && !result[name]) {
263
- result[name] = version;
281
+ const entry = { version };
282
+ const pkg = value;
283
+ const registryUrl = pkg?.resolution?.tarball ? resolvedToOrigin2(pkg.resolution.tarball) : void 0;
284
+ if (registryUrl !== void 0) entry.registryUrl = registryUrl;
285
+ result[name] = entry;
264
286
  }
265
287
  }
266
288
  return result;
@@ -268,6 +290,13 @@ function parsePnpmLegacy(packages) {
268
290
  function stripVersionSuffix(version) {
269
291
  return version.split("(")[0].split("_")[0].trim();
270
292
  }
293
+ function resolvedToOrigin2(url) {
294
+ try {
295
+ return new URL(url).origin;
296
+ } catch {
297
+ return void 0;
298
+ }
299
+ }
271
300
 
272
301
  // src/ecosystems/javascript/parsers/yarn.ts
273
302
  import { parse as parseYaml2 } from "yaml";
@@ -298,7 +327,13 @@ function parseYarnV1(content) {
298
327
  const firstSpecifier = headerLine.split(",")[0].trim().replace(/^"|"$/g, "");
299
328
  const name = extractNameFromSpecifier(firstSpecifier);
300
329
  if (name && !packages[name]) {
301
- packages[name] = versionMatch[1];
330
+ const entry = { version: versionMatch[1] };
331
+ const resolvedMatch = trimmed.match(/^[ \t]+resolved "([^"]+)"/m);
332
+ if (resolvedMatch) {
333
+ const registryUrl = resolvedToOrigin3(resolvedMatch[1]);
334
+ if (registryUrl !== void 0) entry.registryUrl = registryUrl;
335
+ }
336
+ packages[name] = entry;
302
337
  }
303
338
  }
304
339
  return packages;
@@ -309,13 +344,16 @@ function parseYarnBerry(content) {
309
344
  for (const [key, value] of Object.entries(data)) {
310
345
  if (key === "__metadata") continue;
311
346
  if (typeof value !== "object" || !value) continue;
312
- const entry = value;
313
- if (entry.linkType === "soft") continue;
314
- if (!entry.version) continue;
347
+ const berryEntry = value;
348
+ if (berryEntry.linkType === "soft") continue;
349
+ if (!berryEntry.version) continue;
315
350
  const cleanKey = key.replace(/^"|"$/g, "");
316
351
  const name = extractNameFromBerryKey(cleanKey);
317
352
  if (name && !packages[name]) {
318
- packages[name] = entry.version;
353
+ const entry = { version: berryEntry.version };
354
+ const registryUrl = extractBerryRegistryOrigin(berryEntry.resolution);
355
+ if (registryUrl !== void 0) entry.registryUrl = registryUrl;
356
+ packages[name] = entry;
319
357
  }
320
358
  }
321
359
  return packages;
@@ -327,6 +365,23 @@ function extractNameFromBerryKey(key) {
327
365
  }
328
366
  return key.split("@")[0];
329
367
  }
368
+ function extractBerryRegistryOrigin(resolution) {
369
+ if (!resolution) return void 0;
370
+ const atIdx = resolution.startsWith("@") ? resolution.indexOf("@", 1) : resolution.indexOf("@");
371
+ if (atIdx < 0) return void 0;
372
+ const spec = resolution.slice(atIdx + 1);
373
+ if (spec.startsWith("http://") || spec.startsWith("https://")) {
374
+ return resolvedToOrigin3(spec.split("#")[0]);
375
+ }
376
+ return void 0;
377
+ }
378
+ function resolvedToOrigin3(url) {
379
+ try {
380
+ return new URL(url).origin;
381
+ } catch {
382
+ return void 0;
383
+ }
384
+ }
330
385
 
331
386
  // src/ecosystems/javascript/index.ts
332
387
  var SUPPORTED_LOCKFILES2 = [
@@ -373,7 +428,15 @@ function parseTomlPackages(content) {
373
428
  const packages = {};
374
429
  for (const pkg of [...data.package ?? [], ...data.packages ?? []]) {
375
430
  if (typeof pkg.name === "string" && typeof pkg.version === "string") {
376
- packages[pkg.name] = pkg.version;
431
+ const entry = { version: pkg.version };
432
+ const sourceUrl = typeof pkg.source?.registry === "string" ? pkg.source.registry : typeof pkg.source?.url === "string" ? pkg.source.url : void 0;
433
+ if (sourceUrl !== void 0) {
434
+ try {
435
+ entry.registryUrl = new URL(sourceUrl).origin;
436
+ } catch {
437
+ }
438
+ }
439
+ packages[pkg.name] = entry;
377
440
  }
378
441
  }
379
442
  return packages;
@@ -388,7 +451,17 @@ function parseTomlPackagesRegex(content) {
388
451
  const nameMatch = block.match(/\nname\s*=\s*"([^"]+)"/);
389
452
  const versionMatch = block.match(/\nversion\s*=\s*"([^"]+)"/);
390
453
  if (nameMatch && versionMatch) {
391
- packages[nameMatch[1]] = versionMatch[1];
454
+ const entry = { version: versionMatch[1] };
455
+ const sourceRegistryMatch = block.match(/source\s*=\s*\{[^}]*registry\s*=\s*"([^"]+)"/);
456
+ const sourceUrlMatch = block.match(/\nurl\s*=\s*"([^"]+)"/);
457
+ const sourceUrl = sourceRegistryMatch?.[1] ?? sourceUrlMatch?.[1];
458
+ if (sourceUrl !== void 0) {
459
+ try {
460
+ entry.registryUrl = new URL(sourceUrl).origin;
461
+ } catch {
462
+ }
463
+ }
464
+ packages[nameMatch[1]] = entry;
392
465
  }
393
466
  }
394
467
  return packages;
@@ -539,18 +612,23 @@ function diffPackages(oldPkgs, newPkgs, directDeps, normalizeName) {
539
612
  for (const name of [...allNames].sort()) {
540
613
  const inOld = name in oldPkgs;
541
614
  const inNew = name in newPkgs;
542
- if (inOld && inNew && oldPkgs[name] === newPkgs[name]) continue;
615
+ if (inOld && inNew && oldPkgs[name].version === newPkgs[name].version) continue;
543
616
  const normalized = normalizeName(name);
544
617
  const isProd = directDeps.prod.has(normalized);
545
618
  const isDev = directDeps.dev.has(normalized) && !isProd;
546
- changes.push({
619
+ const change = {
547
620
  name,
548
621
  change_type: !inOld ? "added" : !inNew ? "removed" : "updated",
549
- old_version: inOld ? oldPkgs[name] : null,
550
- new_version: inNew ? newPkgs[name] : null,
622
+ old_version: inOld ? oldPkgs[name].version : null,
623
+ new_version: inNew ? newPkgs[name].version : null,
551
624
  is_direct: isProd || isDev,
552
625
  is_dev: isDev
553
- });
626
+ };
627
+ const oldRegistryUrl = inOld ? oldPkgs[name].registryUrl : void 0;
628
+ const newRegistryUrl = inNew ? newPkgs[name].registryUrl : void 0;
629
+ if (oldRegistryUrl !== void 0) change.old_registry_url = oldRegistryUrl;
630
+ if (newRegistryUrl !== void 0) change.new_registry_url = newRegistryUrl;
631
+ changes.push(change);
554
632
  }
555
633
  return changes;
556
634
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/core/report.ts","../src/ecosystems/deno/deno-json.ts","../src/ecosystems/deno/parsers/deno-lock.ts","../src/ecosystems/deno/index.ts","../src/ecosystems/javascript/package-json.ts","../src/ecosystems/javascript/parsers/bun.ts","../src/ecosystems/javascript/parsers/npm.ts","../src/ecosystems/javascript/parsers/pnpm.ts","../src/ecosystems/javascript/parsers/yarn.ts","../src/ecosystems/javascript/index.ts","../src/ecosystems/python/parsers/toml.ts","../src/ecosystems/python/pyproject.ts","../src/ecosystems/python/index.ts","../src/ecosystems/index.ts","../src/core/diff.ts","../src/core/discovery.ts","../src/sources/git.ts","../src/sources/github.ts","../src/sources/local.ts","../src/index.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs';\nimport { Command } from 'commander';\nimport { run } from './index.js';\n\nconst program = new Command();\n\nprogram\n .name('lockdelta')\n .description('Diff dependency lockfiles between git refs, PRs, or local files')\n .version('0.1.0')\n .option(\n '--base <ref>',\n 'Base git ref (default: HEAD~1). In CI, reads GITHUB_BASE_REF — may need \"origin/\" prefix.',\n process.env.GITHUB_BASE_REF,\n )\n .option(\n '--head <ref>',\n 'Head git ref (default: HEAD). In CI, reads GITHUB_HEAD_REF.',\n process.env.GITHUB_HEAD_REF,\n )\n .option(\n '--pr <number>',\n 'GitHub PR number. Fetches exact SHAs via gh CLI.',\n process.env.GITHUB_PR_NUMBER,\n )\n .option(\n '--repo <owner/name>',\n 'GitHub repo in OWNER/NAME format. Auto-detected if omitted.',\n process.env.GITHUB_REPOSITORY,\n )\n .option('--lockfile <path>', 'Specific lockfile path. Auto-discovers all lockfiles if omitted.')\n .option('--type <type>', 'Force lockfile type: uv, poetry, pdm. Only used with --lockfile.')\n .option('--old <path>', 'Old lockfile path (local file comparison mode).')\n .option('--new <path>', 'New lockfile path (local file comparison mode).')\n .option('--output <path>', 'Write JSON report to file instead of stdout.')\n .action(async (opts) => {\n try {\n const report = await run({\n base: opts.base,\n head: opts.head,\n prNumber: opts.pr,\n repo: opts.repo,\n lockfile: opts.lockfile,\n lockfileType: opts.type,\n oldFile: opts.old,\n newFile: opts.new,\n onNote: (msg) => process.stderr.write(`Note: ${msg}\\n`),\n });\n\n const json = `${JSON.stringify(report, null, 2)}\\n`;\n\n if (opts.output) {\n writeFileSync(opts.output, json, 'utf-8');\n process.stderr.write(`Report written to ${opts.output}\\n`);\n } else {\n process.stdout.write(json);\n }\n } catch (err) {\n process.stderr.write(`ERROR: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n }\n });\n\nprogram.parse();\n","import { posix } from 'node:path';\nimport { getEcosystemByName, getEcosystemForLockfile } from '../ecosystems/index.js';\nimport type { DiffReport, FileSource, LockfileEntry, LockfilePair } from '../types.js';\nimport { diffPackages } from './diff.js';\nimport {\n findAllLockfiles,\n findLockfiles,\n groupByWorkspace,\n resolveLockfilePair,\n} from './discovery.js';\n\nexport async function buildLockfileEntry(\n pair: LockfilePair,\n workspace: string,\n getBase: FileSource,\n getHead: FileSource,\n): Promise<LockfileEntry | null> {\n const ecosystem = getEcosystemByName(pair.ecosystemName);\n if (!ecosystem) return null;\n\n const manifestPath = ecosystem.manifestName\n ? workspace === '.'\n ? ecosystem.manifestName\n : posix.join(workspace, ecosystem.manifestName)\n : null;\n\n const [oldContent, newContent, manifestContent] = await Promise.all([\n pair.basePath ? getBase(pair.basePath) : Promise.resolve(null),\n pair.headPath ? getHead(pair.headPath) : Promise.resolve(null),\n manifestPath ? getHead(manifestPath) : Promise.resolve(null),\n ]);\n\n const oldPkgs =\n oldContent && pair.baseType ? ecosystem.parseLockfile(oldContent, pair.baseType) : {};\n const newPkgs =\n newContent && pair.headType ? ecosystem.parseLockfile(newContent, pair.headType) : {};\n\n const directDeps = manifestContent\n ? ecosystem.parseDirectDeps(manifestContent)\n : { prod: new Set<string>(), dev: new Set<string>() };\n\n const changes = diffPackages(\n oldPkgs,\n newPkgs,\n directDeps,\n ecosystem.normalizeName.bind(ecosystem),\n );\n\n const added = changes.filter((c) => c.change_type === 'added').length;\n const removed = changes.filter((c) => c.change_type === 'removed').length;\n const updated = changes.filter((c) => c.change_type === 'updated').length;\n\n return {\n path: pair.headPath ?? pair.basePath,\n workspace,\n type: pair.headType ?? pair.baseType,\n ecosystem: pair.ecosystemName,\n summary: { added, removed, updated, total_changes: changes.length },\n changes,\n migration: pair.migrationNote\n ? {\n note: pair.migrationNote,\n base_lockfile: pair.basePath,\n base_lockfile_type: pair.baseType,\n head_lockfile: pair.headPath,\n head_lockfile_type: pair.headType,\n }\n : null,\n };\n}\n\nexport interface CollectOptions {\n getBase: FileSource;\n getHead: FileSource;\n allBasePaths: string[];\n allHeadPaths: string[];\n lockfile?: string;\n lockfileType?: string;\n onNote?: (message: string) => void;\n}\n\nexport async function collectLockfileEntries(options: CollectOptions): Promise<LockfileEntry[]> {\n const { getBase, getHead, allBasePaths, allHeadPaths, lockfile, lockfileType, onNote } = options;\n\n if (lockfile) {\n const filename = posix.basename(lockfile);\n const ecosystem = getEcosystemForLockfile(filename);\n if (!ecosystem) throw new Error(`Cannot determine ecosystem for lockfile: ${lockfile}`);\n const type = lockfileType ?? ecosystem.getLockfileType(filename);\n if (!type) throw new Error(`Cannot determine lockfile type for ${lockfile} — use --type`);\n const ws = posix.dirname(lockfile);\n const pair: LockfilePair = {\n basePath: lockfile,\n baseType: type,\n headPath: lockfile,\n headType: type,\n migrationNote: null,\n ecosystemName: ecosystem.name,\n };\n const entry = await buildLockfileEntry(\n pair,\n ws === '.' || ws === '' ? '.' : ws,\n getBase,\n getHead,\n );\n return entry ? [entry] : [];\n }\n\n let baseAll = findAllLockfiles(allBasePaths);\n let headAll = findAllLockfiles(allHeadPaths);\n\n if (baseAll.length === 0 && headAll.length === 0) {\n [baseAll, headAll] = await Promise.all([findLockfiles(getBase), findLockfiles(getHead)]);\n }\n\n const baseByWs = groupByWorkspace(baseAll);\n const headByWs = groupByWorkspace(headAll);\n const allWorkspaces = [...new Set([...baseByWs.keys(), ...headByWs.keys()])].sort();\n\n const entries = await Promise.all(\n allWorkspaces.map(async (ws) => {\n const baseFiles = baseByWs.get(ws) ?? [];\n const headFiles = headByWs.get(ws) ?? [];\n const pair = resolveLockfilePair(baseFiles, headFiles);\n if (!pair) return null;\n if (pair.migrationNote) onNote?.(`[${ws}]: ${pair.migrationNote}`);\n return buildLockfileEntry(pair, ws, getBase, getHead);\n }),\n );\n\n return entries.filter((e): e is LockfileEntry => e !== null);\n}\n\nexport function buildDiffReport(\n lockfiles: LockfileEntry[],\n baseRef: string,\n headRef: string,\n): DiffReport {\n const totalAdded = lockfiles.reduce((sum, lf) => sum + lf.summary.added, 0);\n const totalRemoved = lockfiles.reduce((sum, lf) => sum + lf.summary.removed, 0);\n const totalUpdated = lockfiles.reduce((sum, lf) => sum + lf.summary.updated, 0);\n const ecosystems = [...new Set(lockfiles.map((lf) => lf.ecosystem))].sort();\n\n return {\n schema_version: '1',\n generated_at: new Date().toISOString(),\n base_ref: baseRef,\n head_ref: headRef,\n summary: {\n added: totalAdded,\n removed: totalRemoved,\n updated: totalUpdated,\n total_changes: totalAdded + totalRemoved + totalUpdated,\n ecosystems,\n },\n lockfiles,\n };\n}\n","import type { DirectDeps } from '../../types.js';\n\nexport function normalizeDenoName(name: string): string {\n return name.toLowerCase();\n}\n\nexport function parseDirectDeps(content: string): DirectDeps {\n const prod = new Set<string>();\n\n let data: Record<string, unknown>;\n try {\n data = JSON.parse(content) as Record<string, unknown>;\n } catch {\n return { prod, dev: new Set() };\n }\n\n const imports = data.imports as Record<string, string> | undefined;\n if (imports) {\n for (const specifier of Object.values(imports)) {\n const name = extractPackageName(specifier);\n if (name) prod.add(normalizeDenoName(name));\n }\n }\n\n const workspace = data.workspace as { dependencies?: string[] } | undefined;\n for (const specifier of workspace?.dependencies ?? []) {\n const name = extractPackageName(specifier);\n if (name) prod.add(normalizeDenoName(name));\n }\n\n return { prod, dev: new Set() };\n}\n\nfunction extractPackageName(specifier: string): string | null {\n // Handles \"npm:chalk@^5.3.0\", \"jsr:@std/path@^0.224.0\", \"node:fs\"\n const withoutProtocol = specifier.replace(/^(?:npm|jsr|node):/, '');\n\n // node: builtins have no version — skip\n if (specifier.startsWith('node:')) return null;\n\n if (withoutProtocol.startsWith('@')) {\n const atIdx = withoutProtocol.indexOf('@', 1);\n return atIdx > 0 ? withoutProtocol.slice(0, atIdx) : withoutProtocol;\n }\n const atIdx = withoutProtocol.indexOf('@');\n return atIdx > 0 ? withoutProtocol.slice(0, atIdx) : withoutProtocol || null;\n}\n","interface DenoLock {\n version?: string;\n packages?: {\n npm?: Record<string, unknown>;\n jsr?: Record<string, unknown>;\n };\n}\n\nexport function parseDenoLock(content: string): Record<string, string> {\n const data = JSON.parse(content) as DenoLock;\n const result: Record<string, string> = {};\n\n for (const [key, registry] of [\n ['npm', data.packages?.npm],\n ['jsr', data.packages?.jsr],\n ] as const) {\n if (!registry) continue;\n for (const specifier of Object.keys(registry)) {\n const { name, version } = splitSpecifier(specifier);\n // Prefix JSR packages to avoid collisions with same-named npm packages\n const resultKey = key === 'jsr' ? `jsr:${name}` : name;\n if (name && version && !result[resultKey]) {\n result[resultKey] = version;\n }\n }\n }\n\n return result;\n}\n\nfunction splitSpecifier(specifier: string): { name: string; version: string } {\n if (specifier.startsWith('@')) {\n const atIdx = specifier.indexOf('@', 1);\n if (atIdx < 0) return { name: specifier, version: '' };\n return { name: specifier.slice(0, atIdx), version: specifier.slice(atIdx + 1) };\n }\n const atIdx = specifier.indexOf('@');\n if (atIdx < 0) return { name: specifier, version: '' };\n return { name: specifier.slice(0, atIdx), version: specifier.slice(atIdx + 1) };\n}\n","import type { Ecosystem, SupportedLockfile } from '../base.js';\nimport { normalizeDenoName, parseDirectDeps } from './deno-json.js';\nimport { parseDenoLock } from './parsers/deno-lock.js';\n\nconst SUPPORTED_LOCKFILES: SupportedLockfile[] = [{ filename: 'deno.lock', type: 'deno' }];\n\nexport const denoEcosystem: Ecosystem = {\n name: 'deno',\n supportedLockfiles: SUPPORTED_LOCKFILES,\n manifestName: 'deno.json',\n\n getLockfileType(filename: string): string | undefined {\n return filename === 'deno.lock' ? 'deno' : undefined;\n },\n\n parseLockfile(content: string, _lockfileType: string): Record<string, string> {\n return parseDenoLock(content);\n },\n\n parseDirectDeps(manifestContent: string) {\n return parseDirectDeps(manifestContent);\n },\n\n normalizeName(name: string): string {\n return normalizeDenoName(name);\n },\n};\n","import type { DirectDeps } from '../../types.js';\n\nconst PROD_SECTIONS = ['dependencies', 'optionalDependencies', 'peerDependencies'] as const;\n\nexport function normalizeJsName(name: string): string {\n return name.toLowerCase();\n}\n\nexport function parseDirectDeps(content: string): DirectDeps {\n const prod = new Set<string>();\n const dev = new Set<string>();\n\n let data: Record<string, Record<string, string>>;\n try {\n data = JSON.parse(content) as Record<string, Record<string, string>>;\n } catch {\n return { prod, dev };\n }\n\n for (const section of PROD_SECTIONS) {\n const deps = data[section];\n if (deps && typeof deps === 'object') {\n for (const name of Object.keys(deps)) {\n prod.add(normalizeJsName(name));\n }\n }\n }\n\n const devDeps = data.devDependencies;\n if (devDeps && typeof devDeps === 'object') {\n for (const name of Object.keys(devDeps)) {\n const normalized = normalizeJsName(name);\n if (!prod.has(normalized)) dev.add(normalized);\n }\n }\n\n return { prod, dev };\n}\n","interface BunLock {\n lockfileVersion?: number;\n packages?: Record<string, unknown[]>;\n}\n\nexport function parseBunLock(content: string): Record<string, string> {\n const data = JSON.parse(content) as BunLock;\n const result: Record<string, string> = {};\n\n for (const [name, entry] of Object.entries(data.packages ?? {})) {\n if (!Array.isArray(entry)) continue;\n const nameAtVersion = entry[0];\n if (typeof nameAtVersion !== 'string') continue;\n\n const version = extractVersion(nameAtVersion);\n if (!version || version.startsWith('workspace:')) continue;\n\n result[name] = version;\n }\n\n return result;\n}\n\nfunction extractVersion(nameAtVersion: string): string {\n // Format: \"name@version\" or \"@scope/name@version\"\n if (nameAtVersion.startsWith('@')) {\n const atIdx = nameAtVersion.indexOf('@', 1);\n return atIdx > 0 ? nameAtVersion.slice(atIdx + 1) : '';\n }\n const atIdx = nameAtVersion.indexOf('@');\n return atIdx > 0 ? nameAtVersion.slice(atIdx + 1) : '';\n}\n","interface NpmPackageV1 {\n version?: string;\n dependencies?: Record<string, NpmPackageV1>;\n}\n\ninterface NpmPackageLockV1 {\n lockfileVersion?: number;\n dependencies?: Record<string, NpmPackageV1>;\n}\n\ninterface NpmPackageLockV2 {\n lockfileVersion?: number;\n packages?: Record<string, { version?: string }>;\n}\n\nexport function parseNpmLock(content: string): Record<string, string> {\n const data = JSON.parse(content) as NpmPackageLockV1 & NpmPackageLockV2;\n const version = data.lockfileVersion ?? 1;\n\n if (version >= 2 && data.packages) {\n return parseV2Packages(data.packages);\n }\n\n if (data.dependencies) {\n return parseV1Dependencies(data.dependencies);\n }\n\n return {};\n}\n\nfunction parseV2Packages(packages: Record<string, { version?: string }>): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const [key, pkg] of Object.entries(packages)) {\n if (!key) continue;\n if (!key.startsWith('node_modules/')) continue;\n\n const segments = key.split('node_modules/');\n if (segments.length > 2) continue;\n\n const name = key.slice('node_modules/'.length);\n const pkgVersion = pkg.version;\n if (pkgVersion && !result[name]) {\n result[name] = pkgVersion;\n }\n }\n\n return result;\n}\n\nfunction parseV1Dependencies(\n deps: Record<string, NpmPackageV1>,\n result: Record<string, string> = {},\n): Record<string, string> {\n for (const [name, pkg] of Object.entries(deps)) {\n if (pkg.version && !result[name]) {\n result[name] = pkg.version;\n }\n if (pkg.dependencies) {\n parseV1Dependencies(pkg.dependencies, result);\n }\n }\n return result;\n}\n","import { parse as parseYaml } from 'yaml';\n\ninterface PnpmLock {\n lockfileVersion?: string | number;\n packages?: Record<string, unknown>;\n}\n\nexport function parsePnpmLock(content: string): Record<string, string> {\n const data = parseYaml(content) as PnpmLock;\n if (!data?.packages) return {};\n\n const lockfileVersion = parseLockfileVersion(data.lockfileVersion);\n\n if (lockfileVersion >= 9) {\n return parsePnpmV9(data.packages);\n }\n return parsePnpmLegacy(data.packages);\n}\n\nfunction parseLockfileVersion(v: string | number | undefined): number {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') return Number.parseFloat(v);\n return 0;\n}\n\nfunction parsePnpmV9(packages: Record<string, unknown>): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const key of Object.keys(packages)) {\n let name: string;\n let version: string;\n\n if (key.startsWith('@')) {\n const atIdx = key.indexOf('@', 1);\n if (atIdx < 0) continue;\n name = key.slice(0, atIdx);\n version = key.slice(atIdx + 1);\n } else {\n const atIdx = key.indexOf('@');\n if (atIdx < 0) continue;\n name = key.slice(0, atIdx);\n version = key.slice(atIdx + 1);\n }\n\n version = stripVersionSuffix(version);\n if (name && version && !result[name]) {\n result[name] = version;\n }\n }\n\n return result;\n}\n\nfunction parsePnpmLegacy(packages: Record<string, unknown>): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const key of Object.keys(packages)) {\n const cleaned = key.startsWith('/') ? key.slice(1) : key;\n\n let name: string;\n let version: string;\n\n if (cleaned.startsWith('@')) {\n // Scoped package: @scope/name/version (v5) or @scope/name@version (v6)\n const secondSlash = cleaned.indexOf('/', cleaned.indexOf('/') + 1);\n const secondAt = cleaned.indexOf('@', 1);\n\n if (secondAt > 0 && (secondSlash < 0 || secondAt < secondSlash)) {\n // v6 style: @scope/name@version\n name = cleaned.slice(0, secondAt);\n version = cleaned.slice(secondAt + 1);\n } else if (secondSlash > 0) {\n // v5 style: @scope/name/version\n name = cleaned.slice(0, secondSlash);\n version = cleaned.slice(secondSlash + 1);\n } else {\n continue;\n }\n } else {\n const atIdx = cleaned.indexOf('@');\n const slashIdx = cleaned.indexOf('/');\n\n if (atIdx > 0 && (slashIdx < 0 || atIdx < slashIdx)) {\n // v6 style: name@version\n name = cleaned.slice(0, atIdx);\n version = cleaned.slice(atIdx + 1);\n } else if (slashIdx > 0) {\n // v5 style: name/version\n name = cleaned.slice(0, slashIdx);\n version = cleaned.slice(slashIdx + 1);\n } else {\n continue;\n }\n }\n\n version = stripVersionSuffix(version);\n if (name && version && !result[name]) {\n result[name] = version;\n }\n }\n\n return result;\n}\n\n// Remove peer dep hash suffixes: \"1.2.3_abc123\" or \"1.2.3(peer@1.0)\" → \"1.2.3\"\nfunction stripVersionSuffix(version: string): string {\n return version.split('(')[0].split('_')[0].trim();\n}\n","import { parse as parseYaml } from 'yaml';\n\nexport function parseYarnLock(content: string): Record<string, string> {\n return isYarnBerry(content) ? parseYarnBerry(content) : parseYarnV1(content);\n}\n\nfunction isYarnBerry(content: string): boolean {\n return content.includes('__metadata:');\n}\n\nfunction extractNameFromSpecifier(spec: string): string {\n const trimmed = spec.trim().replace(/^\"|\"$/g, '');\n if (trimmed.startsWith('@')) {\n const idx = trimmed.indexOf('@', 1);\n return idx > 0 ? trimmed.slice(0, idx) : trimmed;\n }\n const atIdx = trimmed.indexOf('@');\n return atIdx > 0 ? trimmed.slice(0, atIdx) : trimmed;\n}\n\nfunction parseYarnV1(content: string): Record<string, string> {\n const packages: Record<string, string> = {};\n const blocks = content.split(/\\n\\n+/);\n\n for (const block of blocks) {\n const trimmed = block.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n const versionMatch = trimmed.match(/^[ \\t]+version \"([^\"]+)\"/m);\n if (!versionMatch) continue;\n\n const headerLine = trimmed.split('\\n')[0].trim().replace(/:$/, '');\n const firstSpecifier = headerLine.split(',')[0].trim().replace(/^\"|\"$/g, '');\n const name = extractNameFromSpecifier(firstSpecifier);\n\n if (name && !packages[name]) {\n packages[name] = versionMatch[1];\n }\n }\n\n return packages;\n}\n\ninterface BerryEntry {\n version?: string;\n linkType?: string;\n}\n\nfunction parseYarnBerry(content: string): Record<string, string> {\n const data = parseYaml(content) as Record<string, BerryEntry | unknown>;\n const packages: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (key === '__metadata') continue;\n if (typeof value !== 'object' || !value) continue;\n\n const entry = value as BerryEntry;\n if (entry.linkType === 'soft') continue;\n if (!entry.version) continue;\n\n const cleanKey = key.replace(/^\"|\"$/g, '');\n const name = extractNameFromBerryKey(cleanKey);\n if (name && !packages[name]) {\n packages[name] = entry.version;\n }\n }\n\n return packages;\n}\n\nfunction extractNameFromBerryKey(key: string): string {\n // Format: \"pkgname@protocol:specifier\" e.g. \"lodash@npm:^4.17.21\"\n if (key.startsWith('@')) {\n const idx = key.indexOf('@', 1);\n return idx > 0 ? key.slice(0, idx) : key;\n }\n return key.split('@')[0];\n}\n","import type { Ecosystem, SupportedLockfile } from '../base.js';\nimport { normalizeJsName, parseDirectDeps } from './package-json.js';\nimport { parseBunLock } from './parsers/bun.js';\nimport { parseNpmLock } from './parsers/npm.js';\nimport { parsePnpmLock } from './parsers/pnpm.js';\nimport { parseYarnLock } from './parsers/yarn.js';\n\nconst SUPPORTED_LOCKFILES: SupportedLockfile[] = [\n { filename: 'package-lock.json', type: 'npm' },\n { filename: 'yarn.lock', type: 'yarn' },\n { filename: 'pnpm-lock.yaml', type: 'pnpm' },\n { filename: 'bun.lock', type: 'bun' },\n];\n\nconst lockfileTypeMap = new Map(SUPPORTED_LOCKFILES.map((l) => [l.filename, l.type]));\n\nexport const javascriptEcosystem: Ecosystem = {\n name: 'javascript',\n supportedLockfiles: SUPPORTED_LOCKFILES,\n manifestName: 'package.json',\n\n getLockfileType(filename: string): string | undefined {\n return lockfileTypeMap.get(filename);\n },\n\n parseLockfile(content: string, lockfileType: string): Record<string, string> {\n switch (lockfileType) {\n case 'npm':\n return parseNpmLock(content);\n case 'yarn':\n return parseYarnLock(content);\n case 'pnpm':\n return parsePnpmLock(content);\n case 'bun':\n return parseBunLock(content);\n default:\n return {};\n }\n },\n\n parseDirectDeps(manifestContent: string) {\n return parseDirectDeps(manifestContent);\n },\n\n normalizeName(name: string): string {\n return normalizeJsName(name);\n },\n};\n","import { parse } from 'smol-toml';\n\ninterface TomlPackage {\n name?: unknown;\n version?: unknown;\n}\n\ninterface TomlData {\n package?: TomlPackage[];\n packages?: TomlPackage[]; // PEP 751 (pylock.toml) uses plural\n}\n\nexport function parseTomlPackages(content: string): Record<string, string> {\n try {\n const data = parse(content) as TomlData;\n const packages: Record<string, string> = {};\n for (const pkg of [...(data.package ?? []), ...(data.packages ?? [])]) {\n if (typeof pkg.name === 'string' && typeof pkg.version === 'string') {\n packages[pkg.name] = pkg.version;\n }\n }\n return packages;\n } catch {\n return parseTomlPackagesRegex(content);\n }\n}\n\nfunction parseTomlPackagesRegex(content: string): Record<string, string> {\n const packages: Record<string, string> = {};\n // matches both [[package]] (uv/poetry/pdm) and [[packages]] (pylock.toml / PEP 751)\n const blocks = content.split(/\\[\\[packages?\\]\\]/);\n for (const block of blocks) {\n const nameMatch = block.match(/\\nname\\s*=\\s*\"([^\"]+)\"/);\n const versionMatch = block.match(/\\nversion\\s*=\\s*\"([^\"]+)\"/);\n if (nameMatch && versionMatch) {\n packages[nameMatch[1]] = versionMatch[1];\n }\n }\n return packages;\n}\n","import { parse } from 'smol-toml';\nimport type { DirectDeps } from '../../types.js';\n\nexport function normalizePythonName(name: string): string {\n return name.toLowerCase().replace(/[-_.]+/g, '_');\n}\n\nfunction extractPkgName(dep: string): string | null {\n const match = String(dep).match(/^([\\w][\\w.-]*)/);\n return match ? normalizePythonName(match[1]) : null;\n}\n\nexport function parseDirectDeps(content: string): DirectDeps {\n const prod = new Set<string>();\n const dev = new Set<string>();\n\n let data: Record<string, unknown>;\n try {\n data = parse(content) as Record<string, unknown>;\n } catch {\n return { prod, dev };\n }\n\n // PEP 517/518: [project].dependencies → prod\n const project = data.project as Record<string, unknown> | undefined;\n const pep517Deps = project?.dependencies as string[] | undefined;\n if (Array.isArray(pep517Deps)) {\n for (const dep of pep517Deps) {\n const name = extractPkgName(dep);\n if (name) prod.add(name);\n }\n }\n\n // PEP 517/518: [project.optional-dependencies].* → dev\n const optDeps = project?.['optional-dependencies'] as Record<string, string[]> | undefined;\n if (optDeps && typeof optDeps === 'object') {\n for (const group of Object.values(optDeps)) {\n if (Array.isArray(group)) {\n for (const dep of group) {\n const name = extractPkgName(dep);\n if (name && !prod.has(name)) dev.add(name);\n }\n }\n }\n }\n\n const tool = data.tool as Record<string, unknown> | undefined;\n const poetry = tool?.poetry as Record<string, unknown> | undefined;\n if (poetry) {\n // [tool.poetry.dependencies] → prod\n const poetryDeps = poetry.dependencies as Record<string, unknown> | undefined;\n if (poetryDeps) {\n for (const key of Object.keys(poetryDeps)) {\n if (key.toLowerCase() !== 'python') prod.add(normalizePythonName(key));\n }\n }\n\n // [tool.poetry.dev-dependencies] → dev\n const devDeps = poetry['dev-dependencies'] as Record<string, unknown> | undefined;\n if (devDeps) {\n for (const key of Object.keys(devDeps)) {\n const normalized = normalizePythonName(key);\n if (!prod.has(normalized)) dev.add(normalized);\n }\n }\n\n // [tool.poetry.group.*].dependencies → dev\n const groups = poetry.group as Record<string, Record<string, unknown>> | undefined;\n if (groups) {\n for (const group of Object.values(groups)) {\n const groupDeps = group.dependencies as Record<string, unknown> | undefined;\n if (groupDeps) {\n for (const key of Object.keys(groupDeps)) {\n const normalized = normalizePythonName(key);\n if (!prod.has(normalized)) dev.add(normalized);\n }\n }\n }\n }\n }\n\n // [tool.uv.dev-dependencies] → dev\n const uv = tool?.uv as Record<string, unknown> | undefined;\n const uvDevDeps = uv?.['dev-dependencies'] as string[] | undefined;\n if (Array.isArray(uvDevDeps)) {\n for (const dep of uvDevDeps) {\n const name = extractPkgName(dep);\n if (name && !prod.has(name)) dev.add(name);\n }\n }\n\n // [dependency-groups].* → dev (PEP 735)\n const depGroups = data['dependency-groups'] as Record<string, unknown[]> | undefined;\n if (depGroups && typeof depGroups === 'object') {\n for (const group of Object.values(depGroups)) {\n if (Array.isArray(group)) {\n for (const entry of group) {\n if (typeof entry === 'string') {\n const name = extractPkgName(entry);\n if (name && !prod.has(name)) dev.add(name);\n }\n }\n }\n }\n }\n\n return { prod, dev };\n}\n","import type { Ecosystem, SupportedLockfile } from '../base.js';\nimport { parseTomlPackages } from './parsers/toml.js';\nimport { normalizePythonName, parseDirectDeps } from './pyproject.js';\n\nconst SUPPORTED_LOCKFILES: SupportedLockfile[] = [\n { filename: 'uv.lock', type: 'uv' },\n { filename: 'poetry.lock', type: 'poetry' },\n { filename: 'pdm.lock', type: 'pdm' },\n { filename: 'pylock.toml', type: 'pylock' }, // PEP 751\n];\n\nconst lockfileTypeMap = new Map(SUPPORTED_LOCKFILES.map((l) => [l.filename, l.type]));\n\nexport const pythonEcosystem: Ecosystem = {\n name: 'python',\n supportedLockfiles: SUPPORTED_LOCKFILES,\n manifestName: 'pyproject.toml',\n\n getLockfileType(filename: string): string | undefined {\n return lockfileTypeMap.get(filename);\n },\n\n parseLockfile(content: string, _lockfileType: string): Record<string, string> {\n return parseTomlPackages(content);\n },\n\n parseDirectDeps(manifestContent: string) {\n return parseDirectDeps(manifestContent);\n },\n\n normalizeName(name: string): string {\n return normalizePythonName(name);\n },\n};\n","import type { Ecosystem } from './base.js';\nimport { denoEcosystem } from './deno/index.js';\nimport { javascriptEcosystem } from './javascript/index.js';\nimport { pythonEcosystem } from './python/index.js';\n\nconst registry = new Map<string, Ecosystem>();\n\nexport function registerEcosystem(ecosystem: Ecosystem): void {\n registry.set(ecosystem.name, ecosystem);\n}\n\nexport function getEcosystemByName(name: string): Ecosystem | undefined {\n return registry.get(name);\n}\n\nexport function getEcosystemForLockfile(filename: string): Ecosystem | undefined {\n for (const ecosystem of registry.values()) {\n if (ecosystem.getLockfileType(filename) !== undefined) return ecosystem;\n }\n return undefined;\n}\n\nexport function getAllEcosystems(): Ecosystem[] {\n return [...registry.values()];\n}\n\nregisterEcosystem(pythonEcosystem);\nregisterEcosystem(javascriptEcosystem);\nregisterEcosystem(denoEcosystem);\n","import type { DirectDeps, PackageChange } from '../types.js';\n\nexport function diffPackages(\n oldPkgs: Record<string, string>,\n newPkgs: Record<string, string>,\n directDeps: DirectDeps,\n normalizeName: (name: string) => string,\n): PackageChange[] {\n const allNames = new Set([...Object.keys(oldPkgs), ...Object.keys(newPkgs)]);\n const changes: PackageChange[] = [];\n\n for (const name of [...allNames].sort()) {\n const inOld = name in oldPkgs;\n const inNew = name in newPkgs;\n\n if (inOld && inNew && oldPkgs[name] === newPkgs[name]) continue;\n\n const normalized = normalizeName(name);\n const isProd = directDeps.prod.has(normalized);\n const isDev = directDeps.dev.has(normalized) && !isProd;\n\n changes.push({\n name,\n change_type: !inOld ? 'added' : !inNew ? 'removed' : 'updated',\n old_version: inOld ? oldPkgs[name] : null,\n new_version: inNew ? newPkgs[name] : null,\n is_direct: isProd || isDev,\n is_dev: isDev,\n });\n }\n\n return changes;\n}\n","import { posix } from 'node:path';\nimport { getAllEcosystems, getEcosystemForLockfile } from '../ecosystems/index.js';\nimport type { FileSource, LockfilePair } from '../types.js';\n\nexport interface LockfileInfo {\n path: string;\n type: string;\n ecosystemName: string;\n}\n\nexport function workspaceFromPath(filePath: string): string {\n const parent = posix.dirname(filePath);\n return parent === '.' || parent === '' ? '.' : parent;\n}\n\nexport function detectLockfileInfo(filePath: string): LockfileInfo | null {\n const filename = posix.basename(filePath);\n const ecosystem = getEcosystemForLockfile(filename);\n if (!ecosystem) return null;\n const type = ecosystem.getLockfileType(filename);\n if (!type) return null;\n return { path: filePath, type, ecosystemName: ecosystem.name };\n}\n\nexport function findAllLockfiles(paths: string[]): LockfileInfo[] {\n return paths.flatMap((p) => {\n const info = detectLockfileInfo(p);\n return info ? [info] : [];\n });\n}\n\nexport async function findLockfiles(getFile: FileSource): Promise<LockfileInfo[]> {\n const candidates = getAllEcosystems().flatMap((ecosystem) =>\n ecosystem.supportedLockfiles.map(({ filename, type }) => ({\n filename,\n type,\n ecosystemName: ecosystem.name,\n })),\n );\n\n const results = await Promise.all(\n candidates.map(async ({ filename, type, ecosystemName }) => {\n const content = await getFile(filename);\n return content !== null ? ({ path: filename, type, ecosystemName } as LockfileInfo) : null;\n }),\n );\n\n return results.filter((r): r is LockfileInfo => r !== null);\n}\n\nexport function groupByWorkspace(lockfiles: LockfileInfo[]): Map<string, LockfileInfo[]> {\n const result = new Map<string, LockfileInfo[]>();\n for (const lf of lockfiles) {\n const ws = workspaceFromPath(lf.path);\n const existing = result.get(ws) ?? [];\n existing.push(lf);\n result.set(ws, existing);\n }\n return result;\n}\n\nconst LOCKFILE_PRIORITY: Record<string, number> = {\n 'uv.lock': 0,\n 'poetry.lock': 1,\n 'pdm.lock': 2,\n};\n\nfunction lockfilePriority(path: string): number {\n return LOCKFILE_PRIORITY[posix.basename(path)] ?? 99;\n}\n\nexport function resolveLockfilePair(\n baseFiles: LockfileInfo[],\n headFiles: LockfileInfo[],\n): LockfilePair | null {\n const headByPath = new Map(headFiles.map((f) => [f.path, f]));\n const common = baseFiles.filter((f) => headByPath.has(f.path));\n\n if (common.length > 0) {\n const chosen = common.sort((a, b) => lockfilePriority(a.path) - lockfilePriority(b.path))[0];\n return {\n basePath: chosen.path,\n baseType: chosen.type,\n headPath: chosen.path,\n // biome-ignore lint/style/noNonNullAssertion: path is guaranteed present (comes from common set)\n headType: headByPath.get(chosen.path)!.type,\n migrationNote: null,\n ecosystemName: chosen.ecosystemName,\n };\n }\n\n if (baseFiles.length > 0 && headFiles.length > 0) {\n const base = baseFiles[0];\n const head = headFiles[0];\n return {\n basePath: base.path,\n baseType: base.type,\n headPath: head.path,\n headType: head.type,\n migrationNote: `lockfile migration: ${posix.basename(base.path)} (${base.type}) → ${posix.basename(head.path)} (${head.type})`,\n ecosystemName: head.ecosystemName,\n };\n }\n\n if (headFiles.length > 0) {\n const head = headFiles[0];\n return {\n basePath: null,\n baseType: null,\n headPath: head.path,\n headType: head.type,\n migrationNote: `new lockfile added: ${posix.basename(head.path)} (${head.type})`,\n ecosystemName: head.ecosystemName,\n };\n }\n\n if (baseFiles.length > 0) {\n const base = baseFiles[0];\n return {\n basePath: base.path,\n baseType: base.type,\n headPath: null,\n headType: null,\n migrationNote: `lockfile removed: ${posix.basename(base.path)} (${base.type})`,\n ecosystemName: base.ecosystemName,\n };\n }\n\n return null;\n}\n","import { execFileSync } from 'node:child_process';\n\nexport function gitShow(ref: string, path: string): string | null {\n try {\n const result = execFileSync('git', ['show', `${ref}:${path}`], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return result || null;\n } catch {\n return null;\n }\n}\n\nexport function gitLsTree(ref: string): string[] {\n try {\n const result = execFileSync('git', ['ls-tree', '-r', '--name-only', ref], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return result.trim().split('\\n').filter(Boolean);\n } catch {\n return [];\n }\n}\n","import { execFileSync } from 'node:child_process';\n\nconst API_BASE = 'https://api.github.com';\n\nlet cachedToken: string | undefined;\n\nexport function resolveToken(): string {\n if (cachedToken) return cachedToken;\n if (process.env.GITHUB_TOKEN) {\n cachedToken = process.env.GITHUB_TOKEN;\n return cachedToken;\n }\n try {\n const t = execFileSync('gh', ['auth', 'token'], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n if (t) {\n cachedToken = t;\n return cachedToken;\n }\n } catch {\n // gh not installed or not authenticated\n }\n throw new Error('No GitHub token found. Set GITHUB_TOKEN or run `gh auth login`.');\n}\n\nfunction headers(accept = 'application/vnd.github+json'): Record<string, string> {\n return {\n Authorization: `Bearer ${resolveToken()}`,\n Accept: accept,\n 'X-GitHub-Api-Version': '2022-11-28',\n };\n}\n\nexport async function ghFileAtSha(sha: string, path: string, repo: string): Promise<string | null> {\n const url = `${API_BASE}/repos/${repo}/contents/${path}?ref=${sha}`;\n const response = await fetch(url, {\n headers: headers('application/vnd.github.raw+json'),\n });\n if (!response.ok) return null;\n return response.text();\n}\n\nexport async function ghLsTree(sha: string, repo: string): Promise<string[]> {\n const url = `${API_BASE}/repos/${repo}/git/trees/${sha}?recursive=1`;\n const response = await fetch(url, { headers: headers() });\n if (!response.ok) return [];\n const data = (await response.json()) as {\n tree: Array<{ path: string; type: string }>;\n truncated: boolean;\n };\n return data.tree.filter((item) => item.type === 'blob').map((item) => item.path);\n}\n\nexport interface PrShas {\n baseRefOid: string;\n headRefOid: string;\n}\n\nexport async function getPrShas(prNumber: string, repo: string): Promise<PrShas> {\n const url = `${API_BASE}/repos/${repo}/pulls/${prNumber}`;\n const response = await fetch(url, { headers: headers() });\n if (!response.ok) {\n throw new Error(`GitHub API error ${response.status}: failed to fetch PR #${prNumber}`);\n }\n const data = (await response.json()) as { base: { sha: string }; head: { sha: string } };\n return { baseRefOid: data.base.sha, headRefOid: data.head.sha };\n}\n\nexport function detectRepo(): string {\n const fromEnv = process.env.GITHUB_REPOSITORY;\n if (fromEnv) return fromEnv;\n\n try {\n const remote = execFileSync('git', ['remote', 'get-url', 'origin'], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n const match = remote.match(/github\\.com[:/]([^/]+\\/[^/.]+?)(?:\\.git)?$/);\n if (match) return match[1];\n } catch {\n // fall through\n }\n\n throw new Error('Could not detect GitHub repo — set GITHUB_REPOSITORY or pass --repo');\n}\n","import { readFileSync } from 'node:fs';\n\nexport function readLocalFile(path: string): string | null {\n try {\n return readFileSync(path, 'utf-8');\n } catch {\n return null;\n }\n}\n","import { buildDiffReport, collectLockfileEntries } from './core/report.js';\nimport { gitLsTree, gitShow } from './sources/git.js';\nimport { detectRepo, getPrShas, ghFileAtSha, ghLsTree } from './sources/github.js';\nimport { readLocalFile } from './sources/local.js';\nimport type { DiffReport, FileSource } from './types.js';\n\nexport type { Ecosystem, SupportedLockfile } from './ecosystems/base.js';\nexport { registerEcosystem } from './ecosystems/index.js';\nexport type {\n DiffReport,\n DirectDeps,\n LockfileEntry,\n LockfilePair,\n MigrationInfo,\n PackageChange,\n} from './types.js';\n\nexport interface RunOptions {\n base?: string;\n head?: string;\n /** Explicit base commit SHA — skips getPrShas. Used for push events. */\n baseSha?: string;\n /** Explicit head commit SHA — skips getPrShas. Used for push events. */\n headSha?: string;\n prNumber?: string;\n repo?: string;\n lockfile?: string;\n lockfileType?: string;\n oldFile?: string;\n newFile?: string;\n onNote?: (message: string) => void;\n}\n\nasync function resolveApiShas(\n options: RunOptions,\n): Promise<{ baseSha: string; headSha: string; repo: string } | null> {\n if (options.baseSha && options.headSha) {\n return {\n baseSha: options.baseSha,\n headSha: options.headSha,\n repo: options.repo ?? detectRepo(),\n };\n }\n if (options.prNumber) {\n const repo = options.repo ?? detectRepo();\n const { baseRefOid, headRefOid } = await getPrShas(options.prNumber, repo);\n return { baseSha: baseRefOid, headSha: headRefOid, repo };\n }\n return null;\n}\n\nexport async function run(options: RunOptions = {}): Promise<DiffReport> {\n const { lockfile, lockfileType, onNote } = options;\n\n if (options.oldFile && options.newFile) {\n const oldPath = options.oldFile;\n const newPath = options.newFile;\n\n const getBase: FileSource = (path) =>\n Promise.resolve(path === oldPath ? readLocalFile(oldPath) : null);\n const getHead: FileSource = (path) =>\n Promise.resolve(path === newPath ? readLocalFile(newPath) : null);\n\n const lockfiles = await collectLockfileEntries({\n getBase,\n getHead,\n allBasePaths: [oldPath],\n allHeadPaths: [newPath],\n lockfile: newPath,\n lockfileType,\n onNote,\n });\n\n if (lockfiles.length === 0) throw new Error('No supported lockfiles found');\n return buildDiffReport(lockfiles, 'local_old', 'local_new');\n }\n\n const apiShas = await resolveApiShas(options);\n\n if (apiShas) {\n const { baseSha, headSha, repo } = apiShas;\n\n const getBase: FileSource = (path) => ghFileAtSha(baseSha, path, repo);\n const getHead: FileSource = (path) => ghFileAtSha(headSha, path, repo);\n\n const [basePaths, headPaths] = await Promise.all([\n ghLsTree(baseSha, repo),\n ghLsTree(headSha, repo),\n ]);\n\n const lockfiles = await collectLockfileEntries({\n getBase,\n getHead,\n allBasePaths: basePaths,\n allHeadPaths: headPaths,\n lockfile,\n lockfileType,\n onNote,\n });\n\n if (lockfiles.length === 0) throw new Error('No supported lockfiles found');\n return buildDiffReport(lockfiles, baseSha, headSha);\n }\n\n // Git ref mode: local CLI usage\n const baseRef = options.base ?? 'HEAD~1';\n const headRef = options.head ?? 'HEAD';\n\n const getBase: FileSource = (path) => Promise.resolve(gitShow(baseRef, path));\n const getHead: FileSource = (path) => Promise.resolve(gitShow(headRef, path));\n\n const lockfiles = await collectLockfileEntries({\n getBase,\n getHead,\n allBasePaths: gitLsTree(baseRef),\n allHeadPaths: gitLsTree(headRef),\n lockfile,\n lockfileType,\n onNote,\n });\n\n if (lockfiles.length === 0) throw new Error('No supported lockfiles found');\n return buildDiffReport(lockfiles, baseRef, headRef);\n}\n"],"mappings":"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","names":["posix","atIdx","registry","atIdx","parseDirectDeps","atIdx","parseYaml","SUPPORTED_LOCKFILES","parseDirectDeps","parse","parseDirectDeps","SUPPORTED_LOCKFILES","lockfileTypeMap","parseDirectDeps","posix","execFileSync","getBase","getHead","lockfiles"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/core/report.ts","../src/ecosystems/deno/deno-json.ts","../src/ecosystems/deno/parsers/deno-lock.ts","../src/ecosystems/deno/index.ts","../src/ecosystems/javascript/package-json.ts","../src/ecosystems/javascript/parsers/bun.ts","../src/ecosystems/javascript/parsers/npm.ts","../src/ecosystems/javascript/parsers/pnpm.ts","../src/ecosystems/javascript/parsers/yarn.ts","../src/ecosystems/javascript/index.ts","../src/ecosystems/python/parsers/toml.ts","../src/ecosystems/python/pyproject.ts","../src/ecosystems/python/index.ts","../src/ecosystems/index.ts","../src/core/diff.ts","../src/core/discovery.ts","../src/sources/git.ts","../src/sources/github.ts","../src/sources/local.ts","../src/index.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs';\nimport { Command } from 'commander';\nimport { run } from './index.js';\n\nconst program = new Command();\n\nprogram\n .name('lockdelta')\n .description('Diff dependency lockfiles between git refs, PRs, or local files')\n .version('0.1.0')\n .option(\n '--base <ref>',\n 'Base git ref (default: HEAD~1). In CI, reads GITHUB_BASE_REF — may need \"origin/\" prefix.',\n process.env.GITHUB_BASE_REF,\n )\n .option(\n '--head <ref>',\n 'Head git ref (default: HEAD). In CI, reads GITHUB_HEAD_REF.',\n process.env.GITHUB_HEAD_REF,\n )\n .option(\n '--pr <number>',\n 'GitHub PR number. Fetches exact SHAs via gh CLI.',\n process.env.GITHUB_PR_NUMBER,\n )\n .option(\n '--repo <owner/name>',\n 'GitHub repo in OWNER/NAME format. Auto-detected if omitted.',\n process.env.GITHUB_REPOSITORY,\n )\n .option('--lockfile <path>', 'Specific lockfile path. Auto-discovers all lockfiles if omitted.')\n .option('--type <type>', 'Force lockfile type: uv, poetry, pdm. Only used with --lockfile.')\n .option('--old <path>', 'Old lockfile path (local file comparison mode).')\n .option('--new <path>', 'New lockfile path (local file comparison mode).')\n .option('--output <path>', 'Write JSON report to file instead of stdout.')\n .action(async (opts) => {\n try {\n const report = await run({\n base: opts.base,\n head: opts.head,\n prNumber: opts.pr,\n repo: opts.repo,\n lockfile: opts.lockfile,\n lockfileType: opts.type,\n oldFile: opts.old,\n newFile: opts.new,\n onNote: (msg) => process.stderr.write(`Note: ${msg}\\n`),\n });\n\n const json = `${JSON.stringify(report, null, 2)}\\n`;\n\n if (opts.output) {\n writeFileSync(opts.output, json, 'utf-8');\n process.stderr.write(`Report written to ${opts.output}\\n`);\n } else {\n process.stdout.write(json);\n }\n } catch (err) {\n process.stderr.write(`ERROR: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n }\n });\n\nprogram.parse();\n","import { posix } from 'node:path';\nimport { getEcosystemByName, getEcosystemForLockfile } from '../ecosystems/index.js';\nimport type { DiffReport, FileSource, LockfileEntry, LockfilePair } from '../types.js';\nimport { diffPackages } from './diff.js';\nimport {\n findAllLockfiles,\n findLockfiles,\n groupByWorkspace,\n resolveLockfilePair,\n} from './discovery.js';\n\nexport async function buildLockfileEntry(\n pair: LockfilePair,\n workspace: string,\n getBase: FileSource,\n getHead: FileSource,\n): Promise<LockfileEntry | null> {\n const ecosystem = getEcosystemByName(pair.ecosystemName);\n if (!ecosystem) return null;\n\n const manifestPath = ecosystem.manifestName\n ? workspace === '.'\n ? ecosystem.manifestName\n : posix.join(workspace, ecosystem.manifestName)\n : null;\n\n const [oldContent, newContent, manifestContent] = await Promise.all([\n pair.basePath ? getBase(pair.basePath) : Promise.resolve(null),\n pair.headPath ? getHead(pair.headPath) : Promise.resolve(null),\n manifestPath ? getHead(manifestPath) : Promise.resolve(null),\n ]);\n\n const oldPkgs =\n oldContent && pair.baseType ? ecosystem.parseLockfile(oldContent, pair.baseType) : {};\n const newPkgs =\n newContent && pair.headType ? ecosystem.parseLockfile(newContent, pair.headType) : {};\n\n const directDeps = manifestContent\n ? ecosystem.parseDirectDeps(manifestContent)\n : { prod: new Set<string>(), dev: new Set<string>() };\n\n const changes = diffPackages(\n oldPkgs,\n newPkgs,\n directDeps,\n ecosystem.normalizeName.bind(ecosystem),\n );\n\n const added = changes.filter((c) => c.change_type === 'added').length;\n const removed = changes.filter((c) => c.change_type === 'removed').length;\n const updated = changes.filter((c) => c.change_type === 'updated').length;\n\n return {\n path: pair.headPath ?? pair.basePath,\n workspace,\n type: pair.headType ?? pair.baseType,\n ecosystem: pair.ecosystemName,\n summary: { added, removed, updated, total_changes: changes.length },\n changes,\n migration: pair.migrationNote\n ? {\n note: pair.migrationNote,\n base_lockfile: pair.basePath,\n base_lockfile_type: pair.baseType,\n head_lockfile: pair.headPath,\n head_lockfile_type: pair.headType,\n }\n : null,\n };\n}\n\nexport interface CollectOptions {\n getBase: FileSource;\n getHead: FileSource;\n allBasePaths: string[];\n allHeadPaths: string[];\n lockfile?: string;\n lockfileType?: string;\n onNote?: (message: string) => void;\n}\n\nexport async function collectLockfileEntries(options: CollectOptions): Promise<LockfileEntry[]> {\n const { getBase, getHead, allBasePaths, allHeadPaths, lockfile, lockfileType, onNote } = options;\n\n if (lockfile) {\n const filename = posix.basename(lockfile);\n const ecosystem = getEcosystemForLockfile(filename);\n if (!ecosystem) throw new Error(`Cannot determine ecosystem for lockfile: ${lockfile}`);\n const type = lockfileType ?? ecosystem.getLockfileType(filename);\n if (!type) throw new Error(`Cannot determine lockfile type for ${lockfile} — use --type`);\n const ws = posix.dirname(lockfile);\n const pair: LockfilePair = {\n basePath: lockfile,\n baseType: type,\n headPath: lockfile,\n headType: type,\n migrationNote: null,\n ecosystemName: ecosystem.name,\n };\n const entry = await buildLockfileEntry(\n pair,\n ws === '.' || ws === '' ? '.' : ws,\n getBase,\n getHead,\n );\n return entry ? [entry] : [];\n }\n\n let baseAll = findAllLockfiles(allBasePaths);\n let headAll = findAllLockfiles(allHeadPaths);\n\n if (baseAll.length === 0 && headAll.length === 0) {\n [baseAll, headAll] = await Promise.all([findLockfiles(getBase), findLockfiles(getHead)]);\n }\n\n const baseByWs = groupByWorkspace(baseAll);\n const headByWs = groupByWorkspace(headAll);\n const allWorkspaces = [...new Set([...baseByWs.keys(), ...headByWs.keys()])].sort();\n\n const entries = await Promise.all(\n allWorkspaces.map(async (ws) => {\n const baseFiles = baseByWs.get(ws) ?? [];\n const headFiles = headByWs.get(ws) ?? [];\n const pair = resolveLockfilePair(baseFiles, headFiles);\n if (!pair) return null;\n if (pair.migrationNote) onNote?.(`[${ws}]: ${pair.migrationNote}`);\n return buildLockfileEntry(pair, ws, getBase, getHead);\n }),\n );\n\n return entries.filter((e): e is LockfileEntry => e !== null);\n}\n\nexport function buildDiffReport(\n lockfiles: LockfileEntry[],\n baseRef: string,\n headRef: string,\n): DiffReport {\n const totalAdded = lockfiles.reduce((sum, lf) => sum + lf.summary.added, 0);\n const totalRemoved = lockfiles.reduce((sum, lf) => sum + lf.summary.removed, 0);\n const totalUpdated = lockfiles.reduce((sum, lf) => sum + lf.summary.updated, 0);\n const ecosystems = [...new Set(lockfiles.map((lf) => lf.ecosystem))].sort();\n\n return {\n schema_version: '1',\n generated_at: new Date().toISOString(),\n base_ref: baseRef,\n head_ref: headRef,\n summary: {\n added: totalAdded,\n removed: totalRemoved,\n updated: totalUpdated,\n total_changes: totalAdded + totalRemoved + totalUpdated,\n ecosystems,\n },\n lockfiles,\n };\n}\n","import type { DirectDeps } from '../../types.js';\n\nexport function normalizeDenoName(name: string): string {\n return name.toLowerCase();\n}\n\nexport function parseDirectDeps(content: string): DirectDeps {\n const prod = new Set<string>();\n\n let data: Record<string, unknown>;\n try {\n data = JSON.parse(content) as Record<string, unknown>;\n } catch {\n return { prod, dev: new Set() };\n }\n\n const imports = data.imports as Record<string, string> | undefined;\n if (imports) {\n for (const specifier of Object.values(imports)) {\n const name = extractPackageName(specifier);\n if (name) prod.add(normalizeDenoName(name));\n }\n }\n\n const workspace = data.workspace as { dependencies?: string[] } | undefined;\n for (const specifier of workspace?.dependencies ?? []) {\n const name = extractPackageName(specifier);\n if (name) prod.add(normalizeDenoName(name));\n }\n\n return { prod, dev: new Set() };\n}\n\nfunction extractPackageName(specifier: string): string | null {\n // Handles \"npm:chalk@^5.3.0\", \"jsr:@std/path@^0.224.0\", \"node:fs\"\n const withoutProtocol = specifier.replace(/^(?:npm|jsr|node):/, '');\n\n // node: builtins have no version — skip\n if (specifier.startsWith('node:')) return null;\n\n if (withoutProtocol.startsWith('@')) {\n const atIdx = withoutProtocol.indexOf('@', 1);\n return atIdx > 0 ? withoutProtocol.slice(0, atIdx) : withoutProtocol;\n }\n const atIdx = withoutProtocol.indexOf('@');\n return atIdx > 0 ? withoutProtocol.slice(0, atIdx) : withoutProtocol || null;\n}\n","import type { PackageEntry } from '../../../types.js';\n\ninterface DenoLock {\n version?: string;\n packages?: {\n npm?: Record<string, unknown>;\n jsr?: Record<string, unknown>;\n };\n}\n\nexport function parseDenoLock(content: string): Record<string, PackageEntry> {\n const data = JSON.parse(content) as DenoLock;\n const result: Record<string, PackageEntry> = {};\n\n for (const [key, registry] of [\n ['npm', data.packages?.npm],\n ['jsr', data.packages?.jsr],\n ] as const) {\n if (!registry) continue;\n for (const specifier of Object.keys(registry)) {\n const { name, version } = splitSpecifier(specifier);\n // Prefix JSR packages to avoid collisions with same-named npm packages\n const resultKey = key === 'jsr' ? `jsr:${name}` : name;\n if (name && version && !result[resultKey]) {\n result[resultKey] = { version };\n }\n }\n }\n\n return result;\n}\n\nfunction splitSpecifier(specifier: string): { name: string; version: string } {\n if (specifier.startsWith('@')) {\n const atIdx = specifier.indexOf('@', 1);\n if (atIdx < 0) return { name: specifier, version: '' };\n return { name: specifier.slice(0, atIdx), version: specifier.slice(atIdx + 1) };\n }\n const atIdx = specifier.indexOf('@');\n if (atIdx < 0) return { name: specifier, version: '' };\n return { name: specifier.slice(0, atIdx), version: specifier.slice(atIdx + 1) };\n}\n","import type { Ecosystem, SupportedLockfile } from '../base.js';\nimport { normalizeDenoName, parseDirectDeps } from './deno-json.js';\nimport { parseDenoLock } from './parsers/deno-lock.js';\n\nconst SUPPORTED_LOCKFILES: SupportedLockfile[] = [{ filename: 'deno.lock', type: 'deno' }];\n\nexport const denoEcosystem: Ecosystem = {\n name: 'deno',\n supportedLockfiles: SUPPORTED_LOCKFILES,\n manifestName: 'deno.json',\n\n getLockfileType(filename: string): string | undefined {\n return filename === 'deno.lock' ? 'deno' : undefined;\n },\n\n parseLockfile(content: string, _lockfileType: string) {\n return parseDenoLock(content);\n },\n\n parseDirectDeps(manifestContent: string) {\n return parseDirectDeps(manifestContent);\n },\n\n normalizeName(name: string): string {\n return normalizeDenoName(name);\n },\n};\n","import type { DirectDeps } from '../../types.js';\n\nconst PROD_SECTIONS = ['dependencies', 'optionalDependencies', 'peerDependencies'] as const;\n\nexport function normalizeJsName(name: string): string {\n return name.toLowerCase();\n}\n\nexport function parseDirectDeps(content: string): DirectDeps {\n const prod = new Set<string>();\n const dev = new Set<string>();\n\n let data: Record<string, Record<string, string>>;\n try {\n data = JSON.parse(content) as Record<string, Record<string, string>>;\n } catch {\n return { prod, dev };\n }\n\n for (const section of PROD_SECTIONS) {\n const deps = data[section];\n if (deps && typeof deps === 'object') {\n for (const name of Object.keys(deps)) {\n prod.add(normalizeJsName(name));\n }\n }\n }\n\n const devDeps = data.devDependencies;\n if (devDeps && typeof devDeps === 'object') {\n for (const name of Object.keys(devDeps)) {\n const normalized = normalizeJsName(name);\n if (!prod.has(normalized)) dev.add(normalized);\n }\n }\n\n return { prod, dev };\n}\n","import type { PackageEntry } from '../../../types.js';\n\ninterface BunLock {\n lockfileVersion?: number;\n packages?: Record<string, unknown[]>;\n}\n\nexport function parseBunLock(content: string): Record<string, PackageEntry> {\n const data = JSON.parse(content) as BunLock;\n const result: Record<string, PackageEntry> = {};\n\n for (const [name, entry] of Object.entries(data.packages ?? {})) {\n if (!Array.isArray(entry)) continue;\n const nameAtVersion = entry[0];\n if (typeof nameAtVersion !== 'string') continue;\n\n const version = extractVersion(nameAtVersion);\n if (!version || version.startsWith('workspace:')) continue;\n\n result[name] = { version };\n }\n\n return result;\n}\n\nfunction extractVersion(nameAtVersion: string): string {\n // Format: \"name@version\" or \"@scope/name@version\"\n if (nameAtVersion.startsWith('@')) {\n const atIdx = nameAtVersion.indexOf('@', 1);\n return atIdx > 0 ? nameAtVersion.slice(atIdx + 1) : '';\n }\n const atIdx = nameAtVersion.indexOf('@');\n return atIdx > 0 ? nameAtVersion.slice(atIdx + 1) : '';\n}\n","import type { PackageEntry } from '../../../types.js';\n\ninterface NpmPackageV1 {\n version?: string;\n resolved?: string;\n dependencies?: Record<string, NpmPackageV1>;\n}\n\ninterface NpmPackageLockV1 {\n lockfileVersion?: number;\n dependencies?: Record<string, NpmPackageV1>;\n}\n\ninterface NpmPackageV2 {\n version?: string;\n resolved?: string;\n}\n\ninterface NpmPackageLockV2 {\n lockfileVersion?: number;\n packages?: Record<string, NpmPackageV2>;\n}\n\nexport function parseNpmLock(content: string): Record<string, PackageEntry> {\n const data = JSON.parse(content) as NpmPackageLockV1 & NpmPackageLockV2;\n const version = data.lockfileVersion ?? 1;\n\n if (version >= 2 && data.packages) {\n return parseV2Packages(data.packages);\n }\n\n if (data.dependencies) {\n return parseV1Dependencies(data.dependencies);\n }\n\n return {};\n}\n\nfunction parseV2Packages(packages: Record<string, NpmPackageV2>): Record<string, PackageEntry> {\n const result: Record<string, PackageEntry> = {};\n\n for (const [key, pkg] of Object.entries(packages)) {\n if (!key) continue;\n if (!key.startsWith('node_modules/')) continue;\n\n const segments = key.split('node_modules/');\n if (segments.length > 2) continue;\n\n const name = key.slice('node_modules/'.length);\n const pkgVersion = pkg.version;\n if (pkgVersion && !result[name]) {\n const entry: PackageEntry = { version: pkgVersion };\n const registryUrl = resolvedToOrigin(pkg.resolved);\n if (registryUrl !== undefined) entry.registryUrl = registryUrl;\n result[name] = entry;\n }\n }\n\n return result;\n}\n\nfunction parseV1Dependencies(\n deps: Record<string, NpmPackageV1>,\n result: Record<string, PackageEntry> = {},\n): Record<string, PackageEntry> {\n for (const [name, pkg] of Object.entries(deps)) {\n if (pkg.version && !result[name]) {\n const entry: PackageEntry = { version: pkg.version };\n const registryUrl = resolvedToOrigin(pkg.resolved);\n if (registryUrl !== undefined) entry.registryUrl = registryUrl;\n result[name] = entry;\n }\n if (pkg.dependencies) {\n parseV1Dependencies(pkg.dependencies, result);\n }\n }\n return result;\n}\n\nfunction resolvedToOrigin(resolved: string | undefined): string | undefined {\n if (!resolved) return undefined;\n try {\n return new URL(resolved).origin;\n } catch {\n return undefined;\n }\n}\n","import { parse as parseYaml } from 'yaml';\nimport type { PackageEntry } from '../../../types.js';\n\ninterface PnpmPackageResolution {\n integrity?: string;\n tarball?: string;\n}\n\ninterface PnpmPackageInfo {\n resolution?: PnpmPackageResolution;\n}\n\ninterface PnpmLock {\n lockfileVersion?: string | number;\n packages?: Record<string, unknown>;\n}\n\nexport function parsePnpmLock(content: string): Record<string, PackageEntry> {\n const data = parseYaml(content) as PnpmLock;\n if (!data?.packages) return {};\n\n const lockfileVersion = parseLockfileVersion(data.lockfileVersion);\n\n if (lockfileVersion >= 9) {\n return parsePnpmV9(data.packages);\n }\n return parsePnpmLegacy(data.packages);\n}\n\nfunction parseLockfileVersion(v: string | number | undefined): number {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') return Number.parseFloat(v);\n return 0;\n}\n\nfunction parsePnpmV9(packages: Record<string, unknown>): Record<string, PackageEntry> {\n const result: Record<string, PackageEntry> = {};\n\n for (const [key, value] of Object.entries(packages)) {\n let name: string;\n let version: string;\n\n if (key.startsWith('@')) {\n const atIdx = key.indexOf('@', 1);\n if (atIdx < 0) continue;\n name = key.slice(0, atIdx);\n version = key.slice(atIdx + 1);\n } else {\n const atIdx = key.indexOf('@');\n if (atIdx < 0) continue;\n name = key.slice(0, atIdx);\n version = key.slice(atIdx + 1);\n }\n\n version = stripVersionSuffix(version);\n if (name && version && !result[name]) {\n const entry: PackageEntry = { version };\n const pkg = value as PnpmPackageInfo | null;\n const registryUrl = pkg?.resolution?.tarball\n ? resolvedToOrigin(pkg.resolution.tarball)\n : undefined;\n if (registryUrl !== undefined) entry.registryUrl = registryUrl;\n result[name] = entry;\n }\n }\n\n return result;\n}\n\nfunction parsePnpmLegacy(packages: Record<string, unknown>): Record<string, PackageEntry> {\n const result: Record<string, PackageEntry> = {};\n\n for (const [key, value] of Object.entries(packages)) {\n const cleaned = key.startsWith('/') ? key.slice(1) : key;\n\n let name: string;\n let version: string;\n\n if (cleaned.startsWith('@')) {\n // Scoped package: @scope/name/version (v5) or @scope/name@version (v6)\n const secondSlash = cleaned.indexOf('/', cleaned.indexOf('/') + 1);\n const secondAt = cleaned.indexOf('@', 1);\n\n if (secondAt > 0 && (secondSlash < 0 || secondAt < secondSlash)) {\n // v6 style: @scope/name@version\n name = cleaned.slice(0, secondAt);\n version = cleaned.slice(secondAt + 1);\n } else if (secondSlash > 0) {\n // v5 style: @scope/name/version\n name = cleaned.slice(0, secondSlash);\n version = cleaned.slice(secondSlash + 1);\n } else {\n continue;\n }\n } else {\n const atIdx = cleaned.indexOf('@');\n const slashIdx = cleaned.indexOf('/');\n\n if (atIdx > 0 && (slashIdx < 0 || atIdx < slashIdx)) {\n // v6 style: name@version\n name = cleaned.slice(0, atIdx);\n version = cleaned.slice(atIdx + 1);\n } else if (slashIdx > 0) {\n // v5 style: name/version\n name = cleaned.slice(0, slashIdx);\n version = cleaned.slice(slashIdx + 1);\n } else {\n continue;\n }\n }\n\n version = stripVersionSuffix(version);\n if (name && version && !result[name]) {\n const entry: PackageEntry = { version };\n const pkg = value as PnpmPackageInfo | null;\n const registryUrl = pkg?.resolution?.tarball\n ? resolvedToOrigin(pkg.resolution.tarball)\n : undefined;\n if (registryUrl !== undefined) entry.registryUrl = registryUrl;\n result[name] = entry;\n }\n }\n\n return result;\n}\n\n// Remove peer dep hash suffixes: \"1.2.3_abc123\" or \"1.2.3(peer@1.0)\" → \"1.2.3\"\nfunction stripVersionSuffix(version: string): string {\n return version.split('(')[0].split('_')[0].trim();\n}\n\nfunction resolvedToOrigin(url: string): string | undefined {\n try {\n return new URL(url).origin;\n } catch {\n return undefined;\n }\n}\n","import { parse as parseYaml } from 'yaml';\nimport type { PackageEntry } from '../../../types.js';\n\nexport function parseYarnLock(content: string): Record<string, PackageEntry> {\n return isYarnBerry(content) ? parseYarnBerry(content) : parseYarnV1(content);\n}\n\nfunction isYarnBerry(content: string): boolean {\n return content.includes('__metadata:');\n}\n\nfunction extractNameFromSpecifier(spec: string): string {\n const trimmed = spec.trim().replace(/^\"|\"$/g, '');\n if (trimmed.startsWith('@')) {\n const idx = trimmed.indexOf('@', 1);\n return idx > 0 ? trimmed.slice(0, idx) : trimmed;\n }\n const atIdx = trimmed.indexOf('@');\n return atIdx > 0 ? trimmed.slice(0, atIdx) : trimmed;\n}\n\nfunction parseYarnV1(content: string): Record<string, PackageEntry> {\n const packages: Record<string, PackageEntry> = {};\n const blocks = content.split(/\\n\\n+/);\n\n for (const block of blocks) {\n const trimmed = block.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n\n const versionMatch = trimmed.match(/^[ \\t]+version \"([^\"]+)\"/m);\n if (!versionMatch) continue;\n\n const headerLine = trimmed.split('\\n')[0].trim().replace(/:$/, '');\n const firstSpecifier = headerLine.split(',')[0].trim().replace(/^\"|\"$/g, '');\n const name = extractNameFromSpecifier(firstSpecifier);\n\n if (name && !packages[name]) {\n const entry: PackageEntry = { version: versionMatch[1] };\n const resolvedMatch = trimmed.match(/^[ \\t]+resolved \"([^\"]+)\"/m);\n if (resolvedMatch) {\n const registryUrl = resolvedToOrigin(resolvedMatch[1]);\n if (registryUrl !== undefined) entry.registryUrl = registryUrl;\n }\n packages[name] = entry;\n }\n }\n\n return packages;\n}\n\ninterface BerryEntry {\n version?: string;\n linkType?: string;\n resolution?: string;\n}\n\nfunction parseYarnBerry(content: string): Record<string, PackageEntry> {\n const data = parseYaml(content) as Record<string, BerryEntry | unknown>;\n const packages: Record<string, PackageEntry> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (key === '__metadata') continue;\n if (typeof value !== 'object' || !value) continue;\n\n const berryEntry = value as BerryEntry;\n if (berryEntry.linkType === 'soft') continue;\n if (!berryEntry.version) continue;\n\n const cleanKey = key.replace(/^\"|\"$/g, '');\n const name = extractNameFromBerryKey(cleanKey);\n if (name && !packages[name]) {\n const entry: PackageEntry = { version: berryEntry.version };\n const registryUrl = extractBerryRegistryOrigin(berryEntry.resolution);\n if (registryUrl !== undefined) entry.registryUrl = registryUrl;\n packages[name] = entry;\n }\n }\n\n return packages;\n}\n\nfunction extractNameFromBerryKey(key: string): string {\n // Format: \"pkgname@protocol:specifier\" e.g. \"lodash@npm:^4.17.21\"\n if (key.startsWith('@')) {\n const idx = key.indexOf('@', 1);\n return idx > 0 ? key.slice(0, idx) : key;\n }\n return key.split('@')[0];\n}\n\nfunction extractBerryRegistryOrigin(resolution: string | undefined): string | undefined {\n if (!resolution) return undefined;\n // \"pkgname@npm:version\" → npm public, no registryUrl\n // \"pkgname@https://registry.example.com/...\" → private tarball\n const atIdx = resolution.startsWith('@') ? resolution.indexOf('@', 1) : resolution.indexOf('@');\n if (atIdx < 0) return undefined;\n const spec = resolution.slice(atIdx + 1);\n if (spec.startsWith('http://') || spec.startsWith('https://')) {\n return resolvedToOrigin(spec.split('#')[0]);\n }\n return undefined;\n}\n\nfunction resolvedToOrigin(url: string): string | undefined {\n try {\n return new URL(url).origin;\n } catch {\n return undefined;\n }\n}\n","import type { Ecosystem, SupportedLockfile } from '../base.js';\nimport { normalizeJsName, parseDirectDeps } from './package-json.js';\nimport { parseBunLock } from './parsers/bun.js';\nimport { parseNpmLock } from './parsers/npm.js';\nimport { parsePnpmLock } from './parsers/pnpm.js';\nimport { parseYarnLock } from './parsers/yarn.js';\n\nconst SUPPORTED_LOCKFILES: SupportedLockfile[] = [\n { filename: 'package-lock.json', type: 'npm' },\n { filename: 'yarn.lock', type: 'yarn' },\n { filename: 'pnpm-lock.yaml', type: 'pnpm' },\n { filename: 'bun.lock', type: 'bun' },\n];\n\nconst lockfileTypeMap = new Map(SUPPORTED_LOCKFILES.map((l) => [l.filename, l.type]));\n\nexport const javascriptEcosystem: Ecosystem = {\n name: 'javascript',\n supportedLockfiles: SUPPORTED_LOCKFILES,\n manifestName: 'package.json',\n\n getLockfileType(filename: string): string | undefined {\n return lockfileTypeMap.get(filename);\n },\n\n parseLockfile(content: string, lockfileType: string) {\n switch (lockfileType) {\n case 'npm':\n return parseNpmLock(content);\n case 'yarn':\n return parseYarnLock(content);\n case 'pnpm':\n return parsePnpmLock(content);\n case 'bun':\n return parseBunLock(content);\n default:\n return {};\n }\n },\n\n parseDirectDeps(manifestContent: string) {\n return parseDirectDeps(manifestContent);\n },\n\n normalizeName(name: string): string {\n return normalizeJsName(name);\n },\n};\n","import { parse } from 'smol-toml';\nimport type { PackageEntry } from '../../../types.js';\n\ninterface TomlPackageSource {\n registry?: unknown;\n url?: unknown;\n}\n\ninterface TomlPackage {\n name?: unknown;\n version?: unknown;\n source?: TomlPackageSource;\n}\n\ninterface TomlData {\n package?: TomlPackage[];\n packages?: TomlPackage[]; // PEP 751 (pylock.toml) uses plural\n}\n\nexport function parseTomlPackages(content: string): Record<string, PackageEntry> {\n try {\n const data = parse(content) as TomlData;\n const packages: Record<string, PackageEntry> = {};\n for (const pkg of [...(data.package ?? []), ...(data.packages ?? [])]) {\n if (typeof pkg.name === 'string' && typeof pkg.version === 'string') {\n const entry: PackageEntry = { version: pkg.version };\n // uv.lock: source = { registry = \"...\" }\n // poetry.lock: [package.source] with url = \"...\"\n const sourceUrl =\n typeof pkg.source?.registry === 'string'\n ? pkg.source.registry\n : typeof pkg.source?.url === 'string'\n ? pkg.source.url\n : undefined;\n if (sourceUrl !== undefined) {\n try {\n entry.registryUrl = new URL(sourceUrl).origin;\n } catch {\n // skip malformed URL\n }\n }\n packages[pkg.name] = entry;\n }\n }\n return packages;\n } catch {\n return parseTomlPackagesRegex(content);\n }\n}\n\nfunction parseTomlPackagesRegex(content: string): Record<string, PackageEntry> {\n const packages: Record<string, PackageEntry> = {};\n // matches both [[package]] (uv/poetry/pdm) and [[packages]] (pylock.toml / PEP 751)\n const blocks = content.split(/\\[\\[packages?\\]\\]/);\n for (const block of blocks) {\n const nameMatch = block.match(/\\nname\\s*=\\s*\"([^\"]+)\"/);\n const versionMatch = block.match(/\\nversion\\s*=\\s*\"([^\"]+)\"/);\n if (nameMatch && versionMatch) {\n const entry: PackageEntry = { version: versionMatch[1] };\n // uv.lock inline: source = { registry = \"https://...\" }\n const sourceRegistryMatch = block.match(/source\\s*=\\s*\\{[^}]*registry\\s*=\\s*\"([^\"]+)\"/);\n // poetry.lock sub-table: url = \"https://...\"\n const sourceUrlMatch = block.match(/\\nurl\\s*=\\s*\"([^\"]+)\"/);\n const sourceUrl = sourceRegistryMatch?.[1] ?? sourceUrlMatch?.[1];\n if (sourceUrl !== undefined) {\n try {\n entry.registryUrl = new URL(sourceUrl).origin;\n } catch {\n // skip malformed URL\n }\n }\n packages[nameMatch[1]] = entry;\n }\n }\n return packages;\n}\n","import { parse } from 'smol-toml';\nimport type { DirectDeps } from '../../types.js';\n\nexport function normalizePythonName(name: string): string {\n return name.toLowerCase().replace(/[-_.]+/g, '_');\n}\n\nfunction extractPkgName(dep: string): string | null {\n const match = String(dep).match(/^([\\w][\\w.-]*)/);\n return match ? normalizePythonName(match[1]) : null;\n}\n\nexport function parseDirectDeps(content: string): DirectDeps {\n const prod = new Set<string>();\n const dev = new Set<string>();\n\n let data: Record<string, unknown>;\n try {\n data = parse(content) as Record<string, unknown>;\n } catch {\n return { prod, dev };\n }\n\n // PEP 517/518: [project].dependencies → prod\n const project = data.project as Record<string, unknown> | undefined;\n const pep517Deps = project?.dependencies as string[] | undefined;\n if (Array.isArray(pep517Deps)) {\n for (const dep of pep517Deps) {\n const name = extractPkgName(dep);\n if (name) prod.add(name);\n }\n }\n\n // PEP 517/518: [project.optional-dependencies].* → dev\n const optDeps = project?.['optional-dependencies'] as Record<string, string[]> | undefined;\n if (optDeps && typeof optDeps === 'object') {\n for (const group of Object.values(optDeps)) {\n if (Array.isArray(group)) {\n for (const dep of group) {\n const name = extractPkgName(dep);\n if (name && !prod.has(name)) dev.add(name);\n }\n }\n }\n }\n\n const tool = data.tool as Record<string, unknown> | undefined;\n const poetry = tool?.poetry as Record<string, unknown> | undefined;\n if (poetry) {\n // [tool.poetry.dependencies] → prod\n const poetryDeps = poetry.dependencies as Record<string, unknown> | undefined;\n if (poetryDeps) {\n for (const key of Object.keys(poetryDeps)) {\n if (key.toLowerCase() !== 'python') prod.add(normalizePythonName(key));\n }\n }\n\n // [tool.poetry.dev-dependencies] → dev\n const devDeps = poetry['dev-dependencies'] as Record<string, unknown> | undefined;\n if (devDeps) {\n for (const key of Object.keys(devDeps)) {\n const normalized = normalizePythonName(key);\n if (!prod.has(normalized)) dev.add(normalized);\n }\n }\n\n // [tool.poetry.group.*].dependencies → dev\n const groups = poetry.group as Record<string, Record<string, unknown>> | undefined;\n if (groups) {\n for (const group of Object.values(groups)) {\n const groupDeps = group.dependencies as Record<string, unknown> | undefined;\n if (groupDeps) {\n for (const key of Object.keys(groupDeps)) {\n const normalized = normalizePythonName(key);\n if (!prod.has(normalized)) dev.add(normalized);\n }\n }\n }\n }\n }\n\n // [tool.uv.dev-dependencies] → dev\n const uv = tool?.uv as Record<string, unknown> | undefined;\n const uvDevDeps = uv?.['dev-dependencies'] as string[] | undefined;\n if (Array.isArray(uvDevDeps)) {\n for (const dep of uvDevDeps) {\n const name = extractPkgName(dep);\n if (name && !prod.has(name)) dev.add(name);\n }\n }\n\n // [dependency-groups].* → dev (PEP 735)\n const depGroups = data['dependency-groups'] as Record<string, unknown[]> | undefined;\n if (depGroups && typeof depGroups === 'object') {\n for (const group of Object.values(depGroups)) {\n if (Array.isArray(group)) {\n for (const entry of group) {\n if (typeof entry === 'string') {\n const name = extractPkgName(entry);\n if (name && !prod.has(name)) dev.add(name);\n }\n }\n }\n }\n }\n\n return { prod, dev };\n}\n","import type { Ecosystem, SupportedLockfile } from '../base.js';\nimport { parseTomlPackages } from './parsers/toml.js';\nimport { normalizePythonName, parseDirectDeps } from './pyproject.js';\n\nconst SUPPORTED_LOCKFILES: SupportedLockfile[] = [\n { filename: 'uv.lock', type: 'uv' },\n { filename: 'poetry.lock', type: 'poetry' },\n { filename: 'pdm.lock', type: 'pdm' },\n { filename: 'pylock.toml', type: 'pylock' }, // PEP 751\n];\n\nconst lockfileTypeMap = new Map(SUPPORTED_LOCKFILES.map((l) => [l.filename, l.type]));\n\nexport const pythonEcosystem: Ecosystem = {\n name: 'python',\n supportedLockfiles: SUPPORTED_LOCKFILES,\n manifestName: 'pyproject.toml',\n\n getLockfileType(filename: string): string | undefined {\n return lockfileTypeMap.get(filename);\n },\n\n parseLockfile(content: string, _lockfileType: string) {\n return parseTomlPackages(content);\n },\n\n parseDirectDeps(manifestContent: string) {\n return parseDirectDeps(manifestContent);\n },\n\n normalizeName(name: string): string {\n return normalizePythonName(name);\n },\n};\n","import type { Ecosystem } from './base.js';\nimport { denoEcosystem } from './deno/index.js';\nimport { javascriptEcosystem } from './javascript/index.js';\nimport { pythonEcosystem } from './python/index.js';\n\nconst registry = new Map<string, Ecosystem>();\n\nexport function registerEcosystem(ecosystem: Ecosystem): void {\n registry.set(ecosystem.name, ecosystem);\n}\n\nexport function getEcosystemByName(name: string): Ecosystem | undefined {\n return registry.get(name);\n}\n\nexport function getEcosystemForLockfile(filename: string): Ecosystem | undefined {\n for (const ecosystem of registry.values()) {\n if (ecosystem.getLockfileType(filename) !== undefined) return ecosystem;\n }\n return undefined;\n}\n\nexport function getAllEcosystems(): Ecosystem[] {\n return [...registry.values()];\n}\n\nregisterEcosystem(pythonEcosystem);\nregisterEcosystem(javascriptEcosystem);\nregisterEcosystem(denoEcosystem);\n","import type { DirectDeps, PackageChange, PackageEntry } from '../types.js';\n\nexport function diffPackages(\n oldPkgs: Record<string, PackageEntry>,\n newPkgs: Record<string, PackageEntry>,\n directDeps: DirectDeps,\n normalizeName: (name: string) => string,\n): PackageChange[] {\n const allNames = new Set([...Object.keys(oldPkgs), ...Object.keys(newPkgs)]);\n const changes: PackageChange[] = [];\n\n for (const name of [...allNames].sort()) {\n const inOld = name in oldPkgs;\n const inNew = name in newPkgs;\n\n if (inOld && inNew && oldPkgs[name].version === newPkgs[name].version) continue;\n\n const normalized = normalizeName(name);\n const isProd = directDeps.prod.has(normalized);\n const isDev = directDeps.dev.has(normalized) && !isProd;\n\n const change: PackageChange = {\n name,\n change_type: !inOld ? 'added' : !inNew ? 'removed' : 'updated',\n old_version: inOld ? oldPkgs[name].version : null,\n new_version: inNew ? newPkgs[name].version : null,\n is_direct: isProd || isDev,\n is_dev: isDev,\n };\n\n const oldRegistryUrl = inOld ? oldPkgs[name].registryUrl : undefined;\n const newRegistryUrl = inNew ? newPkgs[name].registryUrl : undefined;\n if (oldRegistryUrl !== undefined) change.old_registry_url = oldRegistryUrl;\n if (newRegistryUrl !== undefined) change.new_registry_url = newRegistryUrl;\n\n changes.push(change);\n }\n\n return changes;\n}\n","import { posix } from 'node:path';\nimport { getAllEcosystems, getEcosystemForLockfile } from '../ecosystems/index.js';\nimport type { FileSource, LockfilePair } from '../types.js';\n\nexport interface LockfileInfo {\n path: string;\n type: string;\n ecosystemName: string;\n}\n\nexport function workspaceFromPath(filePath: string): string {\n const parent = posix.dirname(filePath);\n return parent === '.' || parent === '' ? '.' : parent;\n}\n\nexport function detectLockfileInfo(filePath: string): LockfileInfo | null {\n const filename = posix.basename(filePath);\n const ecosystem = getEcosystemForLockfile(filename);\n if (!ecosystem) return null;\n const type = ecosystem.getLockfileType(filename);\n if (!type) return null;\n return { path: filePath, type, ecosystemName: ecosystem.name };\n}\n\nexport function findAllLockfiles(paths: string[]): LockfileInfo[] {\n return paths.flatMap((p) => {\n const info = detectLockfileInfo(p);\n return info ? [info] : [];\n });\n}\n\nexport async function findLockfiles(getFile: FileSource): Promise<LockfileInfo[]> {\n const candidates = getAllEcosystems().flatMap((ecosystem) =>\n ecosystem.supportedLockfiles.map(({ filename, type }) => ({\n filename,\n type,\n ecosystemName: ecosystem.name,\n })),\n );\n\n const results = await Promise.all(\n candidates.map(async ({ filename, type, ecosystemName }) => {\n const content = await getFile(filename);\n return content !== null ? ({ path: filename, type, ecosystemName } as LockfileInfo) : null;\n }),\n );\n\n return results.filter((r): r is LockfileInfo => r !== null);\n}\n\nexport function groupByWorkspace(lockfiles: LockfileInfo[]): Map<string, LockfileInfo[]> {\n const result = new Map<string, LockfileInfo[]>();\n for (const lf of lockfiles) {\n const ws = workspaceFromPath(lf.path);\n const existing = result.get(ws) ?? [];\n existing.push(lf);\n result.set(ws, existing);\n }\n return result;\n}\n\nconst LOCKFILE_PRIORITY: Record<string, number> = {\n 'uv.lock': 0,\n 'poetry.lock': 1,\n 'pdm.lock': 2,\n};\n\nfunction lockfilePriority(path: string): number {\n return LOCKFILE_PRIORITY[posix.basename(path)] ?? 99;\n}\n\nexport function resolveLockfilePair(\n baseFiles: LockfileInfo[],\n headFiles: LockfileInfo[],\n): LockfilePair | null {\n const headByPath = new Map(headFiles.map((f) => [f.path, f]));\n const common = baseFiles.filter((f) => headByPath.has(f.path));\n\n if (common.length > 0) {\n const chosen = common.sort((a, b) => lockfilePriority(a.path) - lockfilePriority(b.path))[0];\n return {\n basePath: chosen.path,\n baseType: chosen.type,\n headPath: chosen.path,\n // biome-ignore lint/style/noNonNullAssertion: path is guaranteed present (comes from common set)\n headType: headByPath.get(chosen.path)!.type,\n migrationNote: null,\n ecosystemName: chosen.ecosystemName,\n };\n }\n\n if (baseFiles.length > 0 && headFiles.length > 0) {\n const base = baseFiles[0];\n const head = headFiles[0];\n return {\n basePath: base.path,\n baseType: base.type,\n headPath: head.path,\n headType: head.type,\n migrationNote: `lockfile migration: ${posix.basename(base.path)} (${base.type}) → ${posix.basename(head.path)} (${head.type})`,\n ecosystemName: head.ecosystemName,\n };\n }\n\n if (headFiles.length > 0) {\n const head = headFiles[0];\n return {\n basePath: null,\n baseType: null,\n headPath: head.path,\n headType: head.type,\n migrationNote: `new lockfile added: ${posix.basename(head.path)} (${head.type})`,\n ecosystemName: head.ecosystemName,\n };\n }\n\n if (baseFiles.length > 0) {\n const base = baseFiles[0];\n return {\n basePath: base.path,\n baseType: base.type,\n headPath: null,\n headType: null,\n migrationNote: `lockfile removed: ${posix.basename(base.path)} (${base.type})`,\n ecosystemName: base.ecosystemName,\n };\n }\n\n return null;\n}\n","import { execFileSync } from 'node:child_process';\n\nexport function gitShow(ref: string, path: string): string | null {\n try {\n const result = execFileSync('git', ['show', `${ref}:${path}`], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return result || null;\n } catch {\n return null;\n }\n}\n\nexport function gitLsTree(ref: string): string[] {\n try {\n const result = execFileSync('git', ['ls-tree', '-r', '--name-only', ref], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return result.trim().split('\\n').filter(Boolean);\n } catch {\n return [];\n }\n}\n","import { execFileSync } from 'node:child_process';\n\nconst API_BASE = 'https://api.github.com';\n\nlet cachedToken: string | undefined;\n\nexport function resolveToken(): string {\n if (cachedToken) return cachedToken;\n if (process.env.GITHUB_TOKEN) {\n cachedToken = process.env.GITHUB_TOKEN;\n return cachedToken;\n }\n try {\n const t = execFileSync('gh', ['auth', 'token'], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n if (t) {\n cachedToken = t;\n return cachedToken;\n }\n } catch {\n // gh not installed or not authenticated\n }\n throw new Error('No GitHub token found. Set GITHUB_TOKEN or run `gh auth login`.');\n}\n\nfunction headers(accept = 'application/vnd.github+json'): Record<string, string> {\n return {\n Authorization: `Bearer ${resolveToken()}`,\n Accept: accept,\n 'X-GitHub-Api-Version': '2022-11-28',\n };\n}\n\nexport async function ghFileAtSha(sha: string, path: string, repo: string): Promise<string | null> {\n const url = `${API_BASE}/repos/${repo}/contents/${path}?ref=${sha}`;\n const response = await fetch(url, {\n headers: headers('application/vnd.github.raw+json'),\n });\n if (!response.ok) return null;\n return response.text();\n}\n\nexport async function ghLsTree(sha: string, repo: string): Promise<string[]> {\n const url = `${API_BASE}/repos/${repo}/git/trees/${sha}?recursive=1`;\n const response = await fetch(url, { headers: headers() });\n if (!response.ok) return [];\n const data = (await response.json()) as {\n tree: Array<{ path: string; type: string }>;\n truncated: boolean;\n };\n return data.tree.filter((item) => item.type === 'blob').map((item) => item.path);\n}\n\nexport interface PrShas {\n baseRefOid: string;\n headRefOid: string;\n}\n\nexport async function getPrShas(prNumber: string, repo: string): Promise<PrShas> {\n const url = `${API_BASE}/repos/${repo}/pulls/${prNumber}`;\n const response = await fetch(url, { headers: headers() });\n if (!response.ok) {\n throw new Error(`GitHub API error ${response.status}: failed to fetch PR #${prNumber}`);\n }\n const data = (await response.json()) as { base: { sha: string }; head: { sha: string } };\n return { baseRefOid: data.base.sha, headRefOid: data.head.sha };\n}\n\nexport function detectRepo(): string {\n const fromEnv = process.env.GITHUB_REPOSITORY;\n if (fromEnv) return fromEnv;\n\n try {\n const remote = execFileSync('git', ['remote', 'get-url', 'origin'], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n const match = remote.match(/github\\.com[:/]([^/]+\\/[^/.]+?)(?:\\.git)?$/);\n if (match) return match[1];\n } catch {\n // fall through\n }\n\n throw new Error('Could not detect GitHub repo — set GITHUB_REPOSITORY or pass --repo');\n}\n","import { readFileSync } from 'node:fs';\n\nexport function readLocalFile(path: string): string | null {\n try {\n return readFileSync(path, 'utf-8');\n } catch {\n return null;\n }\n}\n","import { buildDiffReport, collectLockfileEntries } from './core/report.js';\nimport { gitLsTree, gitShow } from './sources/git.js';\nimport { detectRepo, getPrShas, ghFileAtSha, ghLsTree } from './sources/github.js';\nimport { readLocalFile } from './sources/local.js';\nimport type { DiffReport, FileSource } from './types.js';\n\nexport type { Ecosystem, SupportedLockfile } from './ecosystems/base.js';\nexport { registerEcosystem } from './ecosystems/index.js';\nexport type {\n DiffReport,\n DirectDeps,\n LockfileEntry,\n LockfilePair,\n MigrationInfo,\n PackageChange,\n PackageEntry,\n} from './types.js';\n\nexport interface RunOptions {\n base?: string;\n head?: string;\n /** Explicit base commit SHA — skips getPrShas. Used for push events. */\n baseSha?: string;\n /** Explicit head commit SHA — skips getPrShas. Used for push events. */\n headSha?: string;\n prNumber?: string;\n repo?: string;\n lockfile?: string;\n lockfileType?: string;\n oldFile?: string;\n newFile?: string;\n onNote?: (message: string) => void;\n}\n\nasync function resolveApiShas(\n options: RunOptions,\n): Promise<{ baseSha: string; headSha: string; repo: string } | null> {\n if (options.baseSha && options.headSha) {\n return {\n baseSha: options.baseSha,\n headSha: options.headSha,\n repo: options.repo ?? detectRepo(),\n };\n }\n if (options.prNumber) {\n const repo = options.repo ?? detectRepo();\n const { baseRefOid, headRefOid } = await getPrShas(options.prNumber, repo);\n return { baseSha: baseRefOid, headSha: headRefOid, repo };\n }\n return null;\n}\n\nexport async function run(options: RunOptions = {}): Promise<DiffReport> {\n const { lockfile, lockfileType, onNote } = options;\n\n if (options.oldFile && options.newFile) {\n const oldPath = options.oldFile;\n const newPath = options.newFile;\n\n const getBase: FileSource = (path) =>\n Promise.resolve(path === oldPath ? readLocalFile(oldPath) : null);\n const getHead: FileSource = (path) =>\n Promise.resolve(path === newPath ? readLocalFile(newPath) : null);\n\n const lockfiles = await collectLockfileEntries({\n getBase,\n getHead,\n allBasePaths: [oldPath],\n allHeadPaths: [newPath],\n lockfile: newPath,\n lockfileType,\n onNote,\n });\n\n if (lockfiles.length === 0) throw new Error('No supported lockfiles found');\n return buildDiffReport(lockfiles, 'local_old', 'local_new');\n }\n\n const apiShas = await resolveApiShas(options);\n\n if (apiShas) {\n const { baseSha, headSha, repo } = apiShas;\n\n const getBase: FileSource = (path) => ghFileAtSha(baseSha, path, repo);\n const getHead: FileSource = (path) => ghFileAtSha(headSha, path, repo);\n\n const [basePaths, headPaths] = await Promise.all([\n ghLsTree(baseSha, repo),\n ghLsTree(headSha, repo),\n ]);\n\n const lockfiles = await collectLockfileEntries({\n getBase,\n getHead,\n allBasePaths: basePaths,\n allHeadPaths: headPaths,\n lockfile,\n lockfileType,\n onNote,\n });\n\n if (lockfiles.length === 0) throw new Error('No supported lockfiles found');\n return buildDiffReport(lockfiles, baseSha, headSha);\n }\n\n // Git ref mode: local CLI usage\n const baseRef = options.base ?? 'HEAD~1';\n const headRef = options.head ?? 'HEAD';\n\n const getBase: FileSource = (path) => Promise.resolve(gitShow(baseRef, path));\n const getHead: FileSource = (path) => Promise.resolve(gitShow(headRef, path));\n\n const lockfiles = await collectLockfileEntries({\n getBase,\n getHead,\n allBasePaths: gitLsTree(baseRef),\n allHeadPaths: gitLsTree(headRef),\n lockfile,\n lockfileType,\n onNote,\n });\n\n if (lockfiles.length === 0) throw new Error('No supported lockfiles found');\n return buildDiffReport(lockfiles, baseRef, headRef);\n}\n"],"mappings":"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","names":["posix","atIdx","registry","atIdx","parseDirectDeps","atIdx","resolvedToOrigin","parseYaml","resolvedToOrigin","SUPPORTED_LOCKFILES","parseDirectDeps","parse","parseDirectDeps","SUPPORTED_LOCKFILES","lockfileTypeMap","parseDirectDeps","posix","execFileSync","getBase","getHead","lockfiles"]}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,10 @@ interface DirectDeps {
3
3
  prod: Set<string>;
4
4
  dev: Set<string>;
5
5
  }
6
+ interface PackageEntry {
7
+ version: string;
8
+ registryUrl?: string;
9
+ }
6
10
  interface PackageChange {
7
11
  name: string;
8
12
  change_type: ChangeType;
@@ -10,6 +14,8 @@ interface PackageChange {
10
14
  new_version: string | null;
11
15
  is_direct: boolean;
12
16
  is_dev: boolean;
17
+ old_registry_url?: string;
18
+ new_registry_url?: string;
13
19
  }
14
20
  interface MigrationInfo {
15
21
  note: string;
@@ -66,7 +72,7 @@ interface Ecosystem {
66
72
  readonly supportedLockfiles: ReadonlyArray<SupportedLockfile>;
67
73
  readonly manifestName: string | null;
68
74
  getLockfileType(filename: string): string | undefined;
69
- parseLockfile(content: string, lockfileType: string): Record<string, string>;
75
+ parseLockfile(content: string, lockfileType: string): Record<string, PackageEntry>;
70
76
  parseDirectDeps(manifestContent: string): DirectDeps;
71
77
  normalizeName(name: string): string;
72
78
  }
@@ -90,4 +96,4 @@ interface RunOptions {
90
96
  }
91
97
  declare function run(options?: RunOptions): Promise<DiffReport>;
92
98
 
93
- export { type DiffReport, type DirectDeps, type Ecosystem, type LockfileEntry, type LockfilePair, type MigrationInfo, type PackageChange, type RunOptions, type SupportedLockfile, registerEcosystem, run };
99
+ export { type DiffReport, type DirectDeps, type Ecosystem, type LockfileEntry, type LockfilePair, type MigrationInfo, type PackageChange, type PackageEntry, type RunOptions, type SupportedLockfile, registerEcosystem, run };