@eldrforge/core 0.1.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { ExitError, createStorage, incrementPatchVersion, validateVersionString, convertToReleaseVersion, incrementPrereleaseVersion, UserCancellationError, CommandError } from '@eldrforge/shared';
2
2
  export { calculateTargetVersion, convertToReleaseVersion, deepMerge, incrementMajorVersion, incrementMinorVersion, incrementPatchVersion, incrementPrereleaseVersion, stringifyJSON, validateVersionString } from '@eldrforge/shared';
3
3
  import winston from 'winston';
4
+ import { Writable } from 'stream';
4
5
  import * as fs from 'fs';
5
6
  import { statSync } from 'fs';
6
7
  import * as path from 'path';
@@ -419,8 +420,11 @@ const ensureDebugDirectory = ()=>{
419
420
  });
420
421
  debugDirectoryEnsured = true;
421
422
  } catch (error) {
422
- // eslint-disable-next-line no-console
423
- console.error(`Failed to create debug directory ${debugDir}:`, error);
423
+ // Only log to console if not in MCP server mode (MCP mode requires clean stdout)
424
+ if (process.env.KODRDRIV_MCP_SERVER !== 'true') {
425
+ // eslint-disable-next-line no-console
426
+ console.error(`Failed to create debug directory ${debugDir}:`, error);
427
+ }
424
428
  }
425
429
  };
