@eldrforge/kodrdriv 0.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +1 -0
  2. package/dist/application.js +25 -3
  3. package/dist/application.js.map +1 -1
  4. package/dist/arguments.js +103 -18
  5. package/dist/arguments.js.map +1 -1
  6. package/dist/commands/audio-commit.js +28 -7
  7. package/dist/commands/audio-commit.js.map +1 -1
  8. package/dist/commands/audio-review.js +28 -7
  9. package/dist/commands/audio-review.js.map +1 -1
  10. package/dist/commands/commit.js +75 -18
  11. package/dist/commands/commit.js.map +1 -1
  12. package/dist/commands/development.js +264 -0
  13. package/dist/commands/development.js.map +1 -0
  14. package/dist/commands/link.js +356 -181
  15. package/dist/commands/link.js.map +1 -1
  16. package/dist/commands/publish.js +166 -32
  17. package/dist/commands/publish.js.map +1 -1
  18. package/dist/commands/release.js +78 -13
  19. package/dist/commands/release.js.map +1 -1
  20. package/dist/commands/review.js +10 -6
  21. package/dist/commands/review.js.map +1 -1
  22. package/dist/commands/tree.js +450 -24
  23. package/dist/commands/tree.js.map +1 -1
  24. package/dist/commands/unlink.js +267 -372
  25. package/dist/commands/unlink.js.map +1 -1
  26. package/dist/commands/versions.js +224 -0
  27. package/dist/commands/versions.js.map +1 -0
  28. package/dist/constants.js +29 -10
  29. package/dist/constants.js.map +1 -1
  30. package/dist/content/diff.js.map +1 -1
  31. package/dist/content/files.js +192 -0
  32. package/dist/content/files.js.map +1 -0
  33. package/dist/content/log.js +16 -0
  34. package/dist/content/log.js.map +1 -1
  35. package/dist/main.js +0 -0
  36. package/dist/prompt/commit.js +9 -2
  37. package/dist/prompt/commit.js.map +1 -1
  38. package/dist/prompt/instructions/commit.md +20 -2
  39. package/dist/prompt/instructions/release.md +27 -10
  40. package/dist/prompt/instructions/review.md +75 -8
  41. package/dist/prompt/release.js +13 -5
  42. package/dist/prompt/release.js.map +1 -1
  43. package/dist/types.js +21 -5
  44. package/dist/types.js.map +1 -1
  45. package/dist/util/child.js +112 -26
  46. package/dist/util/child.js.map +1 -1
  47. package/dist/util/countdown.js +215 -0
  48. package/dist/util/countdown.js.map +1 -0
  49. package/dist/util/general.js +10 -2
  50. package/dist/util/general.js.map +1 -1
  51. package/dist/util/git.js +587 -0
  52. package/dist/util/git.js.map +1 -0
  53. package/dist/util/github.js +519 -3
  54. package/dist/util/github.js.map +1 -1
  55. package/dist/util/interactive.js +245 -79
  56. package/dist/util/interactive.js.map +1 -1
  57. package/dist/util/openai.js +70 -22
  58. package/dist/util/openai.js.map +1 -1
  59. package/dist/util/performance.js +1 -69
  60. package/dist/util/performance.js.map +1 -1
  61. package/dist/util/storage.js +28 -1
  62. package/dist/util/storage.js.map +1 -1
  63. package/dist/util/validation.js +1 -25
  64. package/dist/util/validation.js.map +1 -1
  65. package/package.json +10 -8
  66. package/test-multiline/cli/package.json +8 -0
  67. package/test-multiline/core/package.json +5 -0
  68. package/test-multiline/mobile/package.json +8 -0
  69. package/test-multiline/web/package.json +8 -0
  70. package/dist/util/npmOptimizations.js +0 -174
  71. package/dist/util/npmOptimizations.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"link.js","sources":["../../src/commands/link.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\nimport path from 'path';\nimport { ValidationError, CommandError } from '../error/CommandErrors';\nimport { getLogger, getDryRunLogger } from '../logging';\nimport { Config } from '../types';\nimport { create as createStorage } from '../util/storage';\nimport { safeJsonParse, validateLinkBackup, type LinkBackup } from '../util/validation';\nimport {\n PerformanceTimer,\n PackageJson,\n PackageJsonLocation,\n findAllPackageJsonFiles,\n scanDirectoryForPackages\n} from '../util/performance';\nimport { smartNpmInstall } from '../util/npmOptimizations';\n\ninterface ExtendedPackageJson extends PackageJson {\n overrides?: Record<string, string>;\n}\n\n\n\nconst EXCLUDED_DIRECTORIES = [\n 'node_modules',\n 'dist',\n 'build',\n 'coverage',\n '.git',\n '.next',\n '.nuxt',\n 'out',\n 'public',\n 'static',\n 'assets'\n];\n\nconst findPackagesToLink = async (scopeRoots: Record<string, string>, storage: any): Promise<Map<string, string>> => {\n const logger = getLogger();\n const timer = PerformanceTimer.start(logger, 'Finding packages to link');\n const packagesToLink = new Map<string, string>();\n\n logger.silly(`Finding packages to link from scope roots: ${JSON.stringify(scopeRoots)}`);\n\n // Scan all scope roots to build a comprehensive map of packages that can be linked\n const scopeTimer = PerformanceTimer.start(logger, 'Scanning all scope roots for linkable packages');\n const allScopePackages = new Map<string, string>(); // packageName -> relativePath\n\n // Process all scopes in parallel for better performance\n const scopePromises = Object.entries(scopeRoots).map(async ([scope, rootDir]) => {\n logger.verbose(`Scanning scope ${scope} at root directory: ${rootDir}`);\n const scopePackages = await scanDirectoryForPackages(rootDir, storage);\n\n // Add packages from this scope to the overall map\n const scopeResults: Array<[string, string]> = [];\n for (const [packageName, packagePath] of scopePackages) {\n if (packageName.startsWith(scope)) {\n scopeResults.push([packageName, packagePath]);\n logger.debug(`Linkable package: ${packageName} -> ${packagePath}`);\n }\n }\n return scopeResults;\n });\n\n const allScopeResults = await Promise.all(scopePromises);\n\n // Flatten results\n for (const scopeResults of allScopeResults) {\n for (const [packageName, packagePath] of scopeResults) {\n allScopePackages.set(packageName, packagePath);\n }\n }\n\n scopeTimer.end(`Scanned ${Object.keys(scopeRoots).length} scope roots, found ${allScopePackages.size} packages`);\n\n // Now we have all scope packages, we can resolve the ones we want to link\n for (const [packageName, packagePath] of allScopePackages) {\n packagesToLink.set(packageName, packagePath);\n }\n\n timer.end(`Found ${packagesToLink.size} packages to link`);\n return packagesToLink;\n};\n\nconst readLinkBackup = async (storage: any, logger?: any): Promise<LinkBackup> => {\n const backupPath = path.join(process.cwd(), '.kodrdriv-link-backup.json');\n if (await storage.exists(backupPath)) {\n try {\n const content = await storage.readFile(backupPath, 'utf-8');\n return JSON.parse(content) as LinkBackup;\n } catch (error) {\n // Log warning but continue with empty backup instead of throwing\n if (logger) {\n logger.warn(`Failed to parse link backup file: ${error}`);\n }\n return {};\n }\n }\n return {};\n};\n\nconst writeLinkBackup = async (backup: LinkBackup, storage: any): Promise<void> => {\n const backupPath = path.join(process.cwd(), '.kodrdriv-link-backup.json');\n await storage.writeFile(backupPath, JSON.stringify(backup, null, 2), 'utf-8');\n};\n\nconst updatePackageJson = async (\n packageJsonLocation: PackageJsonLocation,\n packagesToLink: Map<string, string>,\n backup: LinkBackup,\n storage: any\n): Promise<number> => {\n const logger = getLogger();\n let linkedCount = 0;\n const { packageJson, path: packageJsonPath, relativePath } = packageJsonLocation;\n\n // Process dependencies, devDependencies, and peerDependencies\n const depTypes: Array<keyof Pick<PackageJson, 'dependencies' | 'devDependencies' | 'peerDependencies'>> = [\n 'dependencies', 'devDependencies', 'peerDependencies'\n ];\n\n for (const depType of depTypes) {\n const dependencies = packageJson[depType];\n if (!dependencies) continue;\n\n for (const [packageName, targetPath] of packagesToLink) {\n if (dependencies[packageName]) {\n // Backup original version before linking\n const backupKey = `${relativePath}:${packageName}`;\n if (!backup[backupKey]) {\n backup[backupKey] = {\n originalVersion: dependencies[packageName],\n dependencyType: depType,\n relativePath\n };\n }\n\n // Update to file: dependency\n const targetAbsolutePath = path.resolve(process.cwd(), targetPath);\n const fileReferencePath = path.relative(path.dirname(packageJsonPath), targetAbsolutePath);\n dependencies[packageName] = `file:${fileReferencePath}`;\n linkedCount++;\n logger.verbose(`Linked ${relativePath}/${depType}.${packageName}: ${backup[backupKey].originalVersion} -> file:${fileReferencePath}`);\n }\n }\n }\n\n // NOTE: Don't write the file here - let the caller handle all modifications\n return linkedCount;\n};\n\nconst executeInternal = async (runConfig: Config): Promise<string> => {\n const isDryRun = runConfig.dryRun || runConfig.link?.dryRun || false;\n const logger = getDryRunLogger(isDryRun);\n const overallTimer = PerformanceTimer.start(logger, 'Link command execution');\n const storage = createStorage({ log: logger.info });\n\n logger.info('🔗 Linking workspace packages...');\n\n // Get configuration\n const configTimer = PerformanceTimer.start(logger, 'Reading configuration');\n const scopeRoots = runConfig.link?.scopeRoots || {};\n configTimer.end('Configuration loaded');\n\n if (Object.keys(scopeRoots).length === 0) {\n logger.info('No scope roots configured. Skipping link management.');\n overallTimer.end('Link command (no scope roots)');\n return 'No scope roots configured. Skipping link management.';\n }\n\n // Find all package.json files in current directory tree\n const packageJsonFiles = await findAllPackageJsonFiles(process.cwd(), storage);\n\n if (packageJsonFiles.length === 0) {\n overallTimer.end('Link command (no package.json files)');\n throw new ValidationError('No package.json files found in current directory or subdirectories.');\n }\n\n logger.info(`Found ${packageJsonFiles.length} package.json file(s) to process`);\n logger.info(`Scanning ${Object.keys(scopeRoots).length} scope root(s): ${Object.keys(scopeRoots).join(', ')}`);\n\n // Check if any package.json files already have file: dependencies (safety check)\n const safetyTimer = PerformanceTimer.start(logger, 'Safety check for existing file: dependencies');\n // checkForFileDependencies(packageJsonFiles); // This function is no longer imported\n safetyTimer.end('Safety check completed');\n\n // Collect all dependencies from all package.json files using optimized function\n // const allDependencies = collectAllDependencies(packageJsonFiles); // This function is no longer imported\n\n // logger.verbose(`Found ${Object.keys(allDependencies).length} total unique dependencies across all package.json files`);\n\n // Find matching sibling packages\n const packagesToLink = await findPackagesToLink(scopeRoots, storage);\n\n if (packagesToLink.size === 0) {\n logger.info('✅ No matching sibling packages found for linking.');\n overallTimer.end('Link command (no packages to link)');\n return 'No matching sibling packages found for linking.';\n }\n\n logger.info(`Found ${packagesToLink.size} package(s) to link: ${[...packagesToLink.keys()].join(', ')}`);\n\n // Read existing backup\n const backupTimer = PerformanceTimer.start(logger, 'Reading link backup');\n const backup = await readLinkBackup(storage, logger);\n backupTimer.end('Link backup loaded');\n\n if (isDryRun) {\n logger.info('Would update package.json files with file: dependencies and run npm install');\n for (const { relativePath } of packageJsonFiles) {\n logger.verbose(`Would process ${relativePath}/package.json`);\n }\n for (const [packageName, packagePath] of packagesToLink.entries()) {\n logger.verbose(`Would link ${packageName} -> file:${packagePath}`);\n }\n overallTimer.end('Link command (dry run)');\n return `DRY RUN: Would link ${packagesToLink.size} packages across ${packageJsonFiles.length} package.json files`;\n } else {\n // Update all package.json files with file: dependencies\n const updateTimer = PerformanceTimer.start(logger, 'Updating package.json files');\n let totalLinksCreated = 0;\n for (const packageJsonLocation of packageJsonFiles) {\n const linksCreated = await updatePackageJson(packageJsonLocation, packagesToLink, backup, storage);\n totalLinksCreated += linksCreated;\n\n // Write the modified package.json file to disk\n if (linksCreated > 0) {\n await storage.writeFile(packageJsonLocation.path, JSON.stringify(packageJsonLocation.packageJson, null, 2) + '\\n', 'utf-8');\n logger.verbose(`Updated ${packageJsonLocation.relativePath}/package.json with ${linksCreated} file: dependencies`);\n }\n }\n updateTimer.end(`Updated ${packageJsonFiles.length} package.json files, created ${totalLinksCreated} links`);\n\n if (totalLinksCreated === 0) {\n logger.info('✅ No dependencies were linked (packages may not be referenced).');\n overallTimer.end('Link command (no links created)');\n return 'No dependencies were linked.';\n }\n\n // Save backup after all changes\n const saveTimer = PerformanceTimer.start(logger, 'Saving link backup');\n await writeLinkBackup(backup, storage);\n saveTimer.end('Link backup saved');\n logger.info(`Updated ${packageJsonFiles.length} package.json file(s) with file: dependencies`);\n\n // Run optimized npm install to create symlinks\n logger.info('⏳ Installing dependencies to create symlinks...');\n try {\n const installResult = await smartNpmInstall({\n skipIfNotNeeded: false, // Always install after linking changes\n preferCi: false, // Use npm install to handle new file: dependencies\n verbose: false\n });\n\n if (installResult.skipped) {\n logger.info(`⚡ Dependencies were up to date (${installResult.method})`);\n } else {\n logger.info(`✅ Links applied successfully using ${installResult.method} (${installResult.duration}ms)`);\n }\n } catch (error) {\n logger.warn(`Failed to install dependencies: ${error}. You may need to run 'npm install' manually.`);\n }\n\n const summary = `Successfully linked ${totalLinksCreated} dependency reference(s) across ${packageJsonFiles.length} package.json file(s):\\n${[...packagesToLink.entries()].map(([name, path]) => ` - ${name}: file:${path}`).join('\\n')}`;\n\n overallTimer.end('Link command execution completed');\n return summary;\n }\n};\n\nexport const execute = async (runConfig: Config): Promise<string> => {\n try {\n return await executeInternal(runConfig);\n } catch (error: any) {\n const logger = getLogger();\n\n if (error instanceof ValidationError || error instanceof CommandError) {\n logger.error(`link failed: ${error.message}`);\n if (error.cause) {\n logger.debug(`Caused by: ${error.cause.message}`);\n }\n throw error;\n }\n\n // Unexpected errors\n logger.error(`link encountered unexpected error: ${error.message}`);\n throw error;\n }\n};\n"],"names":["findPackagesToLink","scopeRoots","storage","logger","getLogger","timer","PerformanceTimer","start","packagesToLink","Map","silly","JSON","stringify","scopeTimer","allScopePackages","scopePromises","Object","entries","map","scope","rootDir","verbose","scopePackages","scanDirectoryForPackages","scopeResults","packageName","packagePath","startsWith","push","debug","allScopeResults","Promise","all","set","end","keys","length","size","readLinkBackup","backupPath","path","join","process","cwd","exists","content","readFile","parse","error","warn","writeLinkBackup","backup","writeFile","updatePackageJson","packageJsonLocation","linkedCount","packageJson","packageJsonPath","relativePath","depTypes","depType","dependencies","targetPath","backupKey","originalVersion","dependencyType","targetAbsolutePath","resolve","fileReferencePath","relative","dirname","executeInternal","runConfig","isDryRun","dryRun","link","getDryRunLogger","overallTimer","createStorage","log","info","configTimer","packageJsonFiles","findAllPackageJsonFiles","ValidationError","safetyTimer","backupTimer","updateTimer","totalLinksCreated","linksCreated","saveTimer","installResult","smartNpmInstall","skipIfNotNeeded","preferCi","skipped","method","duration","summary","name","execute","CommandError","message","cause"],"mappings":"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"}
