repowise 0.1.79 → 0.1.80

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.
@@ -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 dirname3, join as join16 } from "path";
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
- const urlRes = await fetch(`${apiUrl}/v1/repos/${repoId}/context/${file.fileName}`, {
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
- await writeFile4(join5(contextDir, file.fileName), content, "utf-8");
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 dirname2 } from "path";
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 desc = fileDescriptionFromName(f.fileName);
1711
- const isOverview = f.fileName === "project-overview.md";
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 = dirname2(fullPath);
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
- return entries.filter((e) => e.isFile() && e.name.endsWith(".md")).map((e) => ({
1801
- fileName: e.name,
1802
- relativePath: `${contextFolder}/${e.name}`
1803
- })).sort((a, b) => a.fileName.localeCompare(b.fileName));
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;
@@ -2141,8 +2154,6 @@ var ProgressRenderer = class {
2141
2154
  const snapshot = fileStatuses.map((f) => `${f.fileName}:${f.status}`).join(",");
2142
2155
  if (snapshot === this.lastFileStatusSnapshot) return;
2143
2156
  this.lastFileStatusSnapshot = snapshot;
2144
- const completedCount = fileStatuses.filter((f) => f.status === "completed").length;
2145
- const totalCount = fileStatuses.length;
2146
2157
  spinner.stop();
2147
2158
  if (!this.fileStatusHeaderShown) {
2148
2159
  this.fileStatusHeaderShown = true;
@@ -2184,8 +2195,6 @@ var ProgressRenderer = class {
2184
2195
  }
2185
2196
  };
2186
2197
  const lines = [];
2187
- lines.push(chalk4.dim(` Generated ${completedCount}/${totalCount} files`));
2188
- lines.push("");
2189
2198
  const coreCompleted = coreFiles.filter((f) => f.status === "completed").length;
2190
2199
  const coreGenerating = coreFiles.filter((f) => f.status === "generating");
2191
2200
  if (coreCompleted === coreFiles.length) {
@@ -2258,7 +2267,15 @@ var ProgressRenderer = class {
2258
2267
  if (completed === total) {
2259
2268
  progressText = stepLabel;
2260
2269
  } else if (generating) {
2261
- progressText = `Generating ${generating.fileName} (${completed}/${total})`;
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})`;
2262
2279
  } else {
2263
2280
  progressText = `Generating (${completed}/${total})`;
2264
2281
  }
@@ -2319,7 +2336,7 @@ var MAX_POLL_ATTEMPTS = 7200;
2319
2336
  var DEFAULT_CONTEXT_FOLDER = "repowise-context";
2320
2337
  async function create() {
2321
2338
  const startTime = Date.now();
2322
- const spinner = ora("Checking authentication...").start();
2339
+ const spinner = ora({ text: "Checking authentication...", stream: process.stdout }).start();
2323
2340
  try {
2324
2341
  let credentials = await getValidCredentials2();
2325
2342
  if (!credentials) {
@@ -2535,16 +2552,18 @@ async function create() {
2535
2552
  let downloadedCount = 0;
2536
2553
  let failedCount = 0;
2537
2554
  for (const file of files) {
2538
- if (file.fileName.includes("..") || file.fileName.includes("/")) {
2555
+ if (file.fileName.includes("..")) {
2539
2556
  failedCount++;
2540
2557
  continue;
2541
2558
  }
2542
- const urlResult = await apiRequest(`/v1/repos/${repoId}/context/${file.fileName}`);
2559
+ const urlResult = await apiRequest(`/v1/repos/${repoId}/context/files/${file.fileName}`);
2543
2560
  const presignedUrl = urlResult.data?.url ?? urlResult.url;
2544
2561
  const response = await fetch(presignedUrl);
2545
2562
  if (response.ok) {
2546
2563
  const content = await response.text();
2547
- writeFileSync2(join13(contextDir, file.fileName), content, "utf-8");
2564
+ const filePath = join13(contextDir, file.fileName);
2565
+ mkdirSync(dirname4(filePath), { recursive: true });
2566
+ writeFileSync2(filePath, content, "utf-8");
2548
2567
  downloadedCount++;
2549
2568
  } else {
2550
2569
  failedCount++;
@@ -2796,7 +2815,7 @@ async function status() {
2796
2815
  // src/commands/sync.ts
2797
2816
  import { execSync as execSync2 } from "child_process";
2798
2817
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
2799
- import { join as join15 } from "path";
2818
+ import { dirname as dirname5, join as join15 } from "path";
2800
2819
  import chalk8 from "chalk";
2801
2820
  import ora3 from "ora";
2802
2821
  var POLL_INTERVAL_MS2 = 3e3;
@@ -2826,7 +2845,7 @@ function formatElapsed2(ms) {
2826
2845
  }
2827
2846
  async function sync() {
2828
2847
  const startTime = Date.now();
2829
- const spinner = ora3("Checking authentication...").start();
2848
+ const spinner = ora3({ text: "Checking authentication...", stream: process.stdout }).start();
2830
2849
  try {
2831
2850
  let credentials = await getValidCredentials2();
2832
2851
  if (!credentials) {
@@ -2957,16 +2976,18 @@ async function sync() {
2957
2976
  let downloadedCount = 0;
2958
2977
  let failedCount = 0;
2959
2978
  for (const file of files) {
2960
- if (file.fileName.includes("..") || file.fileName.includes("/")) {
2979
+ if (file.fileName.includes("..")) {
2961
2980
  failedCount++;
2962
2981
  continue;
2963
2982
  }
2964
- const urlResult = await apiRequest(`/v1/repos/${repoId}/context/${file.fileName}`);
2983
+ const urlResult = await apiRequest(`/v1/repos/${repoId}/context/files/${file.fileName}`);
2965
2984
  const presignedUrl = urlResult.data?.url ?? urlResult.url;
2966
2985
  const response = await fetch(presignedUrl);
2967
2986
  if (response.ok) {
2968
2987
  const content = await response.text();
2969
- writeFileSync3(join15(contextDir, file.fileName), content, "utf-8");
2988
+ const filePath = join15(contextDir, file.fileName);
2989
+ mkdirSync2(dirname5(filePath), { recursive: true });
2990
+ writeFileSync3(filePath, content, "utf-8");
2970
2991
  downloadedCount++;
2971
2992
  } else {
2972
2993
  failedCount++;
@@ -3184,7 +3205,7 @@ async function config() {
3184
3205
 
3185
3206
  // bin/repowise.ts
3186
3207
  var __filename = fileURLToPath3(import.meta.url);
3187
- var __dirname = dirname3(__filename);
3208
+ var __dirname = dirname6(__filename);
3188
3209
  var pkg = JSON.parse(readFileSync2(join16(__dirname, "..", "..", "package.json"), "utf-8"));
3189
3210
  var program = new Command();
3190
3211
  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.79",
3
+ "version": "0.1.80",
4
4
  "type": "module",
5
5
  "description": "AI-optimized codebase context generator",
6
6
  "bin": {