@eldrforge/kodrdriv 1.2.133 → 1.2.135

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 (96) hide show
  1. package/.cursor/rules/no-local-dependencies.md +6 -0
  2. package/AI-GUIDE.md +4 -1
  3. package/LICENSE +1 -1
  4. package/dist/application.js +34 -42
  5. package/dist/application.js.map +1 -1
  6. package/dist/arguments.js +3 -3
  7. package/dist/arguments.js.map +1 -1
  8. package/dist/constants.js +5 -7
  9. package/dist/constants.js.map +1 -1
  10. package/dist/logging.js +4 -32
  11. package/dist/logging.js.map +1 -1
  12. package/dist/types.js +283 -0
  13. package/dist/types.js.map +1 -0
  14. package/guide/ai-system.md +3 -0
  15. package/guide/architecture.md +3 -0
  16. package/guide/commands.md +3 -0
  17. package/guide/configuration.md +3 -0
  18. package/guide/debugging.md +4 -1
  19. package/guide/development.md +3 -0
  20. package/guide/index.md +4 -1
  21. package/guide/integration.md +3 -0
  22. package/guide/monorepo.md +3 -0
  23. package/guide/quickstart.md +3 -0
  24. package/guide/testing.md +3 -0
  25. package/guide/tree-operations.md +3 -0
  26. package/guide/usage.md +3 -0
  27. package/package.json +15 -10
  28. package/DUPLICATION-CLEANUP.md +0 -104
  29. package/agentic-reflection-commit-2025-12-27T22-56-06-143Z.md +0 -50
  30. package/agentic-reflection-commit-2025-12-27T23-01-57-294Z.md +0 -50
  31. package/agentic-reflection-commit-2025-12-27T23-11-57-811Z.md +0 -50
  32. package/agentic-reflection-commit-2025-12-27T23-12-50-645Z.md +0 -50
  33. package/agentic-reflection-commit-2025-12-27T23-13-59-347Z.md +0 -52
  34. package/agentic-reflection-commit-2025-12-27T23-14-36-001Z.md +0 -50
  35. package/agentic-reflection-commit-2025-12-27T23-18-59-832Z.md +0 -50
  36. package/agentic-reflection-commit-2025-12-27T23-25-20-667Z.md +0 -62
  37. package/dist/commands/audio-commit.js +0 -152
  38. package/dist/commands/audio-commit.js.map +0 -1
  39. package/dist/commands/audio-review.js +0 -274
  40. package/dist/commands/audio-review.js.map +0 -1
  41. package/dist/commands/clean.js +0 -49
  42. package/dist/commands/clean.js.map +0 -1
  43. package/dist/commands/commit.js +0 -680
  44. package/dist/commands/commit.js.map +0 -1
  45. package/dist/commands/development.js +0 -467
  46. package/dist/commands/development.js.map +0 -1
  47. package/dist/commands/link.js +0 -646
  48. package/dist/commands/link.js.map +0 -1
  49. package/dist/commands/precommit.js +0 -99
  50. package/dist/commands/precommit.js.map +0 -1
  51. package/dist/commands/publish.js +0 -1432
  52. package/dist/commands/publish.js.map +0 -1
  53. package/dist/commands/release.js +0 -376
  54. package/dist/commands/release.js.map +0 -1
  55. package/dist/commands/review.js +0 -733
  56. package/dist/commands/review.js.map +0 -1
  57. package/dist/commands/select-audio.js +0 -46
  58. package/dist/commands/select-audio.js.map +0 -1
  59. package/dist/commands/tree.js +0 -2363
  60. package/dist/commands/tree.js.map +0 -1
  61. package/dist/commands/unlink.js +0 -537
  62. package/dist/commands/unlink.js.map +0 -1
  63. package/dist/commands/updates.js +0 -211
  64. package/dist/commands/updates.js.map +0 -1
  65. package/dist/commands/versions.js +0 -221
  66. package/dist/commands/versions.js.map +0 -1
  67. package/dist/content/diff.js +0 -346
  68. package/dist/content/diff.js.map +0 -1
  69. package/dist/content/files.js +0 -190
  70. package/dist/content/files.js.map +0 -1
  71. package/dist/content/log.js +0 -72
  72. package/dist/content/log.js.map +0 -1
  73. package/dist/util/aiAdapter.js +0 -28
  74. package/dist/util/aiAdapter.js.map +0 -1
  75. package/dist/util/fileLock.js +0 -241
  76. package/dist/util/fileLock.js.map +0 -1
  77. package/dist/util/general.js +0 -379
  78. package/dist/util/general.js.map +0 -1
  79. package/dist/util/gitMutex.js +0 -161
  80. package/dist/util/gitMutex.js.map +0 -1
  81. package/dist/util/interactive.js +0 -32
  82. package/dist/util/interactive.js.map +0 -1
  83. package/dist/util/loggerAdapter.js +0 -41
  84. package/dist/util/loggerAdapter.js.map +0 -1
  85. package/dist/util/performance.js +0 -134
  86. package/dist/util/performance.js.map +0 -1
  87. package/dist/util/precommitOptimizations.js +0 -310
  88. package/dist/util/precommitOptimizations.js.map +0 -1
  89. package/dist/util/stopContext.js +0 -146
  90. package/dist/util/stopContext.js.map +0 -1
  91. package/dist/util/storageAdapter.js +0 -31
  92. package/dist/util/storageAdapter.js.map +0 -1
  93. package/dist/util/validation.js +0 -45
  94. package/dist/util/validation.js.map +0 -1
  95. package/dist/utils/branchState.js +0 -700
  96. package/dist/utils/branchState.js.map +0 -1