1
+ {"version":3,"file":"link.js","sources":["../../src/commands/link.ts"],"sourcesContent":["import { getLogger, getDryRunLogger } from '../logging';\nimport { Config } from '../types';\nimport { run, runSecure } from '../util/child';\nimport {\n findAllPackageJsonFiles\n} from '../util/performance';\nimport { create as createStorage } from '../util/storage';\nimport { safeJsonParse, validatePackageJson } from '../util/validation';\nimport fs from 'fs/promises';\nimport path from 'path';\n\n// Helper function to create symbolic links manually\nconst createSymbolicLink = async (\n packageName: string,\n sourcePath: string,\n targetDir: string,\n logger: any,\n isDryRun: boolean = false\n): Promise<boolean> => {\n try {\n // Parse package name to get scope and name parts\n const [scope, name] = packageName.startsWith('@')\n ? packageName.split('/')\n : [null, packageName];\n\n // Create the target path structure\n const nodeModulesPath = path.join(targetDir, 'node_modules');\n let targetPath: string;\n\n if (scope) {\n // Scoped package: node_modules/@scope/name\n const scopeDir = path.join(nodeModulesPath, scope);\n targetPath = path.join(scopeDir, name);\n\n if (!isDryRun) {\n // Ensure scope directory exists\n await fs.mkdir(scopeDir, { recursive: true });\n }\n } else {\n // Unscoped package: node_modules/name\n targetPath = path.join(nodeModulesPath, name);\n\n if (!isDryRun) {\n // Ensure node_modules directory exists\n await fs.mkdir(nodeModulesPath, { recursive: true });\n }\n }\n\n if (isDryRun) {\n logger.verbose(`DRY RUN: Would create symlink: ${targetPath} -> ${sourcePath}`);\n return true;\n }\n\n // Create the symbolic link using relative path for better portability\n const relativePath = path.relative(path.dirname(targetPath), sourcePath);\n\n // Check if something already exists at the target path\n try {\n const stats = await fs.lstat(targetPath); // Use lstat to not follow symlinks\n\n if (stats.isSymbolicLink()) {\n // It's a symlink, check if it points to the correct target\n const existingLink = await fs.readlink(targetPath);\n if (existingLink === relativePath) {\n logger.verbose(`Symlink already exists and points to correct target: ${targetPath} -> ${relativePath}`);\n return true;\n } else {\n logger.info(`🔧 Fixing symlink: ${targetPath} (was pointing to ${existingLink}, now pointing to ${relativePath})`);\n await fs.unlink(targetPath);\n await fs.symlink(relativePath, targetPath, 'dir');\n logger.info(`✅ Fixed symlink: ${targetPath} -> ${relativePath}`);\n return true;\n }\n } else if (stats.isDirectory()) {\n // It's a directory, remove it\n logger.warn(`⚠️ Removing existing directory to create symlink: ${targetPath}`);\n await fs.rm(targetPath, { recursive: true, force: true });\n await fs.symlink(relativePath, targetPath, 'dir');\n logger.info(`✅ Created symlink: ${targetPath} -> ${relativePath}`);\n return true;\n } else {\n // It's a file, remove it\n logger.warn(`⚠️ Removing existing file to create symlink: ${targetPath}`);\n await fs.unlink(targetPath);\n await fs.symlink(relativePath, targetPath, 'dir');\n logger.info(`✅ Created symlink: ${targetPath} -> ${relativePath}`);\n return true;\n }\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n // Nothing exists at target path, create the symlink\n await fs.symlink(relativePath, targetPath, 'dir');\n logger.verbose(`Created symlink: ${targetPath} -> ${relativePath}`);\n return true;\n } else {\n throw error; // Re-throw unexpected errors\n }\n }\n } catch (error: any) {\n logger.warn(`Failed to create symlink for ${packageName}: ${error.message}`);\n return false;\n }\n};\n\n// Helper function to parse package names and scopes\nconst parsePackageArgument = (packageArg: string): { scope: string; packageName?: string } => {\n if (packageArg.startsWith('@')) {\n const parts = packageArg.split('/');\n if (parts.length === 1) {\n // Just a scope like \"@fjell\"\n return { scope: parts[0] };\n } else {\n // Full package name like \"@fjell/core\"\n return { scope: parts[0], packageName: packageArg };\n }\n } else {\n throw new Error(`Package argument must start with @ (scope): ${packageArg}`);\n }\n};\n\n// Find packages in the workspace that match the given scope or package name\nconst findMatchingPackages = async (\n targetDirectories: string[],\n scope: string,\n storage: any,\n logger: any,\n packageName?: string\n): Promise<Array<{ name: string; path: string; isSource: boolean }>> => {\n const matchingPackages: Array<{ name: string; path: string; isSource: boolean }> = [];\n\n // Find all package.json files in target directories\n let allPackageJsonFiles: any[] = [];\n for (const targetDirectory of targetDirectories) {\n const packageJsonFiles = await findAllPackageJsonFiles(targetDirectory, storage);\n allPackageJsonFiles = allPackageJsonFiles.concat(packageJsonFiles);\n }\n\n for (const packageJsonLocation of allPackageJsonFiles) {\n const packageDir = packageJsonLocation.path.replace('/package.json', '');\n\n try {\n const packageJsonContent = await storage.readFile(packageJsonLocation.path, 'utf-8');\n const parsed = safeJsonParse(packageJsonContent, packageJsonLocation.path);\n const packageJson = validatePackageJson(parsed, packageJsonLocation.path);\n\n if (!packageJson.name) continue;\n\n const isInScope = packageJson.name.startsWith(scope + '/');\n const isExactMatch = packageName && packageJson.name === packageName;\n\n if (isInScope || isExactMatch) {\n matchingPackages.push({\n name: packageJson.name,\n path: packageDir,\n isSource: packageName ? packageJson.name === packageName : isInScope\n });\n }\n } catch (error: any) {\n logger.warn(`Failed to parse ${packageJsonLocation.path}: ${error.message}`);\n }\n }\n\n return matchingPackages;\n};\n\n// Find packages that depend on the target package\nconst findConsumingPackages = async (\n targetDirectories: string[],\n targetPackageName: string,\n storage: any,\n logger: any\n): Promise<Array<{ name: string; path: string }>> => {\n const consumingPackages: Array<{ name: string; path: string }> = [];\n\n // Find all package.json files in target directories\n let allPackageJsonFiles: any[] = [];\n for (const targetDirectory of targetDirectories) {\n const packageJsonFiles = await findAllPackageJsonFiles(targetDirectory, storage);\n allPackageJsonFiles = allPackageJsonFiles.concat(packageJsonFiles);\n }\n\n for (const packageJsonLocation of allPackageJsonFiles) {\n const packageDir = packageJsonLocation.path.replace('/package.json', '');\n\n try {\n const packageJsonContent = await storage.readFile(packageJsonLocation.path, 'utf-8');\n const parsed = safeJsonParse(packageJsonContent, packageJsonLocation.path);\n const packageJson = validatePackageJson(parsed, packageJsonLocation.path);\n\n if (!packageJson.name) continue;\n\n // Check if this package depends on the target package\n const dependencyTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'];\n const hasDependency = dependencyTypes.some(depType =>\n packageJson[depType] && packageJson[depType][targetPackageName]\n );\n\n if (hasDependency && packageJson.name !== targetPackageName) {\n consumingPackages.push({\n name: packageJson.name,\n path: packageDir\n });\n }\n } catch (error: any) {\n logger.warn(`Failed to parse ${packageJsonLocation.path}: ${error.message}`);\n }\n }\n\n return consumingPackages;\n};\n\nconst executeInternal = async (runConfig: Config, packageArgument?: string): Promise<string> => {\n const isDryRun = runConfig.dryRun || runConfig.link?.dryRun || false;\n const logger = getDryRunLogger(isDryRun);\n const storage = createStorage({ log: logger.info });\n\n // Get target directories from config, default to current directory\n const targetDirectories = runConfig.tree?.directories || [process.cwd()];\n\n if (targetDirectories.length === 1) {\n logger.info(`Analyzing workspace at: ${targetDirectories[0]}`);\n } else {\n logger.info(`Analyzing workspaces at: ${targetDirectories.join(', ')}`);\n }\n\n // If no package argument provided, use new smart same-scope linking behavior\n if (!packageArgument) {\n logger.info('🔗 Smart linking current project...');\n\n // Work in current directory only - read the package.json\n const currentDir = process.cwd();\n const packageJsonPath = `${currentDir}/package.json`;\n\n let currentPackageJson;\n try {\n const packageJsonContent = await storage.readFile(packageJsonPath, 'utf-8');\n const parsed = safeJsonParse(packageJsonContent, packageJsonPath);\n currentPackageJson = validatePackageJson(parsed, packageJsonPath);\n } catch (error: any) {\n const message = `No valid package.json found in current directory: ${error.message}`;\n logger.error(message);\n return message;\n }\n\n if (!currentPackageJson.name) {\n const message = 'package.json must have a name field';\n logger.error(message);\n return message;\n }\n\n // Extract the scope from the current package name\n const currentScope = currentPackageJson.name.startsWith('@')\n ? currentPackageJson.name.split('/')[0]\n : null;\n\n if (!currentScope) {\n const message = 'Current package must have a scoped name (e.g., @scope/package) for smart linking';\n logger.warn(message);\n return message;\n }\n\n logger.info(`Current package: ${currentPackageJson.name} (scope: ${currentScope})`);\n\n // Step 1: Link the current package globally\n try {\n if (isDryRun) {\n logger.info(`DRY RUN: Would run 'npm link' in current directory`);\n } else {\n logger.verbose(`Running 'npm link' to register ${currentPackageJson.name} globally...`);\n await run('npm link');\n logger.info(`✅ Self-linked: ${currentPackageJson.name}`);\n }\n } catch (error: any) {\n logger.error(`❌ Failed to self-link ${currentPackageJson.name}: ${error.message}`);\n throw new Error(`Failed to self-link ${currentPackageJson.name}: ${error.message}`);\n }\n\n // Step 2: Find same-scope dependencies in current package\n const allDependencies = {\n ...currentPackageJson.dependencies,\n ...currentPackageJson.devDependencies\n };\n\n const sameScopeDependencies = Object.keys(allDependencies).filter(depName =>\n depName.startsWith(currentScope + '/')\n );\n\n if (sameScopeDependencies.length === 0) {\n logger.info(`No same-scope dependencies found for ${currentScope}`);\n if (isDryRun) {\n return `DRY RUN: Would self-link, no same-scope dependencies found to link`;\n } else {\n return `Self-linked ${currentPackageJson.name}, no same-scope dependencies to link`;\n }\n }\n\n // Step 3: Get globally linked packages directories (only if we have same-scope dependencies)\n let globallyLinkedPackages: { [key: string]: string } = {};\n try {\n if (isDryRun) {\n logger.info(`DRY RUN: Would run 'npm ls --link -g -p' to discover linked package directories`);\n logger.info(`DRY RUN: Would attempt to link same-scope dependencies: ${sameScopeDependencies.join(', ')}`);\n return `DRY RUN: Would self-link and attempt to link ${sameScopeDependencies.length} same-scope dependencies`;\n } else {\n logger.verbose(`Discovering globally linked package directories...`);\n const result = await run('npm ls --link -g -p');\n const resultStr = typeof result === 'string' ? result : result.stdout;\n\n // Parse the directory paths - each line is a directory path\n const directoryPaths = resultStr.trim().split('\\n').filter(line => line.trim() !== '');\n\n // Extract package names from directory paths and build a map\n for (const dirPath of directoryPaths) {\n try {\n // Read the package.json to get the actual package name\n const packageJsonPath = `${dirPath.trim()}/package.json`;\n const packageJsonContent = await storage.readFile(packageJsonPath, 'utf-8');\n const parsed = safeJsonParse(packageJsonContent, packageJsonPath);\n const packageJson = validatePackageJson(parsed, packageJsonPath);\n\n if (packageJson.name) {\n globallyLinkedPackages[packageJson.name] = dirPath.trim();\n }\n } catch (packageError: any) {\n logger.verbose(`Could not read package.json from ${dirPath}: ${packageError.message}`);\n }\n }\n\n const linkedCount = Object.keys(globallyLinkedPackages).length;\n logger.verbose(`Found ${linkedCount} globally linked package(s)`);\n }\n } catch (error: any) {\n logger.warn(`Failed to get globally linked packages (continuing anyway): ${error.message}`);\n globallyLinkedPackages = {};\n }\n\n logger.info(`Found ${sameScopeDependencies.length} same-scope dependencies: ${sameScopeDependencies.join(', ')}`);\n\n // Step 4: Link same-scope dependencies that are available globally using manual symlinks\n const linkedDependencies: string[] = [];\n\n for (const depName of sameScopeDependencies) {\n const sourcePath = globallyLinkedPackages[depName];\n if (sourcePath) {\n try {\n logger.verbose(`Linking same-scope dependency: ${depName} from ${sourcePath}`);\n\n // Create the symbolic link manually using the directory path directly\n const success = await createSymbolicLink(depName, sourcePath, currentDir, logger, isDryRun);\n\n if (success) {\n logger.info(`✅ Linked dependency: ${depName}`);\n linkedDependencies.push(depName);\n } else {\n logger.warn(`⚠️ Failed to link ${depName}`);\n }\n } catch (error: any) {\n logger.warn(`⚠️ Failed to link ${depName}: ${error.message}`);\n }\n } else {\n logger.verbose(`Skipping ${depName} (not globally linked)`);\n }\n }\n\n const summary = linkedDependencies.length > 0\n ? `Self-linked ${currentPackageJson.name} and linked ${linkedDependencies.length} same-scope dependencies: ${linkedDependencies.join(', ')}`\n : `Self-linked ${currentPackageJson.name}, no same-scope dependencies were available to link`;\n\n logger.info(summary);\n return summary;\n }\n\n // New scope-based linking behavior\n logger.info(`🔗 Linking scope/package: ${packageArgument}`);\n\n const { scope, packageName } = parsePackageArgument(packageArgument);\n logger.verbose(`Parsed scope: ${scope}, package: ${packageName || 'all packages in scope'}`);\n\n // Find matching packages in the workspace\n const matchingPackages = await findMatchingPackages(targetDirectories, scope, storage, logger, packageName);\n\n if (matchingPackages.length === 0) {\n const message = packageName\n ? `No package found matching: ${packageName}`\n : `No packages found in scope: ${scope}`;\n logger.warn(message);\n return message;\n }\n\n logger.info(`Found ${matchingPackages.length} matching package(s)`);\n\n const linkedPackages: string[] = [];\n\n // If specific package name provided, use that; otherwise link all packages in scope\n const packagesToLink = packageName\n ? matchingPackages.filter(pkg => pkg.name === packageName)\n : matchingPackages;\n\n for (const pkg of packagesToLink) {\n logger.info(`Processing package: ${pkg.name}`);\n\n // Step A: Run 'npm link' in the source package directory\n try {\n const originalCwd = process.cwd();\n process.chdir(pkg.path);\n\n try {\n if (isDryRun) {\n logger.info(`DRY RUN: Would run 'npm link' in: ${pkg.path}`);\n } else {\n logger.verbose(`Running 'npm link' in source: ${pkg.path}`);\n await run('npm link');\n logger.info(`✅ Source linked: ${pkg.name}`);\n }\n } finally {\n process.chdir(originalCwd);\n }\n\n // Step B: Find all packages that depend on this package and link them\n const consumingPackages = await findConsumingPackages(targetDirectories, pkg.name, storage, logger);\n\n if (consumingPackages.length === 0) {\n logger.info(`No consuming packages found for: ${pkg.name}`);\n } else {\n logger.info(`Found ${consumingPackages.length} consuming package(s) for: ${pkg.name}`);\n\n for (const consumer of consumingPackages) {\n try {\n const consumerOriginalCwd = process.cwd();\n process.chdir(consumer.path);\n\n try {\n if (isDryRun) {\n logger.info(`DRY RUN: Would run 'npm link ${pkg.name}' in: ${consumer.path}`);\n } else {\n logger.verbose(`Running 'npm link ${pkg.name}' in consumer: ${consumer.path}`);\n await runSecure('npm', ['link', pkg.name]);\n logger.info(`✅ Consumer linked: ${consumer.name} -> ${pkg.name}`);\n }\n } finally {\n process.chdir(consumerOriginalCwd);\n }\n } catch (error: any) {\n logger.error(`❌ Failed to link ${pkg.name} in ${consumer.name}: ${error.message}`);\n throw new Error(`Failed to link ${pkg.name} in consumer ${consumer.name}: ${error.message}`);\n }\n }\n }\n\n linkedPackages.push(pkg.name);\n } catch (error: any) {\n logger.error(`❌ Failed to link source package ${pkg.name}: ${error.message}`);\n throw new Error(`Failed to link source package ${pkg.name}: ${error.message}`);\n }\n }\n\n const summary = `Successfully linked ${linkedPackages.length} package(s): ${linkedPackages.join(', ')}`;\n logger.info(summary);\n return summary;\n};\n\nexport const execute = async (runConfig: Config, packageArgument?: string): Promise<string> => {\n try {\n // Use packageArgument from runConfig if not provided as parameter\n const finalPackageArgument = packageArgument || runConfig.link?.packageArgument;\n return await executeInternal(runConfig, finalPackageArgument);\n } catch (error: any) {\n const logger = getLogger();\n logger.error(`link failed: ${error.message}`);\n throw error;\n }\n};\n"],"names":["createSymbolicLink","packageName","sourcePath","targetDir","logger","isDryRun","scope","name","startsWith","split","nodeModulesPath","path","join","targetPath","scopeDir","fs","mkdir","recursive","verbose","relativePath","relative","dirname","stats","lstat","isSymbolicLink","existingLink","readlink","info","unlink","symlink","isDirectory","warn","rm","force","error","code","message","parsePackageArgument","packageArg","parts","length","Error","findMatchingPackages","targetDirectories","storage","matchingPackages","allPackageJsonFiles","targetDirectory","packageJsonFiles","findAllPackageJsonFiles","concat","packageJsonLocation","packageDir","replace","packageJsonContent","readFile","parsed","safeJsonParse","packageJson","validatePackageJson","isInScope","isExactMatch","push","isSource","findConsumingPackages","targetPackageName","consumingPackages","dependencyTypes","hasDependency","some","depType","executeInternal","runConfig","packageArgument","dryRun","link","getDryRunLogger","createStorage","log","tree","directories","process","cwd","currentDir","packageJsonPath","currentPackageJson","currentScope","run","allDependencies","dependencies","devDependencies","sameScopeDependencies","Object","keys","filter","depName","globallyLinkedPackages","result","resultStr","stdout","directoryPaths","trim","line","dirPath","packageError","linkedCount","linkedDependencies","success","summary","linkedPackages","packagesToLink","pkg","originalCwd","chdir","consumer","consumerOriginalCwd","runSecure","execute","finalPackageArgument","getLogger"],"mappings":"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"}
@@ -3,12 +3,13 @@ import { execute as execute$1 } from './commit.js';
3
3
  import { hasStagedChanges } from '../content/diff.js';
