@eldrforge/kodrdriv 0.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +1 -0
  2. package/dist/application.js +25 -3
  3. package/dist/application.js.map +1 -1
  4. package/dist/arguments.js +103 -18
  5. package/dist/arguments.js.map +1 -1
  6. package/dist/commands/audio-commit.js +28 -7
  7. package/dist/commands/audio-commit.js.map +1 -1
  8. package/dist/commands/audio-review.js +28 -7
  9. package/dist/commands/audio-review.js.map +1 -1
  10. package/dist/commands/commit.js +75 -18
  11. package/dist/commands/commit.js.map +1 -1
  12. package/dist/commands/development.js +264 -0
  13. package/dist/commands/development.js.map +1 -0
  14. package/dist/commands/link.js +356 -181
  15. package/dist/commands/link.js.map +1 -1
  16. package/dist/commands/publish.js +166 -32
  17. package/dist/commands/publish.js.map +1 -1
  18. package/dist/commands/release.js +78 -13
  19. package/dist/commands/release.js.map +1 -1
  20. package/dist/commands/review.js +10 -6
  21. package/dist/commands/review.js.map +1 -1
  22. package/dist/commands/tree.js +450 -24
  23. package/dist/commands/tree.js.map +1 -1
  24. package/dist/commands/unlink.js +267 -372
  25. package/dist/commands/unlink.js.map +1 -1
  26. package/dist/commands/versions.js +224 -0
  27. package/dist/commands/versions.js.map +1 -0
  28. package/dist/constants.js +29 -10
  29. package/dist/constants.js.map +1 -1
  30. package/dist/content/diff.js.map +1 -1
  31. package/dist/content/files.js +192 -0
  32. package/dist/content/files.js.map +1 -0
  33. package/dist/content/log.js +16 -0
  34. package/dist/content/log.js.map +1 -1
  35. package/dist/main.js +0 -0
  36. package/dist/prompt/commit.js +9 -2
  37. package/dist/prompt/commit.js.map +1 -1
  38. package/dist/prompt/instructions/commit.md +20 -2
  39. package/dist/prompt/instructions/release.md +27 -10
  40. package/dist/prompt/instructions/review.md +75 -8
  41. package/dist/prompt/release.js +13 -5
  42. package/dist/prompt/release.js.map +1 -1
  43. package/dist/types.js +21 -5
  44. package/dist/types.js.map +1 -1
  45. package/dist/util/child.js +112 -26
  46. package/dist/util/child.js.map +1 -1
  47. package/dist/util/countdown.js +215 -0
  48. package/dist/util/countdown.js.map +1 -0
  49. package/dist/util/general.js +10 -2
  50. package/dist/util/general.js.map +1 -1
  51. package/dist/util/git.js +587 -0
  52. package/dist/util/git.js.map +1 -0
  53. package/dist/util/github.js +519 -3
  54. package/dist/util/github.js.map +1 -1
  55. package/dist/util/interactive.js +245 -79
  56. package/dist/util/interactive.js.map +1 -1
  57. package/dist/util/openai.js +70 -22
  58. package/dist/util/openai.js.map +1 -1
  59. package/dist/util/performance.js +1 -69
  60. package/dist/util/performance.js.map +1 -1
  61. package/dist/util/storage.js +28 -1
  62. package/dist/util/storage.js.map +1 -1
  63. package/dist/util/validation.js +1 -25
  64. package/dist/util/validation.js.map +1 -1
  65. package/package.json +10 -8
  66. package/test-multiline/cli/package.json +8 -0
  67. package/test-multiline/core/package.json +5 -0
  68. package/test-multiline/mobile/package.json +8 -0
  69. package/test-multiline/web/package.json +8 -0
  70. package/dist/util/npmOptimizations.js +0 -174
  71. package/dist/util/npmOptimizations.js.map +0 -1
@@ -4,18 +4,32 @@ import 'dotenv/config';
4
4
  import shellescape from 'shell-escape';
5
5
  import { DEFAULT_MAX_DIFF_BYTES, DEFAULT_EXCLUDED_PATTERNS, DEFAULT_OUTPUT_DIRECTORY } from '../constants.js';
6
6
  import { create, hasCriticalExcludedChanges, getMinimalExcludedPatterns, hasStagedChanges, truncateDiffByFiles } from '../content/diff.js';
