repowise 0.1.81 → 0.1.82

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 (2) hide show
  1. package/dist/bin/repowise.js +116 -177
  2. package/package.json +1 -2
@@ -1932,7 +1932,6 @@ 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";
1936
1935
  var CORE_FILES = /* @__PURE__ */ new Set([
1937
1936
  "project-overview.md",
1938
1937
  "architecture.md",
@@ -1940,31 +1939,6 @@ var CORE_FILES = /* @__PURE__ */ new Set([
1940
1939
  "api-contracts.md",
1941
1940
  "coding-patterns.md"
1942
1941
  ]);
1943
- var FILE_DESCRIPTIONS = {
1944
- // Core
1945
- "project-overview.md": "Project overview & file index",
1946
- "architecture.md": "System design & components",
1947
- "data-models.md": "Schemas, entities & relationships",
1948
- "api-contracts.md": "API endpoints & contracts",
1949
- "coding-patterns.md": "Code conventions & patterns",
1950
- // Tailored
1951
- "domain-knowledge.md": "Business domain & terminology",
1952
- "testing-strategy.md": "Test frameworks & coverage",
1953
- "deployment-workflows.md": "CI/CD & release process",
1954
- "state-management.md": "State & caching patterns",
1955
- "performance-optimization.md": "Performance & optimization",
1956
- "accessibility-patterns.md": "Accessibility & ARIA patterns",
1957
- "tech-stack.md": "Technology inventory & versions",
1958
- "tribal-knowledge.md": "Team knowledge & conventions",
1959
- "development-setup.md": "Dev environment setup",
1960
- "ui-patterns.md": "UI components & design system",
1961
- "ux-patterns.md": "UX interactions & feedback",
1962
- "user-flows.md": "User journeys & navigation",
1963
- "security-patterns.md": "Auth & security patterns",
1964
- "error-handling.md": "Error handling & recovery",
1965
- "integration-patterns.md": "External integrations & APIs",
1966
- "configuration.md": "Config & environment settings"
1967
- };
1968
1942
  var ALL_PERSONAS = ["pm", "architect", "dev", "analyst", "tea", "ux", "sm", "techWriter"];
1969
1943
  var PERSONA_LABELS = {
1970
1944
  pm: "Product Manager",
@@ -1987,13 +1961,14 @@ var ProgressRenderer = class {
1987
1961
  discoveryShown = false;
1988
1962
  scanHeaderShown = false;
1989
1963
  scanSummaryShown = false;
1964
+ generationHeaderShown = false;
1965
+ coreSubtitleShown = false;
1966
+ coreCompleteShown = false;
1967
+ tailoredSubtitleShown = false;
1968
+ tailoredCompleteShown = false;
1969
+ validationHeaderShown = false;
1990
1970
  validationShown = false;
1991
- lastValidationSnapshot = "";
1992
1971
  pushShown = false;
1993
- fileStatusHeaderShown = false;
1994
- lastFileStatusSnapshot = "";
1995
- /** Tracks which section logUpdate is currently managing */
1996
- activeSection = null;
1997
1972
  renderPrivacyShield(enabled, spinner) {
1998
1973
  if (this.privacyShieldShown) return;
1999
1974
  this.privacyShieldShown = true;
@@ -2080,14 +2055,6 @@ var ProgressRenderer = class {
2080
2055
  printNode(child, "", idx === topLevel.length - 1);
2081
2056
  });
2082
2057
  }
2083
- switchSection(section, spinner) {
2084
- if (this.activeSection === section) return;
2085
- if (this.activeSection) {
2086
- logUpdate.done();
2087
- }
2088
- this.activeSection = section;
2089
- spinner.stop();
2090
- }
2091
2058
  renderScanProgress(progress, spinner) {
2092
2059
  if (!this.scanHeaderShown) {
2093
2060
  this.scanHeaderShown = true;
@@ -2095,47 +2062,30 @@ var ProgressRenderer = class {
2095
2062
  console.log("");
2096
2063
  console.log(chalk4.cyan.bold(" \u2500\u2500 Code Analysis \u2500\u2500"));
2097
2064
  console.log(chalk4.dim(" Analyzing your codebase structure, functions, and relationships."));
2065
+ spinner.start();
2098
2066
  }
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;
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}%)`)}`
2067
+ if (progress.summary && !this.scanSummaryShown) {
2068
+ this.scanSummaryShown = true;
2069
+ const s = progress.summary;
2070
+ spinner.stop();
2071
+ console.log(
2072
+ ` ${chalk4.green("\u2713")} ${s.totalFiles} files, ${s.totalFunctions} functions, ${s.totalClasses} classes, ${s.totalEndpoints} entry points`
2115
2073
  );
2074
+ console.log("");
2075
+ spinner.start();
2116
2076
  }
2117
2077
  }
2118
2078
  renderFileStatuses(fileStatuses, spinner) {
2119
- const snapshot = fileStatuses.map((f) => `${f.fileName}:${f.status}`).join(",");
2120
- if (snapshot === this.lastFileStatusSnapshot) return;
2121
- this.lastFileStatusSnapshot = snapshot;
2122
- if (!this.fileStatusHeaderShown) {
2123
- this.fileStatusHeaderShown = true;
2124
- if (this.activeSection === "scan") {
2125
- logUpdate.done();
2126
- this.activeSection = null;
2127
- }
2079
+ if (!this.generationHeaderShown) {
2080
+ this.generationHeaderShown = true;
2128
2081
  spinner.stop();
2129
- console.log("");
2130
- console.log(chalk4.cyan.bold(" \u2500\u2500 RepoWise Context Generation \u2500\u2500"));
2131
- console.log(chalk4.dim(" Building AI-optimized context files from your codebase."));
2082
+ console.log(chalk4.cyan.bold(" \u2500\u2500 Context Generation \u2500\u2500"));
2132
2083
  console.log(
2133
- chalk4.cyan(
2134
- " \u2615 This takes a few minutes \u2014 grab a coffee, we'll handle the rest!"
2135
- )
2084
+ chalk4.cyan(" \u2615 This takes a few minutes \u2014 grab a coffee, we'll handle the rest!")
2136
2085
  );
2086
+ console.log("");
2087
+ spinner.start();
2137
2088
  }
2138
- this.switchSection("generation", spinner);
2139
2089
  const coreFiles = [];
2140
2090
  const tailoredFiles = [];
2141
2091
  for (const file of fileStatuses) {
@@ -2146,140 +2096,131 @@ var ProgressRenderer = class {
2146
2096
  tailoredFiles.push(file);
2147
2097
  }
2148
2098
  }
2149
- const maxCoreLen = coreFiles.reduce((m, f) => Math.max(m, f.fileName.length), 0);
2150
- const maxTailoredLen = tailoredFiles.reduce((m, f) => Math.max(m, f.fileName.length), 0);
2151
- const formatFileLine = (file, padLen) => {
2152
- const baseName = file.fileName.split("/").pop() ?? file.fileName;
2153
- const desc = FILE_DESCRIPTIONS[baseName] ?? baseName.replace(/\.md$/, "").replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
2154
- const padded = file.fileName.padEnd(padLen);
2155
- switch (file.status) {
2156
- case "completed":
2157
- return ` ${chalk4.green("\u2713")} ${padded} ${chalk4.dim(`\u2014 ${desc}`)}`;
2158
- case "generating":
2159
- return ` ${chalk4.cyan("\u27F3")} ${padded} ${chalk4.dim(`\u2014 ${desc}`)}`;
2160
- case "failed":
2161
- return ` ${chalk4.red("\u2717")} ${padded} ${chalk4.dim(`\u2014 ${desc}`)}`;
2162
- case "pending":
2163
- return ` ${chalk4.dim("\u25CB")} ${chalk4.dim(`${padded} \u2014 ${desc}`)}`;
2164
- }
2165
- };
2166
- const lines = [];
2167
2099
  const coreCompleted = coreFiles.filter((f) => f.status === "completed").length;
2168
- const coreGenerating = coreFiles.filter((f) => f.status === "generating");
2169
- if (coreCompleted === coreFiles.length) {
2170
- lines.push(
2171
- ` ${chalk4.bold("Core")} ${chalk4.green("\u2713")} ${coreCompleted}/${coreFiles.length} completed`
2172
- );
2173
- } else {
2174
- lines.push(` ${chalk4.bold("Core")} (${coreCompleted}/${coreFiles.length} completed)`);
2175
- for (const file of coreGenerating) {
2176
- lines.push(formatFileLine(file, maxCoreLen));
2177
- }
2100
+ const coreTotal = coreFiles.length;
2101
+ const coreAllDone = coreCompleted === coreTotal && coreTotal > 0;
2102
+ if (coreTotal > 0 && !this.coreSubtitleShown) {
2103
+ this.coreSubtitleShown = true;
2104
+ spinner.stop();
2105
+ console.log(chalk4.dim(" Generating core context files:"));
2106
+ spinner.start();
2178
2107
  }
2179
- if (tailoredFiles.length > 0) {
2180
- const tailoredCompleted = tailoredFiles.filter((f) => f.status === "completed").length;
2181
- const tailoredGenerating = tailoredFiles.filter((f) => f.status === "generating");
2182
- lines.push("");
2183
- if (tailoredCompleted === tailoredFiles.length) {
2184
- lines.push(
2185
- ` ${chalk4.bold("Tailored")} ${chalk4.green("\u2713")} ${tailoredCompleted}/${tailoredFiles.length} completed`
2186
- );
2187
- } else {
2188
- lines.push(
2189
- ` ${chalk4.bold("Tailored")} (${tailoredCompleted}/${tailoredFiles.length} completed)`
2190
- );
2191
- for (const file of tailoredGenerating) {
2192
- lines.push(formatFileLine(file, maxTailoredLen));
2193
- }
2194
- }
2108
+ if (coreAllDone && !this.coreCompleteShown) {
2109
+ this.coreCompleteShown = true;
2110
+ spinner.stop();
2111
+ console.log(` Core ${chalk4.green("\u2713")} ${coreCompleted}/${coreTotal} completed`);
2112
+ console.log("");
2113
+ spinner.start();
2114
+ }
2115
+ const tailoredCompleted = tailoredFiles.filter((f) => f.status === "completed").length;
2116
+ const tailoredTotal = tailoredFiles.length;
2117
+ const tailoredAllDone = tailoredCompleted === tailoredTotal && tailoredTotal > 0;
2118
+ if (tailoredTotal > 0 && coreAllDone && !this.tailoredSubtitleShown) {
2119
+ this.tailoredSubtitleShown = true;
2120
+ spinner.stop();
2121
+ console.log(chalk4.dim(" Generating tailored context files:"));
2122
+ spinner.start();
2123
+ }
2124
+ if (tailoredAllDone && !this.tailoredCompleteShown) {
2125
+ this.tailoredCompleteShown = true;
2126
+ spinner.stop();
2127
+ console.log(
2128
+ ` Tailored ${chalk4.green("\u2713")} ${tailoredCompleted}/${tailoredTotal} completed`
2129
+ );
2130
+ console.log("");
2131
+ spinner.start();
2195
2132
  }
2196
- logUpdate(lines.join("\n"));
2197
2133
  }
2198
2134
  renderValidation(progress, spinner) {
2199
- const resultMap = new Map(progress.personaResults.map((r) => [r.persona, r.score]));
2200
2135
  const isComplete = progress.status === "complete";
2201
2136
  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
- }
2137
+ if (!this.validationHeaderShown) {
2138
+ this.validationHeaderShown = true;
2211
2139
  spinner.stop();
2212
- console.log("");
2213
- }
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(
2140
+ console.log(chalk4.cyan.bold(" \u2500\u2500 Context Validation \u2500\u2500"));
2141
+ console.log(
2220
2142
  chalk4.dim(
2221
2143
  ` ${ALL_PERSONAS.length} AI reviewers checking context quality \u2014 issues are auto-fixed.`
2222
2144
  )
2223
2145
  );
2146
+ spinner.start();
2224
2147
  }
2225
- const passCount = progress.personaResults.filter((r) => r.score === "PASS").length;
2226
2148
  if (isComplete) {
2149
+ this.validationShown = true;
2150
+ spinner.stop();
2151
+ const passCount = progress.personaResults.filter((r) => r.score === "PASS").length;
2227
2152
  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}`
2153
+ console.log(
2154
+ ` ${chalk4.green("\u2713")} ${passCount}/${ALL_PERSONAS.length} PASS${roundInfo}`
2233
2155
  );
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)}`);
2156
+ const resultMap = new Map(progress.personaResults.map((r) => [r.persona, r.score]));
2157
+ for (const persona of ALL_PERSONAS) {
2158
+ const label = PERSONA_LABELS[persona] ?? persona;
2159
+ const score = resultMap.get(persona);
2160
+ if (score) {
2161
+ const icon = score === "PASS" ? chalk4.green("\u2713") : chalk4.red("\u2717");
2162
+ const scoreColor = score === "PASS" ? chalk4.green : score === "PARTIAL" ? chalk4.yellow : chalk4.red;
2163
+ console.log(` ${icon} ${label}: ${scoreColor(score)}`);
2164
+ }
2165
+ }
2166
+ if (passCount < ALL_PERSONAS.length) {
2167
+ console.log(chalk4.yellow(" \u26A0 Continuing with best-effort context"));
2247
2168
  }
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
2169
  console.log("");
2256
- this.activeSection = null;
2170
+ spinner.start();
2257
2171
  }
2258
2172
  }
2259
2173
  renderPush(spinner) {
2260
2174
  if (this.pushShown) return;
2261
2175
  this.pushShown = true;
2262
- if (this.activeSection) {
2263
- logUpdate.done();
2264
- this.activeSection = null;
2265
- }
2266
2176
  spinner.stop();
2267
- console.log("");
2268
2177
  console.log(chalk4.cyan.bold(" \u2500\u2500 Saving Context \u2500\u2500"));
2269
2178
  console.log(` ${chalk4.dim("Encrypting and saving context files to RepoWise servers...")}`);
2270
2179
  console.log("");
2271
2180
  spinner.start();
2272
2181
  }
2273
- /** Finalize any active logUpdate block. Call before resuming ora. */
2182
+ /** No-op kept for backward compat with create.ts/sync.ts finalize() calls */
2274
2183
  finalize() {
2275
- if (this.activeSection) {
2276
- logUpdate.done();
2277
- this.activeSection = null;
2278
- }
2279
2184
  }
2280
2185
  getSpinnerText(syncResult) {
2281
- const stepLabel = syncResult.stepLabel ?? syncResult.currentStep ?? "Processing";
2282
2186
  const overallPct = computeOverallProgress(syncResult);
2187
+ const stepLabel = syncResult.stepLabel ?? syncResult.currentStep ?? "Processing";
2188
+ if (syncResult.scanProgress && !syncResult.scanProgress.summary) {
2189
+ const sp = syncResult.scanProgress;
2190
+ const pct = sp.totalBatches > 0 ? Math.round(sp.currentBatch / sp.totalBatches * 100) : 0;
2191
+ return `Scanning batch ${sp.currentBatch}/${sp.totalBatches} ${chalk4.dim(`(${pct}%)`)}`;
2192
+ }
2193
+ if (syncResult.validationProgress && syncResult.validationProgress.status !== "complete") {
2194
+ const vp = syncResult.validationProgress;
2195
+ const passCount = vp.personaResults.filter((r) => r.score === "PASS").length;
2196
+ if (vp.status === "regenerating") {
2197
+ return `Improving files based on feedback (round ${vp.round}) ${chalk4.dim(`(${overallPct}%)`)}`;
2198
+ }
2199
+ if (vp.personaResults.length > 0) {
2200
+ return `Round ${vp.round}/${vp.maxRounds}: ${passCount}/${ALL_PERSONAS.length} passed ${chalk4.dim(`(${overallPct}%)`)}`;
2201
+ }
2202
+ return `Round ${vp.round}/${vp.maxRounds}: validating... ${chalk4.dim(`(${overallPct}%)`)}`;
2203
+ }
2204
+ if (syncResult.generationProgress) {
2205
+ const gp = syncResult.generationProgress;
2206
+ if (gp.fileStatuses && gp.fileStatuses.length > 0) {
2207
+ const generating = gp.fileStatuses.find((f) => f.status === "generating");
2208
+ if (generating) {
2209
+ const genBaseName = generating.fileName.split("/").pop() ?? generating.fileName;
2210
+ const isCore = CORE_FILES.has(genBaseName);
2211
+ const sectionFiles = gp.fileStatuses.filter((f) => {
2212
+ const bn = f.fileName.split("/").pop() ?? f.fileName;
2213
+ return isCore ? CORE_FILES.has(bn) : !CORE_FILES.has(bn);
2214
+ });
2215
+ const sectionCompleted = sectionFiles.filter((f) => f.status === "completed").length;
2216
+ return `${generating.fileName} (${sectionCompleted}/${sectionFiles.length}) ${chalk4.dim(`(${overallPct}%)`)}`;
2217
+ }
2218
+ const allDone = gp.fileStatuses.every((f) => f.status === "completed");
2219
+ if (allDone) {
2220
+ return `${stepLabel}... ${chalk4.dim(`(${overallPct}%)`)}`;
2221
+ }
2222
+ }
2223
+ }
2283
2224
  return `${stepLabel}... ${chalk4.dim(`(${overallPct}%)`)}`;
2284
2225
  }
2285
2226
  update(syncResult, spinner) {
@@ -2301,9 +2242,7 @@ var ProgressRenderer = class {
2301
2242
  if (syncResult.currentStep === "push-context") {
2302
2243
  this.renderPush(spinner);
2303
2244
  }
2304
- if (!this.activeSection) {
2305
- spinner.text = this.getSpinnerText(syncResult);
2306
- }
2245
+ spinner.text = this.getSpinnerText(syncResult);
2307
2246
  }
2308
2247
  };
2309
2248
 
@@ -2335,7 +2274,7 @@ var MAX_POLL_ATTEMPTS = 7200;
2335
2274
  var DEFAULT_CONTEXT_FOLDER = "repowise-context";
2336
2275
  async function create() {
2337
2276
  const startTime = Date.now();
2338
- const spinner = ora({ text: "Checking authentication...", stream: process.stdout }).start();
2277
+ const spinner = ora("Checking authentication...").start();
2339
2278
  try {
2340
2279
  let credentials = await getValidCredentials2();
2341
2280
  if (!credentials) {
@@ -2846,7 +2785,7 @@ function formatElapsed2(ms) {
2846
2785
  }
2847
2786
  async function sync() {
2848
2787
  const startTime = Date.now();
2849
- const spinner = ora3({ text: "Checking authentication...", stream: process.stdout }).start();
2788
+ const spinner = ora3("Checking authentication...").start();
2850
2789
  try {
2851
2790
  let credentials = await getValidCredentials2();
2852
2791
  if (!credentials) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repowise",
3
- "version": "0.1.81",
3
+ "version": "0.1.82",
4
4
  "type": "module",
5
5
  "description": "AI-optimized codebase context generator",
6
6
  "bin": {
@@ -21,7 +21,6 @@
21
21
  "chalk": "^5.4.0",
22
22
  "commander": "^12.1.0",
23
23
  "inquirer": "^12.3.0",
24
- "log-update": "^6.1.0",
25
24
  "node-notifier": "^10.0.0",
26
25
  "open": "^11.0.0",
27
26
  "ora": "^8.2.0"