426
430
  const generateDebugLogFilename = ()=>{
@@ -430,69 +434,66 @@ const generateDebugLogFilename = ()=>{
430
434
  };
431
435
  const createTransports = (level)=>{
432
436
  const transports = [];
433
- // Always add console transport for info level and above
434
- if (level === 'info') {
435
- transports.push(new winston.transports.Console({
436
- format: winston.format.combine(winston.format.colorize(), winston.format.printf(({ level, message, dryRun })=>{
437
- const dryRunPrefix = dryRun ? '🔍 DRY RUN: ' : '';
438
- // For info level messages, don't show the level prefix
439
- if (level.includes('info')) {
440
- return `${dryRunPrefix}${String(message)}`;
441
- }
442
- // For warn, error, etc., show the level prefix
443
- return `${level}: ${dryRunPrefix}${String(message)}`;
444
- }))
445
- }));
437
+ // When running as MCP server, NEVER add console transports as they interfere with the protocol
438
+ // All output must go through log capture mechanism instead
439
+ const isMcpServer = process.env.KODRDRIV_MCP_SERVER === 'true';
440
+ if (isMcpServer) {
441
+ // In MCP mode, add a silent Memory transport to prevent winston from logging transport errors
442
+ // Winston complains when there are no transports, so we add a silent one
443
+ // The log capture transport will be added separately via installLogCapture
444
+ // Use a no-op stream that discards all output
445
+ const silentStream = new Writable({
446
+ write (_chunk, _encoding, callback) {
447
+ // Silent - discard all output, log capture handles actual logging
448
+ callback();
449
+ },
450
+ // Suppress any errors from the stream itself
451
+ destroy: function(_err, callback) {
452
+ callback();
453
+ }
454
+ });
455
+ // Suppress winston transport errors by catching them
456
+ const silentTransport = new winston.transports.Stream({
457
+ stream: silentStream,
458
+ silent: true
459
+ });
460
+ // Override error handling on the transport to prevent winston from logging to stderr
461
+ silentTransport.on('error', ()=>{
462
+ // Silently ignore transport errors - don't output to stderr
463
+ });
464
+ transports.push(silentTransport);
446
465
  } else {
447
- // For debug/verbose levels, add console transport that shows info and above
448
- transports.push(new winston.transports.Console({
449
- level: 'info',
450
- format: winston.format.combine(winston.format.colorize(), winston.format.printf(({ timestamp, level, message, dryRun, ...meta })=>{
451
- // For info level messages, use simpler format without timestamp
452
- if (level.includes('info')) {
466
+ // Add console transport for info level and above (only when NOT in MCP mode)
467
+ if (level === 'info') {
468
+ transports.push(new winston.transports.Console({
469
+ format: winston.format.combine(winston.format.colorize(), winston.format.printf(({ level, message, dryRun })=>{
453
470
  const dryRunPrefix = dryRun ? '🔍 DRY RUN: ' : '';
454
- return `${dryRunPrefix}${String(message)}`;
455
- }
456
- // Filter out winston internal metadata
457
- const filteredMeta = Object.keys(meta).reduce((acc, key)=>{
458
- if (![
459
- 'level',
460
- 'message',
461
- 'timestamp',
462
- 'dryRun',
463
- 'service',
464
- 'splat',
465
- 'Symbol(level)',
466
- 'Symbol(message)'
467
- ].includes(key)) {
468
- acc[key] = meta[key];
471
+ // For info level messages, don't show the level prefix
472
+ if (level.includes('info')) {
473
+ return `${dryRunPrefix}${String(message)}`;
469
474
  }
470
- return acc;
471
- }, {});
472
- const metaStr = Object.keys(filteredMeta).length ? ` ${JSON.stringify(filteredMeta, null, 2)}` : '';
473
- const dryRunPrefix = dryRun ? '🔍 DRY RUN: ' : '';
474
- return `${timestamp} ${level}: ${dryRunPrefix}${String(message)}${metaStr}`;
475
- }))
476
- }));
477
- // Add file transport for debug levels (debug and silly)
478
- if (level === 'debug' || level === 'silly') {
479
- ensureDebugDirectory();
480
- const debugLogPath = path__default.join(DEFAULT_OUTPUT_DIRECTORY, 'debug', generateDebugLogFilename());
481
- transports.push(new winston.transports.File({
482
- filename: debugLogPath,
483
- level: 'debug',
484
- format: winston.format.combine(winston.format.timestamp({
485
- format: DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS
486
- }), winston.format.errors({
487
- stack: true
488
- }), winston.format.splat(), winston.format.printf(({ timestamp, level, message, service, ...meta })=>{
489
- // Filter out winston internal metadata and properly format remaining meta
475
+ // For warn, error, etc., show the level prefix
476
+ return `${level}: ${dryRunPrefix}${String(message)}`;
477
+ }))
478
+ }));
479
+ } else {
480
+ // For debug/verbose levels, add console transport that shows info and above
481
+ transports.push(new winston.transports.Console({
482
+ level: 'info',
483
+ format: winston.format.combine(winston.format.colorize(), winston.format.printf(({ timestamp, level, message, dryRun, ...meta })=>{
484
+ // For info level messages, use simpler format without timestamp
485
+ if (level.includes('info')) {
486
+ const dryRunPrefix = dryRun ? '🔍 DRY RUN: ' : '';
487
+ return `${dryRunPrefix}${String(message)}`;
488
+ }
489
+ // Filter out winston internal metadata
490
490
  const filteredMeta = Object.keys(meta).reduce((acc, key)=>{
491
- // Skip internal winston fields
492
491
  if (![
493
492
  'level',
494
493
  'message',
495
494
  'timestamp',
495
+ 'dryRun',
496
+ 'service',
496
497
  'splat',
497
498
  'Symbol(level)',
498
499
  'Symbol(message)'
@@ -502,12 +503,45 @@ const createTransports = (level)=>{
502
503
  return acc;
503
504
  }, {});
504
505
  const metaStr = Object.keys(filteredMeta).length ? ` ${JSON.stringify(filteredMeta, null, 2)}` : '';
505
- const serviceStr = service ? ` [${service}]` : '';
506
- return `${timestamp}${serviceStr} ${level}: ${message}${metaStr}`;
506
+ const dryRunPrefix = dryRun ? '🔍 DRY RUN: ' : '';
507
+ return `${timestamp} ${level}: ${dryRunPrefix}${String(message)}${metaStr}`;
507
508
  }))
508
509
  }));
509
510
  }
510
511
  }
512
+ // Add file transport for debug levels (debug and silly)
513
+ if (level === 'debug' || level === 'silly') {
514
+ ensureDebugDirectory();
515
+ const debugLogPath = path__default.join(DEFAULT_OUTPUT_DIRECTORY, 'debug', generateDebugLogFilename());
516
+ transports.push(new winston.transports.File({
517
+ filename: debugLogPath,
518
+ level: 'debug',
519
+ format: winston.format.combine(winston.format.timestamp({
520
+ format: DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS
521
+ }), winston.format.errors({
522
+ stack: true
523
+ }), winston.format.splat(), winston.format.printf(({ timestamp, level, message, service, ...meta })=>{
524
+ // Filter out winston internal metadata and properly format remaining meta
525
+ const filteredMeta = Object.keys(meta).reduce((acc, key)=>{
526
+ // Skip internal winston fields
527
+ if (![
528
+ 'level',
529
+ 'message',
530
+ 'timestamp',
531
+ 'splat',
532
+ 'Symbol(level)',
533
+ 'Symbol(message)'
534
+ ].includes(key)) {
535
+ acc[key] = meta[key];
536
+ }
537
+ return acc;
538
+ }, {});
539
+ const metaStr = Object.keys(filteredMeta).length ? ` ${JSON.stringify(filteredMeta, null, 2)}` : '';
540
+ const serviceStr = service ? ` [${service}]` : '';
541
+ return `${timestamp}${serviceStr} ${level}: ${message}${metaStr}`;
542
+ }))
543
+ }));
544
+ }
511
545
  return transports;
512
546
  };
513
547
  const createFormat = (level)=>{
@@ -557,17 +591,30 @@ const logger = winston.createLogger({
557
591
  defaultMeta: {
558
592
  service: PROGRAM_NAME
559
593
  },
560
- transports: createTransports('info')
594
+ transports: createTransports('info'),
595
+ // Suppress winston's own error handling in MCP mode to prevent stderr pollution
596
+ exceptionHandlers: process.env.KODRDRIV_MCP_SERVER === 'true' ? [] : undefined,
597
+ rejectionHandlers: process.env.KODRDRIV_MCP_SERVER === 'true' ? [] : undefined,
598
+ // Prevent winston from logging transport errors to stderr
599
+ handleExceptions: false,
600
+ handleRejections: false
561
601
  });
562
602
  const setLogLevel = (level)=>{
563
603
  // Reconfigure the existing logger instead of creating a new one
604
+ const isMcpServer = process.env.KODRDRIV_MCP_SERVER === 'true';
564
605
  logger.configure({
565
606
  level,
566
607
  format: createFormat(level),
567
608
  defaultMeta: {
568
609
  service: PROGRAM_NAME
569
610
  },
570
- transports: createTransports(level)
611
+ transports: createTransports(level),
612
+ // Suppress winston's own error handling in MCP mode to prevent stderr pollution
613
+ exceptionHandlers: isMcpServer ? [] : undefined,
614
+ rejectionHandlers: isMcpServer ? [] : undefined,
615
+ // Prevent winston from logging transport errors to stderr
616
+ handleExceptions: false,
617
+ handleRejections: false
571
618
  });
572
619
  };
573
620
  const getLogger = ()=>logger;
@@ -1840,7 +1887,7 @@ const interactive = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.definePropert
1840
1887
  return Boolean(config.enabled !== false && hasFilters);
1841
1888
  }
1842
1889
 
1843
- function _define_property$1(obj, key, value) {
1890
+ function _define_property$4(obj, key, value) {
1844
1891
  if (key in obj) {
1845
1892
  Object.defineProperty(obj, key, {
1846
1893
  value: value,
@@ -1945,13 +1992,13 @@ function _define_property$1(obj, key, value) {
1945
1992
  return this.lockAcquired;
1946
1993
  }
1947
1994
  constructor(lockPath){
1948
- _define_property$1(this, "lockPath", void 0);
1949
- _define_property$1(this, "lockAcquired", false);
1950
- _define_property$1(this, "maxRetries", 100); // Maximum number of lock attempts
1951
- _define_property$1(this, "retryDelay", 100); // Initial retry delay in ms
1952
- _define_property$1(this, "maxRetryDelay", 2000); // Maximum retry delay in ms
1953
- _define_property$1(this, "lockTimeout", 30000); // Consider lock stale after 30 seconds
1954
- _define_property$1(this, "logger", getLogger());
1995
+ _define_property$4(this, "lockPath", void 0);
1996
+ _define_property$4(this, "lockAcquired", false);
1997
+ _define_property$4(this, "maxRetries", 100); // Maximum number of lock attempts
1998
+ _define_property$4(this, "retryDelay", 100); // Initial retry delay in ms
1999
+ _define_property$4(this, "maxRetryDelay", 2000); // Maximum retry delay in ms
2000
+ _define_property$4(this, "lockTimeout", 30000); // Consider lock stale after 30 seconds
2001
+ _define_property$4(this, "logger", getLogger());
1955
2002
  this.lockPath = lockPath;
1956
2003
  }
1957
2004
  }
@@ -2067,13 +2114,13 @@ function _define_property$1(obj, key, value) {
2067
2114
  this.locks.clear();
2068
2115
  }
2069
2116
  constructor(){
2070
- _define_property$1(this, "locks", new Map());
2071
- _define_property$1(this, "logger", getLogger());
2072
- _define_property$1(this, "cleanupRegistered", false);
2117
+ _define_property$4(this, "locks", new Map());
2118
+ _define_property$4(this, "logger", getLogger());
2119
+ _define_property$4(this, "cleanupRegistered", false);
2073
2120
  }
2074
2121
  }
2075
2122
 
2076
- function _define_property(obj, key, value) {
2123
+ function _define_property$3(obj, key, value) {
2077
2124
  if (key in obj) {
2078
2125
  Object.defineProperty(obj, key, {
2079
2126
  value: value,
@@ -2114,8 +2161,8 @@ function _define_property(obj, key, value) {
2114
2161
  this.lockManager.destroy();
2115
2162
  }
2116
2163
  constructor(){
2117
- _define_property(this, "lockManager", void 0);
2118
- _define_property(this, "logger", getLogger());
2164
+ _define_property$3(this, "lockManager", void 0);
2165
+ _define_property$3(this, "logger", getLogger());
2119
2166
  this.lockManager = new RepositoryFileLockManager();
2120
2167
  }
2121
2168
  }
@@ -2383,9 +2430,11 @@ let globalGitMutexManager = null;
2383
2430
  // Truncate if too long
2384
2431
  if (sanitized.length > maxLength) {
2385
2432
  const truncated = sanitized.substring(0, maxLength - 3) + '...';
2386
- // Log truncation for debugging
2387
- // eslint-disable-next-line no-console
2388
- console.warn(`Direction truncated from ${sanitized.length} to ${truncated.length} characters`);
2433
+ // Log truncation for debugging (only if not in MCP server mode)
2434
+ if (process.env.KODRDRIV_MCP_SERVER !== 'true') {
2435
+ // eslint-disable-next-line no-console
2436
+ console.warn(`Direction truncated from ${sanitized.length} to ${truncated.length} characters`);
2437
+ }
2389
2438
  return truncated;
2390
2439
  }
2391
2440
  return sanitized;
@@ -2465,6 +2514,104 @@ let globalGitMutexManager = null;
2465
2514
  warnings
2466
2515
  });
2467
2516
 
2517
+ /**
2518
+ * Progress tracking for long-running operations
2519
+ *
2520
+ * Provides structured progress updates for MCP integrations
2521
+ */ function _define_property$2(obj, key, value) {
2522
+ if (key in obj) {
2523
+ Object.defineProperty(obj, key, {
2524
+ value: value,
2525
+ enumerable: true,
2526
+ configurable: true,
2527
+ writable: true
2528
+ });
2529
+ } else {
2530
+ obj[key] = value;
2531
+ }
2532
+ return obj;
2533
+ }
2534
+ class ProgressTracker {
2535
+ /**
2536
+ * Set the total number of items
2537
+ */ setTotal(total) {
2538
+ this.total = total;
2539
+ }
2540
+ /**
2541
+ * Start a new step
2542
+ */ startStep(stepName) {
2543
+ this.currentStep = stepName;
2544
+ }
2545
+ /**
2546
+ * Complete the current step
2547
+ */ completeStep() {
2548
+ if (this.currentStep) {
2549
+ this.completedSteps.push(this.currentStep);
2550
+ this.current++;
2551
+ }
2552
+ }
2553
+ /**
2554
+ * Set remaining packages
2555
+ */ setRemainingPackages(packages) {
2556
+ this.remainingPackages = packages;
2557
+ }
2558
+ /**
2559
+ * Get current progress
2560
+ */ getProgress() {
2561
+ return {
2562
+ current: this.current,
2563
+ total: this.total,
2564
+ currentStep: this.currentStep,
2565
+ completedSteps: [
2566
+ ...this.completedSteps
2567
+ ],
2568
+ remainingPackages: [
2569
+ ...this.remainingPackages
2570
+ ],
2571
+ percentage: this.total > 0 ? Math.round(this.current / this.total * 100) : 0
2572
+ };
2573
+ }
2574
+ /**
2575
+ * Reset progress
2576
+ */ reset() {
2577
+ this.completedSteps = [];
2578
+ this.currentStep = '';
2579
+ this.current = 0;
2580
+ this.remainingPackages = [];
2581
+ }
2582
+ /**
2583
+ * Create a progress update for a package execution
2584
+ */ static forPackage(packageName, index, total, completedPackages, remainingPackages) {
2585
+ return {
2586
+ current: index,
2587
+ total: total,
2588
+ currentStep: `Processing: ${packageName}`,
2589
+ completedSteps: completedPackages.map((pkg)=>`Completed: ${pkg}`),
2590
+ remainingPackages: remainingPackages,
2591
+ percentage: total > 0 ? Math.round(index / total * 100) : 0
2592
+ };
2593
+ }
2594
+ /**
2595
+ * Create a progress update for a build phase
2596
+ */ static forPhase(phase, completedPhases, totalPhases) {
2597
+ return {
2598
+ current: completedPhases.length,
2599
+ total: totalPhases,
2600
+ currentStep: phase,
2601
+ completedSteps: completedPhases,
2602
+ percentage: totalPhases > 0 ? Math.round(completedPhases.length / totalPhases * 100) : 0
2603
+ };
2604
+ }
2605
+ constructor(total = 0){
2606
+ _define_property$2(this, "completedSteps", []);
2607
+ _define_property$2(this, "currentStep", '');
2608
+ _define_property$2(this, "current", 0);
2609
+ _define_property$2(this, "total", 0);
2610
+ _define_property$2(this, "remainingPackages", []);
2611
+ this.total = total;
2612
+ }
2613
+ }
2614
+
2468
2615
  const ConfigSchema = z.object({
2469
2616
  dryRun: z.boolean().optional(),
2470
2617
  verbose: z.boolean().optional(),
@@ -2542,6 +2689,7 @@ const ConfigSchema = z.object({
2542
2689
  noMilestones: z.boolean().optional(),
2543
2690
  fromMain: z.boolean().optional(),
2544
2691
  currentBranch: z.string().optional(),
2692
+ version: z.string().optional(),
2545
2693
  // Agentic options (always enabled)
2546
2694
  maxAgenticIterations: z.number().optional(),
2547
2695
  selfReflection: z.boolean().optional()
@@ -2594,6 +2742,9 @@ const ConfigSchema = z.object({
2594
2742
  ]).optional(),
2595
2743
  openaiMaxOutputTokens: z.number().optional()
2596
2744
  }).optional(),
2745
+ precommit: z.object({
2746
+ fix: z.boolean().optional()
2747
+ }).optional(),
2597
2748
  publish: z.object({
2598
2749
  mergeMethod: z.enum([
2599
2750
  'merge',
@@ -2623,7 +2774,8 @@ const ConfigSchema = z.object({
2623
2774
  skipPrePublishMerge: z.boolean().optional(),
2624
2775
  updateDeps: z.string().optional(),
2625
2776
  agenticPublish: z.boolean().optional(),
2626
- agenticPublishMaxIterations: z.number().optional()
2777
+ agenticPublishMaxIterations: z.number().optional(),
2778
+ skipLinkCleanup: z.boolean().optional()
2627
2779
  }).optional(),
2628
2780
  branches: z.record(z.string(), z.object({
2629
2781
  targetBranch: z.string().optional(),
@@ -2669,6 +2821,7 @@ const ConfigSchema = z.object({
2669
2821
  packageArgument: z.string().optional(),
2670
2822
  cleanNodeModules: z.boolean().optional(),
2671
2823
  externals: z.array(z.string()).optional(),
2824
+ fix: z.boolean().optional(),
2672
2825
  // Parallel execution options
2673
2826
  parallel: z.boolean().optional(),
2674
2827
  maxConcurrency: z.number().optional(),
@@ -2704,7 +2857,8 @@ const ConfigSchema = z.object({
2704
2857
  resetPackage: z.string().optional(),
2705
2858
  statusParallel: z.boolean().optional(),
2706
2859
  auditBranches: z.boolean().optional(),
2707
- validateState: z.boolean().optional()
2860
+ validateState: z.boolean().optional(),
2861
+ order: z.boolean().optional()
2708
2862
  }).optional(),
2709
2863
  development: z.object({
2710
2864
  targetVersion: z.string().optional(),
@@ -2758,5 +2912,316 @@ const CommandConfigSchema = z.object({
2758
2912
  commandName: z.string().optional()
2759
2913
  });
2760
2914
 
2761
- export { ALLOWED_COMMANDS, COMMAND_AUDIO_COMMIT, COMMAND_AUDIO_REVIEW, COMMAND_CHECK_CONFIG, COMMAND_CLEAN, COMMAND_COMMIT, COMMAND_DEVELOPMENT, COMMAND_INIT_CONFIG, COMMAND_LINK, COMMAND_PRECOMMIT, COMMAND_PUBLISH, COMMAND_RELEASE, COMMAND_REVIEW, COMMAND_SELECT_AUDIO, COMMAND_TREE, COMMAND_UNLINK, COMMAND_UPDATES, COMMAND_VERSIONS, CommandConfigSchema, ConfigSchema, DATE_FORMAT_DAY, DATE_FORMAT_HOURS, DATE_FORMAT_MILLISECONDS, DATE_FORMAT_MINUTES, DATE_FORMAT_MONTH, DATE_FORMAT_MONTH_DAY, DATE_FORMAT_SECONDS, DATE_FORMAT_SHORT_TIMESTAMP, DATE_FORMAT_YEAR, DATE_FORMAT_YEAR_MONTH, DATE_FORMAT_YEAR_MONTH_DAY, DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES, DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS, DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS, DATE_FORMAT_YEAR_MONTH_DAY_SLASH, DEFAULT_ADD, DEFAULT_AMEND_MODE, DEFAULT_BINARY_TO_TEXT_ENCODING, DEFAULT_CACHED, DEFAULT_CHARACTER_ENCODING, DEFAULT_COMMAND, DEFAULT_CONFIG_DIR, DEFAULT_CONTEXT_DIRECTORIES, DEFAULT_DEBUG, DEFAULT_DIFF, DEFAULT_DIRECTORY_PREFIX, DEFAULT_DRY_RUN, DEFAULT_EXCLUDED_PATTERNS, DEFAULT_FROM_COMMIT_ALIAS, DEFAULT_GIT_COMMAND_MAX_BUFFER, DEFAULT_IGNORE_PATTERNS, DEFAULT_INSTRUCTIONS_COMMIT_FILE, DEFAULT_INSTRUCTIONS_DIR, DEFAULT_INSTRUCTIONS_MAP, DEFAULT_INSTRUCTIONS_RELEASE_FILE, DEFAULT_INSTRUCTIONS_REVIEW_FILE, DEFAULT_INTERACTIVE_MODE, DEFAULT_LOG, DEFAULT_MAX_DIFF_BYTES, DEFAULT_MERGE_METHOD, DEFAULT_MESSAGE_LIMIT, DEFAULT_MODEL, DEFAULT_MODEL_STRONG, DEFAULT_OPENAI_MAX_OUTPUT_TOKENS, DEFAULT_OPENAI_REASONING, DEFAULT_OUTPUT_DIRECTORY, DEFAULT_OVERRIDES, DEFAULT_PATH_SEPARATOR, DEFAULT_PERSONA_DIR, DEFAULT_PERSONA_MAP, DEFAULT_PERSONA_RELEASER_FILE, DEFAULT_PERSONA_YOU_FILE, DEFAULT_PREFERENCES_DIRECTORY, DEFAULT_SENDIT_MODE, DEFAULT_TO_COMMIT_ALIAS, DEFAULT_VERBOSE, diff as Diff, FileLock, files as Files, INTERNAL_DATETIME_FORMAT, INTERNAL_DEFAULT_OUTPUT_FILE, KODRDRIV_DEFAULTS, log as Log, PROGRAM_NAME, RepositoryFileLockManager, RepositoryMutexManager, SecureConfigSchema, VERSION, areInSameRepository, calculateBranchDependentVersion, checkIfTagExists, confirmVersionInteractively, createErrorResult, createLoggerAdapter, createStorageAdapter, createSuccessResult, destroyGitMutexManager, executeWithErrorHandling, filterContent, findDevelopmentBranch, getDryRunLogger, getExpectedVersionPattern, getGitMutexManager, getGitRepositoryRoot, getLogger, getNpmPublishedVersion, getOutputPath, getTagInfo, getTimestampedArchivedAudioFilename, getTimestampedArchivedTranscriptFilename, getTimestampedAudioFilename, getTimestampedCommitFilename, getTimestampedFilename, getTimestampedReleaseNotesFilename, getTimestampedRequestFilename, getTimestampedResponseFilename, getTimestampedReviewFilename, getTimestampedReviewNotesFilename, getTimestampedTranscriptFilename, getVersionFromBranch, handleCommandError, haveSamePrereleaseTag, improveContentWithLLM, isDevelopmentVersion, isInGitRepository, isReleaseVersion, isStopContextEnabled, isVersionPublishedOnNpm, runGitWithLock, sanitizeDirection, setLogLevel, toAIConfig, validateReleaseSummary, validateTranscriptionResult, validateVersionForBranch };
2915
+ /**
2916
+ * Structured error types for kodrdriv operations
2917
+ *
2918
+ * These errors provide detailed context for MCP integrations and AI agents
2919
+ * to understand failures and provide actionable recovery steps.
2920
+ */ function _define_property$1(obj, key, value) {
2921
+ if (key in obj) {
2922
+ Object.defineProperty(obj, key, {
2923
+ value: value,
2924
+ enumerable: true,
2925
+ configurable: true,
2926
+ writable: true
2927
+ });
2928
+ } else {
2929
+ obj[key] = value;
2930
+ }
2931
+ return obj;
2932
+ }
2933
+ /**
2934
+ * Base error class for all kodrdriv operations
2935
+ */ class KodrdrivError extends Error {
2936
+ constructor(message, context, recoverable = true){
2937
+ super(message), _define_property$1(this, "context", void 0), _define_property$1(this, "recoverable", void 0), this.context = context, this.recoverable = recoverable;
2938
+ this.name = 'KodrdrivError';
2939
+ // Capture stack trace
2940
+ if (Error.captureStackTrace) {
2941
+ Error.captureStackTrace(this, this.constructor);
2942
+ }
2943
+ }
2944
+ }
2945
+ /**
2946
+ * Error specific to publish operations
2947
+ */ class PublishError extends KodrdrivError {
2948
+ constructor(message, context){
2949
+ super(message, {
2950
+ ...context,
2951
+ operation: 'publish'
2952
+ });
2953
+ this.name = 'PublishError';
2954
+ }
2955
+ }
2956
+ /**
2957
+ * Error specific to tree operations (monorepo orchestration)
2958
+ */ class TreeExecutionError extends KodrdrivError {
2959
+ constructor(message, context, failedPackages = [], completedPackages = [], checkpointPath){
2960
+ super(message, {
2961
+ ...context,
2962
+ operation: 'tree'
2963
+ }), _define_property$1(this, "failedPackages", void 0), _define_property$1(this, "completedPackages", void 0), _define_property$1(this, "checkpointPath", void 0), this.failedPackages = failedPackages, this.completedPackages = completedPackages, this.checkpointPath = checkpointPath;
2964
+ this.name = 'TreeExecutionError';
2965
+ }
2966
+ }
2967
+ /**
2968
+ * Error for validation failures (pre-flight checks)
2969
+ */ class ValidationError extends KodrdrivError {
2970
+ constructor(message, context, validationErrors = [], validationWarnings = []){
2971
+ super(message, {
2972
+ ...context,
2973
+ operation: 'validation'
2974
+ }, false), _define_property$1(this, "validationErrors", void 0), _define_property$1(this, "validationWarnings", void 0), this.validationErrors = validationErrors, this.validationWarnings = validationWarnings;
2975
+ this.name = 'ValidationError';
2976
+ }
2977
+ }
2978
+ /**
2979
+ * Error for workspace structure issues
2980
+ */ class WorkspaceError extends KodrdrivError {
2981
+ constructor(message, context, expectedStructure){
2982
+ super(message, {
2983
+ ...context,
2984
+ operation: 'workspace'
2985
+ }, false), _define_property$1(this, "expectedStructure", void 0), this.expectedStructure = expectedStructure;
2986
+ this.name = 'WorkspaceError';
2987
+ }
2988
+ }
2989
+ /**
2990
+ * Format error for MCP tool responses
2991
+ */ function formatErrorForMCP(error) {
2992
+ // Handle TreeExecutionError
2993
+ if (error instanceof TreeExecutionError) {
2994
+ const recovery = [];
2995
+ if (error.failedPackages.length > 0) {
2996
+ recovery.push(`Fix the issue in: ${error.failedPackages.join(', ')}`);
2997
+ }
2998
+ if (error.checkpointPath) {
2999
+ recovery.push(`Then resume with: kodrdriv tree_publish --continue`);
3000
+ recovery.push(`Or via MCP: kodrdriv_tree_publish({directory: "...", continue: true})`);
3001
+ }
3002
+ return {
3003
+ message: error.message,
3004
+ context: {
3005
+ ...error.context,
3006
+ failedPackages: error.failedPackages,
3007
+ completedPackages: error.completedPackages,
3008
+ checkpointPath: error.checkpointPath,
3009
+ recoverable: error.recoverable
3010
+ },
3011
+ recovery: recovery.length > 0 ? recovery : undefined
3012
+ };
3013
+ }
3014
+ // Handle ValidationError
3015
+ if (error instanceof ValidationError) {
3016
+ const recovery = [];
3017
+ if (error.validationErrors.length > 0) {
3018
+ recovery.push('Fix the following validation errors:');
3019
+ error.validationErrors.forEach((err, idx)=>{
3020
+ recovery.push(` ${idx + 1}. ${err.check}: ${err.message}`);
3021
+ if (err.files && err.files.length > 0) {
3022
+ recovery.push(` Files: ${err.files.join(', ')}`);
3023
+ }
3024
+ });
3025
+ }
3026
+ return {
3027
+ message: error.message,
3028
+ context: {
3029
+ ...error.context,
3030
+ validationErrors: error.validationErrors,
3031
+ validationWarnings: error.validationWarnings,
3032
+ recoverable: error.recoverable
3033
+ },
3034
+ recovery: recovery.length > 0 ? recovery : undefined
3035
+ };
3036
+ }
3037
+ // Handle PublishError
3038
+ if (error instanceof PublishError) {
3039
+ const recovery = [];
3040
+ if (error.context.phase) {
3041
+ recovery.push(`Failed during: ${error.context.phase}`);
3042
+ }
3043
+ if (error.context.files && error.context.files.length > 0) {
3044
+ recovery.push(`Check these files: ${error.context.files.join(', ')}`);
3045
+ }
3046
+ if (error.context.command) {
3047
+ recovery.push(`Failed command: ${error.context.command}`);
3048
+ if (error.context.exitCode) {
3049
+ recovery.push(`Exit code: ${error.context.exitCode}`);
3050
+ }
3051
+ }
3052
+ return {
3053
+ message: error.message,
3054
+ context: {
3055
+ ...error.context,
3056
+ recoverable: error.recoverable
3057
+ },
3058
+ recovery: recovery.length > 0 ? recovery : undefined
3059
+ };
3060
+ }
3061
+ // Handle WorkspaceError
3062
+ if (error instanceof WorkspaceError) {
3063
+ const recovery = [];
3064
+ if (error.expectedStructure) {
3065
+ recovery.push(`Expected structure: ${error.expectedStructure}`);
3066
+ }
3067
+ if (error.context.files && error.context.files.length > 0) {
3068
+ recovery.push(`Missing or invalid files: ${error.context.files.join(', ')}`);
3069
+ }
3070
+ return {
3071
+ message: error.message,
3072
+ context: {
3073
+ ...error.context,
3074
+ expectedStructure: error.expectedStructure,
3075
+ recoverable: error.recoverable
3076
+ },
3077
+ recovery: recovery.length > 0 ? recovery : undefined
3078
+ };
3079
+ }
3080
+ // Handle generic KodrdrivError
3081
+ if (error instanceof KodrdrivError) {
3082
+ return {
3083
+ message: error.message,
3084
+ context: {
3085
+ ...error.context,
3086
+ recoverable: error.recoverable
3087
+ }
3088
+ };
3089
+ }
3090
+ // Handle generic Error
3091
+ return {
3092
+ message: error.message || 'Unknown error occurred',
3093
+ context: {
3094
+ name: error.name,
3095
+ stack: error.stack
3096
+ }
3097
+ };
3098
+ }
3099
+ /**
3100
+ * Extract error details from command execution errors
3101
+ */ function extractCommandErrorDetails(error) {
3102
+ const context = {};
3103
+ // Extract stdout/stderr from various error formats
3104
+ if (error.stdout) {
3105
+ context.stdout = typeof error.stdout === 'string' ? error.stdout : String(error.stdout);
3106
+ }
3107
+ if (error.stderr) {
3108
+ context.stderr = typeof error.stderr === 'string' ? error.stderr : String(error.stderr);
3109
+ }
3110
+ // Extract exit code
3111
+ if (error.code !== undefined) {
3112
+ context.exitCode = error.code;
3113
+ } else if (error.exitCode !== undefined) {
3114
+ context.exitCode = error.exitCode;
3115
+ }
3116
+ // Extract command if available
3117
+ if (error.cmd) {
3118
+ context.command = error.cmd;
3119
+ } else if (error.command) {
3120
+ context.command = error.command;
3121
+ }
3122
+ return context;
3123
+ }
3124
+
3125
+ function _define_property(obj, key, value) {
3126
+ if (key in obj) {
3127
+ Object.defineProperty(obj, key, {
3128
+ value: value,
3129
+ enumerable: true,
3130
+ configurable: true,
3131
+ writable: true
3132
+ });
3133
+ } else {
3134
+ obj[key] = value;
3135
+ }
3136
+ return obj;
3137
+ }
3138
+ class TransactionLog {
3139
+ /**
3140
+ * Record an operation with its rollback function
3141
+ */ async record(type, details, rollback) {
3142
+ this.operations.push({
3143
+ type,
3144
+ timestamp: new Date(),
3145
+ details,
3146
+ rollback
3147
+ });
3148
+ this.logger.debug(`TRANSACTION_RECORDED: ${type} | Details: ${JSON.stringify(details)}`);
3149
+ }
3150
+ /**
3151
+ * Roll back all operations in reverse order
3152
+ */ async rollbackAll() {
3153
+ this.logger.info('TRANSACTION_ROLLBACK_STARTING: Rolling back operations | Count: ' + this.operations.length);
3154
+ const errors = [];
3155
+ // Rollback in reverse order (LIFO)
3156
+ for(let i = this.operations.length - 1; i >= 0; i--){
3157
+ const op = this.operations[i];
3158
+ try {
3159
+ this.logger.info(`TRANSACTION_ROLLBACK: Rolling back ${op.type} | Timestamp: ${op.timestamp.toISOString()}`);
3160
+ await op.rollback();
3161
+ this.logger.info(`TRANSACTION_ROLLBACK_SUCCESS: ${op.type} rolled back successfully`);
3162
+ } catch (error) {
3163
+ this.logger.error(`TRANSACTION_ROLLBACK_FAILED: Failed to rollback ${op.type} | Error: ${error.message}`);
3164
+ errors.push(error);
3165
+ // Continue rolling back other operations even if one fails
3166
+ }
3167
+ }
3168
+ if (errors.length > 0) {
3169
+ this.logger.error(`TRANSACTION_ROLLBACK_PARTIAL: ${errors.length} rollback operation(s) failed`);
3170
+ throw new Error(`Rollback completed with ${errors.length} error(s). See logs for details.`);
3171
+ }
3172
+ this.logger.info('TRANSACTION_ROLLBACK_COMPLETE: All operations rolled back successfully');
3173
+ this.operations = [];
3174
+ }
3175
+ /**
3176
+ * Clear the transaction log without rolling back
3177
+ */ clear() {
3178
+ this.operations = [];
3179
+ this.logger.debug('TRANSACTION_LOG_CLEARED: Transaction log cleared');
3180
+ }
3181
+ /**
3182
+ * Get the number of recorded operations
3183
+ */ get count() {
3184
+ return this.operations.length;
3185
+ }
3186
+ /**
3187
+ * Get all operations
3188
+ */ getOperations() {
3189
+ return [
3190
+ ...this.operations
3191
+ ];
3192
+ }
3193
+ /**
3194
+ * Check if there are any recorded operations
3195
+ */ hasOperations() {
3196
+ return this.operations.length > 0;
3197
+ }
3198
+ constructor(){
3199
+ _define_property(this, "operations", []);
3200
+ _define_property(this, "logger", getLogger());
3201
+ }
3202
+ }
3203
+ /**
3204
+ * Create a no-op rollback function for operations that can't be rolled back
3205
+ */ function noopRollback() {
3206
+ return Promise.resolve();
3207
+ }
3208
+ /**
3209
+ * Helper to create a file restore rollback
3210
+ */ function createFileRestoreRollback(filePath, originalContent) {
3211
+ return async ()=>{
3212
+ const { createStorage } = await import('@eldrforge/shared');
3213
+ const storage = createStorage();
3214
+ await storage.writeFile(filePath, originalContent, 'utf-8');
3215
+ };
3216
+ }
3217
+ /**
3218
+ * Helper to create a git command rollback
3219
+ */ function createGitRollback(command) {
3220
+ return async ()=>{
3221
+ const { run } = await import('@eldrforge/git-tools');
3222
+ await run(command);
3223
+ };
3224
+ }
3225
+
3226
+ export { ALLOWED_COMMANDS, COMMAND_AUDIO_COMMIT, COMMAND_AUDIO_REVIEW, COMMAND_CHECK_CONFIG, COMMAND_CLEAN, COMMAND_COMMIT, COMMAND_DEVELOPMENT, COMMAND_INIT_CONFIG, COMMAND_LINK, COMMAND_PRECOMMIT, COMMAND_PUBLISH, COMMAND_RELEASE, COMMAND_REVIEW, COMMAND_SELECT_AUDIO, COMMAND_TREE, COMMAND_UNLINK, COMMAND_UPDATES, COMMAND_VERSIONS, CommandConfigSchema, ConfigSchema, DATE_FORMAT_DAY, DATE_FORMAT_HOURS, DATE_FORMAT_MILLISECONDS, DATE_FORMAT_MINUTES, DATE_FORMAT_MONTH, DATE_FORMAT_MONTH_DAY, DATE_FORMAT_SECONDS, DATE_FORMAT_SHORT_TIMESTAMP, DATE_FORMAT_YEAR, DATE_FORMAT_YEAR_MONTH, DATE_FORMAT_YEAR_MONTH_DAY, DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES, DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS, DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS, DATE_FORMAT_YEAR_MONTH_DAY_SLASH, DEFAULT_ADD, DEFAULT_AMEND_MODE, DEFAULT_BINARY_TO_TEXT_ENCODING, DEFAULT_CACHED, DEFAULT_CHARACTER_ENCODING, DEFAULT_COMMAND, DEFAULT_CONFIG_DIR, DEFAULT_CONTEXT_DIRECTORIES, DEFAULT_DEBUG, DEFAULT_DIFF, DEFAULT_DIRECTORY_PREFIX, DEFAULT_DRY_RUN, DEFAULT_EXCLUDED_PATTERNS, DEFAULT_FROM_COMMIT_ALIAS, DEFAULT_GIT_COMMAND_MAX_BUFFER, DEFAULT_IGNORE_PATTERNS, DEFAULT_INSTRUCTIONS_COMMIT_FILE, DEFAULT_INSTRUCTIONS_DIR, DEFAULT_INSTRUCTIONS_MAP, DEFAULT_INSTRUCTIONS_RELEASE_FILE, DEFAULT_INSTRUCTIONS_REVIEW_FILE, DEFAULT_INTERACTIVE_MODE, DEFAULT_LOG, DEFAULT_MAX_DIFF_BYTES, DEFAULT_MERGE_METHOD, DEFAULT_MESSAGE_LIMIT, DEFAULT_MODEL, DEFAULT_MODEL_STRONG, DEFAULT_OPENAI_MAX_OUTPUT_TOKENS, DEFAULT_OPENAI_REASONING, DEFAULT_OUTPUT_DIRECTORY, DEFAULT_OVERRIDES, DEFAULT_PATH_SEPARATOR, DEFAULT_PERSONA_DIR, DEFAULT_PERSONA_MAP, DEFAULT_PERSONA_RELEASER_FILE, DEFAULT_PERSONA_YOU_FILE, DEFAULT_PREFERENCES_DIRECTORY, DEFAULT_SENDIT_MODE, DEFAULT_TO_COMMIT_ALIAS, DEFAULT_VERBOSE, diff as Diff, FileLock, files as Files, INTERNAL_DATETIME_FORMAT, INTERNAL_DEFAULT_OUTPUT_FILE, KODRDRIV_DEFAULTS, KodrdrivError, log as Log, PROGRAM_NAME, ProgressTracker, PublishError, RepositoryFileLockManager, RepositoryMutexManager, SecureConfigSchema, TransactionLog, TreeExecutionError, VERSION, ValidationError, WorkspaceError, areInSameRepository, calculateBranchDependentVersion, checkIfTagExists, confirmVersionInteractively, createErrorResult, createFileRestoreRollback, createGitRollback, createLoggerAdapter, createStorageAdapter, createSuccessResult, destroyGitMutexManager, executeWithErrorHandling, extractCommandErrorDetails, filterContent, findDevelopmentBranch, formatErrorForMCP, getDryRunLogger, getExpectedVersionPattern, getGitMutexManager, getGitRepositoryRoot, getLogger, getNpmPublishedVersion, getOutputPath, getTagInfo, getTimestampedArchivedAudioFilename, getTimestampedArchivedTranscriptFilename, getTimestampedAudioFilename, getTimestampedCommitFilename, getTimestampedFilename, getTimestampedReleaseNotesFilename, getTimestampedRequestFilename, getTimestampedResponseFilename, getTimestampedReviewFilename, getTimestampedReviewNotesFilename, getTimestampedTranscriptFilename, getVersionFromBranch, handleCommandError, haveSamePrereleaseTag, improveContentWithLLM, isDevelopmentVersion, isInGitRepository, isReleaseVersion, isStopContextEnabled, isVersionPublishedOnNpm, noopRollback, runGitWithLock, sanitizeDirection, setLogLevel, toAIConfig, validateReleaseSummary, validateTranscriptionResult, validateVersionForBranch };
2762
3227
  //# sourceMappingURL=index.js.map