repowise 0.1.79 → 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 +165 -141
- package/package.json +2 -1
package/dist/bin/repowise.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// bin/repowise.ts
|
|
4
4
|
import { readFileSync as readFileSync2 } from "fs";
|
|
5
5
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6
|
-
import { dirname as
|
|
6
|
+
import { dirname as dirname6, join as join16 } from "path";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
|
|
9
9
|
// ../listener/dist/main.js
|
|
@@ -377,7 +377,7 @@ function notifyContextUpdated(repoId, fileCount) {
|
|
|
377
377
|
// ../listener/dist/context-fetcher.js
|
|
378
378
|
import { execFile } from "child_process";
|
|
379
379
|
import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
|
|
380
|
-
import { join as join5 } from "path";
|
|
380
|
+
import { dirname as dirname2, join as join5 } from "path";
|
|
381
381
|
import { promisify } from "util";
|
|
382
382
|
|
|
383
383
|
// ../listener/dist/file-writer.js
|
|
@@ -477,7 +477,9 @@ async function fetchContextFromServer(repoId, localPath, apiUrl) {
|
|
|
477
477
|
await mkdir4(contextDir, { recursive: true });
|
|
478
478
|
const updatedFiles = [];
|
|
479
479
|
for (const file of files) {
|
|
480
|
-
|
|
480
|
+
if (file.fileName.includes(".."))
|
|
481
|
+
continue;
|
|
482
|
+
const urlRes = await fetch(`${apiUrl}/v1/repos/${repoId}/context/files/${file.fileName}`, {
|
|
481
483
|
headers
|
|
482
484
|
});
|
|
483
485
|
if (!urlRes.ok) {
|
|
@@ -496,7 +498,9 @@ async function fetchContextFromServer(repoId, localPath, apiUrl) {
|
|
|
496
498
|
continue;
|
|
497
499
|
}
|
|
498
500
|
const content = await contentRes.text();
|
|
499
|
-
|
|
501
|
+
const filePath = join5(contextDir, file.fileName);
|
|
502
|
+
await mkdir4(dirname2(filePath), { recursive: true });
|
|
503
|
+
await writeFile4(filePath, content, "utf-8");
|
|
500
504
|
updatedFiles.push(file.fileName);
|
|
501
505
|
}
|
|
502
506
|
console.log(`Context fetch for ${repoId}: downloaded ${updatedFiles.length}/${files.length} file(s)`);
|
|
@@ -917,7 +921,7 @@ async function showWelcome(currentVersion) {
|
|
|
917
921
|
// src/commands/create.ts
|
|
918
922
|
import { execSync } from "child_process";
|
|
919
923
|
import { mkdirSync, writeFileSync as writeFileSync2 } from "fs";
|
|
920
|
-
import { join as join13 } from "path";
|
|
924
|
+
import { dirname as dirname4, join as join13 } from "path";
|
|
921
925
|
|
|
922
926
|
// ../listener/dist/process-manager.js
|
|
923
927
|
import { spawn } from "child_process";
|
|
@@ -1637,7 +1641,7 @@ async function selectAiTools() {
|
|
|
1637
1641
|
|
|
1638
1642
|
// src/lib/ai-tools.ts
|
|
1639
1643
|
import { readFile as readFile8, writeFile as writeFile10, mkdir as mkdir10, readdir } from "fs/promises";
|
|
1640
|
-
import { join as join11, dirname as
|
|
1644
|
+
import { join as join11, dirname as dirname3 } from "path";
|
|
1641
1645
|
var AI_TOOL_CONFIG = {
|
|
1642
1646
|
cursor: {
|
|
1643
1647
|
label: "Cursor",
|
|
@@ -1707,8 +1711,9 @@ function generateReference(tool, repoName, contextFolder, contextFiles) {
|
|
|
1707
1711
|
const config2 = AI_TOOL_CONFIG[tool];
|
|
1708
1712
|
const safeName = sanitizeRepoName(repoName);
|
|
1709
1713
|
const fileLines = contextFiles.map((f) => {
|
|
1710
|
-
const
|
|
1711
|
-
const
|
|
1714
|
+
const baseName = f.fileName.split("/").pop() ?? f.fileName;
|
|
1715
|
+
const desc = fileDescriptionFromName(baseName);
|
|
1716
|
+
const isOverview = baseName === "project-overview.md";
|
|
1712
1717
|
return { path: f.relativePath, desc: isOverview ? `${desc} (full index of all files)` : desc };
|
|
1713
1718
|
});
|
|
1714
1719
|
const hasFiles = fileLines.length > 0;
|
|
@@ -1766,7 +1771,7 @@ function generateReference(tool, repoName, contextFolder, contextFiles) {
|
|
|
1766
1771
|
async function updateToolConfig(repoRoot, tool, repoName, contextFolder, contextFiles) {
|
|
1767
1772
|
const config2 = AI_TOOL_CONFIG[tool];
|
|
1768
1773
|
const fullPath = join11(repoRoot, config2.filePath);
|
|
1769
|
-
const dir =
|
|
1774
|
+
const dir = dirname3(fullPath);
|
|
1770
1775
|
if (dir !== repoRoot) {
|
|
1771
1776
|
await mkdir10(dir, { recursive: true });
|
|
1772
1777
|
}
|
|
@@ -1796,11 +1801,19 @@ async function updateToolConfig(repoRoot, tool, repoName, contextFolder, context
|
|
|
1796
1801
|
async function scanLocalContextFiles(repoRoot, contextFolder) {
|
|
1797
1802
|
const folderPath = join11(repoRoot, contextFolder);
|
|
1798
1803
|
try {
|
|
1799
|
-
const entries = await readdir(folderPath, { withFileTypes: true });
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
+
const entries = await readdir(folderPath, { withFileTypes: true, recursive: true });
|
|
1805
|
+
const results = [];
|
|
1806
|
+
for (const entry of entries) {
|
|
1807
|
+
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
1808
|
+
const parentDir = entry.parentPath ?? folderPath;
|
|
1809
|
+
const fullPath = join11(parentDir, entry.name);
|
|
1810
|
+
const relFromContext = fullPath.slice(folderPath.length + 1);
|
|
1811
|
+
results.push({
|
|
1812
|
+
fileName: relFromContext,
|
|
1813
|
+
relativePath: `${contextFolder}/${relFromContext}`
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1816
|
+
return results.sort((a, b) => a.fileName.localeCompare(b.fileName));
|
|
1804
1817
|
} catch (err) {
|
|
1805
1818
|
if (err.code === "ENOENT") return [];
|
|
1806
1819
|
throw err;
|
|
@@ -1919,6 +1932,7 @@ async function handleInterview(syncId, questionId, questionText, questionContext
|
|
|
1919
1932
|
|
|
1920
1933
|
// src/lib/progress-renderer.ts
|
|
1921
1934
|
import chalk4 from "chalk";
|
|
1935
|
+
import logUpdate from "log-update";
|
|
1922
1936
|
var CORE_FILES = /* @__PURE__ */ new Set([
|
|
1923
1937
|
"project-overview.md",
|
|
1924
1938
|
"architecture.md",
|
|
@@ -1971,14 +1985,15 @@ function computeOverallProgress(syncResult) {
|
|
|
1971
1985
|
var ProgressRenderer = class {
|
|
1972
1986
|
privacyShieldShown = false;
|
|
1973
1987
|
discoveryShown = false;
|
|
1988
|
+
scanHeaderShown = false;
|
|
1974
1989
|
scanSummaryShown = false;
|
|
1975
1990
|
validationShown = false;
|
|
1976
1991
|
lastValidationSnapshot = "";
|
|
1977
|
-
lastValidationLineCount = 0;
|
|
1978
1992
|
pushShown = false;
|
|
1979
1993
|
fileStatusHeaderShown = false;
|
|
1980
1994
|
lastFileStatusSnapshot = "";
|
|
1981
|
-
|
|
1995
|
+
/** Tracks which section logUpdate is currently managing */
|
|
1996
|
+
activeSection = null;
|
|
1982
1997
|
renderPrivacyShield(enabled, spinner) {
|
|
1983
1998
|
if (this.privacyShieldShown) return;
|
|
1984
1999
|
this.privacyShieldShown = true;
|
|
@@ -2065,97 +2080,62 @@ var ProgressRenderer = class {
|
|
|
2065
2080
|
printNode(child, "", idx === topLevel.length - 1);
|
|
2066
2081
|
});
|
|
2067
2082
|
}
|
|
2068
|
-
|
|
2069
|
-
if (this.
|
|
2070
|
-
this.
|
|
2083
|
+
switchSection(section, spinner) {
|
|
2084
|
+
if (this.activeSection === section) return;
|
|
2085
|
+
if (this.activeSection) {
|
|
2086
|
+
logUpdate.done();
|
|
2087
|
+
}
|
|
2088
|
+
this.activeSection = section;
|
|
2071
2089
|
spinner.stop();
|
|
2072
|
-
console.log(
|
|
2073
|
-
chalk4.dim(
|
|
2074
|
-
` Scan complete: ${summary.totalFiles} files, ${summary.totalFunctions} functions, ${summary.totalClasses} classes, ${summary.totalEndpoints} entry points`
|
|
2075
|
-
)
|
|
2076
|
-
);
|
|
2077
|
-
console.log("");
|
|
2078
|
-
spinner.start();
|
|
2079
2090
|
}
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
if (
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
)
|
|
2100
|
-
);
|
|
2101
|
-
}
|
|
2102
|
-
const passCount = progress.personaResults.filter((r) => r.score === "PASS").length;
|
|
2103
|
-
if (isComplete) {
|
|
2104
|
-
const roundInfo = progress.round > 1 ? ` (${progress.round} rounds)` : "";
|
|
2105
|
-
lines.push(chalk4.dim(` ${passCount}/${ALL_PERSONAS.length} PASS${roundInfo}`));
|
|
2106
|
-
} else if (progress.personaResults.length > 0) {
|
|
2107
|
-
const statusSuffix = progress.status === "regenerating" ? chalk4.dim(" \u2014 improving files based on feedback") : "";
|
|
2108
|
-
lines.push(
|
|
2109
|
-
` Round ${progress.round}/${progress.maxRounds}: ${passCount}/${ALL_PERSONAS.length} passed${statusSuffix}`
|
|
2110
|
-
);
|
|
2111
|
-
} else {
|
|
2112
|
-
lines.push(chalk4.dim(` Round ${progress.round}/${progress.maxRounds}: validating...`));
|
|
2113
|
-
}
|
|
2114
|
-
for (const persona of ALL_PERSONAS) {
|
|
2115
|
-
const label = PERSONA_LABELS[persona] ?? persona;
|
|
2116
|
-
const score = resultMap.get(persona);
|
|
2117
|
-
if (score) {
|
|
2118
|
-
const icon = score === "PASS" ? chalk4.green("\u2713") : chalk4.red("\u2717");
|
|
2119
|
-
const scoreColor = score === "PASS" ? chalk4.green : score === "PARTIAL" ? chalk4.yellow : chalk4.red;
|
|
2120
|
-
const fixingSuffix = progress.status === "regenerating" && score !== "PASS" ? chalk4.dim(" \u2192 fixing...") : "";
|
|
2121
|
-
lines.push(` ${icon} ${label}: ${scoreColor(score)}${fixingSuffix}`);
|
|
2122
|
-
} else {
|
|
2123
|
-
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;
|
|
2124
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
|
+
);
|
|
2125
2116
|
}
|
|
2126
|
-
if (isComplete && passCount < ALL_PERSONAS.length) {
|
|
2127
|
-
lines.push(chalk4.yellow(" \u26A0 Continuing with best-effort context"));
|
|
2128
|
-
}
|
|
2129
|
-
lines.push("");
|
|
2130
|
-
for (const line of lines) {
|
|
2131
|
-
process.stdout.write(`\x1B[2K${line}
|
|
2132
|
-
`);
|
|
2133
|
-
}
|
|
2134
|
-
for (let i = lines.length; i < this.lastValidationLineCount; i++) {
|
|
2135
|
-
process.stdout.write("\x1B[2K\n");
|
|
2136
|
-
}
|
|
2137
|
-
this.lastValidationLineCount = lines.length;
|
|
2138
|
-
spinner.start();
|
|
2139
2117
|
}
|
|
2140
2118
|
renderFileStatuses(fileStatuses, spinner) {
|
|
2141
2119
|
const snapshot = fileStatuses.map((f) => `${f.fileName}:${f.status}`).join(",");
|
|
2142
2120
|
if (snapshot === this.lastFileStatusSnapshot) return;
|
|
2143
2121
|
this.lastFileStatusSnapshot = snapshot;
|
|
2144
|
-
const completedCount = fileStatuses.filter((f) => f.status === "completed").length;
|
|
2145
|
-
const totalCount = fileStatuses.length;
|
|
2146
|
-
spinner.stop();
|
|
2147
2122
|
if (!this.fileStatusHeaderShown) {
|
|
2148
2123
|
this.fileStatusHeaderShown = true;
|
|
2124
|
+
if (this.activeSection === "scan") {
|
|
2125
|
+
logUpdate.done();
|
|
2126
|
+
this.activeSection = null;
|
|
2127
|
+
}
|
|
2128
|
+
spinner.stop();
|
|
2149
2129
|
console.log("");
|
|
2150
2130
|
console.log(chalk4.cyan.bold(" \u2500\u2500 RepoWise Context Generation \u2500\u2500"));
|
|
2151
2131
|
console.log(chalk4.dim(" Building AI-optimized context files from your codebase."));
|
|
2152
2132
|
console.log(
|
|
2153
|
-
chalk4.cyan(
|
|
2133
|
+
chalk4.cyan(
|
|
2134
|
+
" \u2615 This takes a few minutes \u2014 grab a coffee, we'll handle the rest!"
|
|
2135
|
+
)
|
|
2154
2136
|
);
|
|
2155
2137
|
}
|
|
2156
|
-
|
|
2157
|
-
process.stdout.write(`\x1B[${this.lastFileStatusLineCount}A`);
|
|
2158
|
-
}
|
|
2138
|
+
this.switchSection("generation", spinner);
|
|
2159
2139
|
const coreFiles = [];
|
|
2160
2140
|
const tailoredFiles = [];
|
|
2161
2141
|
for (const file of fileStatuses) {
|
|
@@ -2184,8 +2164,6 @@ var ProgressRenderer = class {
|
|
|
2184
2164
|
}
|
|
2185
2165
|
};
|
|
2186
2166
|
const lines = [];
|
|
2187
|
-
lines.push(chalk4.dim(` Generated ${completedCount}/${totalCount} files`));
|
|
2188
|
-
lines.push("");
|
|
2189
2167
|
const coreCompleted = coreFiles.filter((f) => f.status === "completed").length;
|
|
2190
2168
|
const coreGenerating = coreFiles.filter((f) => f.status === "generating");
|
|
2191
2169
|
if (coreCompleted === coreFiles.length) {
|
|
@@ -2215,20 +2193,76 @@ var ProgressRenderer = class {
|
|
|
2215
2193
|
}
|
|
2216
2194
|
}
|
|
2217
2195
|
}
|
|
2218
|
-
lines.
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
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("");
|
|
2222
2213
|
}
|
|
2223
|
-
|
|
2224
|
-
|
|
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;
|
|
2225
2257
|
}
|
|
2226
|
-
this.lastFileStatusLineCount = lines.length;
|
|
2227
|
-
spinner.start();
|
|
2228
2258
|
}
|
|
2229
2259
|
renderPush(spinner) {
|
|
2230
2260
|
if (this.pushShown) return;
|
|
2231
2261
|
this.pushShown = true;
|
|
2262
|
+
if (this.activeSection) {
|
|
2263
|
+
logUpdate.done();
|
|
2264
|
+
this.activeSection = null;
|
|
2265
|
+
}
|
|
2232
2266
|
spinner.stop();
|
|
2233
2267
|
console.log("");
|
|
2234
2268
|
console.log(chalk4.cyan.bold(" \u2500\u2500 Saving Context \u2500\u2500"));
|
|
@@ -2236,37 +2270,17 @@ var ProgressRenderer = class {
|
|
|
2236
2270
|
console.log("");
|
|
2237
2271
|
spinner.start();
|
|
2238
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
|
+
}
|
|
2239
2280
|
getSpinnerText(syncResult) {
|
|
2240
2281
|
const stepLabel = syncResult.stepLabel ?? syncResult.currentStep ?? "Processing";
|
|
2241
2282
|
const overallPct = computeOverallProgress(syncResult);
|
|
2242
|
-
|
|
2243
|
-
if (syncResult.scanProgress && !syncResult.scanProgress.summary) {
|
|
2244
|
-
progressText = `Scanning batch ${syncResult.scanProgress.currentBatch}/${syncResult.scanProgress.totalBatches}`;
|
|
2245
|
-
} else if (syncResult.validationProgress && syncResult.validationProgress.status !== "complete") {
|
|
2246
|
-
const vp = syncResult.validationProgress;
|
|
2247
|
-
if (vp.status === "regenerating") {
|
|
2248
|
-
progressText = `Improving files based on feedback (round ${vp.round})`;
|
|
2249
|
-
} else {
|
|
2250
|
-
progressText = `Validation round ${vp.round}/${vp.maxRounds}`;
|
|
2251
|
-
}
|
|
2252
|
-
} else if (syncResult.generationProgress) {
|
|
2253
|
-
const gp = syncResult.generationProgress;
|
|
2254
|
-
if (gp.fileStatuses && gp.fileStatuses.length > 0) {
|
|
2255
|
-
const completed = gp.fileStatuses.filter((f) => f.status === "completed").length;
|
|
2256
|
-
const total = gp.fileStatuses.length;
|
|
2257
|
-
const generating = gp.fileStatuses.find((f) => f.status === "generating");
|
|
2258
|
-
if (completed === total) {
|
|
2259
|
-
progressText = stepLabel;
|
|
2260
|
-
} else if (generating) {
|
|
2261
|
-
progressText = `Generating ${generating.fileName} (${completed}/${total})`;
|
|
2262
|
-
} else {
|
|
2263
|
-
progressText = `Generating (${completed}/${total})`;
|
|
2264
|
-
}
|
|
2265
|
-
} else {
|
|
2266
|
-
progressText = `Generating ${gp.currentFileName} (${gp.currentFile}/${gp.totalFiles})`;
|
|
2267
|
-
}
|
|
2268
|
-
}
|
|
2269
|
-
return `${progressText}... ${chalk4.dim(`(${overallPct}%)`)}`;
|
|
2283
|
+
return `${stepLabel}... ${chalk4.dim(`(${overallPct}%)`)}`;
|
|
2270
2284
|
}
|
|
2271
2285
|
update(syncResult, spinner) {
|
|
2272
2286
|
if (syncResult.privacyShieldEnabled !== void 0) {
|
|
@@ -2275,8 +2289,8 @@ var ProgressRenderer = class {
|
|
|
2275
2289
|
if (syncResult.discoveryResult) {
|
|
2276
2290
|
this.renderDiscovery(syncResult.discoveryResult, spinner);
|
|
2277
2291
|
}
|
|
2278
|
-
if (syncResult.scanProgress
|
|
2279
|
-
this.
|
|
2292
|
+
if (syncResult.scanProgress) {
|
|
2293
|
+
this.renderScanProgress(syncResult.scanProgress, spinner);
|
|
2280
2294
|
}
|
|
2281
2295
|
if (syncResult.generationProgress?.fileStatuses && syncResult.generationProgress.fileStatuses.length > 0) {
|
|
2282
2296
|
this.renderFileStatuses(syncResult.generationProgress.fileStatuses, spinner);
|
|
@@ -2287,7 +2301,9 @@ var ProgressRenderer = class {
|
|
|
2287
2301
|
if (syncResult.currentStep === "push-context") {
|
|
2288
2302
|
this.renderPush(spinner);
|
|
2289
2303
|
}
|
|
2290
|
-
|
|
2304
|
+
if (!this.activeSection) {
|
|
2305
|
+
spinner.text = this.getSpinnerText(syncResult);
|
|
2306
|
+
}
|
|
2291
2307
|
}
|
|
2292
2308
|
};
|
|
2293
2309
|
|
|
@@ -2319,7 +2335,7 @@ var MAX_POLL_ATTEMPTS = 7200;
|
|
|
2319
2335
|
var DEFAULT_CONTEXT_FOLDER = "repowise-context";
|
|
2320
2336
|
async function create() {
|
|
2321
2337
|
const startTime = Date.now();
|
|
2322
|
-
const spinner = ora("Checking authentication...").start();
|
|
2338
|
+
const spinner = ora({ text: "Checking authentication...", stream: process.stdout }).start();
|
|
2323
2339
|
try {
|
|
2324
2340
|
let credentials = await getValidCredentials2();
|
|
2325
2341
|
if (!credentials) {
|
|
@@ -2498,6 +2514,7 @@ async function create() {
|
|
|
2498
2514
|
continue;
|
|
2499
2515
|
}
|
|
2500
2516
|
if (syncResult.status === "completed") {
|
|
2517
|
+
progressRenderer.finalize();
|
|
2501
2518
|
const generatedFiles = syncResult.filesGenerated ?? [];
|
|
2502
2519
|
const fileCount = generatedFiles.length;
|
|
2503
2520
|
if (fileCount > 0) {
|
|
@@ -2519,6 +2536,7 @@ async function create() {
|
|
|
2519
2536
|
break;
|
|
2520
2537
|
}
|
|
2521
2538
|
if (syncResult.status === "failed") {
|
|
2539
|
+
progressRenderer.finalize();
|
|
2522
2540
|
spinner.fail(chalk5.red(`Pipeline failed: ${syncResult.error ?? "Unknown error"}`));
|
|
2523
2541
|
process.exitCode = 1;
|
|
2524
2542
|
return;
|
|
@@ -2535,16 +2553,18 @@ async function create() {
|
|
|
2535
2553
|
let downloadedCount = 0;
|
|
2536
2554
|
let failedCount = 0;
|
|
2537
2555
|
for (const file of files) {
|
|
2538
|
-
if (file.fileName.includes("..")
|
|
2556
|
+
if (file.fileName.includes("..")) {
|
|
2539
2557
|
failedCount++;
|
|
2540
2558
|
continue;
|
|
2541
2559
|
}
|
|
2542
|
-
const urlResult = await apiRequest(`/v1/repos/${repoId}/context/${file.fileName}`);
|
|
2560
|
+
const urlResult = await apiRequest(`/v1/repos/${repoId}/context/files/${file.fileName}`);
|
|
2543
2561
|
const presignedUrl = urlResult.data?.url ?? urlResult.url;
|
|
2544
2562
|
const response = await fetch(presignedUrl);
|
|
2545
2563
|
if (response.ok) {
|
|
2546
2564
|
const content = await response.text();
|
|
2547
|
-
|
|
2565
|
+
const filePath = join13(contextDir, file.fileName);
|
|
2566
|
+
mkdirSync(dirname4(filePath), { recursive: true });
|
|
2567
|
+
writeFileSync2(filePath, content, "utf-8");
|
|
2548
2568
|
downloadedCount++;
|
|
2549
2569
|
} else {
|
|
2550
2570
|
failedCount++;
|
|
@@ -2796,7 +2816,7 @@ async function status() {
|
|
|
2796
2816
|
// src/commands/sync.ts
|
|
2797
2817
|
import { execSync as execSync2 } from "child_process";
|
|
2798
2818
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2799
|
-
import { join as join15 } from "path";
|
|
2819
|
+
import { dirname as dirname5, join as join15 } from "path";
|
|
2800
2820
|
import chalk8 from "chalk";
|
|
2801
2821
|
import ora3 from "ora";
|
|
2802
2822
|
var POLL_INTERVAL_MS2 = 3e3;
|
|
@@ -2826,7 +2846,7 @@ function formatElapsed2(ms) {
|
|
|
2826
2846
|
}
|
|
2827
2847
|
async function sync() {
|
|
2828
2848
|
const startTime = Date.now();
|
|
2829
|
-
const spinner = ora3("Checking authentication...").start();
|
|
2849
|
+
const spinner = ora3({ text: "Checking authentication...", stream: process.stdout }).start();
|
|
2830
2850
|
try {
|
|
2831
2851
|
let credentials = await getValidCredentials2();
|
|
2832
2852
|
if (!credentials) {
|
|
@@ -2932,6 +2952,7 @@ async function sync() {
|
|
|
2932
2952
|
continue;
|
|
2933
2953
|
}
|
|
2934
2954
|
if (syncResult.status === "completed") {
|
|
2955
|
+
progressRenderer.finalize();
|
|
2935
2956
|
const generatedFiles = syncResult.filesGenerated ?? [];
|
|
2936
2957
|
const fileCount = generatedFiles.length;
|
|
2937
2958
|
if (fileCount > 0) {
|
|
@@ -2942,6 +2963,7 @@ async function sync() {
|
|
|
2942
2963
|
break;
|
|
2943
2964
|
}
|
|
2944
2965
|
if (syncResult.status === "failed") {
|
|
2966
|
+
progressRenderer.finalize();
|
|
2945
2967
|
spinner.fail(chalk8.red(`Sync failed: ${syncResult.error ?? "Unknown error"}`));
|
|
2946
2968
|
process.exitCode = 1;
|
|
2947
2969
|
return;
|
|
@@ -2957,16 +2979,18 @@ async function sync() {
|
|
|
2957
2979
|
let downloadedCount = 0;
|
|
2958
2980
|
let failedCount = 0;
|
|
2959
2981
|
for (const file of files) {
|
|
2960
|
-
if (file.fileName.includes("..")
|
|
2982
|
+
if (file.fileName.includes("..")) {
|
|
2961
2983
|
failedCount++;
|
|
2962
2984
|
continue;
|
|
2963
2985
|
}
|
|
2964
|
-
const urlResult = await apiRequest(`/v1/repos/${repoId}/context/${file.fileName}`);
|
|
2986
|
+
const urlResult = await apiRequest(`/v1/repos/${repoId}/context/files/${file.fileName}`);
|
|
2965
2987
|
const presignedUrl = urlResult.data?.url ?? urlResult.url;
|
|
2966
2988
|
const response = await fetch(presignedUrl);
|
|
2967
2989
|
if (response.ok) {
|
|
2968
2990
|
const content = await response.text();
|
|
2969
|
-
|
|
2991
|
+
const filePath = join15(contextDir, file.fileName);
|
|
2992
|
+
mkdirSync2(dirname5(filePath), { recursive: true });
|
|
2993
|
+
writeFileSync3(filePath, content, "utf-8");
|
|
2970
2994
|
downloadedCount++;
|
|
2971
2995
|
} else {
|
|
2972
2996
|
failedCount++;
|
|
@@ -3184,7 +3208,7 @@ async function config() {
|
|
|
3184
3208
|
|
|
3185
3209
|
// bin/repowise.ts
|
|
3186
3210
|
var __filename = fileURLToPath3(import.meta.url);
|
|
3187
|
-
var __dirname =
|
|
3211
|
+
var __dirname = dirname6(__filename);
|
|
3188
3212
|
var pkg = JSON.parse(readFileSync2(join16(__dirname, "..", "..", "package.json"), "utf-8"));
|
|
3189
3213
|
var program = new Command();
|
|
3190
3214
|
program.name("repowise").description("AI-optimized codebase context generator").version(pkg.version).option("--staging", "Use the staging environment").hook("preAction", async () => {
|
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"
|