7
- import { create as create$1 } from '../content/log.js';
7
+ import { create as create$2 } from '../content/log.js';
8
+ import { create as create$1 } from '../content/files.js';
8
9
  import { ValidationError, ExternalDependencyError, CommandError } from '../error/CommandErrors.js';
9
10
  import { getDryRunLogger } from '../logging.js';
10
11
  import { createPrompt } from '../prompt/commit.js';
11
12
  import { run } from '../util/child.js';
12
- import { validateString } from '../util/validation.js';
13
+ import { validateString, safeJsonParse, validatePackageJson } from '../util/validation.js';
13
14
  import { stringifyJSON, getOutputPath, getTimestampedResponseFilename, getTimestampedRequestFilename, getTimestampedCommitFilename } from '../util/general.js';
14
15
  import { getModelForCommand, createCompletionWithRetry } from '../util/openai.js';
15
16
  import { checkForFileDependencies, logFileDependencyWarning, logFileDependencySuggestions } from '../util/safety.js';
16
- import { create as create$2 } from '../util/storage.js';
17
+ import { create as create$3 } from '../util/storage.js';
18
+ import { getRecentClosedIssuesForCommit } from '../util/github.js';
17
19
  import { requireTTY, getUserChoice, STANDARD_CHOICES, getLLMFeedbackInEditor, improveContentWithLLM, editContentInEditor } from '../util/interactive.js';
18
20
 
21
+ // Helper function to get current version from package.json
22
+ async function getCurrentVersion(storage) {
23
+ try {
24
+ const packageJsonContents = await storage.readFile('package.json', 'utf-8');
25
+ const packageJson = safeJsonParse(packageJsonContents, 'package.json');
26
+ const validated = validatePackageJson(packageJson, 'package.json');
27
+ return validated.version;
28
+ } catch {
29
+ // Return undefined if we can't read the version (not a critical failure)
30
+ return undefined;
31
+ }
32
+ }
19
33
  // Helper function to edit commit message using editor