4
4
  import { execute as execute$2 } from './release.js';
5
5
  import { getDryRunLogger, getLogger } from '../logging.js';
6
- import { runWithDryRunSupport, run } from '../util/child.js';
7
- import { getCurrentBranchName, findOpenPullRequestByHeadRef, createPullRequest, waitForPullRequestChecks, mergePullRequest, createRelease, getWorkflowsTriggeredByRelease, waitForReleaseWorkflows } from '../util/github.js';
6
+ import { runWithDryRunSupport, run, validateGitRef, runSecure } from '../util/child.js';
7
+ import { getCurrentBranchName, findOpenPullRequestByHeadRef, createPullRequest, waitForPullRequestChecks, mergePullRequest, createRelease, closeMilestoneForVersion, getWorkflowsTriggeredByRelease, waitForReleaseWorkflows } from '../util/github.js';
8
8
  import { create } from '../util/storage.js';
9
9
  import { calculateTargetVersion, checkIfTagExists, confirmVersionInteractively, getOutputPath } from '../util/general.js';
10
10
  import { DEFAULT_OUTPUT_DIRECTORY } from '../constants.js';
11
11
  import { safeJsonParse, validatePackageJson } from '../util/validation.js';
12
+ import { safeSyncBranchWithRemote, localBranchExists, isBranchInSyncWithRemote } from '../util/git.js';
12
13
 