@@ -1,700 +0,0 @@
1
- import { run } from '@eldrforge/git-tools';
2
- import { getLogger } from '../logging.js';
3
- import { getGitRepositoryRoot, isInGitRepository } from '../util/gitMutex.js';
4
-
5
- /**
6
- * Check the branch status for a package
7
- */ async function checkBranchStatus(packagePath, expectedBranch, targetBranch = 'main', checkPR = false, options = {}) {
8
- const logger = getLogger();
9
- // Check if path is in a git repository
10
- if (!isInGitRepository(packagePath)) {
11
- logger.debug(`Path is not in a git repository: ${packagePath}. Skipping branch status check.`);
12
- return {
13
- name: 'non-git',
14
- isOnExpectedBranch: true,
15
- ahead: 0,
16
- behind: 0,
17
- hasUnpushedCommits: false,
18
- needsSync: false,
19
- remoteExists: false
20
- };
21
- }
22
- try {
23
- // Get current branch
24
- const { stdout: currentBranch } = await run('git rev-parse --abbrev-ref HEAD', {
25
- cwd: packagePath,
26
- suppressErrorLogging: true
27
- });
28
- const branch = currentBranch.trim();
29
- // Check if remote exists
30
- let remoteExists = false;
31
- try {
32
- await run(`git ls-remote --exit-code --heads origin ${branch}`, {
33
- cwd: packagePath,
34
- suppressErrorLogging: true
35
- });
36
- remoteExists = true;
37
- } catch {
38
- remoteExists = false;
39
- }
40
- // Get ahead/behind counts if remote exists
41
- let ahead = 0;
42
- let behind = 0;
43
- if (remoteExists) {
44
- try {
45
- const { stdout: revList } = await run(`git rev-list --left-right --count origin/${branch}...HEAD`, {
46
- cwd: packagePath,
47
- suppressErrorLogging: true
48
- });
49
- const [behindStr, aheadStr] = revList.trim().split('\t');
50
- behind = parseInt(behindStr, 10) || 0;
51
- ahead = parseInt(aheadStr, 10) || 0;
52
- } catch (error) {
53
- logger.verbose(`Could not get ahead/behind counts for ${packagePath}: ${error}`);
54
- }
55
- }
56
- // Check for merge conflicts with target branch
57
- let hasMergeConflicts = false;
58
- let conflictsWith;
59
- if (branch !== targetBranch) {
60
- try {
61
- // Fetch latest to ensure we're checking against current target
62
- if (!options.skipFetch) {
63
- logger.verbose(` Fetching latest from origin for ${packagePath}...`);
64
- await run('git fetch origin --quiet', {
65
- cwd: packagePath,
66
- suppressErrorLogging: true
67
- });
68
- }
69
- logger.verbose(` Checking for merge conflicts with ${targetBranch}...`);
70
- // Use git merge-tree to test for conflicts without actually merging
71
- const { stdout: mergeTree } = await run(`git merge-tree $(git merge-base ${branch} origin/${targetBranch}) ${branch} origin/${targetBranch}`, {
72
- cwd: packagePath,
73
- suppressErrorLogging: true
74
- });
75
- // If merge-tree output contains conflict markers, there are conflicts
76
- if (mergeTree.includes('<<<<<<<') || mergeTree.includes('=======') || mergeTree.includes('>>>>>>>')) {
77
- hasMergeConflicts = true;
78
- conflictsWith = targetBranch;
79
- logger.verbose(` ⚠️ Merge conflicts detected with ${targetBranch}`);
80
- }
81
- } catch (error) {
82
- // If merge-tree fails, might be due to git version or other issues
83
- logger.verbose(`Could not check merge conflicts for ${packagePath}: ${error.message}`);
84
- }
85
- }
86
- // Check for existing PR if requested
87
- let hasOpenPR = false;
88
- let prUrl;
89
- let prNumber;
90
- if (checkPR) {
91
- try {
92
- logger.verbose(` Checking GitHub for existing PRs...`);
93
- const { findOpenPullRequestByHeadRef } = await import('@eldrforge/github-tools');
94
- const pr = await findOpenPullRequestByHeadRef(branch, packagePath);
95
- if (pr) {
96
- hasOpenPR = true;
97
- prUrl = pr.html_url;
98
- prNumber = pr.number;
99
- logger.verbose(` Found existing PR #${prNumber}: ${prUrl}`);
100
- }
101
- } catch (error) {
102
- logger.verbose(`Could not check for PR for ${packagePath}: ${error.message}`);
103
- }
104
- }
105
- const isOnExpectedBranch = !expectedBranch || branch === expectedBranch;
106
- const hasUnpushedCommits = ahead > 0;
107
- const needsSync = behind > 0;
108
- return {
109
- name: branch,
110
- isOnExpectedBranch,
111
- expectedBranch,
112
- ahead,
113
- behind,
114
- hasUnpushedCommits,
115
- needsSync,
116
- remoteExists,
117
- hasMergeConflicts,
118
- conflictsWith,
119
- hasOpenPR,
120
- prUrl,
121
- prNumber
122
- };
123
- } catch (error) {
124
- logger.error(`Error checking branch status for ${packagePath}: ${error.message}`);
125
- return {
126
- name: 'unknown',
127
- isOnExpectedBranch: false,
128
- ahead: 0,
129
- behind: 0,
130
- hasUnpushedCommits: false,
131
- needsSync: false,
132
- remoteExists: false
133
- };
134
- }
135
- }
136
- /**
137
- * Check if target branch (e.g., main) is exactly in sync with remote
138
- */ async function checkTargetBranchSync(packagePath, targetBranch = 'main', options = {}) {
139
- const logger = getLogger();
140
- // Check if path is in a git repository
141
- if (!isInGitRepository(packagePath)) {
142
- return {
143
- targetBranch,
144
- localExists: false,
145
- remoteExists: false,
146
- exactMatch: true,
147
- canFastForward: false,
148
- needsReset: false
149
- };
150
- }
151
- try {
152
- // Fetch latest from origin to ensure we have current info
153
- if (!options.skipFetch) {
154
- try {
155
- await run('git fetch origin --quiet', {
156
- cwd: packagePath,
157
- suppressErrorLogging: true
158
- });
159
- } catch (error) {
160
- logger.verbose(`Could not fetch from origin in ${packagePath}: ${error.message}`);
161
- }
162
- }
163
- // Check if local target branch exists
164
- let localExists = false;
165
- let localSha;
166
- try {
167
- const { stdout } = await run(`git rev-parse --verify ${targetBranch}`, {
168
- cwd: packagePath,
169
- suppressErrorLogging: true
170
- });
171
- localSha = stdout.trim();
172
- localExists = true;
173
- } catch {
174
- localExists = false;
175
- }
176
- // Check if remote target branch exists
177
- let remoteExists = false;
178
- let remoteSha;
179
- try {
180
- const { stdout } = await run(`git ls-remote origin ${targetBranch}`, {
181
- cwd: packagePath,
182
- suppressErrorLogging: true
183
- });
184
- if (stdout.trim()) {
185
- remoteSha = stdout.split(/\s+/)[0];
186
- remoteExists = true;
187
- }
188
- } catch {
189
- remoteExists = false;
190
- }
191
- // Determine sync status
192
- const exactMatch = localExists && remoteExists && localSha === remoteSha;
193
- let canFastForward = false;
194
- let needsReset = false;
195
- if (localExists && remoteExists && !exactMatch) {
196
- // Check if local is ancestor of remote (can fast-forward)
197
- try {
198
- await run(`git merge-base --is-ancestor ${targetBranch} origin/${targetBranch}`, {
199
- cwd: packagePath,
200
- suppressErrorLogging: true
201
- });
202
- canFastForward = true;
203
- needsReset = false;
204
- } catch {
205
- // Local is not ancestor of remote, need reset
206
- canFastForward = false;
207
- needsReset = true;
208
- }
209
- }
210
- return {
211
- targetBranch,
212
- localExists,
213
- remoteExists,
214
- localSha,
215
- remoteSha,
216
- exactMatch,
217
- canFastForward,
218
- needsReset
219
- };
220
- } catch (error) {
221
- return {
222
- targetBranch,
223
- localExists: false,
224
- remoteExists: false,
225
- exactMatch: false,
226
- canFastForward: false,
227
- needsReset: false,
228
- error: error.message
229
- };
230
- }
231
- }
232
- /**
233
- * Audit branch state across multiple packages
234
- */ async function auditBranchState(packages, expectedBranch, options = {}) {
235
- const logger = getLogger();
236
- const targetBranch = options.targetBranch || 'main';
237
- const checkPR = options.checkPR !== false; // Default true
238
- const checkConflicts = options.checkConflicts !== false; // Default true
239
- const checkVersions = options.checkVersions !== false; // Default true
240
- const concurrency = options.concurrency || 5;
241
- logger.info(`BRANCH_STATE_AUDIT: Auditing branch state for packages | Package Count: ${packages.length} | Concurrency: ${concurrency} | Purpose: Verify synchronization`);
242
- // Helper for concurrency-limited parallel map
243
- const parallelMap = async (items, fn)=>{
244
- const results = new Array(items.length);
245
- const queue = items.map((item, index)=>({
246
- item,
247
- index
248
- }));
249
- let nextIndex = 0;
250
- const workers = Array(Math.min(concurrency, items.length)).fill(null).map(async ()=>{
251
- while(nextIndex < queue.length){
252
- const task = queue[nextIndex++];
253
- results[task.index] = await fn(task.item, task.index);
254
- }
255
- });
256
- await Promise.all(workers);
257
- return results;
258
- };
259
- // If no expected branch specified, find the most common branch
260
- let actualExpectedBranch = expectedBranch;
261
- if (!expectedBranch) {
262
- logger.info('📋 Phase 1/3: Detecting most common branch across packages (optimized)...');
263
- const branchNames = await parallelMap(packages, async (pkg)=>{
264
- if (!isInGitRepository(pkg.path)) {
265
- return 'non-git';
266
- }
267
- try {
268
- const { stdout } = await run('git rev-parse --abbrev-ref HEAD', {
269
- cwd: pkg.path,
270
- suppressErrorLogging: true
271
- });
272
- return stdout.trim();
273
- } catch {
274
- return 'unknown';
275
- }
276
- });
277
- const branchCounts = new Map();
278
- for (const name of branchNames){
279
- branchCounts.set(name, (branchCounts.get(name) || 0) + 1);
280
- }
281
- // Find most common branch
282
- let maxCount = 0;
283
- for (const [branch, count] of branchCounts.entries()){
284
- if (count > maxCount && branch !== 'unknown' && branch !== 'non-git') {
285
- maxCount = count;
286
- actualExpectedBranch = branch;
287
- }
288
- }
289
- if (!actualExpectedBranch) actualExpectedBranch = 'main';
290
- logger.info(`✓ Most common branch: ${actualExpectedBranch} (${maxCount}/${packages.length} packages)`);
291
- }
292
- // Phase 2: Identify unique repos and fetch once per repo
293
- logger.info(`\n📋 Phase 2/3: Fetching latest from remotes (one fetch per repository)...`);
294
- const repoRoots = new Set();
295
- for (const pkg of packages){
296
- const root = getGitRepositoryRoot(pkg.path);
297
- if (root) repoRoots.add(root);
298
- }
299
- const repoList = Array.from(repoRoots);
300
- await parallelMap(repoList, async (repo, i)=>{
301
- try {
302
- logger.verbose(` [${i + 1}/${repoList.length}] Fetching in: ${repo}`);
303
- await run('git fetch origin --quiet', {
304
- cwd: repo,
305
- suppressErrorLogging: true
306
- });
307
- } catch (error) {
308
- logger.debug(`Could not fetch in ${repo}: ${error.message}`);
309
- }
310
- });
311
- logger.info(`✓ Fetched latest information for ${repoList.length} unique repositories`);
312
- // Phase 3: Full audit in parallel
313
- logger.info(`\n📋 Phase 3/3: Auditing package state (git status, conflicts, PRs, versions)...`);
314
- let completedCount = 0;
315
- const audits = await parallelMap(packages, async (pkg)=>{
316
- // Check target branch sync (e.g., is local main exactly in sync with remote main?)
317
- const targetBranchSync = await checkTargetBranchSync(pkg.path, targetBranch, {
318
- skipFetch: true
319
- });
320
- const status = await checkBranchStatus(pkg.path, actualExpectedBranch, targetBranch, checkPR, {
321
- skipFetch: true
322
- });
323
- const issues = [];
324
- const fixes = [];
325
- let versionStatus;
326
- // Skip issues for non-git repositories
327
- if (status.name === 'non-git') {
328
- completedCount++;
329
- if (completedCount % 5 === 0 || completedCount === packages.length) {
330
- logger.info(` Progress: ${completedCount}/${packages.length} packages audited`);
331
- }
332
- return {
333
- packageName: pkg.name,
334
- path: pkg.path,
335
- status,
336
- versionStatus,
337
- targetBranchSync,
338
- issues,
339
- fixes
340
- };
341
- }
342
- // Check for issues
343
- if (!status.isOnExpectedBranch && actualExpectedBranch) {
344
- issues.push(`On branch '${status.name}' (most packages are on '${actualExpectedBranch}')`);
345
- fixes.push(`cd ${pkg.path} && git checkout ${actualExpectedBranch}`);
346
- }
347
- if (checkConflicts && status.hasMergeConflicts && status.conflictsWith) {
348
- issues.push(`⚠️ MERGE CONFLICTS with '${status.conflictsWith}'`);
349
- fixes.push(`cd ${pkg.path} && git merge origin/${status.conflictsWith} # Resolve conflicts manually`);
350
- }
351
- if (checkPR && status.hasOpenPR) {
352
- issues.push(`Has existing PR #${status.prNumber}: ${status.prUrl}`);
353
- fixes.push(`# Review PR: ${status.prUrl}`);
354
- }
355
- if (status.hasUnpushedCommits) {
356
- issues.push(`Ahead of remote by ${status.ahead} commit(s)`);
357
- fixes.push(`cd ${pkg.path} && git push origin ${status.name}`);
358
- }
359
- if (status.needsSync) {
360
- issues.push(`Behind remote by ${status.behind} commit(s)`);
361
- fixes.push(`cd ${pkg.path} && git pull origin ${status.name}`);
362
- }
363
- if (!status.remoteExists) {
364
- issues.push(`Remote branch does not exist`);
365
- fixes.push(`cd ${pkg.path} && git push -u origin ${status.name}`);
366
- }
367
- // Check version consistency if enabled
368
- if (checkVersions) {
369
- try {
370
- const { validateVersionForBranch } = await import('../util/general.js');
371
- const fs = await import('fs/promises');
372
- const pathModule = await import('path');
373
- const packageJsonPath = pathModule.join(pkg.path, 'package.json');
374
- const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8');
375
- const packageJson = JSON.parse(packageJsonContent);
376
- const version = packageJson.version;
377
- const validation = validateVersionForBranch(version, status.name);
378
- versionStatus = {
379
- version,
380
- isValid: validation.valid,
381
- issue: validation.issue,
382
- fix: validation.fix
383
- };
384
- if (!validation.valid) {
385
- issues.push(`Version: ${version} - ${validation.issue}`);
386
- fixes.push(`cd ${pkg.path} && kodrdriv development # ${validation.fix}`);
387
- }
388
- } catch (error) {
389
- logger.verbose(`Could not check version for ${pkg.name}: ${error.message}`);
390
- }
391
- }
392
- // Check target branch sync (e.g., is local main exactly in sync with remote main?)
393
- if (targetBranchSync.localExists && targetBranchSync.remoteExists && !targetBranchSync.exactMatch) {
394
- if (targetBranchSync.needsReset) {
395
- issues.push(`Target branch '${targetBranch}' is NOT in sync with remote (local has diverged)`);
396
- fixes.push(`cd ${pkg.path} && git checkout ${targetBranch} && git reset --hard origin/${targetBranch} && git checkout ${status.name}`);
397
- } else if (targetBranchSync.canFastForward) {
398
- issues.push(`Target branch '${targetBranch}' is behind remote (can fast-forward)`);
399
- fixes.push(`cd ${pkg.path} && git checkout ${targetBranch} && git pull origin ${targetBranch} && git checkout ${status.name}`);
400
- } else {
401
- issues.push(`Target branch '${targetBranch}' is NOT in exact sync with remote`);
402
- fixes.push(`cd ${pkg.path} && git checkout ${targetBranch} && git pull origin ${targetBranch} && git checkout ${status.name}`);
403
- }
404
- } else if (!targetBranchSync.localExists && targetBranchSync.remoteExists) {
405
- // Local target branch doesn't exist but exists on remote
406
- issues.push(`Target branch '${targetBranch}' does not exist locally (exists on remote)`);
407
- fixes.push(`cd ${pkg.path} && git branch ${targetBranch} origin/${targetBranch}`);
408
- } else if (targetBranchSync.error) {
409
- logger.verbose(`Could not check target branch sync for ${pkg.name}: ${targetBranchSync.error}`);
410
- }
411
- completedCount++;
412
- if (completedCount % 5 === 0 || completedCount === packages.length) {
413
- logger.info(` Progress: ${completedCount}/${packages.length} packages audited`);
414
- }
415
- return {
416
- packageName: pkg.name,
417
- path: pkg.path,
418
- status,
419
- versionStatus,
420
- targetBranchSync,
421
- issues,
422
- fixes
423
- };
424
- });
425
- const issuesFound = audits.filter((a)=>a.issues.length > 0).length;
426
- const versionIssues = audits.filter((a)=>a.versionStatus && !a.versionStatus.isValid).length;
427
- const targetBranchSyncIssues = audits.filter((a)=>a.targetBranchSync && !a.targetBranchSync.exactMatch && a.targetBranchSync.localExists && a.targetBranchSync.remoteExists).length;
428
- const goodPackages = audits.filter((a)=>a.issues.length === 0).length;
429
- logger.info(`✓ Audit complete: ${goodPackages}/${packages.length} packages have no issues`);
430
- if (issuesFound > 0) {
431
- logger.info(` Issues found in ${issuesFound} package(s)`);
432
- }
433
- return {
434
- totalPackages: packages.length,
435
- goodPackages,
436
- issuesFound,
437
- versionIssues,
438
- targetBranchSyncIssues,
439
- audits
440
- };
441
- }
442
- /**
443
- * Format audit results for display with detailed fix instructions
444
- */ function formatAuditResults(result) {
445
- const lines = [];
446
- // Determine the common branch if any
447
- const branchCounts = new Map();
448
- for (const audit of result.audits){
449
- const branch = audit.status.name;
450
- branchCounts.set(branch, (branchCounts.get(branch) || 0) + 1);
451
- }
452
- let commonBranch;
453
- let maxCount = 0;
454
- for (const [branch, count] of branchCounts.entries()){
455
- if (count > maxCount) {
456
- maxCount = count;
457
- commonBranch = branch;
458
- }
459
- }
460
- lines.push('╔══════════════════════════════════════════════════════════════╗');
461
- lines.push(`║ Branch State Audit (${result.totalPackages} packages)`.padEnd(63) + '║');
462
- if (commonBranch && maxCount === result.totalPackages) {
463
- lines.push(`║ All packages on: ${commonBranch}`.padEnd(63) + '║');
464
- } else if (commonBranch) {
465
- lines.push(`║ Most packages on: ${commonBranch} (${maxCount}/${result.totalPackages})`.padEnd(63) + '║');
466
- }
467
- lines.push('╠══════════════════════════════════════════════════════════════╣');
468
- lines.push('');
469
- if (result.goodPackages > 0) {
470
- lines.push(`✅ Good State (${result.goodPackages} package${result.goodPackages === 1 ? '' : 's'}):`);
471
- const goodAudits = result.audits.filter((a)=>a.issues.length === 0);
472
- const displayCount = Math.min(goodAudits.length, 5);
473
- goodAudits.slice(0, displayCount).forEach((audit)=>{
474
- const versionInfo = audit.versionStatus ? ` (v${audit.versionStatus.version})` : '';
475
- lines.push(` ${audit.packageName}${versionInfo}`);
476
- });
477
- if (goodAudits.length > displayCount) {
478
- lines.push(` ... and ${goodAudits.length - displayCount} more`);
479
- }
480
- lines.push('');
481
- }
482
- // Show version issues prominently if any
483
- if (result.versionIssues > 0) {
484
- lines.push(`⚠️ Version Issues (${result.versionIssues} package${result.versionIssues === 1 ? '' : 's'}):`);
485
- const versionIssueAudits = result.audits.filter((a)=>a.versionStatus && !a.versionStatus.isValid);
486
- versionIssueAudits.forEach((audit)=>{
487
- lines.push(` ${audit.packageName}`);
488
- lines.push(` - Branch: ${audit.status.name}`);
489
- lines.push(` - Version: ${audit.versionStatus.version}`);
490
- lines.push(` - Issue: ${audit.versionStatus.issue}`);
491
- lines.push(` - Fix: ${audit.versionStatus.fix}`);
492
- lines.push('');
493
- });
494
- }
495
- // Show target branch sync issues prominently if any
496
- if (result.targetBranchSyncIssues > 0) {
497
- lines.push(`🚨 Target Branch Sync Issues (${result.targetBranchSyncIssues} package${result.targetBranchSyncIssues === 1 ? '' : 's'}):`);
498
- lines.push(` ⚠️ ${result.targetBranchSyncIssues} package${result.targetBranchSyncIssues === 1 ? '' : 's'} with target branch NOT in sync with remote`);
499
- lines.push(` This will cause "branch out of sync" errors during parallel publish!`);
500
- lines.push('');
501
- const targetSyncIssueAudits = result.audits.filter((a)=>a.targetBranchSync && !a.targetBranchSync.exactMatch && a.targetBranchSync.localExists && a.targetBranchSync.remoteExists);
502
- targetSyncIssueAudits.forEach((audit)=>{
503
- var _sync_localSha, _sync_remoteSha;
504
- const sync = audit.targetBranchSync;
505
- lines.push(` ${audit.packageName}`);
506
- lines.push(` - Target Branch: ${sync.targetBranch}`);
507
- lines.push(` - Local SHA: ${(_sync_localSha = sync.localSha) === null || _sync_localSha === void 0 ? void 0 : _sync_localSha.substring(0, 8)}...`);
508
- lines.push(` - Remote SHA: ${(_sync_remoteSha = sync.remoteSha) === null || _sync_remoteSha === void 0 ? void 0 : _sync_remoteSha.substring(0, 8)}...`);
509
- if (sync.needsReset) {
510
- lines.push(` - Action: RESET REQUIRED (local has diverged)`);
511
- } else if (sync.canFastForward) {
512
- lines.push(` - Action: Pull to fast-forward`);
513
- }
514
- lines.push('');
515
- });
516
- }
517
- if (result.issuesFound > 0) {
518
- // Count critical issues (merge conflicts, existing PRs, target branch sync)
519
- const conflictCount = result.audits.filter((a)=>a.status.hasMergeConflicts).length;
520
- const prCount = result.audits.filter((a)=>a.status.hasOpenPR).length;
521
- const branchInconsistentCount = result.audits.filter((a)=>!a.status.isOnExpectedBranch).length;
522
- const unpushedCount = result.audits.filter((a)=>a.status.hasUnpushedCommits).length;
523
- const behindCount = result.audits.filter((a)=>a.status.needsSync).length;
524
- const noRemoteCount = result.audits.filter((a)=>!a.status.remoteExists).length;
525
- if (conflictCount > 0 || prCount > 0 || result.targetBranchSyncIssues > 0) {
526
- lines.push(`🚨 CRITICAL ISSUES:`);
527
- if (result.targetBranchSyncIssues > 0) {
528
- lines.push(` 🔄 ${result.targetBranchSyncIssues} package${result.targetBranchSyncIssues === 1 ? '' : 's'} with target branch sync issues`);
529
- }
530
- if (conflictCount > 0) {
531
- lines.push(` ⚠️ ${conflictCount} package${conflictCount === 1 ? '' : 's'} with merge conflicts`);
532
- }
533
- if (prCount > 0) {
534
- lines.push(` 📋 ${prCount} package${prCount === 1 ? '' : 's'} with existing PRs`);
535
- }
536
- lines.push('');
537
- }
538
- lines.push(`⚠️ Issues Summary:`);
539
- if (result.targetBranchSyncIssues > 0) lines.push(` • ${result.targetBranchSyncIssues} target branch sync issue${result.targetBranchSyncIssues === 1 ? '' : 's'}`);
540
- if (conflictCount > 0) lines.push(` • ${conflictCount} merge conflict${conflictCount === 1 ? '' : 's'}`);
541
- if (prCount > 0) lines.push(` • ${prCount} existing PR${prCount === 1 ? '' : 's'}`);
542
- if (branchInconsistentCount > 0) lines.push(` • ${branchInconsistentCount} branch inconsistenc${branchInconsistentCount === 1 ? 'y' : 'ies'}`);
543
- if (unpushedCount > 0) lines.push(` • ${unpushedCount} package${unpushedCount === 1 ? '' : 's'} with unpushed commits`);
544
- if (behindCount > 0) lines.push(` • ${behindCount} package${behindCount === 1 ? '' : 's'} behind remote`);
545
- if (noRemoteCount > 0) lines.push(` • ${noRemoteCount} package${noRemoteCount === 1 ? '' : 's'} with no remote branch`);
546
- lines.push('');
547
- lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
548
- lines.push('📋 DETAILED ISSUES AND FIXES:');
549
- lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
550
- lines.push('');
551
- // Sort issues by severity: conflicts first, then PRs, then others
552
- const auditsWithIssues = result.audits.filter((a)=>a.issues.length > 0);
553
- const sortedAudits = auditsWithIssues.sort((a, b)=>{
554
- const aScore = (a.status.hasMergeConflicts ? 1000 : 0) + (a.status.hasOpenPR ? 100 : 0);
555
- const bScore = (b.status.hasMergeConflicts ? 1000 : 0) + (b.status.hasOpenPR ? 100 : 0);
556
- return bScore - aScore;
557
- });
558
- sortedAudits.forEach((audit, index)=>{
559
- // Highlight critical issues
560
- const hasCritical = audit.status.hasMergeConflicts || audit.status.hasOpenPR;
561
- const prefix = hasCritical ? '🚨 CRITICAL' : '⚠️ WARNING';
562
- lines.push(`${prefix} [${index + 1}/${sortedAudits.length}] ${audit.packageName}`);
563
- lines.push(`Location: ${audit.path}`);
564
- lines.push(`Branch: ${audit.status.name}`);
565
- if (audit.status.remoteExists) {
566
- const syncStatus = [];
567
- if (audit.status.ahead > 0) syncStatus.push(`ahead ${audit.status.ahead}`);
568
- if (audit.status.behind > 0) syncStatus.push(`behind ${audit.status.behind}`);
569
- if (syncStatus.length > 0) {
570
- lines.push(`Sync: ${syncStatus.join(', ')}`);
571
- }
572
- } else {
573
- lines.push(`Remote: Does not exist`);
574
- }
575
- lines.push('');
576
- lines.push('Issues:');
577
- audit.issues.forEach((issue)=>{
578
- const icon = issue.includes('MERGE CONFLICTS') ? '⚠️ ' : issue.includes('PR') ? '📋 ' : '❌ ';
579
- lines.push(` ${icon} ${issue}`);
580
- });
581
- lines.push('');
582
- lines.push('Fix Commands (execute in order):');
583
- audit.fixes.forEach((fix, fixIndex)=>{
584
- lines.push(` ${fixIndex + 1}. ${fix}`);
585
- });
586
- // Add context-specific guidance
587
- if (audit.status.hasMergeConflicts) {
588
- lines.push('');
589
- lines.push(' ⚠️ Merge Conflict Resolution:');
590
- lines.push(' After running the merge command above, you will need to:');
591
- lines.push(' a) Manually edit conflicting files to resolve conflicts');
592
- lines.push(' b) Stage resolved files: git add <file>');
593
- lines.push(' c) Complete the merge: git commit');
594
- lines.push(' d) Push the resolved merge: git push origin ' + audit.status.name);
595
- lines.push(' e) Re-run audit to verify: kodrdriv tree publish --audit-branches');
596
- }
597
- if (audit.status.hasOpenPR) {
598
- lines.push('');
599
- lines.push(' 📋 Existing PR Handling:');
600
- lines.push(' You have options:');
601
- lines.push(' a) Continue with existing PR (kodrdriv publish will detect and use it)');
602
- lines.push(' b) Close the PR if no longer needed');
603
- lines.push(' c) Merge the PR if ready, then create new one');
604
- }
605
- lines.push('');
606
- lines.push('─────────────────────────────────────────────────────────────');
607
- lines.push('');
608
- });
609
- lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
610
- lines.push('📝 RECOMMENDED WORKFLOW:');
611
- lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
612
- lines.push('');
613
- let stepNumber = 1;
614
- // Target branch sync is FIRST and most critical
615
- if (result.targetBranchSyncIssues > 0) {
616
- lines.push(`${stepNumber}️⃣ SYNC TARGET BRANCHES (CRITICAL - Do this FIRST):`);
617
- stepNumber++;
618
- const targetSyncIssueAudits = result.audits.filter((a)=>a.targetBranchSync && !a.targetBranchSync.exactMatch && a.targetBranchSync.localExists && a.targetBranchSync.remoteExists);
619
- targetSyncIssueAudits.forEach((audit)=>{
620
- const sync = audit.targetBranchSync;
621
- if (sync.needsReset) {
622
- lines.push(` • ${audit.packageName}: cd ${audit.path} && git checkout ${sync.targetBranch} && git reset --hard origin/${sync.targetBranch} && git checkout ${audit.status.name}`);
623
- } else {
624
- lines.push(` • ${audit.packageName}: cd ${audit.path} && git checkout ${sync.targetBranch} && git pull origin ${sync.targetBranch} && git checkout ${audit.status.name}`);
625
- }
626
- });
627
- lines.push('');
628
- }
629
- if (conflictCount > 0) {
630
- lines.push(`${stepNumber}️⃣ RESOLVE MERGE CONFLICTS FIRST (blocking):`);
631
- stepNumber++;
632
- sortedAudits.filter((a)=>a.status.hasMergeConflicts).forEach((audit)=>{
633
- lines.push(` • ${audit.packageName}: cd ${audit.path} && git merge origin/${audit.status.conflictsWith}`);
634
- });
635
- lines.push(' Then resolve conflicts, commit, and push.');
636
- lines.push('');
637
- }
638
- if (result.versionIssues > 0) {
639
- lines.push(`${stepNumber}️⃣ FIX VERSION ISSUES (recommended before publish):`);
640
- stepNumber++;
641
- sortedAudits.filter((a)=>a.versionStatus && !a.versionStatus.isValid).forEach((audit)=>{
642
- lines.push(` • ${audit.packageName}: cd ${audit.path} && kodrdriv development`);
643
- });
644
- lines.push('');
645
- }
646
- if (prCount > 0) {
647
- lines.push(`${stepNumber}️⃣ HANDLE EXISTING PRS:`);
648
- stepNumber++;
649
- sortedAudits.filter((a)=>a.status.hasOpenPR).forEach((audit)=>{
650
- lines.push(` • ${audit.packageName}: Review ${audit.status.prUrl}`);
651
- lines.push(` Option: Continue (publish will reuse PR) or close/merge it first`);
652
- });
653
- lines.push('');
654
- }
655
- if (branchInconsistentCount > 0) {
656
- lines.push(`${stepNumber}️⃣ ALIGN BRANCHES (if needed):`);
657
- stepNumber++;
658
- sortedAudits.filter((a)=>!a.status.isOnExpectedBranch).forEach((audit)=>{
659
- lines.push(` • ${audit.packageName}: cd ${audit.path} && git checkout ${audit.status.expectedBranch}`);
660
- });
661
- lines.push('');
662
- }
663
- if (behindCount > 0) {
664
- lines.push(`${stepNumber}️⃣ SYNC WITH REMOTE:`);
665
- stepNumber++;
666
- sortedAudits.filter((a)=>a.status.needsSync && !a.status.hasMergeConflicts).forEach((audit)=>{
667
- lines.push(` • ${audit.packageName}: cd ${audit.path} && git pull origin ${audit.status.name}`);
668
- });
669
- lines.push('');
670
- }
671
- if (unpushedCount > 0) {
672
- lines.push(`${stepNumber}️⃣ PUSH LOCAL COMMITS:`);
673
- stepNumber++;
674
- sortedAudits.filter((a)=>a.status.hasUnpushedCommits && !a.status.hasMergeConflicts).forEach((audit)=>{
675
- lines.push(` • ${audit.packageName}: cd ${audit.path} && git push origin ${audit.status.name}`);
676
- });
677
- lines.push('');
678
- }
679
- if (noRemoteCount > 0) {
680
- lines.push(`${stepNumber}️⃣ CREATE REMOTE BRANCHES:`);
681
- stepNumber++;
682
- sortedAudits.filter((a)=>!a.status.remoteExists).forEach((audit)=>{
683
- lines.push(` • ${audit.packageName}: cd ${audit.path} && git push -u origin ${audit.status.name}`);
684
- });
685
- lines.push('');
686
- }
687
- lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
688
- lines.push('');
689
- lines.push('🔄 After fixing issues, re-run audit to verify:');
690
- lines.push(' kodrdriv tree publish --audit-branches');
691
- lines.push('');
692
- lines.push('✅ Once all clear, proceed with publish:');
693
- lines.push(' kodrdriv tree publish --parallel --model "gpt-5-mini"');
694
- }
695
- lines.push('╚══════════════════════════════════════════════════════════════╝');
696
- return lines.join('\n');
697
- }
698
-
699
- export { auditBranchState, checkBranchStatus, checkTargetBranchSync, formatAuditResults };
700
- //# sourceMappingURL=branchState.js.map