repowise 0.1.80 → 0.1.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/repowise.js +124 -121
- package/package.json +2 -1
package/dist/bin/repowise.js
CHANGED
|
@@ -1932,6 +1932,7 @@ async function handleInterview(syncId, questionId, questionText, questionContext
|
|
|
1932
1932
|
|
|
1933
1933
|
// src/lib/progress-renderer.ts
|
|
1934
1934
|
import chalk4 from "chalk";
|
|
1935
|
+
import logUpdate from "log-update";
|
|
1935
1936
|
var CORE_FILES = /* @__PURE__ */ new Set([
|
|
1936
1937
|
"project-overview.md",
|
|
1937
1938
|
"architecture.md",
|
|
@@ -1984,14 +1985,15 @@ function computeOverallProgress(syncResult) {
|
|
|
1984
1985
|
var ProgressRenderer = class {
|
|
1985
1986
|
privacyShieldShown = false;
|
|
1986
1987
|
discoveryShown = false;
|
|
1988
|
+
scanHeaderShown = false;
|
|
1987
1989
|
scanSummaryShown = false;
|
|
1988
1990
|
validationShown = false;
|
|
1989
1991
|
lastValidationSnapshot = "";
|
|
1990
|
-
lastValidationLineCount = 0;
|
|
1991
1992
|
pushShown = false;
|
|
1992
1993
|
fileStatusHeaderShown = false;
|
|
1993
1994
|
lastFileStatusSnapshot = "";
|
|
1994
|
-
|
|
1995
|
+
/** Tracks which section logUpdate is currently managing */
|
|
1996
|
+
activeSection = null;
|
|
1995
1997
|
renderPrivacyShield(enabled, spinner) {
|
|
1996
1998
|
if (this.privacyShieldShown) return;
|
|
1997
1999
|
this.privacyShieldShown = true;
|
|
@@ -2078,95 +2080,62 @@ var ProgressRenderer = class {
|
|
|
2078
2080
|
printNode(child, "", idx === topLevel.length - 1);
|
|
2079
2081
|
});
|
|
2080
2082
|
}
|
|
2081
|
-
|
|
2082
|
-
if (this.
|
|
2083
|
-
this.
|
|
2083
|
+
switchSection(section, spinner) {
|
|
2084
|
+
if (this.activeSection === section) return;
|
|
2085
|
+
if (this.activeSection) {
|
|
2086
|
+
logUpdate.done();
|
|
2087
|
+
}
|
|
2088
|
+
this.activeSection = section;
|
|
2084
2089
|
spinner.stop();
|
|
2085
|
-
console.log(
|
|
2086
|
-
chalk4.dim(
|
|
2087
|
-
` Scan complete: ${summary.totalFiles} files, ${summary.totalFunctions} functions, ${summary.totalClasses} classes, ${summary.totalEndpoints} entry points`
|
|
2088
|
-
)
|
|
2089
|
-
);
|
|
2090
|
-
console.log("");
|
|
2091
|
-
spinner.start();
|
|
2092
2090
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
if (
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
)
|
|
2113
|
-
);
|
|
2114
|
-
}
|
|
2115
|
-
const passCount = progress.personaResults.filter((r) => r.score === "PASS").length;
|
|
2116
|
-
if (isComplete) {
|
|
2117
|
-
const roundInfo = progress.round > 1 ? ` (${progress.round} rounds)` : "";
|
|
2118
|
-
lines.push(chalk4.dim(` ${passCount}/${ALL_PERSONAS.length} PASS${roundInfo}`));
|
|
2119
|
-
} else if (progress.personaResults.length > 0) {
|
|
2120
|
-
const statusSuffix = progress.status === "regenerating" ? chalk4.dim(" \u2014 improving files based on feedback") : "";
|
|
2121
|
-
lines.push(
|
|
2122
|
-
` Round ${progress.round}/${progress.maxRounds}: ${passCount}/${ALL_PERSONAS.length} passed${statusSuffix}`
|
|
2123
|
-
);
|
|
2124
|
-
} else {
|
|
2125
|
-
lines.push(chalk4.dim(` Round ${progress.round}/${progress.maxRounds}: validating...`));
|
|
2126
|
-
}
|
|
2127
|
-
for (const persona of ALL_PERSONAS) {
|
|
2128
|
-
const label = PERSONA_LABELS[persona] ?? persona;
|
|
2129
|
-
const score = resultMap.get(persona);
|
|
2130
|
-
if (score) {
|
|
2131
|
-
const icon = score === "PASS" ? chalk4.green("\u2713") : chalk4.red("\u2717");
|
|
2132
|
-
const scoreColor = score === "PASS" ? chalk4.green : score === "PARTIAL" ? chalk4.yellow : chalk4.red;
|
|
2133
|
-
const fixingSuffix = progress.status === "regenerating" && score !== "PASS" ? chalk4.dim(" \u2192 fixing...") : "";
|
|
2134
|
-
lines.push(` ${icon} ${label}: ${scoreColor(score)}${fixingSuffix}`);
|
|
2135
|
-
} else {
|
|
2136
|
-
lines.push(` ${chalk4.dim("\u25CB")} ${chalk4.dim(label)}`);
|
|
2091
|
+
renderScanProgress(progress, spinner) {
|
|
2092
|
+
if (!this.scanHeaderShown) {
|
|
2093
|
+
this.scanHeaderShown = true;
|
|
2094
|
+
spinner.stop();
|
|
2095
|
+
console.log("");
|
|
2096
|
+
console.log(chalk4.cyan.bold(" \u2500\u2500 Code Analysis \u2500\u2500"));
|
|
2097
|
+
console.log(chalk4.dim(" Analyzing your codebase structure, functions, and relationships."));
|
|
2098
|
+
}
|
|
2099
|
+
this.switchSection("scan", spinner);
|
|
2100
|
+
if (progress.summary) {
|
|
2101
|
+
if (!this.scanSummaryShown) {
|
|
2102
|
+
this.scanSummaryShown = true;
|
|
2103
|
+
const s = progress.summary;
|
|
2104
|
+
logUpdate(
|
|
2105
|
+
` ${chalk4.green("\u2713")} Scan complete: ${s.totalFiles} files, ${s.totalFunctions} functions, ${s.totalClasses} classes, ${s.totalEndpoints} entry points`
|
|
2106
|
+
);
|
|
2107
|
+
logUpdate.done();
|
|
2108
|
+
console.log("");
|
|
2109
|
+
this.activeSection = null;
|
|
2137
2110
|
}
|
|
2111
|
+
} else {
|
|
2112
|
+
const pct = progress.totalBatches > 0 ? Math.round(progress.currentBatch / progress.totalBatches * 100) : 0;
|
|
2113
|
+
logUpdate(
|
|
2114
|
+
` Scanning batch ${progress.currentBatch}/${progress.totalBatches} ${chalk4.dim(`(${pct}%)`)}`
|
|
2115
|
+
);
|
|
2138
2116
|
}
|
|
2139
|
-
if (isComplete && passCount < ALL_PERSONAS.length) {
|
|
2140
|
-
lines.push(chalk4.yellow(" \u26A0 Continuing with best-effort context"));
|
|
2141
|
-
}
|
|
2142
|
-
lines.push("");
|
|
2143
|
-
for (const line of lines) {
|
|
2144
|
-
process.stdout.write(`\x1B[2K${line}
|
|
2145
|
-
`);
|
|
2146
|
-
}
|
|
2147
|
-
for (let i = lines.length; i < this.lastValidationLineCount; i++) {
|
|
2148
|
-
process.stdout.write("\x1B[2K\n");
|
|
2149
|
-
}
|
|
2150
|
-
this.lastValidationLineCount = lines.length;
|
|
2151
|
-
spinner.start();
|
|
2152
2117
|
}
|
|
2153
2118
|
renderFileStatuses(fileStatuses, spinner) {
|
|
2154
2119
|
const snapshot = fileStatuses.map((f) => `${f.fileName}:${f.status}`).join(",");
|
|
2155
2120
|
if (snapshot === this.lastFileStatusSnapshot) return;
|
|
2156
2121
|
this.lastFileStatusSnapshot = snapshot;
|
|
2157
|
-
spinner.stop();
|
|
2158
2122
|
if (!this.fileStatusHeaderShown) {
|
|
2159
2123
|
this.fileStatusHeaderShown = true;
|
|
2124
|
+
if (this.activeSection === "scan") {
|
|
2125
|
+
logUpdate.done();
|
|
2126
|
+
this.activeSection = null;
|
|
2127
|
+
}
|
|
2128
|
+
spinner.stop();
|
|
2160
2129
|
console.log("");
|
|
2161
2130
|
console.log(chalk4.cyan.bold(" \u2500\u2500 RepoWise Context Generation \u2500\u2500"));
|
|
2162
2131
|
console.log(chalk4.dim(" Building AI-optimized context files from your codebase."));
|
|
2163
2132
|
console.log(
|
|
2164
|
-
chalk4.cyan(
|
|
2133
|
+
chalk4.cyan(
|
|
2134
|
+
" \u2615 This takes a few minutes \u2014 grab a coffee, we'll handle the rest!"
|
|
2135
|
+
)
|
|
2165
2136
|
);
|
|
2166
2137
|
}
|
|
2167
|
-
|
|
2168
|
-
process.stdout.write(`\x1B[${this.lastFileStatusLineCount}A`);
|
|
2169
|
-
}
|
|
2138
|
+
this.switchSection("generation", spinner);
|
|
2170
2139
|
const coreFiles = [];
|
|
2171
2140
|
const tailoredFiles = [];
|
|
2172
2141
|
for (const file of fileStatuses) {
|
|
@@ -2224,20 +2193,76 @@ var ProgressRenderer = class {
|
|
|
2224
2193
|
}
|
|
2225
2194
|
}
|
|
2226
2195
|
}
|
|
2227
|
-
lines.
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2196
|
+
logUpdate(lines.join("\n"));
|
|
2197
|
+
}
|
|
2198
|
+
renderValidation(progress, spinner) {
|
|
2199
|
+
const resultMap = new Map(progress.personaResults.map((r) => [r.persona, r.score]));
|
|
2200
|
+
const isComplete = progress.status === "complete";
|
|
2201
|
+
if (isComplete && this.validationShown) return;
|
|
2202
|
+
const snapshot = `${progress.round}:${progress.status}:${progress.personaResults.map((r) => `${r.persona}:${r.score}`).join(",")}`;
|
|
2203
|
+
if (snapshot === this.lastValidationSnapshot) return;
|
|
2204
|
+
this.lastValidationSnapshot = snapshot;
|
|
2205
|
+
if (isComplete) this.validationShown = true;
|
|
2206
|
+
if (this.activeSection !== "validation") {
|
|
2207
|
+
if (this.activeSection) {
|
|
2208
|
+
logUpdate.done();
|
|
2209
|
+
this.activeSection = null;
|
|
2210
|
+
}
|
|
2211
|
+
spinner.stop();
|
|
2212
|
+
console.log("");
|
|
2231
2213
|
}
|
|
2232
|
-
|
|
2233
|
-
|
|
2214
|
+
this.switchSection("validation", spinner);
|
|
2215
|
+
const lines = [];
|
|
2216
|
+
const title = isComplete ? "Validation Results" : "Validation";
|
|
2217
|
+
lines.push(chalk4.cyan.bold(` \u2500\u2500 ${title} \u2500\u2500`));
|
|
2218
|
+
if (!isComplete) {
|
|
2219
|
+
lines.push(
|
|
2220
|
+
chalk4.dim(
|
|
2221
|
+
` ${ALL_PERSONAS.length} AI reviewers checking context quality \u2014 issues are auto-fixed.`
|
|
2222
|
+
)
|
|
2223
|
+
);
|
|
2224
|
+
}
|
|
2225
|
+
const passCount = progress.personaResults.filter((r) => r.score === "PASS").length;
|
|
2226
|
+
if (isComplete) {
|
|
2227
|
+
const roundInfo = progress.round > 1 ? ` (${progress.round} rounds)` : "";
|
|
2228
|
+
lines.push(chalk4.dim(` ${passCount}/${ALL_PERSONAS.length} PASS${roundInfo}`));
|
|
2229
|
+
} else if (progress.personaResults.length > 0) {
|
|
2230
|
+
const statusSuffix = progress.status === "regenerating" ? chalk4.dim(" \u2014 improving files based on feedback") : "";
|
|
2231
|
+
lines.push(
|
|
2232
|
+
` Round ${progress.round}/${progress.maxRounds}: ${passCount}/${ALL_PERSONAS.length} passed${statusSuffix}`
|
|
2233
|
+
);
|
|
2234
|
+
} else {
|
|
2235
|
+
lines.push(chalk4.dim(` Round ${progress.round}/${progress.maxRounds}: validating...`));
|
|
2236
|
+
}
|
|
2237
|
+
for (const persona of ALL_PERSONAS) {
|
|
2238
|
+
const label = PERSONA_LABELS[persona] ?? persona;
|
|
2239
|
+
const score = resultMap.get(persona);
|
|
2240
|
+
if (score) {
|
|
2241
|
+
const icon = score === "PASS" ? chalk4.green("\u2713") : chalk4.red("\u2717");
|
|
2242
|
+
const scoreColor = score === "PASS" ? chalk4.green : score === "PARTIAL" ? chalk4.yellow : chalk4.red;
|
|
2243
|
+
const fixingSuffix = progress.status === "regenerating" && score !== "PASS" ? chalk4.dim(" \u2192 fixing...") : "";
|
|
2244
|
+
lines.push(` ${icon} ${label}: ${scoreColor(score)}${fixingSuffix}`);
|
|
2245
|
+
} else {
|
|
2246
|
+
lines.push(` ${chalk4.dim("\u25CB")} ${chalk4.dim(label)}`);
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
if (isComplete && passCount < ALL_PERSONAS.length) {
|
|
2250
|
+
lines.push(chalk4.yellow(" \u26A0 Continuing with best-effort context"));
|
|
2251
|
+
}
|
|
2252
|
+
logUpdate(lines.join("\n"));
|
|
2253
|
+
if (isComplete) {
|
|
2254
|
+
logUpdate.done();
|
|
2255
|
+
console.log("");
|
|
2256
|
+
this.activeSection = null;
|
|
2234
2257
|
}
|
|
2235
|
-
this.lastFileStatusLineCount = lines.length;
|
|
2236
|
-
spinner.start();
|
|
2237
2258
|
}
|
|
2238
2259
|
renderPush(spinner) {
|
|
2239
2260
|
if (this.pushShown) return;
|
|
2240
2261
|
this.pushShown = true;
|
|
2262
|
+
if (this.activeSection) {
|
|
2263
|
+
logUpdate.done();
|
|
2264
|
+
this.activeSection = null;
|
|
2265
|
+
}
|
|
2241
2266
|
spinner.stop();
|
|
2242
2267
|
console.log("");
|
|
2243
2268
|
console.log(chalk4.cyan.bold(" \u2500\u2500 Saving Context \u2500\u2500"));
|
|
@@ -2245,45 +2270,17 @@ var ProgressRenderer = class {
|
|
|
2245
2270
|
console.log("");
|
|
2246
2271
|
spinner.start();
|
|
2247
2272
|
}
|
|
2273
|
+
/** Finalize any active logUpdate block. Call before resuming ora. */
|
|
2274
|
+
finalize() {
|
|
2275
|
+
if (this.activeSection) {
|
|
2276
|
+
logUpdate.done();
|
|
2277
|
+
this.activeSection = null;
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2248
2280
|
getSpinnerText(syncResult) {
|
|
2249
2281
|
const stepLabel = syncResult.stepLabel ?? syncResult.currentStep ?? "Processing";
|
|
2250
2282
|
const overallPct = computeOverallProgress(syncResult);
|
|
2251
|
-
|
|
2252
|
-
if (syncResult.scanProgress && !syncResult.scanProgress.summary) {
|
|
2253
|
-
progressText = `Scanning batch ${syncResult.scanProgress.currentBatch}/${syncResult.scanProgress.totalBatches}`;
|
|
2254
|
-
} else if (syncResult.validationProgress && syncResult.validationProgress.status !== "complete") {
|
|
2255
|
-
const vp = syncResult.validationProgress;
|
|
2256
|
-
if (vp.status === "regenerating") {
|
|
2257
|
-
progressText = `Improving files based on feedback (round ${vp.round})`;
|
|
2258
|
-
} else {
|
|
2259
|
-
progressText = `Validation round ${vp.round}/${vp.maxRounds}`;
|
|
2260
|
-
}
|
|
2261
|
-
} else if (syncResult.generationProgress) {
|
|
2262
|
-
const gp = syncResult.generationProgress;
|
|
2263
|
-
if (gp.fileStatuses && gp.fileStatuses.length > 0) {
|
|
2264
|
-
const completed = gp.fileStatuses.filter((f) => f.status === "completed").length;
|
|
2265
|
-
const total = gp.fileStatuses.length;
|
|
2266
|
-
const generating = gp.fileStatuses.find((f) => f.status === "generating");
|
|
2267
|
-
if (completed === total) {
|
|
2268
|
-
progressText = stepLabel;
|
|
2269
|
-
} else if (generating) {
|
|
2270
|
-
const genBaseName = generating.fileName.split("/").pop() ?? generating.fileName;
|
|
2271
|
-
const isCore = CORE_FILES.has(genBaseName);
|
|
2272
|
-
const sectionFiles = gp.fileStatuses.filter((f) => {
|
|
2273
|
-
const bn = f.fileName.split("/").pop() ?? f.fileName;
|
|
2274
|
-
return isCore ? CORE_FILES.has(bn) : !CORE_FILES.has(bn);
|
|
2275
|
-
});
|
|
2276
|
-
const sectionCompleted = sectionFiles.filter((f) => f.status === "completed").length;
|
|
2277
|
-
const sectionLabel = isCore ? "core" : "tailored";
|
|
2278
|
-
progressText = `Generating ${generating.fileName} (${sectionCompleted}/${sectionFiles.length} ${sectionLabel})`;
|
|
2279
|
-
} else {
|
|
2280
|
-
progressText = `Generating (${completed}/${total})`;
|
|
2281
|
-
}
|
|
2282
|
-
} else {
|
|
2283
|
-
progressText = `Generating ${gp.currentFileName} (${gp.currentFile}/${gp.totalFiles})`;
|
|
2284
|
-
}
|
|
2285
|
-
}
|
|
2286
|
-
return `${progressText}... ${chalk4.dim(`(${overallPct}%)`)}`;
|
|
2283
|
+
return `${stepLabel}... ${chalk4.dim(`(${overallPct}%)`)}`;
|
|
2287
2284
|
}
|
|
2288
2285
|
update(syncResult, spinner) {
|
|
2289
2286
|
if (syncResult.privacyShieldEnabled !== void 0) {
|
|
@@ -2292,8 +2289,8 @@ var ProgressRenderer = class {
|
|
|
2292
2289
|
if (syncResult.discoveryResult) {
|
|
2293
2290
|
this.renderDiscovery(syncResult.discoveryResult, spinner);
|
|
2294
2291
|
}
|
|
2295
|
-
if (syncResult.scanProgress
|
|
2296
|
-
this.
|
|
2292
|
+
if (syncResult.scanProgress) {
|
|
2293
|
+
this.renderScanProgress(syncResult.scanProgress, spinner);
|
|
2297
2294
|
}
|
|
2298
2295
|
if (syncResult.generationProgress?.fileStatuses && syncResult.generationProgress.fileStatuses.length > 0) {
|
|
2299
2296
|
this.renderFileStatuses(syncResult.generationProgress.fileStatuses, spinner);
|
|
@@ -2304,7 +2301,9 @@ var ProgressRenderer = class {
|
|
|
2304
2301
|
if (syncResult.currentStep === "push-context") {
|
|
2305
2302
|
this.renderPush(spinner);
|
|
2306
2303
|
}
|
|
2307
|
-
|
|
2304
|
+
if (!this.activeSection) {
|
|
2305
|
+
spinner.text = this.getSpinnerText(syncResult);
|
|
2306
|
+
}
|
|
2308
2307
|
}
|
|
2309
2308
|
};
|
|
2310
2309
|
|
|
@@ -2515,6 +2514,7 @@ async function create() {
|
|
|
2515
2514
|
continue;
|
|
2516
2515
|
}
|
|
2517
2516
|
if (syncResult.status === "completed") {
|
|
2517
|
+
progressRenderer.finalize();
|
|
2518
2518
|
const generatedFiles = syncResult.filesGenerated ?? [];
|
|
2519
2519
|
const fileCount = generatedFiles.length;
|
|
2520
2520
|
if (fileCount > 0) {
|
|
@@ -2536,6 +2536,7 @@ async function create() {
|
|
|
2536
2536
|
break;
|
|
2537
2537
|
}
|
|
2538
2538
|
if (syncResult.status === "failed") {
|
|
2539
|
+
progressRenderer.finalize();
|
|
2539
2540
|
spinner.fail(chalk5.red(`Pipeline failed: ${syncResult.error ?? "Unknown error"}`));
|
|
2540
2541
|
process.exitCode = 1;
|
|
2541
2542
|
return;
|
|
@@ -2951,6 +2952,7 @@ async function sync() {
|
|
|
2951
2952
|
continue;
|
|
2952
2953
|
}
|
|
2953
2954
|
if (syncResult.status === "completed") {
|
|
2955
|
+
progressRenderer.finalize();
|
|
2954
2956
|
const generatedFiles = syncResult.filesGenerated ?? [];
|
|
2955
2957
|
const fileCount = generatedFiles.length;
|
|
2956
2958
|
if (fileCount > 0) {
|
|
@@ -2961,6 +2963,7 @@ async function sync() {
|
|
|
2961
2963
|
break;
|
|
2962
2964
|
}
|
|
2963
2965
|
if (syncResult.status === "failed") {
|
|
2966
|
+
progressRenderer.finalize();
|
|
2964
2967
|
spinner.fail(chalk8.red(`Sync failed: ${syncResult.error ?? "Unknown error"}`));
|
|
2965
2968
|
process.exitCode = 1;
|
|
2966
2969
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "repowise",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.81",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AI-optimized codebase context generator",
|
|
6
6
|
"bin": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"chalk": "^5.4.0",
|
|
22
22
|
"commander": "^12.1.0",
|
|
23
23
|
"inquirer": "^12.3.0",
|
|
24
|
+
"log-update": "^6.1.0",
|
|
24
25
|
"node-notifier": "^10.0.0",
|
|
25
26
|
"open": "^11.0.0",
|
|
26
27
|
"ora": "^8.2.0"
|