13
14
  const scanNpmrcForEnvVars = async (storage)=>{
14
15
  const logger = getLogger();
@@ -105,6 +106,40 @@ const runPrechecks = async (runConfig)=>{
105
106
  throw new Error(`Cannot run publish from the target branch '${targetBranch}'. Please switch to a different branch before running publish.`);
106
107
  }
107
108
  }
109
+ // Check target branch sync with remote
110
+ logger.info(`Checking target branch '${targetBranch}' sync with remote...`);
111
+ if (isDryRun) {
112
+ logger.info(`Would verify target branch '${targetBranch}' is in sync with remote origin`);
113
+ } else {
114
+ // Only check if local target branch exists (it's okay if it doesn't exist locally)
115
+ const targetBranchExists = await localBranchExists(targetBranch);
116
+ if (targetBranchExists) {
117
+ const syncStatus = await isBranchInSyncWithRemote(targetBranch);
118
+ if (!syncStatus.inSync) {
119
+ logger.error(`❌ Target branch '${targetBranch}' is not in sync with remote.`);
120
+ logger.error('');
121
+ if (syncStatus.error) {
122
+ logger.error(` Error: ${syncStatus.error}`);
123
+ } else if (syncStatus.localSha && syncStatus.remoteSha) {
124
+ logger.error(` Local: ${syncStatus.localSha.substring(0, 8)}`);
125
+ logger.error(` Remote: ${syncStatus.remoteSha.substring(0, 8)}`);
126
+ }
127
+ logger.error('');
128
+ logger.error('📋 To resolve this issue:');
129
+ logger.error(` 1. Switch to the target branch: git checkout ${targetBranch}`);
130
+ logger.error(` 2. Pull the latest changes: git pull origin ${targetBranch}`);
131
+ logger.error(' 3. Resolve any merge conflicts if they occur');
132
+ logger.error(' 4. Switch back to your feature branch and re-run publish');
133
+ logger.error('');
134
+ logger.error('💡 Alternatively, run "kodrdriv publish --sync-target" to attempt automatic sync.');
135
+ throw new Error(`Target branch '${targetBranch}' is not in sync with remote. Please sync the branch before running publish.`);
136
+ } else {
137
+ logger.info(`✅ Target branch '${targetBranch}' is in sync with remote.`);
138
+ }
139
+ } else {
140
+ logger.info(`ℹ️ Target branch '${targetBranch}' does not exist locally - will be created when needed.`);
141
+ }
142
+ }
108
143
  // Check if prepublishOnly script exists in package.json
