@eldrforge/kodrdriv 1.2.137 → 1.3.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.
@@ -0,0 +1,79 @@
1
+ # Bug: tree_publish passes incorrect --config-dir path
2
+
3
+ ## Problem
4
+
5
+ When `tree_publish` executes `kodrdriv publish` for each package, it passes `--config-dir` with the parent directory path, but kodrdriv's config discovery expects either:
6
+ 1. The full path to the config directory (`.kodrdriv`), or
7
+ 2. No `--config-dir` flag at all (to allow hierarchical discovery)
8
+
9
+ ## Current Behavior
10
+
11
+ When `tree_publish` runs from `/Users/tobrien/gitw/grunnverk/kodrdriv`, it passes:
12
+ ```
13
+ --config-dir "/Users/tobrien/gitw/grunnverk/kodrdriv"
14
+ ```
15
+
16
+ This causes kodrdriv to look for a config directory named `kodrdriv` instead of `.kodrdriv`.
17
+
18
+ When `tree_publish` runs from `/Users/tobrien/gitw/grunnverk`, it passes:
19
+ ```
20
+ --config-dir "/Users/tobrien/gitw/grunnverk"
21
+ ```
22
+
23
+ This causes kodrdriv to look for a config directory named `grunnverk` instead of `.kodrdriv`.
24
+
25
+ ## Expected Behavior
26
+
27
+ The config file exists at: `/Users/tobrien/gitw/grunnverk/.kodrdriv/config.yaml`
28
+
29
+ `tree_publish` should either:
30
+ 1. Pass `--config-dir "/Users/tobrien/gitw/grunnverk/.kodrdriv"` (full path to config directory), or
31
+ 2. Not pass `--config-dir` at all and let hierarchical discovery find `.kodrdriv` automatically
32
+
33
+ ## Error Details
34
+
35
+ ```
36
+ Command failed: kodrdriv publish --config-dir "/Users/tobrien/gitw/grunnverk"
37
+ [winston] ... "Using hierarchical discovery: configDirName=grunnverk, startingDir=/Users/tobrien/gitw"
38
+ [winston] ... "Checking for config directory: /Users/tobrien/gitw/grunnverk"
39
+ [winston] ... "Found config directory at level 0: /Users/tobrien/gitw/grunnverk"
40
+ [winston] ... "Attempting to load config file: /Users/tobrien/gitw/grunnverk/config.yaml"
41
+ [winston] ... "Config file not found at /Users/tobrien/gitw/grunnverk/config.yaml"
42
+ ```
43
+
44
+ The system is looking for `/Users/tobrien/gitw/grunnverk/config.yaml` but the actual file is at `/Users/tobrien/gitw/grunnverk/.kodrdriv/config.yaml`.
45
+
46
+ ## Location of Issue
47
+
48
+ The issue is in `/Users/tobrien/gitw/grunnverk/commands-tree/src/commands/tree.ts` around line 2476:
49
+
50
+ ```typescript
51
+ if (runConfig.configDirectory) globalOptions.push(`--config-dir "${runConfig.configDirectory}"`);
52
+ ```
53
+
54
+ ## Investigation Needed
55
+
56
+ 1. Find where `runConfig.configDirectory` is set in the tree_publish flow
57
+ 2. Determine if it should:
58
+ - Be set to the full path of the `.kodrdriv` directory (e.g., `/Users/tobrien/gitw/grunnverk/.kodrdriv`)
59
+ - Not be set at all (let hierarchical discovery work)
60
+ - Be set differently based on how kodrdriv's config discovery works
61
+
62
+ ## Suggested Fix
63
+
64
+ Option 1: If `configDirectory` should point to the config directory itself:
65
+ - When setting `runConfig.configDirectory`, append `/.kodrdriv` to the directory path
66
+ - Or detect the config directory location and use that full path
67
+
68
+ Option 2: If hierarchical discovery should handle it:
69
+ - Don't set `runConfig.configDirectory` when it would point to a parent directory
70
+ - Only set it when explicitly provided by the user or when pointing to the actual `.kodrdriv` directory
71
+
72
+ ## Testing
73
+
74
+ After fixing, verify that:
75
+ 1. `tree_publish` can find the config at `/Users/tobrien/gitw/grunnverk/.kodrdriv/config.yaml`
76
+ 2. The publish workflow completes successfully
77
+ 3. Both scenarios work:
78
+ - Running from `/Users/tobrien/gitw/grunnverk/kodrdriv`
79
+ - Running from `/Users/tobrien/gitw/grunnverk`
package/README.md CHANGED
@@ -1,3 +1,12 @@
1
+ # KodrDriv - AI-Powered Git Workflow Automation
2
+
3
+ <!-- Build trigger: 2026-01-21 -->
4
+
5
+ [![MCP Integration](https://img.shields.io/badge/MCP-Enabled-blue)](https://modelcontextprotocol.io)
6
+ [![14 MCP Tools](https://img.shields.io/badge/MCP_Tools-14-brightgreen)]()
7
+ [![8 Resources](https://img.shields.io/badge/MCP_Resources-8-brightgreen)]()
8
+ [![6 Prompts](https://img.shields.io/badge/MCP_Prompts-6-brightgreen)]()
9
+
1
10
  # KodrDriv
2
11
 
3
12
  KodrDriv is an AI-powered Git workflow automation tool that generates intelligent commit messages and release notes from your code changes. It analyzes your repository to create meaningful documentation while automating the entire release process.
@@ -14,12 +23,55 @@ Writing good commit messages and release notes is time-consuming and often done
14
23
 
15
24
  KodrDriv reads your code changes and Git history to automatically generate contextual, meaningful documentation that reflects your actual work.
16
25
 
26
+ ## Requirements
27
+
28
+ - **Node.js 24.0.0 or higher** - KodrDriv uses Vite 7+ which requires Node.js 24+
29
+ - Git installed and configured
30
+ - OpenAI API key (for AI-powered content generation)
31
+
32
+ To check your Node.js version:
33
+ ```bash
34
+ node --version
35
+ ```
36
+
37
+ If you need to upgrade Node.js, visit [nodejs.org](https://nodejs.org/) or use a version manager like [nvm](https://github.com/nvm-sh/nvm).
38
+
17
39
  ## Installation
18
40
 
19
41
  ```bash
20
42
  npm install -g @eldrforge/kodrdriv
21
43
  ```
22
44
 
45
+ ## 🤖 MCP Integration
46
+
47
+ KodrDriv supports the **Model Context Protocol (MCP)**, enabling AI assistants like Cursor to directly invoke kodrdriv commands.
48
+
49
+ ### Features
50
+ - **14 Fully Implemented Tools**: All kodrdriv commands including automated publish→development workflow
51
+ - **8 Resources**: Access configs, status, workspace data via `kodrdriv://` URIs
52
+ - **6 Workflow Prompts**: Guided multi-step operations
53
+
54
+ ### Quick Setup for Cursor
55
+
56
+ Add to `.cursor/mcp.json`:
57
+ ```json
58
+ {
59
+ "mcpServers": {
60
+ "kodrdriv": {
61
+ "command": "kodrdriv-mcp"
62
+ }
63
+ }
64
+ }
65
+ ```
66
+
67
+ Then simply ask: *"Use kodrdriv to commit my changes"*
68
+
69
+ ### Documentation
70
+ - **[Integration Guide](MCP_INTEGRATION.md)** - Complete MCP documentation
71
+ - **[Tools Reference](docs/mcp-tools-reference.md)** - All 14 tools
72
+ - **[Resources Reference](docs/mcp-resources-reference.md)** - All 8 resources
73
+ - **[Prompts Reference](docs/mcp-prompts-reference.md)** - All 6 workflows
74
+
23
75
 
24
76
  ## Quick Start
25
77
 
@@ -48,6 +100,17 @@ kodrdriv release --context-files CHANGELOG.md --self-reflection
48
100
  kodrdriv publish
49
101
  ```
50
102
 
103
+ ### Smart Git Operations
104
+ ```bash
105
+ # Smart pull with auto-conflict resolution
106
+ kodrdriv pull
107
+ kodrdriv tree pull # Pull all packages in monorepo
108
+
109
+ # Update dependencies with AI analysis
110
+ kodrdriv tree updates --report # See dependency conflicts
111
+ kodrdriv updates --analyze # Get AI upgrade recommendations
112
+ ```
113
+
51
114
  ### Audio-Driven Development
52
115
  ```bash
53
116
  kodrdriv select-audio # Configure microphone (one-time setup)
@@ -62,7 +125,10 @@ kodrdriv audio-commit # Record audio to generate commit messages
62
125
  - 8 tools for commit message generation
63
126
  - Self-reflection reports with tool effectiveness metrics
64
127
  - Configurable iteration limits for complex releases
65
- - **Context Files (NEW)** - Pass documentation files as context for better AI understanding
128
+ - **Smart Git Operations** - Intelligent handling of common git pain points
129
+ - **Smart Pull** - Auto-resolves `package-lock.json`, version bumps, and build artifacts
130
+ - **Dependency Analysis** - AI-powered upgrade recommendations with version conflict detection
131
+ - **Context Files** - Pass documentation files as context for better AI understanding
66
132
  - **Human-Readable Output** - Professional tone without AI slop, emojis, or marketing speak
67
133
  - **GitHub Issues Integration** - Automatically analyzes recently closed issues to provide context for commit messages, prioritizing milestone-relevant issues
68
134
  - **Stop-Context Filtering** - Automatically filters sensitive information from AI-generated content to maintain privacy across projects
@@ -78,8 +144,13 @@ Set up your environment variables:
78
144
  ```bash
79
145
  export OPENAI_API_KEY="your-openai-api-key"
80
146
  export GITHUB_TOKEN="your-github-token" # Required for publish command
147
+
148
+ # If using a project-scoped API key (starts with sk-proj-):
149
+ export OPENAI_PROJECT_ID="proj-your-project-id"
81
150
  ```
82
151
 
152
+ **Note:** If your OpenAI API key starts with `sk-proj-`, you must also set `OPENAI_PROJECT_ID`. You can find your project ID in the [OpenAI dashboard](https://platform.openai.com/settings/organization/projects). Alternatively, create a legacy API key (starts with just `sk-`) to avoid needing the project ID.
153
+
83
154
  Initialize configuration files:
84
155
  ```bash
85
156
  kodrdriv --init-config
@@ -116,6 +187,8 @@ kodrdriv --check-config
116
187
  - **[audio-review](docs/public/commands/audio-review.md)** - Record audio for review analysis
117
188
  - **[release](docs/public/commands/release.md)** - Generate comprehensive release notes
118
189
  - **[publish](docs/public/commands/publish.md)** - Automate the entire release process
190
+ - **[pull](docs/public/commands/pull.md)** - Smart pull with auto-conflict resolution
191
+ - **[updates](docs/public/commands/updates.md)** - Dependency updates with AI analysis
119
192
  - **[link](docs/public/commands/link.md)** - Link local packages for development
120
193
  - **[unlink](docs/public/commands/unlink.md)** - Remove workspace links
121
194
  - **[clean](docs/public/commands/clean.md)** - Clean generated files
@@ -141,5 +214,5 @@ Apache-2.0 - see [LICENSE](LICENSE) file for details.
141
214
  ## About the Name
142
215
 
143
216
  Like Thor's hammer, this tool smashes through your repetitive coding tasks. But unlike Mjölnir, it won't make you worthy — it'll just make you faster. Strike through commits, forge releases, and channel the lightning of AI to automate your workflow. Because sometimes you need a hammer, and sometimes you need a tool that actually works. Pirate.
144
- TEST
145
- TEST
217
+
218
+ <!-- Build: 2026-01-15 15:59:12 UTC -->
@@ -1,5 +1,5 @@
1
+ import { config } from 'dotenv';
1
2
  import * as Cardigantime from '@theunwalked/cardigantime';
2
- import 'dotenv/config';
3
3
  import { setLogger } from '@eldrforge/git-tools';
4
4
  import { setLogger as setLogger$1, setPromptFunction } from '@eldrforge/github-tools';
5
5
  import { promptConfirmation, UserCancellationError } from '@eldrforge/shared';
@@ -9,10 +9,35 @@ import * as CommandsGit from '@eldrforge/commands-git';
9
9
  import * as CommandsTree from '@eldrforge/commands-tree';
10
10
  import * as CommandsPublish from '@eldrforge/commands-publish';
11
11
  import * as CommandsAudio from '@eldrforge/commands-audio';
12
- import { DEFAULT_CONFIG_DIR, VERSION, COMMAND_CHECK_CONFIG, COMMAND_INIT_CONFIG, COMMAND_COMMIT, COMMAND_PRECOMMIT, COMMAND_CLEAN, COMMAND_REVIEW, COMMAND_TREE, COMMAND_LINK, COMMAND_UNLINK, COMMAND_UPDATES, COMMAND_VERSIONS, COMMAND_RELEASE, COMMAND_PUBLISH, COMMAND_DEVELOPMENT, COMMAND_AUDIO_COMMIT, COMMAND_AUDIO_REVIEW, COMMAND_SELECT_AUDIO } from './constants.js';
12
+ import { DEFAULT_CONFIG_DIR, VERSION, BUILD_HOSTNAME, BUILD_TIMESTAMP, COMMAND_CHECK_CONFIG, COMMAND_INIT_CONFIG, COMMAND_COMMIT, COMMAND_PRECOMMIT, COMMAND_CLEAN, COMMAND_PULL, COMMAND_REVIEW, COMMAND_TREE, COMMAND_LINK, COMMAND_UNLINK, COMMAND_UPDATES, COMMAND_VERSIONS, COMMAND_RELEASE, COMMAND_PUBLISH, COMMAND_DEVELOPMENT, COMMAND_AUDIO_COMMIT, COMMAND_AUDIO_REVIEW, COMMAND_SELECT_AUDIO } from './constants.js';
13
13
  import { getLogger, setLogLevel } from './logging.js';
14
14
  import { ConfigSchema } from './types.js';
15
15
 
16
+ // Load .env file if it exists, but NEVER override existing environment variables
17
+ // This MUST be the first thing we do, before any other imports that might load dotenv
18
+ // This ensures that shell-exported variables like OPENAI_API_KEY take precedence
19
+ config({
20
+ override: false,
21
+ debug: false
22
+ });
23
+ /**
24
+ * Check Node.js version and exit with clear error message if version is too old.
25
+ */ function checkNodeVersion() {
26
+ const requiredMajorVersion = 24;
27
+ const currentVersion = process.version;
28
+ const majorVersion = parseInt(currentVersion.slice(1).split('.')[0], 10);
29
+ if (majorVersion < requiredMajorVersion) {
30
+ // eslint-disable-next-line no-console
31
+ console.error(`\n❌ ERROR: Node.js version ${requiredMajorVersion}.0.0 or higher is required.`);
32
+ // eslint-disable-next-line no-console
33
+ console.error(` Current version: ${currentVersion}`);
34
+ // eslint-disable-next-line no-console
35
+ console.error(` Please upgrade your Node.js version to continue.\n`);
36
+ // eslint-disable-next-line no-console
37
+ console.error(` This project uses Vite 7+ which requires Node.js ${requiredMajorVersion}+.\n`);
38
+ process.exit(1);
39
+ }
40
+ }
16
41
  /**
17
42
  * Print debug information about the command being executed when debug flag is enabled.
18
43
  */ function printDebugCommandInfo(commandName, runConfig) {
@@ -21,6 +46,21 @@ import { ConfigSchema } from './types.js';
21
46
  logger.info('DEBUG_INFO_HEADER: KodrDriv debug information');
22
47
  logger.info('DEBUG_INFO_COMMAND: Command being executed | Command: %s', commandName);
23
48
  logger.info('DEBUG_INFO_VERSION: KodrDriv version | Version: %s', VERSION);
49
+ // Log last 4 characters of tokens for debugging permissions issues
50
+ const openaiToken = process.env.OPENAI_API_KEY;
51
+ const githubToken = process.env.GITHUB_TOKEN;
52
+ if (openaiToken) {
53
+ const tokenSuffix = openaiToken.slice(-4);
54
+ logger.info('DEBUG_INFO_TOKEN: OpenAI API Key | Suffix: ...%s', tokenSuffix);
55
+ } else {
56
+ logger.info('DEBUG_INFO_TOKEN: OpenAI API Key | Status: not set');
57
+ }
58
+ if (githubToken) {
59
+ const tokenSuffix = githubToken.slice(-4);
60
+ logger.info('DEBUG_INFO_TOKEN: GitHub Token | Suffix: ...%s', tokenSuffix);
61
+ } else {
62
+ logger.info('DEBUG_INFO_TOKEN: GitHub Token | Status: not set');
63
+ }
24
64
  logger.info('DEBUG_INFO_FOOTER: End of debug information');
25
65
  }
26
66
  }
@@ -42,6 +82,8 @@ import { ConfigSchema } from './types.js';
42
82
  }
43
83
  }
44
84
  async function runApplication() {
85
+ // Check Node.js version first, before doing anything else
86
+ checkNodeVersion();
45
87
  // Configure logging early, before CardiganTime initialization
46
88
  configureEarlyLogging();
47
89
  // Initialize RiotPrompt templates for ai-service
@@ -74,8 +116,8 @@ async function runApplication() {
74
116
  setLogger(logger);
75
117
  setLogger$1(logger);
76
118
  setPromptFunction(promptConfirmation);
77
- // Display version information
78
- logger.info('APPLICATION_STARTING: KodrDriv application initializing | Version: %s | Status: starting', VERSION);
119
+ // Display version information including build metadata
120
+ logger.info('APPLICATION_STARTING: KodrDriv application initializing | Version: %s | BuildHost: %s | BuildTime: %s | Status: starting', VERSION, BUILD_HOSTNAME, BUILD_TIMESTAMP);
79
121
  // Handle check-config command first
80
122
  if (commandConfig.commandName === COMMAND_CHECK_CONFIG) {
81
123
  // CardiganTime's checkConfig has already been called in Arguments.configure()
@@ -100,7 +142,8 @@ async function runApplication() {
100
142
  'link',
101
143
  'unlink',
102
144
  'development',
103
- 'updates'
145
+ 'updates',
146
+ 'pull'
104
147
  ];
105
148
  if (supportedBuiltInCommands.includes(treeBuiltInCommand)) {
106
149
  // This is a tree command with built-in command, keep commandName as 'tree'
@@ -109,7 +152,7 @@ async function runApplication() {
109
152
  // Unknown tree argument, let it fail naturally in tree.ts
110
153
  commandName = 'tree';
111
154
  }
112
- } else if (command === 'commit' || command === 'audio-commit' || command === 'release' || command === 'publish' || command === 'tree' || command === 'link' || command === 'unlink' || command === 'audio-review' || command === 'clean' || command === 'precommit' || command === 'review' || command === 'select-audio' || command === 'development' || command === 'versions' || command === 'updates') {
155
+ } else if (command === 'commit' || command === 'audio-commit' || command === 'release' || command === 'publish' || command === 'tree' || command === 'link' || command === 'unlink' || command === 'audio-review' || command === 'clean' || command === 'pull' || command === 'precommit' || command === 'review' || command === 'select-audio' || command === 'development' || command === 'versions' || command === 'updates') {
113
156
  commandName = command;
114
157
  }
115
158
  let summary = '';
@@ -126,6 +169,8 @@ async function runApplication() {
126
169
  } else if (commandName === COMMAND_CLEAN) {
127
170
  await CommandsGit.clean(runConfig);
128
171
  summary = 'Output directory cleaned successfully.';
172
+ } else if (commandName === COMMAND_PULL) {
173
+ summary = await CommandsGit.pull(runConfig);
129
174
  } else if (commandName === COMMAND_REVIEW) {
130
175
  summary = await CommandsGit.review(runConfig);
131
176
  } else if (commandName === COMMAND_TREE) {
@@ -1 +1 @@
1
- {"version":3,"file":"application.js","sources":["../src/application.ts"],"sourcesContent":["import * as Cardigantime from '@theunwalked/cardigantime';\nimport 'dotenv/config';\nimport { setLogger as setGitLogger } from '@eldrforge/git-tools';\nimport { setLogger as setGitHubLogger, setPromptFunction } from '@eldrforge/github-tools';\nimport { promptConfirmation } from '@eldrforge/shared';\nimport { initializeTemplates } from '@eldrforge/ai-service';\nimport { CommandConfig } from 'types';\nimport * as Arguments from './arguments';\n\n// Import commands from extracted packages\nimport * as CommandsGit from '@eldrforge/commands-git';\nimport * as CommandsTree from '@eldrforge/commands-tree';\nimport * as CommandsPublish from '@eldrforge/commands-publish';\nimport * as CommandsAudio from '@eldrforge/commands-audio';\nimport { 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, DEFAULT_CONFIG_DIR, VERSION } from './constants';\nimport { UserCancellationError } from '@eldrforge/shared';\nimport { getLogger, setLogLevel } from './logging';\nimport { Config, SecureConfig, ConfigSchema } from './types';\n\n/**\n * Print debug information about the command being executed when debug flag is enabled.\n */\nfunction printDebugCommandInfo(commandName: string, runConfig: Config): void {\n if (runConfig.debug) {\n const logger = getLogger();\n logger.info('DEBUG_INFO_HEADER: KodrDriv debug information');\n logger.info('DEBUG_INFO_COMMAND: Command being executed | Command: %s', commandName);\n logger.info('DEBUG_INFO_VERSION: KodrDriv version | Version: %s', VERSION);\n logger.info('DEBUG_INFO_FOOTER: End of debug information');\n }\n}\n\n/**\n * Configure early logging based on command line flags.\n *\n * Hey we need this because we need to be able to debug CardiganTime.\n * This method checks for --verbose and --debug flags early in the process\n * before CardiganTime is configured, allowing us to capture debug output\n * from the CardiganTime initialization itself.\n */\nexport function configureEarlyLogging(): void {\n const hasVerbose = process.argv.includes('--verbose');\n const hasDebug = process.argv.includes('--debug');\n\n // Set log level based on early flag detection\n if (hasDebug) {\n setLogLevel('debug');\n } else if (hasVerbose) {\n setLogLevel('verbose');\n }\n}\n\nexport async function runApplication(): Promise<void> {\n // Configure logging early, before CardiganTime initialization\n configureEarlyLogging();\n\n // Initialize RiotPrompt templates for ai-service\n initializeTemplates();\n\n // Use proper typing for CardiganTime create function\n interface CardigantimeCreateParams {\n defaults?: any;\n features?: string[];\n configShape?: any;\n logger?: any;\n }\n\n interface CardigantimeInstance {\n read: (args: any) => Promise<any>;\n checkConfig: () => Promise<void>;\n generateConfig: (dir: string) => Promise<void>;\n setLogger: (logger: any) => void;\n }\n\n const cardigantimeModule = Cardigantime as any;\n const createCardigantime = cardigantimeModule.create as (params: CardigantimeCreateParams) => CardigantimeInstance;\n\n const cardigantime = createCardigantime({\n defaults: {\n configDirectory: DEFAULT_CONFIG_DIR,\n },\n configShape: ConfigSchema.shape,\n features: ['config', 'hierarchical'],\n logger: getLogger(),\n });\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [runConfig, secureConfig, commandConfig]: [Config, SecureConfig, CommandConfig] = await Arguments.configure(cardigantime); // Pass cardigantime instance\n\n // Set log level based on verbose flag\n if (runConfig.verbose) {\n setLogLevel('verbose');\n }\n if (runConfig.debug) {\n setLogLevel('debug');\n }\n\n const logger = getLogger();\n cardigantime.setLogger(logger);\n\n // Configure external packages to use our logger and prompt\n setGitLogger(logger);\n setGitHubLogger(logger);\n setPromptFunction(promptConfirmation);\n\n // Display version information\n logger.info('APPLICATION_STARTING: KodrDriv application initializing | Version: %s | Status: starting', VERSION);\n\n // Handle check-config command first\n if (commandConfig.commandName === COMMAND_CHECK_CONFIG) {\n // CardiganTime's checkConfig has already been called in Arguments.configure()\n // No additional processing needed here\n return;\n }\n\n // Handle init-config command\n if (commandConfig.commandName === COMMAND_INIT_CONFIG) {\n // CardiganTime's initConfig has already been called in Arguments.configure()\n // No additional processing needed here\n return;\n }\n\n // Get the command from Commander\n const command = process.argv[2];\n let commandName = commandConfig.commandName;\n\n // Handle special case for tree command with built-in command argument\n if (command === 'tree' && process.argv[3]) {\n const treeBuiltInCommand = process.argv[3];\n const supportedBuiltInCommands = ['commit', 'publish', 'link', 'unlink', 'development', 'updates'];\n if (supportedBuiltInCommands.includes(treeBuiltInCommand)) {\n // This is a tree command with built-in command, keep commandName as 'tree'\n commandName = 'tree';\n } else {\n // Unknown tree argument, let it fail naturally in tree.ts\n commandName = 'tree';\n }\n }\n // If we have a specific command argument, use that\n else if (command === 'commit' || command === 'audio-commit' || command === 'release' || command === 'publish' || command === 'tree' || command === 'link' || command === 'unlink' || command === 'audio-review' || command === 'clean' || command === 'precommit' || command === 'review' || command === 'select-audio' || command === 'development' || command === 'versions' || command === 'updates') {\n commandName = command;\n }\n\n let summary: string = '';\n\n try {\n // Print debug info at the start of command execution\n if (commandName) {\n printDebugCommandInfo(commandName, runConfig);\n }\n\n // Git commands (from @eldrforge/commands-git)\n if (commandName === COMMAND_COMMIT) {\n summary = await CommandsGit.commit(runConfig);\n } else if (commandName === COMMAND_PRECOMMIT) {\n summary = await CommandsGit.precommit(runConfig);\n } else if (commandName === COMMAND_CLEAN) {\n await CommandsGit.clean(runConfig);\n summary = 'Output directory cleaned successfully.';\n } else if (commandName === COMMAND_REVIEW) {\n summary = await CommandsGit.review(runConfig);\n }\n // Tree commands (from @eldrforge/commands-tree)\n else if (commandName === COMMAND_TREE) {\n // Handle tree directories mapping from command-specific arguments\n if (runConfig.audioReview?.directory && !runConfig.tree?.directories) {\n runConfig.tree = runConfig.tree || {};\n runConfig.tree.directories = [runConfig.audioReview.directory];\n }\n // Handle tree exclusion patterns - use global excludedPatterns for tree\n if (runConfig.excludedPatterns && !runConfig.tree?.exclude) {\n runConfig.tree = runConfig.tree || {};\n runConfig.tree.exclude = runConfig.excludedPatterns;\n }\n summary = await CommandsTree.tree(runConfig);\n } else if (commandName === COMMAND_LINK) {\n summary = await CommandsTree.link(runConfig);\n } else if (commandName === COMMAND_UNLINK) {\n summary = await CommandsTree.unlink(runConfig);\n } else if (commandName === COMMAND_UPDATES) {\n summary = await CommandsTree.updates(runConfig);\n } else if (commandName === COMMAND_VERSIONS) {\n summary = await CommandsTree.versions(runConfig);\n }\n // Publish commands (from @eldrforge/commands-publish)\n else if (commandName === COMMAND_RELEASE) {\n const releaseSummary = await CommandsPublish.release(runConfig);\n summary = `${releaseSummary.title}\\n\\n${releaseSummary.body}`;\n } else if (commandName === COMMAND_PUBLISH) {\n await CommandsPublish.publish(runConfig);\n } else if (commandName === COMMAND_DEVELOPMENT) {\n summary = await CommandsPublish.development(runConfig);\n }\n // Audio commands (from @eldrforge/commands-audio)\n else if (commandName === COMMAND_AUDIO_COMMIT) {\n summary = await CommandsAudio.audioCommit(runConfig);\n } else if (commandName === COMMAND_AUDIO_REVIEW) {\n summary = await CommandsAudio.audioReview(runConfig);\n } else if (commandName === COMMAND_SELECT_AUDIO) {\n await CommandsAudio.selectAudio(runConfig);\n summary = 'Audio selection completed successfully.';\n }\n\n // eslint-disable-next-line no-console\n console.log(`\\n\\n${summary}\\n\\n`);\n } catch (error: any) {\n // Handle user cancellation gracefully\n if (error instanceof UserCancellationError) {\n logger.info('APPLICATION_ERROR: Application error occurred | Error: ' + error.message);\n process.exit(0);\n }\n\n // Re-throw other errors to be handled by main.ts\n throw error;\n }\n}\n"],"names":["printDebugCommandInfo","commandName","runConfig","debug","logger","getLogger","info","VERSION","configureEarlyLogging","hasVerbose","process","argv","includes","hasDebug","setLogLevel","runApplication","initializeTemplates","cardigantimeModule","Cardigantime","createCardigantime","create","cardigantime","defaults","configDirectory","DEFAULT_CONFIG_DIR","configShape","ConfigSchema","shape","features","secureConfig","commandConfig","Arguments","verbose","setLogger","setGitLogger","setGitHubLogger","setPromptFunction","promptConfirmation","COMMAND_CHECK_CONFIG","COMMAND_INIT_CONFIG","command","treeBuiltInCommand","supportedBuiltInCommands","summary","COMMAND_COMMIT","CommandsGit","commit","COMMAND_PRECOMMIT","precommit","COMMAND_CLEAN","clean","COMMAND_REVIEW","review","COMMAND_TREE","audioReview","directory","tree","directories","excludedPatterns","exclude","CommandsTree","COMMAND_LINK","link","COMMAND_UNLINK","unlink","COMMAND_UPDATES","updates","COMMAND_VERSIONS","versions","COMMAND_RELEASE","releaseSummary","CommandsPublish","release","title","body","COMMAND_PUBLISH","publish","COMMAND_DEVELOPMENT","development","COMMAND_AUDIO_COMMIT","CommandsAudio","audioCommit","COMMAND_AUDIO_REVIEW","COMMAND_SELECT_AUDIO","selectAudio","console","log","error","UserCancellationError","message","exit"],"mappings":"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"}
1
+ {"version":3,"file":"application.js","sources":["../src/application.ts"],"sourcesContent":["// Load .env file if it exists, but NEVER override existing environment variables\n// This MUST be the first thing we do, before any other imports that might load dotenv\n// This ensures that shell-exported variables like OPENAI_API_KEY take precedence\nimport { config as dotenvConfig } from 'dotenv';\ndotenvConfig({ override: false, debug: false });\n\nimport * as Cardigantime from '@theunwalked/cardigantime';\nimport { setLogger as setGitLogger } from '@eldrforge/git-tools';\nimport { setLogger as setGitHubLogger, setPromptFunction } from '@eldrforge/github-tools';\nimport { promptConfirmation } from '@eldrforge/shared';\nimport { initializeTemplates } from '@eldrforge/ai-service';\nimport { CommandConfig } from 'types';\nimport * as Arguments from './arguments';\n\n// Import commands from extracted packages\nimport * as CommandsGit from '@eldrforge/commands-git';\nimport * as CommandsTree from '@eldrforge/commands-tree';\nimport * as CommandsPublish from '@eldrforge/commands-publish';\nimport * as CommandsAudio from '@eldrforge/commands-audio';\nimport { 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_PULL, COMMAND_RELEASE, COMMAND_REVIEW, COMMAND_SELECT_AUDIO, COMMAND_TREE, COMMAND_UNLINK, COMMAND_UPDATES, COMMAND_VERSIONS, DEFAULT_CONFIG_DIR, VERSION, BUILD_HOSTNAME, BUILD_TIMESTAMP } from './constants';\nimport { UserCancellationError } from '@eldrforge/shared';\nimport { getLogger, setLogLevel } from './logging';\nimport { Config, SecureConfig, ConfigSchema } from './types';\n\n/**\n * Check Node.js version and exit with clear error message if version is too old.\n */\nfunction checkNodeVersion(): void {\n const requiredMajorVersion = 24;\n const currentVersion = process.version;\n const majorVersion = parseInt(currentVersion.slice(1).split('.')[0], 10);\n\n if (majorVersion < requiredMajorVersion) {\n // eslint-disable-next-line no-console\n console.error(`\\n❌ ERROR: Node.js version ${requiredMajorVersion}.0.0 or higher is required.`);\n // eslint-disable-next-line no-console\n console.error(` Current version: ${currentVersion}`);\n // eslint-disable-next-line no-console\n console.error(` Please upgrade your Node.js version to continue.\\n`);\n // eslint-disable-next-line no-console\n console.error(` This project uses Vite 7+ which requires Node.js ${requiredMajorVersion}+.\\n`);\n process.exit(1);\n }\n}\n\n/**\n * Get formatted version information including build metadata.\n */\nexport function getVersionInfo(): { version: string; buildHostname: string; buildTimestamp: string; formatted: string } {\n return {\n version: VERSION,\n buildHostname: BUILD_HOSTNAME,\n buildTimestamp: BUILD_TIMESTAMP,\n formatted: `${VERSION}\\nBuilt on: ${BUILD_HOSTNAME}\\nBuild time: ${BUILD_TIMESTAMP}`\n };\n}\n\n/**\n * Print debug information about the command being executed when debug flag is enabled.\n */\nfunction printDebugCommandInfo(commandName: string, runConfig: Config): void {\n if (runConfig.debug) {\n const logger = getLogger();\n logger.info('DEBUG_INFO_HEADER: KodrDriv debug information');\n logger.info('DEBUG_INFO_COMMAND: Command being executed | Command: %s', commandName);\n logger.info('DEBUG_INFO_VERSION: KodrDriv version | Version: %s', VERSION);\n\n // Log last 4 characters of tokens for debugging permissions issues\n const openaiToken = process.env.OPENAI_API_KEY;\n const githubToken = process.env.GITHUB_TOKEN;\n\n if (openaiToken) {\n const tokenSuffix = openaiToken.slice(-4);\n logger.info('DEBUG_INFO_TOKEN: OpenAI API Key | Suffix: ...%s', tokenSuffix);\n } else {\n logger.info('DEBUG_INFO_TOKEN: OpenAI API Key | Status: not set');\n }\n\n if (githubToken) {\n const tokenSuffix = githubToken.slice(-4);\n logger.info('DEBUG_INFO_TOKEN: GitHub Token | Suffix: ...%s', tokenSuffix);\n } else {\n logger.info('DEBUG_INFO_TOKEN: GitHub Token | Status: not set');\n }\n\n logger.info('DEBUG_INFO_FOOTER: End of debug information');\n }\n}\n\n/**\n * Configure early logging based on command line flags.\n *\n * Hey we need this because we need to be able to debug CardiganTime.\n * This method checks for --verbose and --debug flags early in the process\n * before CardiganTime is configured, allowing us to capture debug output\n * from the CardiganTime initialization itself.\n */\nexport function configureEarlyLogging(): void {\n const hasVerbose = process.argv.includes('--verbose');\n const hasDebug = process.argv.includes('--debug');\n\n // Set log level based on early flag detection\n if (hasDebug) {\n setLogLevel('debug');\n } else if (hasVerbose) {\n setLogLevel('verbose');\n }\n}\n\nexport async function runApplication(): Promise<void> {\n // Check Node.js version first, before doing anything else\n checkNodeVersion();\n\n // Configure logging early, before CardiganTime initialization\n configureEarlyLogging();\n\n // Initialize RiotPrompt templates for ai-service\n initializeTemplates();\n\n // Use proper typing for CardiganTime create function\n interface CardigantimeCreateParams {\n defaults?: any;\n features?: string[];\n configShape?: any;\n logger?: any;\n }\n\n interface CardigantimeInstance {\n read: (args: any) => Promise<any>;\n checkConfig: () => Promise<void>;\n generateConfig: (dir: string) => Promise<void>;\n setLogger: (logger: any) => void;\n }\n\n const cardigantimeModule = Cardigantime as any;\n const createCardigantime = cardigantimeModule.create as (params: CardigantimeCreateParams) => CardigantimeInstance;\n\n const cardigantime = createCardigantime({\n defaults: {\n configDirectory: DEFAULT_CONFIG_DIR,\n },\n configShape: ConfigSchema.shape,\n features: ['config', 'hierarchical'],\n logger: getLogger(),\n });\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [runConfig, secureConfig, commandConfig]: [Config, SecureConfig, CommandConfig] = await Arguments.configure(cardigantime); // Pass cardigantime instance\n\n // Set log level based on verbose flag\n if (runConfig.verbose) {\n setLogLevel('verbose');\n }\n if (runConfig.debug) {\n setLogLevel('debug');\n }\n\n const logger = getLogger();\n cardigantime.setLogger(logger);\n\n // Configure external packages to use our logger and prompt\n setGitLogger(logger);\n setGitHubLogger(logger);\n setPromptFunction(promptConfirmation);\n\n // Display version information including build metadata\n logger.info('APPLICATION_STARTING: KodrDriv application initializing | Version: %s | BuildHost: %s | BuildTime: %s | Status: starting',\n VERSION, BUILD_HOSTNAME, BUILD_TIMESTAMP);\n\n // Handle check-config command first\n if (commandConfig.commandName === COMMAND_CHECK_CONFIG) {\n // CardiganTime's checkConfig has already been called in Arguments.configure()\n // No additional processing needed here\n return;\n }\n\n // Handle init-config command\n if (commandConfig.commandName === COMMAND_INIT_CONFIG) {\n // CardiganTime's initConfig has already been called in Arguments.configure()\n // No additional processing needed here\n return;\n }\n\n // Get the command from Commander\n const command = process.argv[2];\n let commandName = commandConfig.commandName;\n\n // Handle special case for tree command with built-in command argument\n if (command === 'tree' && process.argv[3]) {\n const treeBuiltInCommand = process.argv[3];\n const supportedBuiltInCommands = ['commit', 'publish', 'link', 'unlink', 'development', 'updates', 'pull'];\n if (supportedBuiltInCommands.includes(treeBuiltInCommand)) {\n // This is a tree command with built-in command, keep commandName as 'tree'\n commandName = 'tree';\n } else {\n // Unknown tree argument, let it fail naturally in tree.ts\n commandName = 'tree';\n }\n }\n // If we have a specific command argument, use that\n else if (command === 'commit' || command === 'audio-commit' || command === 'release' || command === 'publish' || command === 'tree' || command === 'link' || command === 'unlink' || command === 'audio-review' || command === 'clean' || command === 'pull' || command === 'precommit' || command === 'review' || command === 'select-audio' || command === 'development' || command === 'versions' || command === 'updates') {\n commandName = command;\n }\n\n let summary: string = '';\n\n try {\n // Print debug info at the start of command execution\n if (commandName) {\n printDebugCommandInfo(commandName, runConfig);\n }\n\n // Git commands (from @eldrforge/commands-git)\n if (commandName === COMMAND_COMMIT) {\n summary = await CommandsGit.commit(runConfig);\n } else if (commandName === COMMAND_PRECOMMIT) {\n summary = await CommandsGit.precommit(runConfig);\n } else if (commandName === COMMAND_CLEAN) {\n await CommandsGit.clean(runConfig);\n summary = 'Output directory cleaned successfully.';\n } else if (commandName === COMMAND_PULL) {\n summary = await CommandsGit.pull(runConfig);\n } else if (commandName === COMMAND_REVIEW) {\n summary = await CommandsGit.review(runConfig);\n }\n // Tree commands (from @eldrforge/commands-tree)\n else if (commandName === COMMAND_TREE) {\n // Handle tree directories mapping from command-specific arguments\n if (runConfig.audioReview?.directory && !runConfig.tree?.directories) {\n runConfig.tree = runConfig.tree || {};\n runConfig.tree.directories = [runConfig.audioReview.directory];\n }\n // Handle tree exclusion patterns - use global excludedPatterns for tree\n if (runConfig.excludedPatterns && !runConfig.tree?.exclude) {\n runConfig.tree = runConfig.tree || {};\n runConfig.tree.exclude = runConfig.excludedPatterns;\n }\n summary = await CommandsTree.tree(runConfig);\n } else if (commandName === COMMAND_LINK) {\n summary = await CommandsTree.link(runConfig);\n } else if (commandName === COMMAND_UNLINK) {\n summary = await CommandsTree.unlink(runConfig);\n } else if (commandName === COMMAND_UPDATES) {\n summary = await CommandsTree.updates(runConfig);\n } else if (commandName === COMMAND_VERSIONS) {\n summary = await CommandsTree.versions(runConfig);\n }\n // Publish commands (from @eldrforge/commands-publish)\n else if (commandName === COMMAND_RELEASE) {\n const releaseSummary = await CommandsPublish.release(runConfig);\n summary = `${releaseSummary.title}\\n\\n${releaseSummary.body}`;\n } else if (commandName === COMMAND_PUBLISH) {\n await CommandsPublish.publish(runConfig);\n } else if (commandName === COMMAND_DEVELOPMENT) {\n summary = await CommandsPublish.development(runConfig);\n }\n // Audio commands (from @eldrforge/commands-audio)\n else if (commandName === COMMAND_AUDIO_COMMIT) {\n summary = await CommandsAudio.audioCommit(runConfig);\n } else if (commandName === COMMAND_AUDIO_REVIEW) {\n summary = await CommandsAudio.audioReview(runConfig);\n } else if (commandName === COMMAND_SELECT_AUDIO) {\n await CommandsAudio.selectAudio(runConfig);\n summary = 'Audio selection completed successfully.';\n }\n\n // eslint-disable-next-line no-console\n console.log(`\\n\\n${summary}\\n\\n`);\n } catch (error: any) {\n // Handle user cancellation gracefully\n if (error instanceof UserCancellationError) {\n logger.info('APPLICATION_ERROR: Application error occurred | Error: ' + error.message);\n process.exit(0);\n }\n\n // Re-throw other errors to be handled by main.ts\n throw error;\n }\n}\n"],"names":["dotenvConfig","override","debug","checkNodeVersion","requiredMajorVersion","currentVersion","process","version","majorVersion","parseInt","slice","split","console","error","exit","printDebugCommandInfo","commandName","runConfig","logger","getLogger","info","VERSION","openaiToken","env","OPENAI_API_KEY","githubToken","GITHUB_TOKEN","tokenSuffix","configureEarlyLogging","hasVerbose","argv","includes","hasDebug","setLogLevel","runApplication","initializeTemplates","cardigantimeModule","Cardigantime","createCardigantime","create","cardigantime","defaults","configDirectory","DEFAULT_CONFIG_DIR","configShape","ConfigSchema","shape","features","secureConfig","commandConfig","Arguments","verbose","setLogger","setGitLogger","setGitHubLogger","setPromptFunction","promptConfirmation","BUILD_HOSTNAME","BUILD_TIMESTAMP","COMMAND_CHECK_CONFIG","COMMAND_INIT_CONFIG","command","treeBuiltInCommand","supportedBuiltInCommands","summary","COMMAND_COMMIT","CommandsGit","commit","COMMAND_PRECOMMIT","precommit","COMMAND_CLEAN","clean","COMMAND_PULL","pull","COMMAND_REVIEW","review","COMMAND_TREE","audioReview","directory","tree","directories","excludedPatterns","exclude","CommandsTree","COMMAND_LINK","link","COMMAND_UNLINK","unlink","COMMAND_UPDATES","updates","COMMAND_VERSIONS","versions","COMMAND_RELEASE","releaseSummary","CommandsPublish","release","title","body","COMMAND_PUBLISH","publish","COMMAND_DEVELOPMENT","development","COMMAND_AUDIO_COMMIT","CommandsAudio","audioCommit","COMMAND_AUDIO_REVIEW","COMMAND_SELECT_AUDIO","selectAudio","log","UserCancellationError","message"],"mappings":"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"}
package/dist/arguments.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Command } from 'commander';
2
2
  import path from 'path';
3
3
  import { z } from 'zod';
4
- import { PROGRAM_NAME, VERSION, KODRDRIV_DEFAULTS, ALLOWED_COMMANDS, DEFAULT_COMMAND } from './constants.js';
4
+ import { PROGRAM_NAME, VERSION, BUILD_HOSTNAME, BUILD_TIMESTAMP, KODRDRIV_DEFAULTS, ALLOWED_COMMANDS, DEFAULT_COMMAND } from './constants.js';
5
5
  import { getLogger } from './logging.js';
6
6
  import { readStdin, createStorage } from '@eldrforge/shared';
7
7
  import { safeJsonParse } from '@eldrforge/git-tools';
@@ -34,6 +34,7 @@ z.object({
34
34
  targetVersion: z.string().optional(),
35
35
  skipAlreadyPublished: z.boolean().optional(),
36
36
  forceRepublish: z.boolean().optional(),
37
+ skipLinkCleanup: z.boolean().optional(),
37
38
  excludedPatterns: z.array(z.string()).optional(),
38
39
  excludedPaths: z.array(z.string()).optional(),
39
40
  exclude: z.array(z.string()).optional(),
@@ -83,8 +84,22 @@ z.object({
83
84
  workingTagPrefix: z.string().optional(),
84
85
  updateDeps: z.string().optional(),
85
86
  interProject: z.boolean().optional(),
87
+ report: z.boolean().optional(),
88
+ analyze: z.boolean().optional(),
89
+ strategy: z.enum([
90
+ 'latest',
91
+ 'conservative',
92
+ 'compatible'
93
+ ]).optional(),
86
94
  selfReflection: z.boolean().optional(),
87
- maxAgenticIterations: z.number().optional()
95
+ maxAgenticIterations: z.number().optional(),
96
+ // Pull command options
97
+ remote: z.string().optional(),
98
+ branch: z.string().optional(),
99
+ autoStash: z.boolean().optional(),
100
+ autoResolve: z.boolean().optional(),
101
+ // Precommit command options
102
+ fix: z.boolean().optional()
88
103
  });
89
104
  // Function to transform flat CLI args into nested Config structure
90
105
  const transformCliArgs = (finalCliArgs, commandName)=>{
@@ -153,6 +168,7 @@ const transformCliArgs = (finalCliArgs, commandName)=>{
153
168
  if (finalCliArgs.syncTarget !== undefined) transformedCliArgs.publish.syncTarget = finalCliArgs.syncTarget;
154
169
  if (finalCliArgs.skipAlreadyPublished !== undefined) transformedCliArgs.publish.skipAlreadyPublished = finalCliArgs.skipAlreadyPublished;
155
170
  if (finalCliArgs.forceRepublish !== undefined) transformedCliArgs.publish.forceRepublish = finalCliArgs.forceRepublish;
171
+ if (finalCliArgs.skipLinkCleanup !== undefined) transformedCliArgs.publish.skipLinkCleanup = finalCliArgs.skipLinkCleanup;
156
172
  if ((commandName === 'publish' || finalCliArgs.mergeMethod !== undefined || finalCliArgs.targetVersion !== undefined || finalCliArgs.syncTarget !== undefined || finalCliArgs.interactive !== undefined || finalCliArgs.skipAlreadyPublished !== undefined || finalCliArgs.forceRepublish !== undefined) && finalCliArgs.noMilestones !== undefined) transformedCliArgs.publish.noMilestones = finalCliArgs.noMilestones;
157
173
  if (finalCliArgs.updateDeps !== undefined) transformedCliArgs.publish.updateDeps = finalCliArgs.updateDeps;
158
174
  // Map release-related flags from publish command into release config (only if any are set)
@@ -244,6 +260,11 @@ const transformCliArgs = (finalCliArgs, commandName)=>{
244
260
  if (finalCliArgs.openaiReasoning !== undefined) transformedCliArgs.audioReview.openaiReasoning = finalCliArgs.openaiReasoning;
245
261
  if (finalCliArgs.openaiMaxOutputTokens !== undefined) transformedCliArgs.audioReview.openaiMaxOutputTokens = finalCliArgs.openaiMaxOutputTokens;
246
262
  }
263
+ // Nested mappings for 'precommit' options
264
+ if (finalCliArgs.fix !== undefined) {
265
+ transformedCliArgs.precommit = {};
266
+ transformedCliArgs.precommit.fix = finalCliArgs.fix;
267
+ }
247
268
  // Nested mappings for 'review' options
248
269
  if (finalCliArgs.includeCommitHistory !== undefined || finalCliArgs.includeRecentDiffs !== undefined || finalCliArgs.includeReleaseNotes !== undefined || finalCliArgs.includeGithubIssues !== undefined || finalCliArgs.commitHistoryLimit !== undefined || finalCliArgs.diffHistoryLimit !== undefined || finalCliArgs.releaseNotesLimit !== undefined || finalCliArgs.githubIssuesLimit !== undefined || finalCliArgs.context !== undefined || finalCliArgs.sendit !== undefined || finalCliArgs.note !== undefined || finalCliArgs.openaiReasoning !== undefined || finalCliArgs.openaiMaxOutputTokens !== undefined || commandName === 'review' && (finalCliArgs.file !== undefined || finalCliArgs.directory !== undefined)) {
249
270
  transformedCliArgs.review = {};
@@ -297,7 +318,7 @@ const transformCliArgs = (finalCliArgs, commandName)=>{
297
318
  }
298
319
  // Only create tree object if there are actual tree-specific options
299
320
  const cliArgs = finalCliArgs;
300
- if (finalCliArgs.directories !== undefined || finalCliArgs.directory !== undefined || finalCliArgs.startFrom !== undefined || finalCliArgs.stopAt !== undefined || finalCliArgs.cmd !== undefined || builtInCommand !== undefined || finalCliArgs.continue !== undefined || packageArgument !== undefined || finalCliArgs.cleanNodeModules !== undefined || finalCliArgs.externals !== undefined || cliArgs.statusParallel !== undefined || cliArgs.auditBranches !== undefined || cliArgs.parallel !== undefined || cliArgs.markCompleted !== undefined || cliArgs.skip !== undefined || cliArgs.retryFailed !== undefined || cliArgs.skipFailed !== undefined || cliArgs.validateState !== undefined) {
321
+ if (finalCliArgs.directories !== undefined || finalCliArgs.directory !== undefined || finalCliArgs.startFrom !== undefined || finalCliArgs.stopAt !== undefined || finalCliArgs.cmd !== undefined || builtInCommand !== undefined || finalCliArgs.continue !== undefined || packageArgument !== undefined || finalCliArgs.cleanNodeModules !== undefined || finalCliArgs.externals !== undefined || cliArgs.statusParallel !== undefined || cliArgs.auditBranches !== undefined || cliArgs.parallel !== undefined || cliArgs.markCompleted !== undefined || cliArgs.skip !== undefined || cliArgs.retryFailed !== undefined || cliArgs.skipFailed !== undefined || cliArgs.validateState !== undefined || cliArgs.order !== undefined) {
301
322
  transformedCliArgs.tree = {};
302
323
  if (finalCliArgs.directories !== undefined) transformedCliArgs.tree.directories = finalCliArgs.directories;
303
324
  else if (finalCliArgs.directory !== undefined) transformedCliArgs.tree.directories = [
@@ -336,6 +357,7 @@ const transformCliArgs = (finalCliArgs, commandName)=>{
336
357
  if (cliArgs.retryFailed !== undefined) transformedCliArgs.tree.retryFailed = cliArgs.retryFailed;
337
358
  if (cliArgs.skipFailed !== undefined) transformedCliArgs.tree.skipFailed = cliArgs.skipFailed;
338
359
  if (cliArgs.validateState !== undefined) transformedCliArgs.tree.validateState = cliArgs.validateState;
360
+ if (cliArgs.order !== undefined) transformedCliArgs.tree.order = cliArgs.order;
339
361
  }
340
362
  }
341
363
  // Nested mappings for 'development' options
@@ -354,11 +376,22 @@ const transformCliArgs = (finalCliArgs, commandName)=>{
354
376
  if (finalCliArgs.directories !== undefined) transformedCliArgs.versions.directories = finalCliArgs.directories;
355
377
  }
356
378
  // Nested mappings for 'updates' options
357
- if (commandName === 'updates' && (finalCliArgs.scope !== undefined || finalCliArgs.directories !== undefined || finalCliArgs.interProject !== undefined)) {
379
+ if (commandName === 'updates' && (finalCliArgs.scope !== undefined || finalCliArgs.directories !== undefined || finalCliArgs.interProject !== undefined || finalCliArgs.report !== undefined || finalCliArgs.analyze !== undefined || finalCliArgs.strategy !== undefined)) {
358
380
  transformedCliArgs.updates = {};
359
381
  if (finalCliArgs.scope !== undefined) transformedCliArgs.updates.scope = finalCliArgs.scope;
360
382
  if (finalCliArgs.directories !== undefined) transformedCliArgs.updates.directories = finalCliArgs.directories;
361
383
  if (finalCliArgs.interProject !== undefined) transformedCliArgs.updates.interProject = finalCliArgs.interProject;
384
+ if (finalCliArgs.report !== undefined) transformedCliArgs.updates.report = finalCliArgs.report;
385
+ if (finalCliArgs.analyze !== undefined) transformedCliArgs.updates.analyze = finalCliArgs.analyze;
386
+ if (finalCliArgs.strategy !== undefined) transformedCliArgs.updates.strategy = finalCliArgs.strategy;
387
+ }
388
+ // Nested mappings for 'pull' options
389
+ if (commandName === 'pull' && (finalCliArgs.remote !== undefined || finalCliArgs.branch !== undefined || finalCliArgs.autoStash !== undefined || finalCliArgs.autoResolve !== undefined)) {
390
+ transformedCliArgs.pull = {};
391
+ if (finalCliArgs.remote !== undefined) transformedCliArgs.pull.remote = finalCliArgs.remote;
392
+ if (finalCliArgs.branch !== undefined) transformedCliArgs.pull.branch = finalCliArgs.branch;
393
+ if (finalCliArgs.autoStash !== undefined) transformedCliArgs.pull.autoStash = finalCliArgs.autoStash;
394
+ if (finalCliArgs.autoResolve !== undefined) transformedCliArgs.pull.autoResolve = finalCliArgs.autoResolve;
362
395
  }
363
396
  // Handle excluded patterns (Commander.js converts --excluded-paths to excludedPaths)
364
397
  // Also handle exclude as alias for excludedPatterns
@@ -403,8 +436,9 @@ const configure = async (cardigantime)=>{
403
436
  var _config_contextDirectories, _config_link;
404
437
  const logger = getLogger();
405
438
  let program = new Command();
406
- // Configure program basics
407
- program.name(PROGRAM_NAME).summary('Create Intelligent Release Notes or Change Logs from Git').description('Create Intelligent Release Notes or Change Logs from Git').version(VERSION);
439
+ // Configure program basics with custom version string
440
+ const versionString = `${VERSION}\nBuilt on: ${BUILD_HOSTNAME}\nBuild time: ${BUILD_TIMESTAMP}`;
441
+ program.name(PROGRAM_NAME).summary('Create Intelligent Release Notes or Change Logs from Git').description('Create Intelligent Release Notes or Change Logs from Git').version(versionString, '-V, --version', 'Display version information');
408
442
  // Let cardigantime add its arguments first
409
443
  program = await cardigantime.configure(program);
410
444
  // Check if --check-config is in process.argv early
@@ -704,7 +738,7 @@ async function getCliConfig(program, commands) {
704
738
  addSharedOptions(publishCommand);
705
739
  const treeCommand = program.command('tree [command] [packageArgument]').option('--directory <directory>', 'target directory containing multiple packages (defaults to current directory)').option('--directories [directories...]', 'target directories containing multiple packages (defaults to current directory)').option('--start-from <startFrom>', 'resume execution from this package directory name (useful for restarting failed builds)').option('--stop-at <stopAt>', 'stop execution at this package directory name (the specified package will not be executed)').option('--cmd <cmd>', 'shell command to execute in each package directory (e.g., "npm install", "git status")')// Parallel Execution Options
706
740
  .option('--parallel', 'execute packages in parallel when dependencies allow (packages with no interdependencies run simultaneously)').option('--max-concurrency <number>', 'maximum number of packages to execute concurrently (default: number of CPU cores)', parseInt).option('--max-retries <number>', 'maximum retry attempts for failed packages (default: 3)', parseInt).option('--retry-delay <ms>', 'initial retry delay in milliseconds (default: 5000)', parseInt)// Recovery & Status Options
707
- .option('--continue', 'continue from previous tree publish execution using saved checkpoint state').option('--status', 'check status of running tree publish processes').option('--status-parallel', 'show detailed parallel execution status with package states, timing, and errors').option('--audit-branches', 'audit git branch state across all packages (checks branch consistency, merge conflicts with target, existing PRs, sync status, unpushed commits)').option('--promote <packageName>', 'mark a package as completed in the execution context (useful for recovery after timeouts)').option('--mark-completed <packages>', 'mark packages as completed using directory names (comma-separated, for recovery)').option('--skip <packages>', 'skip packages and their dependents (comma-separated)').option('--retry-failed', 'retry all previously failed packages from checkpoint').option('--skip-failed', 'skip failed packages and continue with remaining packages').option('--validate-state', 'validate checkpoint state integrity before continuing')// Package Filtering
741
+ .option('--continue', 'continue from previous tree publish execution using saved checkpoint state').option('--status', 'check status of running tree publish processes').option('--status-parallel', 'show detailed parallel execution status with package states, timing, and errors').option('--audit-branches', 'audit git branch state across all packages (checks branch consistency, merge conflicts with target, existing PRs, sync status, unpushed commits)').option('--promote <packageName>', 'mark a package as completed in the execution context (useful for recovery after timeouts)').option('--mark-completed <packages>', 'mark packages as completed using directory names (comma-separated, for recovery)').option('--skip <packages>', 'skip packages and their dependents (comma-separated)').option('--retry-failed', 'retry all previously failed packages from checkpoint').option('--skip-failed', 'skip failed packages and continue with remaining packages').option('--validate-state', 'validate checkpoint state integrity before continuing').option('--order', 'show package execution order (topological sort based on dependencies)')// Package Filtering
708
742
  .option('--excluded-patterns [excludedPatterns...]', 'patterns to exclude packages from processing (e.g., "**/node_modules/**", "dist/*")')// Link/Unlink Options
709
743
  .option('--clean-node-modules', 'for unlink command: remove node_modules and package-lock.json, then reinstall dependencies')// Command-specific options (forwarded to commit/release/publish)
710
744
  .option('--context-files [contextFiles...]', 'files containing additional context (forwarded to commit/release/publish)').option('--self-reflection', 'generate self-reflection report (forwarded to commit/release/publish)').option('--max-agentic-iterations <iterations>', 'maximum iterations for AI analysis (forwarded to commit/release/publish)', parseInt).description(`Analyze package dependencies in workspace and execute commands in dependency order.
@@ -735,7 +769,8 @@ Examples:
735
769
  kodrdriv tree --cmd "npm test"
736
770
  kodrdriv tree publish --continue --retry-failed
737
771
  kodrdriv tree publish --audit-branches
738
- kodrdriv tree publish --status-parallel`);
772
+ kodrdriv tree publish --status-parallel
773
+ kodrdriv tree --order`);
739
774
  addSharedOptions(treeCommand);
740
775
  const linkCommand = program.command('link [packageArgument]').option('--scope-roots <scopeRoots>', 'JSON mapping of scopes to root directories (e.g., \'{"@company": "../"}\')').description('Create npm file: dependencies for local development');
741
776
  addSharedOptions(linkCommand);
@@ -884,13 +919,15 @@ Examples:
884
919
  });
885
920
  const cleanCommand = program.command('clean').description('Remove the output directory and all generated files');
886
921
  addSharedOptions(cleanCommand);
887
- const precommitCommand = program.command('precommit').description('Run precommit checks (lint -> build -> test) with optimization');
922
+ const pullCommand = program.command('pull').option('--remote <remote>', 'remote to pull from (default: origin)', 'origin').option('--branch <branch>', 'branch to pull (default: current branch)').option('--no-auto-stash', 'do not auto-stash local changes').option('--no-auto-resolve', 'do not auto-resolve common conflicts').description('Smart pull from remote with auto-conflict resolution for common files (package-lock.json, dist/, etc.)');
923
+ addSharedOptions(pullCommand);
924
+ const precommitCommand = program.command('precommit').option('--fix', 'Attempt to auto-fix linting issues before running precommit checks').description('Run precommit checks (lint -> build -> test) with optimization');
888
925
  addSharedOptions(precommitCommand);
889
926
  const developmentCommand = program.command('development').option('--target-version <targetVersion>', 'target version bump type (patch, minor, major) or explicit version (e.g., "2.1.0")', 'patch').option('--no-milestones', 'disable GitHub milestone integration').option('--tag-working-branch', 'tag working branch with release version before bumping to dev (default: true)').option('--no-tag-working-branch', 'skip tagging working branch').option('--create-retroactive-tags', 'create tags for past releases found in git history (one-time operation)').option('--working-tag-prefix <prefix>', 'tag prefix for working branch tags (default: "working/")').description('Switch to working branch and set up development version');
890
927
  addSharedOptions(developmentCommand);
891
928
  const versionsCommand = program.command('versions <subcommand>').option('--directories [directories...]', 'directories to scan for packages (defaults to current directory)').description('Update dependency versions across packages. Subcommands: minor');
892
929
  addSharedOptions(versionsCommand);
893
- const updatesCommand = program.command('updates [scope]').option('--directories [directories...]', 'directories to scan for packages (tree mode, defaults to current directory)').option('--inter-project', 'update inter-project dependencies based on tree state (requires --scope)').description('Update dependencies matching a specific scope using npm-check-updates (e.g., kodrdriv updates @fjell) or update inter-project dependencies (kodrdriv updates --inter-project @fjell)');
930
+ const updatesCommand = program.command('updates [scope]').option('--directories [directories...]', 'directories to scan for packages (tree mode, defaults to current directory)').option('--inter-project', 'update inter-project dependencies based on tree state (requires --scope)').option('--report', 'generate a dependency analysis report instead of updating').option('--analyze', 'run AI-powered analysis on the dependency report to get upgrade recommendations').option('--strategy <strategy>', 'strategy for analyze mode: latest, conservative, or compatible', 'latest').description('Update dependencies matching a specific scope using npm-check-updates (e.g., kodrdriv updates @fjell) or update inter-project dependencies (kodrdriv updates --inter-project @fjell)');
894
931
  addSharedOptions(updatesCommand);
895
932
  const selectAudioCommand = program.command('select-audio').description('Interactively select and save audio device for recording');
896
933
  addSharedOptions(selectAudioCommand);
@@ -905,7 +942,7 @@ Examples:
905
942
  }
906
943
  // Only proceed with command-specific options if validation passed
907
944
  if (ALLOWED_COMMANDS.includes(commandName)) {
908
- var _chosen_commitCommand, _chosen_commit, _chosen_audioCommitCommand, _chosen_releaseCommand, _chosen_publishCommand, _chosen_treeCommand, _chosen_linkCommand, _chosen_unlinkCommand, _chosen_audioReviewCommand, _chosen_reviewCommand, _chosen_review, _chosen_cleanCommand, _chosen_developmentCommand, _chosen_versionsCommand, _chosen_updatesCommand, _chosen_selectAudioCommand;
945
+ var _chosen_commitCommand, _chosen_commit, _chosen_audioCommitCommand, _chosen_releaseCommand, _chosen_publishCommand, _chosen_treeCommand, _chosen_linkCommand, _chosen_unlinkCommand, _chosen_audioReviewCommand, _chosen_reviewCommand, _chosen_review, _chosen_cleanCommand, _chosen_precommitCommand, _chosen_developmentCommand, _chosen_versionsCommand, _chosen_updatesCommand, _chosen_selectAudioCommand;
909
946
  const chosen = {
910
947
  commitCommand,
911
948
  audioCommitCommand,
@@ -917,6 +954,7 @@ Examples:
917
954
  audioReviewCommand,
918
955
  reviewCommand,
919
956
  cleanCommand,
957
+ precommitCommand,
920
958
  developmentCommand,
921
959
  versionsCommand,
922
960
  updatesCommand,
@@ -1086,6 +1124,9 @@ Examples:
1086
1124
  } else if (commandName === 'clean' && (chosen === null || chosen === void 0 ? void 0 : (_chosen_cleanCommand = chosen.cleanCommand) === null || _chosen_cleanCommand === void 0 ? void 0 : _chosen_cleanCommand.opts)) {
1087
1125
  const cleanCmd = chosen.cleanCommand;
1088
1126
  commandOptions = cleanCmd.opts();
1127
+ } else if (commandName === 'precommit' && (chosen === null || chosen === void 0 ? void 0 : (_chosen_precommitCommand = chosen.precommitCommand) === null || _chosen_precommitCommand === void 0 ? void 0 : _chosen_precommitCommand.opts)) {
1128
+ const precommitCmd = chosen.precommitCommand;
1129
+ commandOptions = precommitCmd.opts();
1089
1130
  } else if (commandName === 'development' && (chosen === null || chosen === void 0 ? void 0 : (_chosen_developmentCommand = chosen.developmentCommand) === null || _chosen_developmentCommand === void 0 ? void 0 : _chosen_developmentCommand.opts)) {
1090
1131
  const developmentCmd = chosen.developmentCommand;
1091
1132
  commandOptions = developmentCmd.opts();