kodevu 0.1.26 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kodevu",
3
- "version": "0.1.26",
3
+ "version": "0.1.27",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Poll SVN revisions or Git commits, send each change diff to a reviewer CLI, and write configurable review reports.",
package/src/logger.js CHANGED
@@ -38,6 +38,10 @@ class Logger {
38
38
  this._log("INFO", message);
39
39
  }
40
40
 
41
+ warn(message) {
42
+ this._log("WARN", message);
43
+ }
44
+
41
45
  error(message, error) {
42
46
  let msg = message;
43
47
  if (error) {
@@ -68,6 +72,7 @@ class Logger {
68
72
  // Console output
69
73
  const isDebug = level === "DEBUG";
70
74
  const isError = level === "ERROR";
75
+ const isWarn = level === "WARN";
71
76
 
72
77
  // If it's debug and debug mode is off, skip console
73
78
  if (isDebug && !this.config?.debug) return;
@@ -75,10 +80,10 @@ class Logger {
75
80
  if (this.progressDisplay) {
76
81
  this.progressDisplay.log(logLine);
77
82
  } else {
78
- if (isError) {
83
+ if (isError || isWarn) {
79
84
  console.error(logLine);
80
85
  } else {
81
- console.error(logLine);
86
+ console.log(logLine);
82
87
  }
83
88
  }
84
89
  }
@@ -1,3 +1,5 @@
1
+ import { logger } from "./logger.js";
2
+
1
3
  function clampProgress(value) {
2
4
  if (!Number.isFinite(value)) {
3
5
  return 0;
@@ -19,6 +21,7 @@ class ProgressItem {
19
21
  start(stage = "starting") {
20
22
  this.active = true;
21
23
  this.stage = stage;
24
+ logger.debug(`${this.label} batch start: ${stage}`);
22
25
  this.writeStatus();
23
26
  }
24
27
 
@@ -27,21 +30,28 @@ class ProgressItem {
27
30
 
28
31
  if (stage) {
29
32
  this.stage = stage;
33
+ logger.debug(`${this.label} stage: ${stage} (${Math.round(this.progress * 100)}%)`);
30
34
  }
31
35
 
32
36
  this.writeStatus();
33
37
  }
34
38
 
35
39
  log(message) {
40
+ // We don't log to file here because usually progress.log() is called alongside logger.info()
41
+ // or we want the caller to decide whether it goes to the log file.
36
42
  this.display.writeLine(message);
37
43
  }
38
44
 
39
45
  succeed(message) {
40
- this.finish("[done]", 1, message || `${this.label} complete`);
46
+ const finalMsg = message || `${this.label} complete`;
47
+ this.finish("[done]", 1, finalMsg);
48
+ logger.debug(`${this.label} batch succeed: ${finalMsg}`);
41
49
  }
42
50
 
43
51
  fail(message) {
44
- this.finish("[fail]", this.progress, message || `${this.label} failed`);
52
+ const finalMsg = message || `${this.label} failed`;
53
+ this.finish("[fail]", this.progress, finalMsg);
54
+ logger.error(`${this.label} batch fail: ${finalMsg}`);
45
55
  }
46
56
 
47
57
  finish(prefix, progress, message) {
@@ -582,6 +582,8 @@ function buildStateSnapshot(backend, targetInfo, changeId) {
582
582
  }
583
583
 
584
584
  async function reviewChange(config, backend, targetInfo, changeId, progress) {
585
+ const displayId = backend.formatChangeId(changeId);
586
+ logger.info(`Starting review for ${backend.changeName} ${displayId}`);
585
587
  progress?.update(0.05, "loading change details");
586
588
  const details = await backend.getChangeDetails(config, targetInfo, changeId);
587
589
 
@@ -650,7 +652,8 @@ async function reviewChange(config, backend, targetInfo, changeId, progress) {
650
652
  }
651
653
 
652
654
  if (reviewerName !== reviewersToTry[reviewersToTry.length - 1]) {
653
- progress?.log(`${reviewer.displayName} failed for ${details.displayId}; trying next reviewer...`);
655
+ const msg = `${reviewer.displayName} failed for ${details.displayId}; trying next reviewer...`;
656
+ logger.warn(msg);
654
657
  }
655
658
  }
656
659
 
@@ -679,6 +682,13 @@ async function reviewChange(config, backend, targetInfo, changeId, progress) {
679
682
  );
680
683
  }
681
684
 
685
+ const outputLabels = [
686
+ shouldWriteFormat(config, "markdown") ? `md: ${outputFile}` : null,
687
+ shouldWriteFormat(config, "json") ? `json: ${jsonOutputFile}` : null
688
+ ].filter(Boolean);
689
+
690
+ logger.info(`Completed review for ${displayId}: ${outputLabels.join(" | ") || "(no report file generated)"}`);
691
+
682
692
  return {
683
693
  success: true,
684
694
  outputFile: shouldWriteFormat(config, "markdown") ? outputFile : null,
@@ -772,15 +782,10 @@ export async function runReviewCycle(config) {
772
782
  throw error;
773
783
  }
774
784
 
775
- const outputLabels = [
776
- result.outputFile ? `md: ${result.outputFile}` : null,
777
- result.jsonOutputFile ? `json: ${result.jsonOutputFile}` : null
778
- ].filter(Boolean);
779
785
  const nextProjectState = buildStateSnapshot(backend, targetInfo, changeId);
780
786
  await saveState(config.stateFilePath, updateProjectState(stateFile, targetInfo, nextProjectState));
781
787
  stateFile.projects[targetInfo.stateKey] = nextProjectState;
782
788
  logger.debug(`Saved checkpoint for ${backend.formatChangeId(changeId)} to ${config.stateFilePath}.`);
783
- progress.log(`[done] reviewed ${displayId}: ${outputLabels.join(" | ") || "(no report file generated)"}`);
784
789
  updateOverallProgress(progress, index + 1, changeIdsToReview.length, 0, `finished ${displayId}`);
785
790
  }
786
791
 
package/src/shell.js CHANGED
@@ -25,7 +25,9 @@ export async function runCommand(command, args = [], options = {}) {
25
25
  } = options;
26
26
 
27
27
  logger.debug(
28
- `run: ${command} ${args.join(" ")}${cwd ? ` | cwd=${cwd}` : ""}${timeoutMs > 0 ? ` | timeoutMs=${timeoutMs}` : ""}`
28
+ `run: ${command} ${args.join(" ")}${cwd ? ` | cwd=${cwd}` : ""}${timeoutMs > 0 ? ` | timeoutMs=${timeoutMs}` : ""}${
29
+ input ? ` | input=${summarizeOutput(input)}` : ""
30
+ }`
29
31
  );
30
32
 
31
33
  return await new Promise((resolve, reject) => {
@@ -51,7 +53,10 @@ export async function runCommand(command, args = [], options = {}) {
51
53
  stderrChunks.push(Buffer.from(chunk));
52
54
  });
53
55
 
54
- child.on("error", reject);
56
+ child.on("error", (err) => {
57
+ logger.error(`spawn error: ${command}`, err);
58
+ reject(err);
59
+ });
55
60
 
56
61
  child.on("close", (code) => {
57
62
  if (timer) {
@@ -67,9 +72,14 @@ export async function runCommand(command, args = [], options = {}) {
67
72
  stderr: trim ? stderr.trim() : stderr
68
73
  };
69
74
 
70
- logger.debug(
71
- `exit: ${command} code=${result.code} timedOut=${result.timedOut} stdout=${summarizeOutput(result.stdout)} stderr=${summarizeOutput(result.stderr)}`
72
- );
75
+ const level = (result.code !== 0 || result.timedOut) && !allowFailure ? "ERROR" : "DEBUG";
76
+ const exitMsg = `exit: ${command} code=${result.code} timedOut=${result.timedOut} stdout=${summarizeOutput(result.stdout)} stderr=${summarizeOutput(result.stderr)}`;
77
+
78
+ if (level === "ERROR") {
79
+ logger.error(exitMsg);
80
+ } else {
81
+ logger.debug(exitMsg);
82
+ }
73
83
 
74
84
  if ((result.code !== 0 || result.timedOut) && !allowFailure) {
75
85
  const error = new Error(