109
144
  logger.info('Checking for prepublishOnly script...');
110
145
  const packageJsonPath = path__default.join(process.cwd(), 'package.json');
@@ -154,13 +189,48 @@ const runPrechecks = async (runConfig)=>{
154
189
  }
155
190
  logger.info('All prechecks passed.');
156
191
  };
192
+ const handleTargetBranchSyncRecovery = async (runConfig)=>{
193
+ var _runConfig_publish;
194
+ const isDryRun = runConfig.dryRun || false;
195
+ const logger = getDryRunLogger(isDryRun);
196
+ const targetBranch = ((_runConfig_publish = runConfig.publish) === null || _runConfig_publish === void 0 ? void 0 : _runConfig_publish.targetBranch) || 'main';
197
+ logger.info(`🔄 Attempting to sync target branch '${targetBranch}' with remote...`);
198
+ if (isDryRun) {
199
+ logger.info(`Would attempt to sync '${targetBranch}' with remote`);
200
+ return;
201
+ }
202
+ const syncResult = await safeSyncBranchWithRemote(targetBranch);
203
+ if (syncResult.success) {
204
+ logger.info(`✅ Successfully synced '${targetBranch}' with remote.`);
205
+ logger.info('You can now re-run the publish command.');
206
+ } else if (syncResult.conflictResolutionRequired) {
207
+ logger.error(`❌ Failed to sync '${targetBranch}': conflicts detected.`);
208
+ logger.error('');
209
+ logger.error('📋 Manual conflict resolution required:');
210
+ logger.error(` 1. Switch to the target branch: git checkout ${targetBranch}`);
211
+ logger.error(` 2. Pull and resolve conflicts: git pull origin ${targetBranch}`);
212
+ logger.error(' 3. Commit the resolved changes');
213
+ logger.error(' 4. Switch back to your feature branch and re-run publish');
214
+ logger.error('');
215
+ throw new Error(`Target branch '${targetBranch}' has conflicts that require manual resolution.`);
216
+ } else {
217
+ logger.error(`❌ Failed to sync '${targetBranch}': ${syncResult.error}`);
218
+ throw new Error(`Failed to sync target branch: ${syncResult.error}`);
219
+ }
220
+ };
157
221
  const execute = async (runConfig)=>{
158
- var _runConfig_publish, _runConfig_publish1, _runConfig_publish2;
222
+ var _runConfig_publish, _runConfig_publish1, _runConfig_publish2, _runConfig_publish3;
159
223
  const isDryRun = runConfig.dryRun || false;
160
224
  const logger = getDryRunLogger(isDryRun);
161
225
  const storage = create({
162
226
  log: logger.info
163
227
  });
228
+ const targetBranch = ((_runConfig_publish = runConfig.publish) === null || _runConfig_publish === void 0 ? void 0 : _runConfig_publish.targetBranch) || 'main';
229
+ // Handle --sync-target flag
230
+ if ((_runConfig_publish1 = runConfig.publish) === null || _runConfig_publish1 === void 0 ? void 0 : _runConfig_publish1.syncTarget) {
231
+ await handleTargetBranchSyncRecovery(runConfig);
232
+ return; // Exit after sync operation
233
+ }
164
234
  // Run prechecks before starting any work
165
235
  await runPrechecks(runConfig);
166
236
  logger.info('Starting release process...');
@@ -175,7 +245,7 @@ const execute = async (runConfig)=>{
175
245
  if (pr) {
176
246
  logger.info(`Found existing pull request for branch: ${pr.html_url}`);
177
247
  } else {
178
- var _runConfig_publish3, _runConfig_publish4, _runConfig_publish5;
248
+ var _runConfig_publish4, _runConfig_publish5, _runConfig_publish6;
179
249
  logger.info('No open pull request found, starting new release publishing process...');
180
250
  // STEP 1: Determine and set target version FIRST (before any commits)
181
251
  logger.info('Determining target version...');
@@ -184,13 +254,13 @@ const execute = async (runConfig)=>{
184
254
  logger.info('Would determine target version and update package.json');
185
255
  newVersion = '1.0.0'; // Mock version for dry run
186
256
  } else {
187
- var _runConfig_publish6, _runConfig_publish7;
257
+ var _runConfig_publish7, _runConfig_publish8;
188
258
  const packageJsonContents = await storage.readFile('package.json', 'utf-8');
189
259
  const parsed = safeJsonParse(packageJsonContents, 'package.json');
190
260
  const packageJson = validatePackageJson(parsed, 'package.json');
191
261
  const currentVersion = packageJson.version;
192
262
  // Determine target version based on --targetVersion option
193
- const targetVersionInput = ((_runConfig_publish6 = runConfig.publish) === null || _runConfig_publish6 === void 0 ? void 0 : _runConfig_publish6.targetVersion) || 'patch';
263
+ const targetVersionInput = ((_runConfig_publish7 = runConfig.publish) === null || _runConfig_publish7 === void 0 ? void 0 : _runConfig_publish7.targetVersion) || 'patch';
194
264
  const proposedVersion = calculateTargetVersion(currentVersion, targetVersionInput);
195
265
  // Check if target tag already exists
196
266
  const targetTagName = `v${proposedVersion}`;
@@ -199,7 +269,7 @@ const execute = async (runConfig)=>{
199
269
  throw new Error(`Tag ${targetTagName} already exists. Please choose a different version or delete the existing tag.`);
200
270
  }
201
271
  // Interactive confirmation if --interactive flag is set
202
- if ((_runConfig_publish7 = runConfig.publish) === null || _runConfig_publish7 === void 0 ? void 0 : _runConfig_publish7.interactive) {
272
+ if ((_runConfig_publish8 = runConfig.publish) === null || _runConfig_publish8 === void 0 ? void 0 : _runConfig_publish8.interactive) {
203
273
  newVersion = await confirmVersionInteractively(currentVersion, proposedVersion, targetVersionInput);
204
274
  // Re-check if the confirmed version's tag exists (in case user entered custom version)
205
275
  const confirmedTagName = `v${newVersion}`;
@@ -219,7 +289,7 @@ const execute = async (runConfig)=>{
219
289
  // STEP 2: Prepare for release (with correct version now in package.json)
220
290
  logger.verbose('Preparing for release: switching from workspace to remote dependencies.');
221
291
  logger.verbose('Updating dependencies to latest versions from registry');
222
- const updatePatterns = (_runConfig_publish3 = runConfig.publish) === null || _runConfig_publish3 === void 0 ? void 0 : _runConfig_publish3.dependencyUpdatePatterns;
292
+ const updatePatterns = (_runConfig_publish4 = runConfig.publish) === null || _runConfig_publish4 === void 0 ? void 0 : _runConfig_publish4.dependencyUpdatePatterns;
223
293
  if (updatePatterns && updatePatterns.length > 0) {
224
294
  logger.verbose(`Updating dependencies matching patterns: ${updatePatterns.join(', ')}`);
225
295
  const patternsArg = updatePatterns.join(' ');
@@ -251,7 +321,7 @@ const execute = async (runConfig)=>{
251
321
  const releaseConfig = {
252
322
  ...runConfig
253
323
  };
254
- if (((_runConfig_publish4 = runConfig.publish) === null || _runConfig_publish4 === void 0 ? void 0 : _runConfig_publish4.from) || ((_runConfig_publish5 = runConfig.publish) === null || _runConfig_publish5 === void 0 ? void 0 : _runConfig_publish5.interactive)) {
324
+ if (((_runConfig_publish5 = runConfig.publish) === null || _runConfig_publish5 === void 0 ? void 0 : _runConfig_publish5.from) || ((_runConfig_publish6 = runConfig.publish) === null || _runConfig_publish6 === void 0 ? void 0 : _runConfig_publish6.interactive)) {
255
325
  // Pass the publish --from and --interactive options to the release config
256
326
  releaseConfig.release = {
257
327
  ...runConfig.release,
@@ -304,18 +374,18 @@ const execute = async (runConfig)=>{
304
374
  }
305
375
  logger.info(`Waiting for PR #${pr.number} checks to complete...`);
306
376
  if (!isDryRun) {
307
- var _runConfig_publish8, _runConfig_publish9, _runConfig_publish10;
377
+ var _runConfig_publish9, _runConfig_publish10, _runConfig_publish11;
308
378
  // Configure timeout and user confirmation behavior
309
- const timeout = ((_runConfig_publish8 = runConfig.publish) === null || _runConfig_publish8 === void 0 ? void 0 : _runConfig_publish8.checksTimeout) || 300000; // 5 minutes default
310
- const senditMode = ((_runConfig_publish9 = runConfig.publish) === null || _runConfig_publish9 === void 0 ? void 0 : _runConfig_publish9.sendit) || false;
379
+ const timeout = ((_runConfig_publish9 = runConfig.publish) === null || _runConfig_publish9 === void 0 ? void 0 : _runConfig_publish9.checksTimeout) || 300000; // 5 minutes default
380
+ const senditMode = ((_runConfig_publish10 = runConfig.publish) === null || _runConfig_publish10 === void 0 ? void 0 : _runConfig_publish10.sendit) || false;
311
381
  // sendit flag overrides skipUserConfirmation - if sendit is true, skip confirmation
312
- const skipUserConfirmation = senditMode || ((_runConfig_publish10 = runConfig.publish) === null || _runConfig_publish10 === void 0 ? void 0 : _runConfig_publish10.skipUserConfirmation) || false;
382
+ const skipUserConfirmation = senditMode || ((_runConfig_publish11 = runConfig.publish) === null || _runConfig_publish11 === void 0 ? void 0 : _runConfig_publish11.skipUserConfirmation) || false;
313
383
  await waitForPullRequestChecks(pr.number, {
314
384
  timeout,
315
385
  skipUserConfirmation
316
386
  });
317
387
  }
318
- const mergeMethod = ((_runConfig_publish = runConfig.publish) === null || _runConfig_publish === void 0 ? void 0 : _runConfig_publish.mergeMethod) || 'squash';
388
+ const mergeMethod = ((_runConfig_publish2 = runConfig.publish) === null || _runConfig_publish2 === void 0 ? void 0 : _runConfig_publish2.mergeMethod) || 'squash';
319
389
  if (isDryRun) {
320
390
  logger.info(`Would merge PR #${pr.number} using ${mergeMethod} method`);
321
391
  } else {
@@ -339,10 +409,32 @@ const execute = async (runConfig)=>{
339
409
  }
340
410
  }
341
411
  }
342
- logger.info('Checking out main branch...');
343
- await runWithDryRunSupport('git checkout main', isDryRun);
344
- await runWithDryRunSupport('git pull origin main', isDryRun);
345
- // Now create and push the tag on the main branch
412
+ // Switch to target branch and pull latest changes
413
+ logger.info(`Checking out target branch: ${targetBranch}...`);
414
+ try {
415
+ await runWithDryRunSupport(`git checkout ${targetBranch}`, isDryRun);
416
+ await runWithDryRunSupport(`git pull origin ${targetBranch}`, isDryRun);
417
+ } catch (error) {
418
+ // Check if this is a merge conflict or sync issue
419
+ if (!isDryRun && (error.message.includes('conflict') || error.message.includes('CONFLICT') || error.message.includes('diverged') || error.message.includes('non-fast-forward'))) {
420
+ logger.error(`❌ Failed to sync target branch '${targetBranch}' with remote.`);
421
+ logger.error('');
422
+ logger.error('📋 Recovery options:');
423
+ logger.error(` 1. Run 'kodrdriv publish --sync-target' to attempt automatic resolution`);
424
+ logger.error(` 2. Manually resolve conflicts:`);
425
+ logger.error(` - git checkout ${targetBranch}`);
426
+ logger.error(` - git pull origin ${targetBranch}`);
427
+ logger.error(` - Resolve any conflicts and commit`);
428
+ logger.error(` - Re-run your original publish command`);
429
+ logger.error('');
430
+ logger.error('💡 The publish process has been stopped to prevent data loss.');
431
+ throw new Error(`Target branch '${targetBranch}' sync failed. Use recovery options above to resolve.`);
432
+ } else {
433
+ // Re-throw other errors
434
+ throw error;
435
+ }
436
+ }
437
+ // Now create and push the tag on the target branch
346
438
  logger.info('Creating release tag...');
347
439
  let tagName;
348
440
  if (isDryRun) {
@@ -350,37 +442,63 @@ const execute = async (runConfig)=>{
350
442
  tagName = 'v1.0.0'; // Mock version for dry run
351
443
  } else {
352
444
  const packageJsonContents = await storage.readFile('package.json', 'utf-8');
353
- const { version } = JSON.parse(packageJsonContents);
445
+ const { version } = safeJsonParse(packageJsonContents, 'package.json');
354
446
  tagName = `v${version}`;
355
447
  // Check if tag already exists locally
356
448
  try {
357
- const { stdout } = await run(`git tag -l ${tagName}`);
449
+ // Validate tag name to prevent injection
450
+ if (!validateGitRef(tagName)) {
451
+ throw new Error(`Invalid tag name: ${tagName}`);
452
+ }
453
+ const { stdout } = await runSecure('git', [
454
+ 'tag',
455
+ '-l',
456
+ tagName
457
+ ]);
358
458
  if (stdout.trim() === tagName) {
359
459
  logger.info(`Tag ${tagName} already exists locally, skipping tag creation`);
360
460
  } else {
361
- await run(`git tag ${tagName}`);
461
+ await runSecure('git', [
462
+ 'tag',
463
+ tagName
464
+ ]);
362
465
  logger.info(`Created local tag: ${tagName}`);
363
466
  }
364
467
  } catch (error) {
365
468
  // If git tag -l fails, create the tag anyway
366
- await run(`git tag ${tagName}`);
469
+ await runSecure('git', [
470
+ 'tag',
471
+ tagName
472
+ ]);
367
473
  logger.info(`Created local tag: ${tagName}`);
368
474
  }
369
475
  // Check if tag exists on remote before pushing
370
476
  let tagWasPushed = false;
371
477
  try {
372
- const { stdout } = await run(`git ls-remote origin refs/tags/${tagName}`);
478
+ const { stdout } = await runSecure('git', [
479
+ 'ls-remote',
480
+ 'origin',
481
+ `refs/tags/${tagName}`
482
+ ]);
373
483
  if (stdout.trim()) {
374
484
  logger.info(`Tag ${tagName} already exists on remote, skipping push`);
375
485
  } else {
376
- await run(`git push origin ${tagName}`);
486
+ await runSecure('git', [
487
+ 'push',
488
+ 'origin',
489
+ tagName
490
+ ]);
377
491
  logger.info(`Pushed tag to remote: ${tagName}`);
378
492
  tagWasPushed = true;
379
493
  }
380
494
  } catch (error) {
381
495
  // If ls-remote fails, try to push anyway (might be a new remote)
382
496
  try {
383
- await run(`git push origin ${tagName}`);
497
+ await runSecure('git', [
498
+ 'push',
499
+ 'origin',
500
+ tagName
501
+ ]);
384
502
  logger.info(`Pushed tag to remote: ${tagName}`);
385
503
  tagWasPushed = true;
386
504
  } catch (pushError) {
@@ -399,7 +517,14 @@ const execute = async (runConfig)=>{
399
517
  }
400
518
  logger.info('Creating GitHub release...');
401
519
  if (isDryRun) {
520
+ var _runConfig_publish12;
402
521
  logger.info('Would read package.json version and create GitHub release with retry logic');
522
+ const milestonesEnabled = !((_runConfig_publish12 = runConfig.publish) === null || _runConfig_publish12 === void 0 ? void 0 : _runConfig_publish12.noMilestones);
523
+ if (milestonesEnabled) {
524
+ logger.info('Would close milestone for released version');
525
+ } else {
526
+ logger.info('Would skip milestone closure (--no-milestones)');
527
+ }
403
528
  } else {
404
529
  const outputDirectory = runConfig.outputDirectory || DEFAULT_OUTPUT_DIRECTORY;
405
530
  const releaseNotesPath = getOutputPath(outputDirectory, 'RELEASE_NOTES.md');
@@ -410,8 +535,18 @@ const execute = async (runConfig)=>{
410
535
  let retries = 3;
411
536
  while(retries > 0){
412
537
  try {
538
+ var _runConfig_publish13;
413
539
  await createRelease(tagName, releaseTitle, releaseNotesContent);
414
540
  logger.info(`GitHub release created successfully for tag: ${tagName}`);
541
+ // Close milestone for this version if enabled
542
+ const milestonesEnabled = !((_runConfig_publish13 = runConfig.publish) === null || _runConfig_publish13 === void 0 ? void 0 : _runConfig_publish13.noMilestones);
543
+ if (milestonesEnabled) {
544
+ logger.info('🏁 Closing milestone for released version...');
545
+ const version = tagName.replace(/^v/, ''); // Remove 'v' prefix if present
546
+ await closeMilestoneForVersion(version);
547
+ } else {
548
+ logger.debug('Milestone integration disabled via --no-milestones');
549
+ }
415
550
  break; // Success - exit retry loop
416
551
  } catch (error) {
417
552
  // Check if this is a tag-not-found error that we can retry
@@ -431,18 +566,18 @@ const execute = async (runConfig)=>{
431
566
  }
432
567
  }
433
568
  // Wait for release workflows to complete (if enabled)
434
- const waitForWorkflows = ((_runConfig_publish1 = runConfig.publish) === null || _runConfig_publish1 === void 0 ? void 0 : _runConfig_publish1.waitForReleaseWorkflows) !== false; // default to true
569
+ const waitForWorkflows = ((_runConfig_publish3 = runConfig.publish) === null || _runConfig_publish3 === void 0 ? void 0 : _runConfig_publish3.waitForReleaseWorkflows) !== false; // default to true
435
570
  if (waitForWorkflows) {
436
571
  logger.info('Waiting for release workflows...');
437
572
  if (isDryRun) {
438
573
  logger.info('Would monitor GitHub Actions workflows triggered by release');
439
574
  } else {
440
- var _runConfig_publish11, _runConfig_publish12, _runConfig_publish13, _runConfig_publish14;
441
- const workflowTimeout = ((_runConfig_publish11 = runConfig.publish) === null || _runConfig_publish11 === void 0 ? void 0 : _runConfig_publish11.releaseWorkflowsTimeout) || 600000; // 10 minutes default
442
- const senditMode = ((_runConfig_publish12 = runConfig.publish) === null || _runConfig_publish12 === void 0 ? void 0 : _runConfig_publish12.sendit) || false;
443
- const skipUserConfirmation = senditMode || ((_runConfig_publish13 = runConfig.publish) === null || _runConfig_publish13 === void 0 ? void 0 : _runConfig_publish13.skipUserConfirmation) || false;
575
+ var _runConfig_publish14, _runConfig_publish15, _runConfig_publish16, _runConfig_publish17;
576
+ const workflowTimeout = ((_runConfig_publish14 = runConfig.publish) === null || _runConfig_publish14 === void 0 ? void 0 : _runConfig_publish14.releaseWorkflowsTimeout) || 600000; // 10 minutes default
577
+ const senditMode = ((_runConfig_publish15 = runConfig.publish) === null || _runConfig_publish15 === void 0 ? void 0 : _runConfig_publish15.sendit) || false;
578
+ const skipUserConfirmation = senditMode || ((_runConfig_publish16 = runConfig.publish) === null || _runConfig_publish16 === void 0 ? void 0 : _runConfig_publish16.skipUserConfirmation) || false;
444
579
  // Get workflow names - either from config or auto-detect
445
- let workflowNames = (_runConfig_publish14 = runConfig.publish) === null || _runConfig_publish14 === void 0 ? void 0 : _runConfig_publish14.releaseWorkflowNames;
580
+ let workflowNames = (_runConfig_publish17 = runConfig.publish) === null || _runConfig_publish17 === void 0 ? void 0 : _runConfig_publish17.releaseWorkflowNames;
446
581
  if (!workflowNames || workflowNames.length === 0) {
447
582
  logger.info('No specific workflow names configured, auto-detecting workflows triggered by release events...');
448
583
  try {
@@ -467,7 +602,6 @@ const execute = async (runConfig)=>{
467
602
  logger.verbose('Skipping waiting for release workflows (disabled in config).');
468
603
  }
469
604
  // Switch to target branch
470
- const targetBranch = ((_runConfig_publish2 = runConfig.publish) === null || _runConfig_publish2 === void 0 ? void 0 : _runConfig_publish2.targetBranch) || 'main';
471
605
  logger.info(`Switching to target branch: ${targetBranch}`);
472
606
  await runWithDryRunSupport(`git checkout ${targetBranch}`, isDryRun);
473
607
  logger.info('Publish process complete.');