20
34
  async function editCommitMessageInteractively(commitMessage) {
21
35
  const templateLines = [
@@ -229,6 +243,7 @@ const executeInternal = async (runConfig)=>{
229
243
  // Validate sendit state early - now returns boolean instead of throwing
230
244
  validateSenditState(runConfig, cached, isDryRun, logger);
231
245
  let diffContent = '';
246
+ let isUsingFileContent = false;
232
247
  var _runConfig_commit_maxDiffBytes;
233
248
  const maxDiffBytes = (_runConfig_commit_maxDiffBytes = (_runConfig_commit1 = runConfig.commit) === null || _runConfig_commit1 === void 0 ? void 0 : _runConfig_commit1.maxDiffBytes) !== null && _runConfig_commit_maxDiffBytes !== void 0 ? _runConfig_commit_maxDiffBytes : DEFAULT_MAX_DIFF_BYTES;
234
249
  var _runConfig_excludedPatterns;
@@ -280,18 +295,35 @@ const executeInternal = async (runConfig)=>{
280
295
  }
281
296
  } else {
282
297
  var _runConfig_commit11;
283
- // No changes at all
298
+ // No changes at all - try fallback to file content for new repositories
299
+ logger.info('No changes detected in the working directory.');
284
300
  if (((_runConfig_commit11 = runConfig.commit) === null || _runConfig_commit11 === void 0 ? void 0 : _runConfig_commit11.sendit) && !isDryRun) {
285
301
  logger.warn('No changes detected to commit. Skipping commit operation.');
286
302
  return 'No changes to commit.';
287
303
  } else {
288
- var _runConfig_commit12;
289
- logger.info('No changes detected in the working directory.');
290
- if ((_runConfig_commit12 = runConfig.commit) === null || _runConfig_commit12 === void 0 ? void 0 : _runConfig_commit12.sendit) {
291
- logger.info('Skipping commit operation due to no changes.');
292
- return 'No changes to commit.';
304
+ logger.info('No diff content available. Attempting to generate commit message from file content...');
305
+ var _runConfig_excludedPatterns3;
306
+ // Create file content collector as fallback
307
+ const fileOptions = {
308
+ excludedPatterns: (_runConfig_excludedPatterns3 = runConfig.excludedPatterns) !== null && _runConfig_excludedPatterns3 !== void 0 ? _runConfig_excludedPatterns3 : DEFAULT_EXCLUDED_PATTERNS,
309
+ maxTotalBytes: maxDiffBytes * 5,
310
+ workingDirectory: process.cwd()
311
+ };
312
+ const files = await create$1(fileOptions);
313
+ const fileContent = await files.get();
314
+ if (fileContent && fileContent.trim().length > 0) {
315
+ logger.info('Using file content for commit message generation (%d characters)', fileContent.length);
316
+ diffContent = fileContent;
317
+ isUsingFileContent = true;
318
+ hasActualChanges = true; // We have content to work with
293
319
  } else {
294
- logger.info('Generating commit message template for future use...');
320
+ var _runConfig_commit12;
321
+ if ((_runConfig_commit12 = runConfig.commit) === null || _runConfig_commit12 === void 0 ? void 0 : _runConfig_commit12.sendit) {
322
+ logger.info('Skipping commit operation due to no changes.');
323
+ return 'No changes to commit.';
324
+ } else {
325
+ logger.info('Generating commit message template for future use...');
326
+ }
295
327
  }
296
328
  }
297
329
  }
@@ -299,15 +331,46 @@ const executeInternal = async (runConfig)=>{
299
331
  const logOptions = {
300
332
  limit: (_runConfig_commit2 = runConfig.commit) === null || _runConfig_commit2 === void 0 ? void 0 : _runConfig_commit2.messageLimit
301
333
  };
302
- const log = await create$1(logOptions);
334
+ const log = await create$2(logOptions);
303
335
  const logContext = await log.get();
336
+ // Always ensure output directory exists for request/response files and GitHub issues lookup
337
+ const outputDirectory = runConfig.outputDirectory || DEFAULT_OUTPUT_DIRECTORY;
338
+ const storage = create$3({
339
+ log: logger.info
340
+ });
341
+ await storage.ensureDirectory(outputDirectory);
342
+ // Get GitHub issues context for large commits [[memory:5887795]]
343
+ let githubIssuesContext = '';
344
+ try {
345
+ const currentVersion = await getCurrentVersion(storage);
346
+ if (currentVersion) {
347
+ logger.debug(`Found current version: ${currentVersion}, fetching related GitHub issues...`);
348
+ githubIssuesContext = await getRecentClosedIssuesForCommit(currentVersion, 10);
349
+ if (githubIssuesContext) {
350
+ logger.debug(`Fetched GitHub issues context (${githubIssuesContext.length} characters)`);
351
+ } else {
352
+ logger.debug('No relevant GitHub issues found for commit context');
353
+ }
354
+ } else {
355
+ logger.debug('Could not determine current version, fetching recent issues without milestone filtering...');
356
+ githubIssuesContext = await getRecentClosedIssuesForCommit(undefined, 10);
357
+ if (githubIssuesContext) {
358
+ logger.debug(`Fetched general GitHub issues context (${githubIssuesContext.length} characters)`);
359
+ }
360
+ }
361
+ } catch (error) {
362
+ logger.debug(`Failed to fetch GitHub issues for commit context: ${error.message}`);
363
+ // Continue without GitHub context - this shouldn't block commit generation
364
+ }
304
365
  const promptConfig = {
305
366
  overridePaths: runConfig.discoveredConfigDirs || [],
306
367
  overrides: runConfig.overrides || false
307
368
  };
308
369
  const promptContent = {
309
370
  diffContent,
310
- userDirection: (_runConfig_commit3 = runConfig.commit) === null || _runConfig_commit3 === void 0 ? void 0 : _runConfig_commit3.direction
371
+ userDirection: (_runConfig_commit3 = runConfig.commit) === null || _runConfig_commit3 === void 0 ? void 0 : _runConfig_commit3.direction,
372
+ isFileContent: isUsingFileContent,
373
+ githubIssuesContext
311
374
  };
312
375
  const promptContext = {
313
376
  logContext,
@@ -327,12 +390,6 @@ const executeInternal = async (runConfig)=>{
327
390
  const request = Formatter.create({
328
391
  logger
329
392
  }).formatPrompt(modelToUse, prompt);
330
- // Always ensure output directory exists for request/response files
331
- const outputDirectory = runConfig.outputDirectory || DEFAULT_OUTPUT_DIRECTORY;
332
- const storage = create$2({
333
- log: logger.info
334
- });
335
- await storage.ensureDirectory(outputDirectory);
336
393
  // Create retry callback that reduces diff size on token limit errors
337
394
  const createRetryCallback = (originalDiffContent)=>async (attempt)=>{
338
395
  var _runConfig_commit, _runConfig_commit1;