repowise 0.1.15 → 0.1.17
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 +158 -111
- package/package.json +3 -5
- package/scripts/postinstall.js +0 -29
package/dist/bin/repowise.js
CHANGED
|
@@ -39,12 +39,37 @@ var init_env = __esm({
|
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
+
// src/lib/config.ts
|
|
43
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
44
|
+
import { homedir } from "os";
|
|
45
|
+
import { join } from "path";
|
|
46
|
+
async function getConfig() {
|
|
47
|
+
try {
|
|
48
|
+
const data = await readFile(CONFIG_PATH, "utf-8");
|
|
49
|
+
return JSON.parse(data);
|
|
50
|
+
} catch {
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function saveConfig(config2) {
|
|
55
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
56
|
+
await writeFile(CONFIG_PATH, JSON.stringify(config2, null, 2));
|
|
57
|
+
}
|
|
58
|
+
var CONFIG_DIR, CONFIG_PATH;
|
|
59
|
+
var init_config = __esm({
|
|
60
|
+
"src/lib/config.ts"() {
|
|
61
|
+
"use strict";
|
|
62
|
+
CONFIG_DIR = join(homedir(), ".repowise");
|
|
63
|
+
CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
42
67
|
// src/lib/auth.ts
|
|
43
68
|
import { createHash, randomBytes } from "crypto";
|
|
44
|
-
import { readFile, writeFile, mkdir, chmod, unlink } from "fs/promises";
|
|
69
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, chmod, unlink } from "fs/promises";
|
|
45
70
|
import http from "http";
|
|
46
|
-
import { homedir } from "os";
|
|
47
|
-
import { join } from "path";
|
|
71
|
+
import { homedir as homedir2 } from "os";
|
|
72
|
+
import { join as join2 } from "path";
|
|
48
73
|
function getCognitoConfig() {
|
|
49
74
|
const env = getEnvConfig();
|
|
50
75
|
return {
|
|
@@ -204,7 +229,7 @@ async function refreshTokens(refreshToken) {
|
|
|
204
229
|
}
|
|
205
230
|
async function getStoredCredentials() {
|
|
206
231
|
try {
|
|
207
|
-
const data = await
|
|
232
|
+
const data = await readFile2(CREDENTIALS_PATH, "utf-8");
|
|
208
233
|
return JSON.parse(data);
|
|
209
234
|
} catch (err) {
|
|
210
235
|
if (err.code === "ENOENT" || err instanceof SyntaxError) {
|
|
@@ -214,8 +239,8 @@ async function getStoredCredentials() {
|
|
|
214
239
|
}
|
|
215
240
|
}
|
|
216
241
|
async function storeCredentials(credentials) {
|
|
217
|
-
await
|
|
218
|
-
await
|
|
242
|
+
await mkdir2(CONFIG_DIR2, { recursive: true, mode: 448 });
|
|
243
|
+
await writeFile2(CREDENTIALS_PATH, JSON.stringify(credentials, null, 2));
|
|
219
244
|
await chmod(CREDENTIALS_PATH, 384);
|
|
220
245
|
}
|
|
221
246
|
async function clearCredentials() {
|
|
@@ -308,13 +333,13 @@ function decodeIdToken(idToken) {
|
|
|
308
333
|
return { email: "unknown" };
|
|
309
334
|
}
|
|
310
335
|
}
|
|
311
|
-
var
|
|
336
|
+
var CONFIG_DIR2, CREDENTIALS_PATH, CLI_CALLBACK_PORT, CALLBACK_TIMEOUT_MS;
|
|
312
337
|
var init_auth = __esm({
|
|
313
338
|
"src/lib/auth.ts"() {
|
|
314
339
|
"use strict";
|
|
315
340
|
init_env();
|
|
316
|
-
|
|
317
|
-
CREDENTIALS_PATH =
|
|
341
|
+
CONFIG_DIR2 = join2(homedir2(), ".repowise");
|
|
342
|
+
CREDENTIALS_PATH = join2(CONFIG_DIR2, "credentials.json");
|
|
318
343
|
CLI_CALLBACK_PORT = 19876;
|
|
319
344
|
CALLBACK_TIMEOUT_MS = 12e4;
|
|
320
345
|
}
|
|
@@ -363,7 +388,7 @@ var init_api = __esm({
|
|
|
363
388
|
|
|
364
389
|
// src/lib/prompts.ts
|
|
365
390
|
import { checkbox, confirm } from "@inquirer/prompts";
|
|
366
|
-
import
|
|
391
|
+
import chalk2 from "chalk";
|
|
367
392
|
async function selectAiTools() {
|
|
368
393
|
const choices = [
|
|
369
394
|
{ name: "Cursor", value: "cursor" },
|
|
@@ -376,9 +401,9 @@ async function selectAiTools() {
|
|
|
376
401
|
{ name: "Other (manual setup)", value: "other" }
|
|
377
402
|
];
|
|
378
403
|
while (true) {
|
|
379
|
-
console.log(
|
|
404
|
+
console.log(chalk2.dim(" Use Space to select, Enter to continue.\n"));
|
|
380
405
|
const selected = await checkbox({
|
|
381
|
-
message:
|
|
406
|
+
message: chalk2.bold("Which AI tools do you use?"),
|
|
382
407
|
choices
|
|
383
408
|
});
|
|
384
409
|
if (selected.length === 0) {
|
|
@@ -400,8 +425,8 @@ var init_prompts = __esm({
|
|
|
400
425
|
});
|
|
401
426
|
|
|
402
427
|
// src/lib/ai-tools.ts
|
|
403
|
-
import { readFile as
|
|
404
|
-
import { join as
|
|
428
|
+
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3, readdir } from "fs/promises";
|
|
429
|
+
import { join as join3, dirname } from "path";
|
|
405
430
|
function sanitizeRepoName(name) {
|
|
406
431
|
return name.replace(/[<>[\]`()|\\]/g, "");
|
|
407
432
|
}
|
|
@@ -467,16 +492,16 @@ function generateReference(tool, repoName, contextFolder, contextFiles) {
|
|
|
467
492
|
}
|
|
468
493
|
async function updateToolConfig(repoRoot, tool, repoName, contextFolder, contextFiles) {
|
|
469
494
|
const config2 = AI_TOOL_CONFIG[tool];
|
|
470
|
-
const fullPath =
|
|
495
|
+
const fullPath = join3(repoRoot, config2.filePath);
|
|
471
496
|
const dir = dirname(fullPath);
|
|
472
497
|
if (dir !== repoRoot) {
|
|
473
|
-
await
|
|
498
|
+
await mkdir3(dir, { recursive: true });
|
|
474
499
|
}
|
|
475
500
|
const referenceBlock = generateReference(tool, repoName, contextFolder, contextFiles);
|
|
476
501
|
let existing = "";
|
|
477
502
|
let created = true;
|
|
478
503
|
try {
|
|
479
|
-
existing = await
|
|
504
|
+
existing = await readFile3(fullPath, "utf-8");
|
|
480
505
|
created = false;
|
|
481
506
|
} catch (err) {
|
|
482
507
|
if (err.code !== "ENOENT") throw err;
|
|
@@ -492,11 +517,11 @@ async function updateToolConfig(repoRoot, tool, repoName, contextFolder, context
|
|
|
492
517
|
const separator = existing.length > 0 && !existing.endsWith("\n") ? "\n\n" : existing.length > 0 ? "\n" : "";
|
|
493
518
|
content = existing + separator + referenceBlock + "\n";
|
|
494
519
|
}
|
|
495
|
-
await
|
|
520
|
+
await writeFile3(fullPath, content, "utf-8");
|
|
496
521
|
return { created };
|
|
497
522
|
}
|
|
498
523
|
async function scanLocalContextFiles(repoRoot, contextFolder) {
|
|
499
|
-
const folderPath =
|
|
524
|
+
const folderPath = join3(repoRoot, contextFolder);
|
|
500
525
|
try {
|
|
501
526
|
const entries = await readdir(folderPath, { withFileTypes: true });
|
|
502
527
|
return entries.filter((e) => e.isFile() && e.name.endsWith(".md")).map((e) => ({
|
|
@@ -574,59 +599,34 @@ var init_ai_tools = __esm({
|
|
|
574
599
|
}
|
|
575
600
|
});
|
|
576
601
|
|
|
577
|
-
// src/lib/config.ts
|
|
578
|
-
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
579
|
-
import { homedir as homedir2 } from "os";
|
|
580
|
-
import { join as join3 } from "path";
|
|
581
|
-
async function getConfig() {
|
|
582
|
-
try {
|
|
583
|
-
const data = await readFile3(CONFIG_PATH, "utf-8");
|
|
584
|
-
return JSON.parse(data);
|
|
585
|
-
} catch {
|
|
586
|
-
return {};
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
async function saveConfig(config2) {
|
|
590
|
-
await mkdir3(CONFIG_DIR2, { recursive: true });
|
|
591
|
-
await writeFile3(CONFIG_PATH, JSON.stringify(config2, null, 2));
|
|
592
|
-
}
|
|
593
|
-
var CONFIG_DIR2, CONFIG_PATH;
|
|
594
|
-
var init_config = __esm({
|
|
595
|
-
"src/lib/config.ts"() {
|
|
596
|
-
"use strict";
|
|
597
|
-
CONFIG_DIR2 = join3(homedir2(), ".repowise");
|
|
598
|
-
CONFIG_PATH = join3(CONFIG_DIR2, "config.json");
|
|
599
|
-
}
|
|
600
|
-
});
|
|
601
|
-
|
|
602
602
|
// src/lib/interview-handler.ts
|
|
603
|
-
import
|
|
603
|
+
import chalk3 from "chalk";
|
|
604
604
|
import { input } from "@inquirer/prompts";
|
|
605
605
|
async function handleInterview(syncId, questionId, questionText, questionContext, estimatedQuestions) {
|
|
606
606
|
questionCounter++;
|
|
607
607
|
if (questionCounter === 1) {
|
|
608
608
|
console.log("");
|
|
609
|
-
console.log(
|
|
610
|
-
console.log(
|
|
609
|
+
console.log(chalk3.cyan.bold(" \u2500\u2500 Interview \u2500\u2500"));
|
|
610
|
+
console.log(chalk3.dim(" Help us understand your project better. Answer a few short"));
|
|
611
611
|
console.log(
|
|
612
|
-
|
|
612
|
+
chalk3.dim(
|
|
613
613
|
` questions so we can generate more relevant context files (up to ${MAX_QUESTIONS}).`
|
|
614
614
|
)
|
|
615
615
|
);
|
|
616
616
|
}
|
|
617
617
|
const total = Math.min(estimatedQuestions ?? MAX_QUESTIONS, MAX_QUESTIONS);
|
|
618
618
|
console.log("");
|
|
619
|
-
console.log(
|
|
619
|
+
console.log(chalk3.cyan.bold(` Question ${questionCounter}/${total}`));
|
|
620
620
|
if (questionContext) {
|
|
621
|
-
console.log(
|
|
621
|
+
console.log(chalk3.dim(` ${questionContext}`));
|
|
622
622
|
}
|
|
623
623
|
console.log(` ${questionText}`);
|
|
624
|
-
console.log(
|
|
624
|
+
console.log(chalk3.dim(' (Enter to skip \xB7 "done" to finish early)'));
|
|
625
625
|
let answer;
|
|
626
626
|
try {
|
|
627
627
|
answer = await Promise.race([
|
|
628
628
|
input({
|
|
629
|
-
message:
|
|
629
|
+
message: chalk3.cyan(">"),
|
|
630
630
|
theme: { prefix: " " }
|
|
631
631
|
}),
|
|
632
632
|
new Promise(
|
|
@@ -635,7 +635,7 @@ async function handleInterview(syncId, questionId, questionText, questionContext
|
|
|
635
635
|
]);
|
|
636
636
|
} catch (err) {
|
|
637
637
|
if (err instanceof Error && err.message === "INTERVIEW_TIMEOUT") {
|
|
638
|
-
console.log(
|
|
638
|
+
console.log(chalk3.yellow(" Timed out \u2014 auto-skipping this question."));
|
|
639
639
|
answer = "skip";
|
|
640
640
|
} else {
|
|
641
641
|
throw err;
|
|
@@ -654,7 +654,7 @@ async function handleInterview(syncId, questionId, questionText, questionContext
|
|
|
654
654
|
}
|
|
655
655
|
if (questionCounter >= MAX_QUESTIONS && action !== "done") {
|
|
656
656
|
action = "done";
|
|
657
|
-
console.log(
|
|
657
|
+
console.log(chalk3.green(" Thanks for your answers! Wrapping up the interview."));
|
|
658
658
|
}
|
|
659
659
|
try {
|
|
660
660
|
await apiRequest(`/v1/sync/${syncId}/answer`, {
|
|
@@ -664,7 +664,7 @@ async function handleInterview(syncId, questionId, questionText, questionContext
|
|
|
664
664
|
} catch (err) {
|
|
665
665
|
const message = err instanceof Error ? err.message : String(err);
|
|
666
666
|
if (message.includes("not awaiting input") || message.includes("expired")) {
|
|
667
|
-
console.log(
|
|
667
|
+
console.log(chalk3.dim(" Pipeline has already moved on \u2014 continuing."));
|
|
668
668
|
return;
|
|
669
669
|
}
|
|
670
670
|
try {
|
|
@@ -674,16 +674,16 @@ async function handleInterview(syncId, questionId, questionText, questionContext
|
|
|
674
674
|
body: JSON.stringify({ questionId, answerText, action })
|
|
675
675
|
});
|
|
676
676
|
} catch {
|
|
677
|
-
console.log(
|
|
677
|
+
console.log(chalk3.yellow(" Could not submit answer \u2014 pipeline will continue."));
|
|
678
678
|
return;
|
|
679
679
|
}
|
|
680
680
|
}
|
|
681
681
|
if (action === "done") {
|
|
682
|
-
console.log(
|
|
682
|
+
console.log(chalk3.dim(" Interview ended early."));
|
|
683
683
|
} else if (action === "skip") {
|
|
684
|
-
console.log(
|
|
684
|
+
console.log(chalk3.dim(" Skipped."));
|
|
685
685
|
} else {
|
|
686
|
-
console.log(
|
|
686
|
+
console.log(chalk3.dim(" Answer recorded."));
|
|
687
687
|
}
|
|
688
688
|
console.log("");
|
|
689
689
|
}
|
|
@@ -699,7 +699,7 @@ var init_interview_handler = __esm({
|
|
|
699
699
|
});
|
|
700
700
|
|
|
701
701
|
// src/lib/progress-renderer.ts
|
|
702
|
-
import
|
|
702
|
+
import chalk4 from "chalk";
|
|
703
703
|
var ProgressRenderer;
|
|
704
704
|
var init_progress_renderer = __esm({
|
|
705
705
|
"src/lib/progress-renderer.ts"() {
|
|
@@ -716,13 +716,13 @@ var init_progress_renderer = __esm({
|
|
|
716
716
|
this.privacyShieldShown = true;
|
|
717
717
|
spinner.stop();
|
|
718
718
|
console.log("");
|
|
719
|
-
console.log(
|
|
719
|
+
console.log(chalk4.cyan.bold(" \u2500\u2500 Privacy Shield \u2500\u2500"));
|
|
720
720
|
if (enabled) {
|
|
721
|
-
console.log(` ${
|
|
722
|
-
console.log(` ${
|
|
721
|
+
console.log(` ${chalk4.green("\u2713")} Privacy Shield active`);
|
|
722
|
+
console.log(` ${chalk4.green("\u2713")} Private connection established`);
|
|
723
723
|
} else {
|
|
724
|
-
console.log(` ${
|
|
725
|
-
console.log(
|
|
724
|
+
console.log(` ${chalk4.yellow("\u2139")} Privacy Shield not in current plan`);
|
|
725
|
+
console.log(chalk4.dim(" Shield your data from the open internet."));
|
|
726
726
|
}
|
|
727
727
|
console.log("");
|
|
728
728
|
spinner.start();
|
|
@@ -732,21 +732,21 @@ var init_progress_renderer = __esm({
|
|
|
732
732
|
this.discoveryShown = true;
|
|
733
733
|
spinner.stop();
|
|
734
734
|
console.log("");
|
|
735
|
-
console.log(
|
|
735
|
+
console.log(chalk4.cyan.bold(" \u2500\u2500 Repository Discovery \u2500\u2500"));
|
|
736
736
|
if (result.languages.length > 0) {
|
|
737
737
|
const langs = result.languages.slice(0, 5).map((l) => `${l.name} (${Math.round(l.percentage)}%)`).join(", ");
|
|
738
|
-
console.log(` ${
|
|
738
|
+
console.log(` ${chalk4.dim("Languages:")} ${langs}`);
|
|
739
739
|
}
|
|
740
740
|
if (result.frameworks.length > 0) {
|
|
741
741
|
console.log(
|
|
742
|
-
` ${
|
|
742
|
+
` ${chalk4.dim("Frameworks:")} ${result.frameworks.map((f) => f.name).join(", ")}`
|
|
743
743
|
);
|
|
744
744
|
}
|
|
745
745
|
console.log(
|
|
746
|
-
` ${
|
|
746
|
+
` ${chalk4.dim("Structure:")} ${result.structureType} ${chalk4.dim(`(${result.fileCount} files)`)}`
|
|
747
747
|
);
|
|
748
748
|
if (result.existingDocs.length > 0) {
|
|
749
|
-
console.log(` ${
|
|
749
|
+
console.log(` ${chalk4.dim("Existing docs:")} ${result.existingDocs.join(", ")}`);
|
|
750
750
|
}
|
|
751
751
|
if (result.fileTree && result.fileTree.length > 0) {
|
|
752
752
|
this.renderTree(result.fileTree);
|
|
@@ -756,7 +756,7 @@ var init_progress_renderer = __esm({
|
|
|
756
756
|
}
|
|
757
757
|
renderTree(entries) {
|
|
758
758
|
console.log("");
|
|
759
|
-
console.log(
|
|
759
|
+
console.log(chalk4.cyan.bold(" \u2500\u2500 Project Structure \u2500\u2500"));
|
|
760
760
|
const root = { name: "", type: "tree", children: /* @__PURE__ */ new Map() };
|
|
761
761
|
for (const entry of entries) {
|
|
762
762
|
const parts = entry.path.split("/");
|
|
@@ -776,7 +776,7 @@ var init_progress_renderer = __esm({
|
|
|
776
776
|
}
|
|
777
777
|
const printNode = (node, prefix, isLast) => {
|
|
778
778
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
779
|
-
const display = node.type === "tree" ?
|
|
779
|
+
const display = node.type === "tree" ? chalk4.bold.dim(`${node.name}/`) : node.name;
|
|
780
780
|
console.log(` ${prefix}${connector}${display}`);
|
|
781
781
|
const sorted = [...node.children.values()].sort((a, b) => {
|
|
782
782
|
if (a.type === "tree" && b.type !== "tree") return -1;
|
|
@@ -802,7 +802,7 @@ var init_progress_renderer = __esm({
|
|
|
802
802
|
this.scanSummaryShown = true;
|
|
803
803
|
spinner.stop();
|
|
804
804
|
console.log(
|
|
805
|
-
|
|
805
|
+
chalk4.dim(
|
|
806
806
|
` Scan complete: ${summary.totalFiles} files, ${summary.totalFunctions} functions, ${summary.totalClasses} classes, ${summary.totalEndpoints} endpoints`
|
|
807
807
|
)
|
|
808
808
|
);
|
|
@@ -813,15 +813,15 @@ var init_progress_renderer = __esm({
|
|
|
813
813
|
if (progress.status === "complete" && !this.validationShown) {
|
|
814
814
|
this.validationShown = true;
|
|
815
815
|
spinner.stop();
|
|
816
|
-
console.log(
|
|
816
|
+
console.log(chalk4.cyan.bold(" \u2500\u2500 Validation Results \u2500\u2500"));
|
|
817
817
|
for (const result of progress.personaResults) {
|
|
818
|
-
const scoreColor = result.score === "PASS" ?
|
|
818
|
+
const scoreColor = result.score === "PASS" ? chalk4.green : result.score === "PARTIAL" ? chalk4.yellow : chalk4.red;
|
|
819
819
|
console.log(` ${result.persona}: ${scoreColor(result.score)}`);
|
|
820
820
|
}
|
|
821
821
|
const passCount = progress.personaResults.filter((r) => r.score === "PASS").length;
|
|
822
822
|
const total = progress.personaResults.length;
|
|
823
823
|
const roundInfo = progress.round > 1 ? ` (${progress.round} rounds)` : "";
|
|
824
|
-
console.log(
|
|
824
|
+
console.log(chalk4.dim(` ${passCount}/${total} PASS${roundInfo}`));
|
|
825
825
|
console.log("");
|
|
826
826
|
spinner.start();
|
|
827
827
|
return;
|
|
@@ -853,7 +853,7 @@ var init_progress_renderer = __esm({
|
|
|
853
853
|
progressText = `Validation round ${vp.round}/${vp.maxRounds}`;
|
|
854
854
|
}
|
|
855
855
|
}
|
|
856
|
-
return `${progressText}... ${
|
|
856
|
+
return `${progressText}... ${chalk4.dim(`(${pct}%)`)}`;
|
|
857
857
|
}
|
|
858
858
|
update(syncResult, spinner) {
|
|
859
859
|
if (syncResult.privacyShieldEnabled !== void 0) {
|
|
@@ -1234,7 +1234,7 @@ __export(create_exports, {
|
|
|
1234
1234
|
create: () => create
|
|
1235
1235
|
});
|
|
1236
1236
|
import { execSync } from "child_process";
|
|
1237
|
-
import
|
|
1237
|
+
import chalk5 from "chalk";
|
|
1238
1238
|
import ora from "ora";
|
|
1239
1239
|
function detectRepoRoot() {
|
|
1240
1240
|
return execSync("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
|
|
@@ -1264,10 +1264,10 @@ async function create() {
|
|
|
1264
1264
|
try {
|
|
1265
1265
|
let credentials = await getValidCredentials();
|
|
1266
1266
|
if (!credentials) {
|
|
1267
|
-
spinner.info(
|
|
1267
|
+
spinner.info(chalk5.yellow("Not logged in. Opening browser to authenticate..."));
|
|
1268
1268
|
credentials = await performLogin();
|
|
1269
1269
|
const { email } = decodeIdToken(credentials.idToken);
|
|
1270
|
-
spinner.succeed(
|
|
1270
|
+
spinner.succeed(chalk5.green(`Authenticated as ${chalk5.bold(email)}`));
|
|
1271
1271
|
} else {
|
|
1272
1272
|
spinner.succeed("Authenticated");
|
|
1273
1273
|
}
|
|
@@ -1280,7 +1280,7 @@ async function create() {
|
|
|
1280
1280
|
if (pending?.repoId) {
|
|
1281
1281
|
repoId = pending.repoId;
|
|
1282
1282
|
repoName = pending.repoName;
|
|
1283
|
-
spinner.succeed(`Found pending repository: ${
|
|
1283
|
+
spinner.succeed(`Found pending repository: ${chalk5.bold(repoName)}`);
|
|
1284
1284
|
apiRequest("/v1/onboarding/pending", { method: "DELETE" }).catch(() => {
|
|
1285
1285
|
});
|
|
1286
1286
|
}
|
|
@@ -1291,10 +1291,10 @@ async function create() {
|
|
|
1291
1291
|
try {
|
|
1292
1292
|
repoRoot = detectRepoRoot();
|
|
1293
1293
|
repoName = detectRepoName(repoRoot);
|
|
1294
|
-
spinner.succeed(`Repository: ${
|
|
1294
|
+
spinner.succeed(`Repository: ${chalk5.bold(repoName)}`);
|
|
1295
1295
|
} catch {
|
|
1296
1296
|
spinner.fail(
|
|
1297
|
-
|
|
1297
|
+
chalk5.red(
|
|
1298
1298
|
"Not in a git repository. Run this command from your repo directory, or select a repo on the dashboard first."
|
|
1299
1299
|
)
|
|
1300
1300
|
);
|
|
@@ -1317,7 +1317,7 @@ async function create() {
|
|
|
1317
1317
|
}
|
|
1318
1318
|
if (!repoId) {
|
|
1319
1319
|
spinner.fail(
|
|
1320
|
-
|
|
1320
|
+
chalk5.red(
|
|
1321
1321
|
"Could not find this repository in your RepoWise account. Connect it on the dashboard first."
|
|
1322
1322
|
)
|
|
1323
1323
|
);
|
|
@@ -1327,14 +1327,14 @@ async function create() {
|
|
|
1327
1327
|
const { tools, hasOther } = await selectAiTools();
|
|
1328
1328
|
if (hasOther) {
|
|
1329
1329
|
console.log(
|
|
1330
|
-
|
|
1330
|
+
chalk5.cyan(
|
|
1331
1331
|
"\nFor AI tools not listed, context files still work with any tool that reads the filesystem.\nRequest support for your tool at: https://dashboard.repowise.ai/support/ai-tools"
|
|
1332
1332
|
)
|
|
1333
1333
|
);
|
|
1334
1334
|
}
|
|
1335
1335
|
if (tools.length === 0 && !hasOther) {
|
|
1336
1336
|
console.log(
|
|
1337
|
-
|
|
1337
|
+
chalk5.yellow(
|
|
1338
1338
|
"\nNo AI tools selected. You can configure them later with `repowise config`."
|
|
1339
1339
|
)
|
|
1340
1340
|
);
|
|
@@ -1363,14 +1363,14 @@ async function create() {
|
|
|
1363
1363
|
throw new Error("Could not find active sync to resume. Please try again.");
|
|
1364
1364
|
}
|
|
1365
1365
|
syncId = active.syncId;
|
|
1366
|
-
spinner.info(
|
|
1366
|
+
spinner.info(chalk5.cyan("Resuming existing pipeline..."));
|
|
1367
1367
|
spinner.start();
|
|
1368
1368
|
}
|
|
1369
1369
|
let pollAttempts = 0;
|
|
1370
1370
|
const progressRenderer = new ProgressRenderer();
|
|
1371
1371
|
while (true) {
|
|
1372
1372
|
if (++pollAttempts > MAX_POLL_ATTEMPTS) {
|
|
1373
|
-
spinner.fail(
|
|
1373
|
+
spinner.fail(chalk5.red("Pipeline timed out. Check dashboard for status."));
|
|
1374
1374
|
process.exitCode = 1;
|
|
1375
1375
|
return;
|
|
1376
1376
|
}
|
|
@@ -1394,7 +1394,7 @@ async function create() {
|
|
|
1394
1394
|
break;
|
|
1395
1395
|
}
|
|
1396
1396
|
if (syncResult.status === "failed") {
|
|
1397
|
-
spinner.fail(
|
|
1397
|
+
spinner.fail(chalk5.red(`Pipeline failed: ${syncResult.error ?? "Unknown error"}`));
|
|
1398
1398
|
process.exitCode = 1;
|
|
1399
1399
|
return;
|
|
1400
1400
|
}
|
|
@@ -1413,7 +1413,7 @@ async function create() {
|
|
|
1413
1413
|
const stderr = err instanceof Error && "stderr" in err ? String(err.stderr).trim() : "";
|
|
1414
1414
|
const reason = stderr || (err instanceof Error ? err.message : "Unknown error");
|
|
1415
1415
|
spinner.warn(
|
|
1416
|
-
|
|
1416
|
+
chalk5.yellow(
|
|
1417
1417
|
`Could not pull latest changes: ${reason}
|
|
1418
1418
|
You may need to run \`git pull\` manually.`
|
|
1419
1419
|
)
|
|
@@ -1441,7 +1441,7 @@ You may need to run \`git pull\` manually.`
|
|
|
1441
1441
|
results.push(` ${action} ${config2.filePath}`);
|
|
1442
1442
|
}
|
|
1443
1443
|
spinner.succeed("AI tools configured");
|
|
1444
|
-
console.log(
|
|
1444
|
+
console.log(chalk5.dim(results.join("\n")));
|
|
1445
1445
|
}
|
|
1446
1446
|
const existingConfig = await getConfig();
|
|
1447
1447
|
await saveConfig({
|
|
@@ -1458,37 +1458,37 @@ You may need to run \`git pull\` manually.`
|
|
|
1458
1458
|
listenerRunning = true;
|
|
1459
1459
|
} catch {
|
|
1460
1460
|
console.log(
|
|
1461
|
-
|
|
1461
|
+
chalk5.yellow(
|
|
1462
1462
|
"Warning: Could not start listener automatically. Run the following to enable it:"
|
|
1463
1463
|
)
|
|
1464
1464
|
);
|
|
1465
|
-
console.log(
|
|
1465
|
+
console.log(chalk5.yellow(` $ repowise listen --install`));
|
|
1466
1466
|
}
|
|
1467
1467
|
const elapsed = formatElapsed(Date.now() - startTime);
|
|
1468
1468
|
console.log("");
|
|
1469
|
-
console.log(
|
|
1469
|
+
console.log(chalk5.green.bold(" All done! Setup complete!"));
|
|
1470
1470
|
console.log(
|
|
1471
|
-
|
|
1472
|
-
` Your AI tools now have access to project context for ${
|
|
1471
|
+
chalk5.green(
|
|
1472
|
+
` Your AI tools now have access to project context for ${chalk5.bold(repoName)}.`
|
|
1473
1473
|
)
|
|
1474
1474
|
);
|
|
1475
1475
|
if (listenerRunning) {
|
|
1476
1476
|
console.log("");
|
|
1477
|
-
console.log(
|
|
1478
|
-
console.log(
|
|
1479
|
-
console.log(
|
|
1477
|
+
console.log(chalk5.cyan(" The RepoWise listener is running in the background \u2014"));
|
|
1478
|
+
console.log(chalk5.cyan(" your context will stay in sync automatically."));
|
|
1479
|
+
console.log(chalk5.cyan(" Go back to coding, we've got it from here!"));
|
|
1480
1480
|
}
|
|
1481
1481
|
console.log("");
|
|
1482
1482
|
console.log(
|
|
1483
|
-
|
|
1483
|
+
chalk5.cyan(
|
|
1484
1484
|
' Head back to the dashboard and click "Complete Onboarding" to explore your RepoWise dashboard!'
|
|
1485
1485
|
)
|
|
1486
1486
|
);
|
|
1487
|
-
console.log(
|
|
1487
|
+
console.log(chalk5.dim(`
|
|
1488
1488
|
Total time: ${elapsed}`));
|
|
1489
1489
|
} catch (err) {
|
|
1490
1490
|
const message = err instanceof Error ? err.message : "Create failed";
|
|
1491
|
-
spinner.fail(
|
|
1491
|
+
spinner.fail(chalk5.red(message));
|
|
1492
1492
|
process.exitCode = 1;
|
|
1493
1493
|
}
|
|
1494
1494
|
}
|
|
@@ -1514,7 +1514,7 @@ var login_exports = {};
|
|
|
1514
1514
|
__export(login_exports, {
|
|
1515
1515
|
login: () => login
|
|
1516
1516
|
});
|
|
1517
|
-
import
|
|
1517
|
+
import chalk6 from "chalk";
|
|
1518
1518
|
import ora2 from "ora";
|
|
1519
1519
|
async function login(options = {}) {
|
|
1520
1520
|
const spinner = ora2("Preparing login...").start();
|
|
@@ -1529,7 +1529,7 @@ async function login(options = {}) {
|
|
|
1529
1529
|
console.log(`
|
|
1530
1530
|
Open this URL in your browser to authenticate:
|
|
1531
1531
|
`);
|
|
1532
|
-
console.log(
|
|
1532
|
+
console.log(chalk6.cyan(authorizeUrl));
|
|
1533
1533
|
console.log(`
|
|
1534
1534
|
Waiting for authentication...`);
|
|
1535
1535
|
} else {
|
|
@@ -1543,7 +1543,7 @@ Waiting for authentication...`);
|
|
|
1543
1543
|
console.log(`
|
|
1544
1544
|
Could not open browser automatically. Open this URL:
|
|
1545
1545
|
`);
|
|
1546
|
-
console.log(
|
|
1546
|
+
console.log(chalk6.cyan(authorizeUrl));
|
|
1547
1547
|
console.log(`
|
|
1548
1548
|
Waiting for authentication...`);
|
|
1549
1549
|
}
|
|
@@ -1556,10 +1556,10 @@ Waiting for authentication...`);
|
|
|
1556
1556
|
const credentials = await exchangeCodeForTokens(code, codeVerifier);
|
|
1557
1557
|
await storeCredentials(credentials);
|
|
1558
1558
|
const { email } = decodeIdToken(credentials.idToken);
|
|
1559
|
-
spinner.succeed(
|
|
1559
|
+
spinner.succeed(chalk6.green(`Logged in as ${chalk6.bold(email)}`));
|
|
1560
1560
|
} catch (err) {
|
|
1561
1561
|
const message = err instanceof Error ? err.message : "Login failed";
|
|
1562
|
-
spinner.fail(
|
|
1562
|
+
spinner.fail(chalk6.red(message));
|
|
1563
1563
|
process.exitCode = 1;
|
|
1564
1564
|
}
|
|
1565
1565
|
}
|
|
@@ -1575,15 +1575,15 @@ var logout_exports = {};
|
|
|
1575
1575
|
__export(logout_exports, {
|
|
1576
1576
|
logout: () => logout
|
|
1577
1577
|
});
|
|
1578
|
-
import
|
|
1578
|
+
import chalk7 from "chalk";
|
|
1579
1579
|
async function logout() {
|
|
1580
1580
|
const creds = await getStoredCredentials();
|
|
1581
1581
|
if (!creds) {
|
|
1582
|
-
console.log(
|
|
1582
|
+
console.log(chalk7.yellow("Not logged in."));
|
|
1583
1583
|
return;
|
|
1584
1584
|
}
|
|
1585
1585
|
await clearCredentials();
|
|
1586
|
-
console.log(
|
|
1586
|
+
console.log(chalk7.green("Logged out successfully."));
|
|
1587
1587
|
}
|
|
1588
1588
|
var init_logout = __esm({
|
|
1589
1589
|
"src/commands/logout.ts"() {
|
|
@@ -2320,11 +2320,58 @@ var init_config3 = __esm({
|
|
|
2320
2320
|
// bin/repowise.ts
|
|
2321
2321
|
init_env();
|
|
2322
2322
|
import { Command } from "commander";
|
|
2323
|
+
import { readFileSync } from "fs";
|
|
2324
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2325
|
+
import { dirname as dirname2, join as join12 } from "path";
|
|
2326
|
+
|
|
2327
|
+
// src/lib/welcome.ts
|
|
2328
|
+
init_config();
|
|
2329
|
+
import chalk from "chalk";
|
|
2330
|
+
async function showWelcome(currentVersion) {
|
|
2331
|
+
try {
|
|
2332
|
+
const config2 = await getConfig();
|
|
2333
|
+
if (config2.lastSeenVersion === currentVersion) return;
|
|
2334
|
+
const isUpgrade = !!config2.lastSeenVersion;
|
|
2335
|
+
console.log("");
|
|
2336
|
+
console.log(chalk.cyan(" \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E"));
|
|
2337
|
+
console.log(chalk.cyan(" \u2502 \u2502"));
|
|
2338
|
+
if (isUpgrade) {
|
|
2339
|
+
console.log(
|
|
2340
|
+
chalk.cyan(" \u2502 ") + chalk.bold(`RepoWise v${currentVersion}`) + chalk.green(" \u2713 updated") + chalk.cyan(" \u2502")
|
|
2341
|
+
);
|
|
2342
|
+
} else {
|
|
2343
|
+
console.log(
|
|
2344
|
+
chalk.cyan(" \u2502 ") + chalk.bold(`RepoWise v${currentVersion}`) + chalk.green(" \u2713 installed") + chalk.cyan(" \u2502")
|
|
2345
|
+
);
|
|
2346
|
+
}
|
|
2347
|
+
console.log(chalk.cyan(" \u2502 \u2502"));
|
|
2348
|
+
console.log(chalk.cyan(" \u2502 ") + chalk.dim("Get started:") + chalk.cyan(" \u2502"));
|
|
2349
|
+
console.log(
|
|
2350
|
+
chalk.cyan(" \u2502 $ ") + chalk.bold("repowise create") + chalk.cyan(" \u2502")
|
|
2351
|
+
);
|
|
2352
|
+
console.log(chalk.cyan(" \u2502 \u2502"));
|
|
2353
|
+
console.log(
|
|
2354
|
+
chalk.cyan(" \u2502 ") + chalk.dim("Thank you for using RepoWise!") + chalk.cyan(" \u2502")
|
|
2355
|
+
);
|
|
2356
|
+
console.log(chalk.cyan(" \u2502 ") + chalk.dim("https://repowise.ai") + chalk.cyan(" \u2502"));
|
|
2357
|
+
console.log(chalk.cyan(" \u2502 \u2502"));
|
|
2358
|
+
console.log(chalk.cyan(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
|
|
2359
|
+
console.log("");
|
|
2360
|
+
await saveConfig({ ...config2, lastSeenVersion: currentVersion });
|
|
2361
|
+
} catch {
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
// bin/repowise.ts
|
|
2366
|
+
var __filename = fileURLToPath3(import.meta.url);
|
|
2367
|
+
var __dirname = dirname2(__filename);
|
|
2368
|
+
var pkg = JSON.parse(readFileSync(join12(__dirname, "..", "package.json"), "utf-8"));
|
|
2323
2369
|
var program = new Command();
|
|
2324
|
-
program.name("repowise").description("AI-optimized codebase context generator").version(
|
|
2370
|
+
program.name("repowise").description("AI-optimized codebase context generator").version(pkg.version).option("--staging", "Use the staging environment").hook("preAction", async () => {
|
|
2325
2371
|
if (program.opts()["staging"]) {
|
|
2326
2372
|
setStagingMode(true);
|
|
2327
2373
|
}
|
|
2374
|
+
await showWelcome(pkg.version);
|
|
2328
2375
|
});
|
|
2329
2376
|
program.command("create").description("Create context for a repository").action(async () => {
|
|
2330
2377
|
const { create: create2 } = await Promise.resolve().then(() => (init_create(), create_exports));
|
package/package.json
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "repowise",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AI-optimized codebase context generator",
|
|
6
6
|
"bin": {
|
|
7
7
|
"repowise": "dist/bin/repowise.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"dist"
|
|
11
|
-
"scripts/postinstall.js"
|
|
10
|
+
"dist"
|
|
12
11
|
],
|
|
13
12
|
"scripts": {
|
|
14
13
|
"build": "tsc",
|
|
15
14
|
"build:bundle": "tsup",
|
|
16
15
|
"lint": "eslint src/ bin/",
|
|
17
16
|
"test": "vitest run",
|
|
18
|
-
"type-check": "tsc --noEmit"
|
|
19
|
-
"postinstall": "node scripts/postinstall.js"
|
|
17
|
+
"type-check": "tsc --noEmit"
|
|
20
18
|
},
|
|
21
19
|
"dependencies": {
|
|
22
20
|
"chalk": "^5.4.0",
|
package/scripts/postinstall.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// Lightweight postinstall banner — no dependencies, plain ANSI codes
|
|
4
|
-
const version = process.env.npm_package_version || '';
|
|
5
|
-
|
|
6
|
-
const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
|
|
7
|
-
const bold = (s) => `\x1b[1m${s}\x1b[0m`;
|
|
8
|
-
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
9
|
-
const green = (s) => `\x1b[32m${s}\x1b[0m`;
|
|
10
|
-
|
|
11
|
-
const v = version ? ` v${version}` : '';
|
|
12
|
-
|
|
13
|
-
try {
|
|
14
|
-
console.log('');
|
|
15
|
-
console.log(cyan(' ╭─────────────────────────────────────────╮'));
|
|
16
|
-
console.log(cyan(' │ │'));
|
|
17
|
-
console.log(cyan(' │ ') + bold(`RepoWise${v} installed`) + green(' ✓') + cyan(' │'));
|
|
18
|
-
console.log(cyan(' │ │'));
|
|
19
|
-
console.log(cyan(' │ ') + dim('Get started:') + cyan(' │'));
|
|
20
|
-
console.log(cyan(' │ $ ') + bold('repowise create') + cyan(' │'));
|
|
21
|
-
console.log(cyan(' │ │'));
|
|
22
|
-
console.log(cyan(' │ ') + dim('Thank you for using RepoWise!') + cyan(' │'));
|
|
23
|
-
console.log(cyan(' │ ') + dim('https://repowise.ai') + cyan(' │'));
|
|
24
|
-
console.log(cyan(' │ │'));
|
|
25
|
-
console.log(cyan(' ╰─────────────────────────────────────────╯'));
|
|
26
|
-
console.log('');
|
|
27
|
-
} catch {
|
|
28
|
-
// Never fail installation on a cosmetic banner
|
|
29
|
-
}
|