@novastorm-ai/cli 0.1.3 → 0.1.5
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/nova.js +3 -3
- package/dist/{chunk-7K55GHF5.js → chunk-ACJAMJVU.js} +3 -2
- package/dist/{chunk-HVDG2MLB.js → chunk-J573S7XU.js} +181 -57
- package/dist/{chunk-DQXTUNZA.js → chunk-RZGTRPQL.js} +1 -1
- package/dist/{dist-NNJKY4T4.js → dist-IDA76B3L.js} +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -3
- package/dist/{package-BSAVJZ7S.js → package-K5FGL7BD.js} +1 -1
- package/dist/{setup-VJMYSGJI.js → setup-DNA6KT2A.js} +2 -2
- package/package.json +1 -1
package/dist/bin/nova.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
run
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-J573S7XU.js";
|
|
5
5
|
import "../chunk-KE7XWO5N.js";
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
import "../chunk-RZGTRPQL.js";
|
|
7
|
+
import "../chunk-ACJAMJVU.js";
|
|
8
8
|
import "../chunk-3RG5ZIWI.js";
|
|
9
9
|
|
|
10
10
|
// bin/nova.ts
|
|
@@ -6201,7 +6201,7 @@ Available packages: ${deps}`);
|
|
|
6201
6201
|
return parts.join("\n");
|
|
6202
6202
|
}
|
|
6203
6203
|
var Lane3Executor = class {
|
|
6204
|
-
constructor(projectPath, llmClient, gitManager, eventBus, maxFixIterations = 3, modelName, agentPromptLoader, pathGuard, commitQueue) {
|
|
6204
|
+
constructor(projectPath, llmClient, gitManager, eventBus, maxFixIterations = 3, modelName, agentPromptLoader, pathGuard, commitQueue, forceSkipValidation = false) {
|
|
6205
6205
|
this.projectPath = projectPath;
|
|
6206
6206
|
this.llmClient = llmClient;
|
|
6207
6207
|
this.gitManager = gitManager;
|
|
@@ -6210,6 +6210,7 @@ var Lane3Executor = class {
|
|
|
6210
6210
|
this.modelName = modelName;
|
|
6211
6211
|
this.agentPromptLoader = agentPromptLoader;
|
|
6212
6212
|
this.pathGuard = pathGuard;
|
|
6213
|
+
this.forceSkipValidation = forceSkipValidation;
|
|
6213
6214
|
this.diffApplier = new DiffApplier();
|
|
6214
6215
|
this.commitQueue = commitQueue ?? new CommitQueue(this.gitManager);
|
|
6215
6216
|
}
|
|
@@ -6317,7 +6318,7 @@ Remember: Output ONLY === FILE === or === DIFF === blocks. No text, no explanati
|
|
|
6317
6318
|
if (missingVars.length > 0 && this.eventBus) {
|
|
6318
6319
|
this.eventBus.emit({ type: "secrets_required", data: { envVars: missingVars, taskId: task.id } });
|
|
6319
6320
|
}
|
|
6320
|
-
const skipValidation = fileBlocks.length === 1 && fileBlocks[0].content.length < 3e3;
|
|
6321
|
+
const skipValidation = this.forceSkipValidation || fileBlocks.length === 1 && fileBlocks[0].content.length < 3e3;
|
|
6321
6322
|
const tscSkip = this.shouldSkipTsc(fileBlocks);
|
|
6322
6323
|
const validator = new CodeValidator(this.projectPath);
|
|
6323
6324
|
const fixer = new CodeFixer(this.llmClient, this.eventBus);
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
ConfigReader,
|
|
8
8
|
runSetup
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RZGTRPQL.js";
|
|
10
10
|
import {
|
|
11
11
|
AgentPromptLoader,
|
|
12
12
|
Brain,
|
|
@@ -25,8 +25,9 @@ import {
|
|
|
25
25
|
ProjectIndexer,
|
|
26
26
|
ProjectScaffolder,
|
|
27
27
|
ProviderFactory,
|
|
28
|
-
SCAFFOLD_PRESETS
|
|
29
|
-
|
|
28
|
+
SCAFFOLD_PRESETS,
|
|
29
|
+
StackDetector
|
|
30
|
+
} from "./chunk-ACJAMJVU.js";
|
|
30
31
|
import {
|
|
31
32
|
__require
|
|
32
33
|
} from "./chunk-3RG5ZIWI.js";
|
|
@@ -39,11 +40,15 @@ import { Command } from "commander";
|
|
|
39
40
|
|
|
40
41
|
// src/commands/start.ts
|
|
41
42
|
import { exec } from "child_process";
|
|
43
|
+
import { existsSync, readdirSync } from "fs";
|
|
44
|
+
import { writeFile as writeFile2 } from "fs/promises";
|
|
42
45
|
import * as net from "net";
|
|
43
46
|
import * as path from "path";
|
|
44
47
|
import chalk6 from "chalk";
|
|
45
48
|
import ora2 from "ora";
|
|
46
|
-
import { resolve as resolve2 } from "path";
|
|
49
|
+
import { resolve as resolve2, join as join2 } from "path";
|
|
50
|
+
import { input as input2 } from "@inquirer/prompts";
|
|
51
|
+
import TOML from "@iarna/toml";
|
|
47
52
|
|
|
48
53
|
// ../licensing/dist/index.js
|
|
49
54
|
import { createHash } from "crypto";
|
|
@@ -507,6 +512,10 @@ var ErrorAutoFixer = class {
|
|
|
507
512
|
MAX_FIX_ATTEMPTS = 3;
|
|
508
513
|
lastErrorSignature = "";
|
|
509
514
|
cooldownUntil = 0;
|
|
515
|
+
autofixTaskIds = /* @__PURE__ */ new Set();
|
|
516
|
+
isAutofixTask(taskId) {
|
|
517
|
+
return this.autofixTaskIds.has(taskId);
|
|
518
|
+
}
|
|
510
519
|
/**
|
|
511
520
|
* Process dev server output. Call this for every stdout/stderr chunk.
|
|
512
521
|
*/
|
|
@@ -603,6 +612,7 @@ Error: ${errorOutput.slice(0, 300)}`;
|
|
|
603
612
|
lane: 3,
|
|
604
613
|
status: "pending"
|
|
605
614
|
};
|
|
615
|
+
this.autofixTaskIds.add(task.id);
|
|
606
616
|
const executor = new Lane3Executor(
|
|
607
617
|
this.projectPath,
|
|
608
618
|
this.llmClient,
|
|
@@ -616,13 +626,16 @@ Error: ${errorOutput.slice(0, 300)}`;
|
|
|
616
626
|
// agentPromptLoader
|
|
617
627
|
void 0,
|
|
618
628
|
// pathGuard
|
|
619
|
-
this.commitQueue
|
|
629
|
+
this.commitQueue,
|
|
630
|
+
true
|
|
631
|
+
// skipValidation — auto-fix tasks skip tsc
|
|
620
632
|
);
|
|
621
633
|
console.log(chalk3.cyan("[Nova] Auto-fixing image errors..."));
|
|
622
634
|
this.wsServer.sendEvent({ type: "status", data: { message: "autofix_start" } });
|
|
623
635
|
this.eventBus.emit({ type: "task_started", data: { taskId: task.id } });
|
|
624
636
|
this.wsServer.sendEvent({ type: "task_created", data: task });
|
|
625
637
|
const result = await executor.execute(task, this.projectMap);
|
|
638
|
+
this.autofixTaskIds.delete(task.id);
|
|
626
639
|
if (result.success) {
|
|
627
640
|
console.log(chalk3.green("[Nova] Image errors fixed automatically"));
|
|
628
641
|
this.eventBus.emit({
|
|
@@ -639,7 +652,6 @@ Error: ${errorOutput.slice(0, 300)}`;
|
|
|
639
652
|
}
|
|
640
653
|
}
|
|
641
654
|
async fixCompilationError(errorOutput) {
|
|
642
|
-
const truncatedError = errorOutput.slice(0, 500);
|
|
643
655
|
console.log(
|
|
644
656
|
chalk3.yellow("[Nova] Detected compilation error \u2014 attempting auto-fix")
|
|
645
657
|
);
|
|
@@ -647,6 +659,56 @@ Error: ${errorOutput.slice(0, 300)}`;
|
|
|
647
659
|
type: "status",
|
|
648
660
|
data: { message: "Compilation error detected. Auto-fixing..." }
|
|
649
661
|
});
|
|
662
|
+
const targetFile = this.extractFilePath(errorOutput);
|
|
663
|
+
if (targetFile && this.projectMap.fileContexts.has(targetFile)) {
|
|
664
|
+
await this.fixWithLane2(targetFile, errorOutput);
|
|
665
|
+
} else {
|
|
666
|
+
await this.fixWithLane3(errorOutput);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
async fixWithLane2(targetFile, errorOutput) {
|
|
670
|
+
const truncatedError = errorOutput.slice(0, 500);
|
|
671
|
+
const task = {
|
|
672
|
+
id: crypto.randomUUID(),
|
|
673
|
+
description: `Fix the following compilation/build error in the project. Read the error carefully and fix the root cause:
|
|
674
|
+
${truncatedError}`,
|
|
675
|
+
files: [targetFile],
|
|
676
|
+
type: "single_file",
|
|
677
|
+
lane: 2,
|
|
678
|
+
status: "pending"
|
|
679
|
+
};
|
|
680
|
+
this.autofixTaskIds.add(task.id);
|
|
681
|
+
const executor = new Lane2Executor(
|
|
682
|
+
this.projectPath,
|
|
683
|
+
this.llmClient,
|
|
684
|
+
this.gitManager,
|
|
685
|
+
void 0,
|
|
686
|
+
// pathGuard
|
|
687
|
+
this.commitQueue
|
|
688
|
+
);
|
|
689
|
+
console.log(chalk3.cyan(`[Nova] Auto-fixing compilation error via Lane 2 (${targetFile})...`));
|
|
690
|
+
this.wsServer.sendEvent({ type: "status", data: { message: "autofix_start" } });
|
|
691
|
+
this.eventBus.emit({ type: "task_started", data: { taskId: task.id } });
|
|
692
|
+
this.wsServer.sendEvent({ type: "task_created", data: task });
|
|
693
|
+
const result = await executor.execute(task, this.projectMap);
|
|
694
|
+
this.autofixTaskIds.delete(task.id);
|
|
695
|
+
if (result.success) {
|
|
696
|
+
console.log(chalk3.green("[Nova] Compilation error fixed automatically (Lane 2)"));
|
|
697
|
+
this.eventBus.emit({
|
|
698
|
+
type: "task_completed",
|
|
699
|
+
data: { taskId: task.id, diff: result.diff ?? "", commitHash: result.commitHash ?? "" }
|
|
700
|
+
});
|
|
701
|
+
this.wsServer.sendEvent({ type: "status", data: { message: "autofix_end" } });
|
|
702
|
+
} else {
|
|
703
|
+
console.log(chalk3.red(`[Nova] Auto-fix failed: ${result.error}`));
|
|
704
|
+
const failEvent = { type: "task_failed", data: { taskId: task.id, error: result.error ?? "Auto-fix failed" } };
|
|
705
|
+
this.eventBus.emit(failEvent);
|
|
706
|
+
this.wsServer.sendEvent(failEvent);
|
|
707
|
+
this.wsServer.sendEvent({ type: "status", data: { message: "autofix_failed" } });
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
async fixWithLane3(errorOutput) {
|
|
711
|
+
const truncatedError = errorOutput.slice(0, 500);
|
|
650
712
|
const task = {
|
|
651
713
|
id: crypto.randomUUID(),
|
|
652
714
|
description: `Fix the following compilation/build error in the project. Read the error carefully and fix the root cause:
|
|
@@ -656,6 +718,7 @@ ${truncatedError}`,
|
|
|
656
718
|
lane: 3,
|
|
657
719
|
status: "pending"
|
|
658
720
|
};
|
|
721
|
+
this.autofixTaskIds.add(task.id);
|
|
659
722
|
const executor = new Lane3Executor(
|
|
660
723
|
this.projectPath,
|
|
661
724
|
this.llmClient,
|
|
@@ -669,13 +732,16 @@ ${truncatedError}`,
|
|
|
669
732
|
// agentPromptLoader
|
|
670
733
|
void 0,
|
|
671
734
|
// pathGuard
|
|
672
|
-
this.commitQueue
|
|
735
|
+
this.commitQueue,
|
|
736
|
+
true
|
|
737
|
+
// skipValidation — auto-fix tasks skip tsc
|
|
673
738
|
);
|
|
674
739
|
console.log(chalk3.cyan("[Nova] Auto-fixing compilation error..."));
|
|
675
740
|
this.wsServer.sendEvent({ type: "status", data: { message: "autofix_start" } });
|
|
676
741
|
this.eventBus.emit({ type: "task_started", data: { taskId: task.id } });
|
|
677
742
|
this.wsServer.sendEvent({ type: "task_created", data: task });
|
|
678
743
|
const result = await executor.execute(task, this.projectMap);
|
|
744
|
+
this.autofixTaskIds.delete(task.id);
|
|
679
745
|
if (result.success) {
|
|
680
746
|
console.log(chalk3.green("[Nova] Compilation error fixed automatically"));
|
|
681
747
|
this.eventBus.emit({
|
|
@@ -691,6 +757,21 @@ ${truncatedError}`,
|
|
|
691
757
|
this.wsServer.sendEvent({ type: "status", data: { message: "autofix_failed" } });
|
|
692
758
|
}
|
|
693
759
|
}
|
|
760
|
+
extractFilePath(errorOutput) {
|
|
761
|
+
const patterns = [
|
|
762
|
+
/\.\/([^\s:]+\.[tj]sx?)/,
|
|
763
|
+
// ./path/to/file.tsx
|
|
764
|
+
/(?:in|at|from)\s+([^\s:]+\.[tj]sx?)/i,
|
|
765
|
+
// in path/to/file.tsx
|
|
766
|
+
/([^\s:]+\.[tj]sx?)[\s:]/
|
|
767
|
+
// path/to/file.tsx:line
|
|
768
|
+
];
|
|
769
|
+
for (const p of patterns) {
|
|
770
|
+
const match = errorOutput.match(p);
|
|
771
|
+
if (match) return match[1];
|
|
772
|
+
}
|
|
773
|
+
return null;
|
|
774
|
+
}
|
|
694
775
|
};
|
|
695
776
|
|
|
696
777
|
// src/chat.ts
|
|
@@ -753,11 +834,11 @@ var NovaChat = class {
|
|
|
753
834
|
this.rl?.close();
|
|
754
835
|
this.rl = null;
|
|
755
836
|
}
|
|
756
|
-
parse(
|
|
757
|
-
const lower =
|
|
837
|
+
parse(input3) {
|
|
838
|
+
const lower = input3.toLowerCase();
|
|
758
839
|
for (const [prefix, type] of Object.entries(SLASH_COMMANDS)) {
|
|
759
840
|
if (lower === prefix || lower.startsWith(prefix + " ")) {
|
|
760
|
-
const args =
|
|
841
|
+
const args = input3.slice(prefix.length).trim();
|
|
761
842
|
return { type, args };
|
|
762
843
|
}
|
|
763
844
|
}
|
|
@@ -767,7 +848,7 @@ var NovaChat = class {
|
|
|
767
848
|
if (lower === "n" || lower === "no" || lower === "cancel") {
|
|
768
849
|
return { type: "cancel", args: "" };
|
|
769
850
|
}
|
|
770
|
-
return { type: "text", args:
|
|
851
|
+
return { type: "text", args: input3 };
|
|
771
852
|
}
|
|
772
853
|
};
|
|
773
854
|
|
|
@@ -1002,7 +1083,7 @@ async function startCommand() {
|
|
|
1002
1083
|
projectHash = createHash2("sha256").update(cwd).digest("hex");
|
|
1003
1084
|
}
|
|
1004
1085
|
const telemetry = new Telemetry();
|
|
1005
|
-
const cliPkg = await import("./package-
|
|
1086
|
+
const cliPkg = await import("./package-K5FGL7BD.js").catch(
|
|
1006
1087
|
() => ({ default: { version: "0.0.1" } })
|
|
1007
1088
|
);
|
|
1008
1089
|
telemetry.send({
|
|
@@ -1031,39 +1112,98 @@ ${nudgeMessage}
|
|
|
1031
1112
|
}).catch(() => {
|
|
1032
1113
|
});
|
|
1033
1114
|
}
|
|
1115
|
+
if (!config.apiKeys.key && config.apiKeys.provider !== "ollama" && config.apiKeys.provider !== "claude-cli") {
|
|
1116
|
+
console.log(chalk6.yellow("\nNo API key configured. Running setup...\n"));
|
|
1117
|
+
const { runSetup: runSetup2 } = await import("./setup-DNA6KT2A.js");
|
|
1118
|
+
await runSetup2(cwd);
|
|
1119
|
+
const updatedConfig = await configReader.read(cwd);
|
|
1120
|
+
config.apiKeys = updatedConfig.apiKeys;
|
|
1121
|
+
}
|
|
1122
|
+
const providerFactory = new ProviderFactory();
|
|
1123
|
+
let llmClient;
|
|
1124
|
+
try {
|
|
1125
|
+
llmClient = providerFactory.create(config.apiKeys.provider, config.apiKeys.key);
|
|
1126
|
+
} catch (err) {
|
|
1127
|
+
console.log(chalk6.yellow("\nAI provider not configured. Nova is running without AI analysis."));
|
|
1128
|
+
console.log(chalk6.dim('Run "nova setup" to configure your API key.\n'));
|
|
1129
|
+
llmClient = null;
|
|
1130
|
+
}
|
|
1131
|
+
const brain = llmClient ? new Brain(llmClient, eventBus) : null;
|
|
1034
1132
|
spinner.start("Detecting project...");
|
|
1035
|
-
const { StackDetector } = await import("./dist-NNJKY4T4.js");
|
|
1036
1133
|
const stackDetector = new StackDetector();
|
|
1037
1134
|
let stack = await stackDetector.detectStack(cwd);
|
|
1038
1135
|
let detectedDevCommand = await stackDetector.detectDevCommand(stack, cwd);
|
|
1039
1136
|
let detectedPort = await stackDetector.detectPort(stack, cwd);
|
|
1040
1137
|
spinner.succeed(`Detecting project... ${chalk6.cyan(stack.framework || "unknown")} + ${chalk6.cyan(stack.typescript ? "TypeScript" : stack.language || "unknown")}`);
|
|
1138
|
+
if (stack.framework !== "unknown") {
|
|
1139
|
+
console.log(chalk6.green(` Detected: ${stack.framework} + ${stack.language}`));
|
|
1140
|
+
} else {
|
|
1141
|
+
const dirFiles = readdirSync(cwd).slice(0, 10).join(", ");
|
|
1142
|
+
console.log(chalk6.yellow(` Could not detect framework. Files in directory: ${dirFiles}`));
|
|
1143
|
+
}
|
|
1041
1144
|
let devCommand = config.project.devCommand || detectedDevCommand;
|
|
1042
1145
|
let devPort = config.project.port || detectedPort;
|
|
1043
1146
|
if (!devCommand) {
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1147
|
+
const projectMarkers = ["package.json", "requirements.txt", "go.mod", "Cargo.toml", "pom.xml", "build.gradle", "composer.json", "Gemfile"];
|
|
1148
|
+
const hasProjectFiles = projectMarkers.some((f) => existsSync(join2(cwd, f))) || readdirSync(cwd).some((f) => f.endsWith(".sln") || f.endsWith(".csproj"));
|
|
1149
|
+
if (hasProjectFiles) {
|
|
1150
|
+
const defaultCmd = stack.framework === "dotnet" ? "dotnet run" : stack.framework === "django" ? "python manage.py runserver" : stack.framework === "fastapi" ? "uvicorn main:app --reload" : stack.framework === "flask" ? "flask run" : stack.framework === "rails" ? "bin/rails server" : stack.framework === "laravel" ? "php artisan serve" : stack.framework === "spring-boot" ? "./mvnw spring-boot:run" : existsSync(join2(cwd, "package.json")) ? "npm run dev" : "";
|
|
1151
|
+
const stackLabel = stack.framework !== "unknown" ? ` (${chalk6.cyan(stack.framework)} detected)` : "";
|
|
1152
|
+
let devCmd;
|
|
1153
|
+
try {
|
|
1154
|
+
devCmd = await input2({
|
|
1155
|
+
message: `Dev command not found${stackLabel}. Enter your dev command:`,
|
|
1156
|
+
default: defaultCmd || void 0
|
|
1157
|
+
});
|
|
1158
|
+
} catch {
|
|
1159
|
+
console.log("\nCancelled.");
|
|
1160
|
+
process.exit(0);
|
|
1161
|
+
}
|
|
1162
|
+
if (devCmd && devCmd.trim()) {
|
|
1163
|
+
devCommand = devCmd.trim();
|
|
1164
|
+
try {
|
|
1165
|
+
const novaTomlPath = join2(cwd, "nova.toml");
|
|
1166
|
+
let tomlContent = {};
|
|
1167
|
+
if (existsSync(novaTomlPath)) {
|
|
1168
|
+
const { readFileSync: readFileSync2 } = await import("fs");
|
|
1169
|
+
tomlContent = TOML.parse(readFileSync2(novaTomlPath, "utf-8"));
|
|
1170
|
+
}
|
|
1171
|
+
const project = tomlContent["project"] ?? {};
|
|
1172
|
+
project["devCommand"] = devCommand;
|
|
1173
|
+
tomlContent["project"] = project;
|
|
1174
|
+
await writeFile2(novaTomlPath, TOML.stringify(tomlContent), "utf-8");
|
|
1175
|
+
console.log(chalk6.dim(`Saved devCommand to nova.toml`));
|
|
1176
|
+
} catch {
|
|
1177
|
+
}
|
|
1178
|
+
} else {
|
|
1179
|
+
console.error(chalk6.red('Dev command is required. Add [project] devCommand = "..." to nova.toml'));
|
|
1180
|
+
process.exit(1);
|
|
1181
|
+
}
|
|
1182
|
+
} else {
|
|
1183
|
+
if (novaDir.exists(cwd)) {
|
|
1184
|
+
await novaDir.clean(cwd);
|
|
1185
|
+
}
|
|
1186
|
+
const scaffoldInfo = await promptAndScaffold(cwd);
|
|
1187
|
+
if (!scaffoldInfo.scaffolded) {
|
|
1188
|
+
process.exit(0);
|
|
1189
|
+
}
|
|
1190
|
+
if (scaffoldInfo.frontend) config.project.frontend = scaffoldInfo.frontend;
|
|
1191
|
+
if (scaffoldInfo.backends) config.project.backends = scaffoldInfo.backends;
|
|
1192
|
+
spinner.start("Re-detecting project...");
|
|
1193
|
+
stack = await stackDetector.detectStack(cwd);
|
|
1194
|
+
detectedDevCommand = await stackDetector.detectDevCommand(stack, cwd);
|
|
1195
|
+
detectedPort = await stackDetector.detectPort(stack, cwd);
|
|
1196
|
+
spinner.succeed(
|
|
1197
|
+
`Detecting project... ${chalk6.cyan(stack.framework || "unknown")} + ${chalk6.cyan(stack.typescript ? "TypeScript" : stack.language || "unknown")}`
|
|
1065
1198
|
);
|
|
1066
|
-
|
|
1199
|
+
devCommand = config.project.devCommand || detectedDevCommand;
|
|
1200
|
+
devPort = config.project.port || detectedPort;
|
|
1201
|
+
if (!devCommand) {
|
|
1202
|
+
console.error(
|
|
1203
|
+
chalk6.red('No dev command found after scaffolding. Set project.devCommand in nova.toml or ensure package.json has a "dev" script.')
|
|
1204
|
+
);
|
|
1205
|
+
process.exit(1);
|
|
1206
|
+
}
|
|
1067
1207
|
}
|
|
1068
1208
|
}
|
|
1069
1209
|
spinner.start("Initializing .nova/ directory...");
|
|
@@ -1078,7 +1218,7 @@ ${nudgeMessage}
|
|
|
1078
1218
|
throw err;
|
|
1079
1219
|
}
|
|
1080
1220
|
spinner.succeed("Project indexed.");
|
|
1081
|
-
const { ProjectAnalyzer, RagIndexer, createEmbeddingService } = await import("./dist-
|
|
1221
|
+
const { ProjectAnalyzer, RagIndexer, createEmbeddingService } = await import("./dist-IDA76B3L.js");
|
|
1082
1222
|
const { ProjectMapApi } = await import("./dist-5FLNK6MH.js");
|
|
1083
1223
|
const projectAnalyzer = new ProjectAnalyzer();
|
|
1084
1224
|
spinner.start("Analyzing project structure...");
|
|
@@ -1086,7 +1226,7 @@ ${nudgeMessage}
|
|
|
1086
1226
|
spinner.succeed(`Project analyzed: ${analysis.fileCount} files, ${analysis.methods.length} methods.`);
|
|
1087
1227
|
let ragIndexer = null;
|
|
1088
1228
|
try {
|
|
1089
|
-
const { VectorStore } = await import("./dist-
|
|
1229
|
+
const { VectorStore } = await import("./dist-IDA76B3L.js");
|
|
1090
1230
|
let embeddingProvider = "tfidf";
|
|
1091
1231
|
let embeddingApiKey;
|
|
1092
1232
|
let embeddingBaseUrl;
|
|
@@ -1178,7 +1318,7 @@ Tips:`));
|
|
|
1178
1318
|
wsServer.start(httpServer);
|
|
1179
1319
|
}
|
|
1180
1320
|
proxyServer.setProjectMapApi(projectMapApi);
|
|
1181
|
-
const { GraphStore: GS, SearchRouter: SR } = await import("./dist-
|
|
1321
|
+
const { GraphStore: GS, SearchRouter: SR } = await import("./dist-IDA76B3L.js");
|
|
1182
1322
|
const novaPath = novaDir.getPath(cwd);
|
|
1183
1323
|
const graphStoreForApi = new GS(novaPath);
|
|
1184
1324
|
const searchRouterForApi = new SR(graphStoreForApi);
|
|
@@ -1200,23 +1340,6 @@ Tips:`));
|
|
|
1200
1340
|
} else {
|
|
1201
1341
|
exec(`google-chrome "${openUrl}" 2>/dev/null || chromium "${openUrl}" 2>/dev/null || xdg-open "${openUrl}"`);
|
|
1202
1342
|
}
|
|
1203
|
-
if (!config.apiKeys.key && config.apiKeys.provider !== "ollama" && config.apiKeys.provider !== "claude-cli") {
|
|
1204
|
-
console.log(chalk6.yellow("\nNo API key configured. Running setup...\n"));
|
|
1205
|
-
const { runSetup: runSetup2 } = await import("./setup-VJMYSGJI.js");
|
|
1206
|
-
await runSetup2(cwd);
|
|
1207
|
-
const updatedConfig = await configReader.read(cwd);
|
|
1208
|
-
config.apiKeys = updatedConfig.apiKeys;
|
|
1209
|
-
}
|
|
1210
|
-
const providerFactory = new ProviderFactory();
|
|
1211
|
-
let llmClient;
|
|
1212
|
-
try {
|
|
1213
|
-
llmClient = providerFactory.create(config.apiKeys.provider, config.apiKeys.key);
|
|
1214
|
-
} catch (err) {
|
|
1215
|
-
console.log(chalk6.yellow("\nAI provider not configured. Nova is running without AI analysis."));
|
|
1216
|
-
console.log(chalk6.dim('Run "nova setup" to configure your API key.\n'));
|
|
1217
|
-
llmClient = null;
|
|
1218
|
-
}
|
|
1219
|
-
const brain = llmClient ? new Brain(llmClient, eventBus) : null;
|
|
1220
1343
|
try {
|
|
1221
1344
|
const { execSync } = await import("child_process");
|
|
1222
1345
|
execSync("git rev-parse --git-dir", { cwd, stdio: "ignore" });
|
|
@@ -1407,6 +1530,7 @@ ${pendingMessage}
|
|
|
1407
1530
|
}
|
|
1408
1531
|
wsServer.sendEvent(event);
|
|
1409
1532
|
setTimeout(async () => {
|
|
1533
|
+
if (autoFixer?.isAutofixTask(event.data.taskId)) return;
|
|
1410
1534
|
const logs = devServer.getLogs();
|
|
1411
1535
|
const recentLogs = logs.slice(-2e3);
|
|
1412
1536
|
const hasLogError = /error|Error|failed|Failed|Module not found|SyntaxError|TypeError/i.test(recentLogs) && !/Successfully compiled|Compiled/.test(recentLogs.slice(-500));
|
|
@@ -2278,14 +2402,14 @@ function createCli() {
|
|
|
2278
2402
|
if (opts.provider && (opts.key || opts.provider === "ollama" || opts.provider === "claude-cli")) {
|
|
2279
2403
|
const fs2 = await import("fs/promises");
|
|
2280
2404
|
const path4 = await import("path");
|
|
2281
|
-
const
|
|
2405
|
+
const TOML2 = (await import("@iarna/toml")).default;
|
|
2282
2406
|
const cwd = process.cwd();
|
|
2283
2407
|
const novaDir = path4.join(cwd, ".nova");
|
|
2284
2408
|
await fs2.mkdir(novaDir, { recursive: true });
|
|
2285
2409
|
const config = { apiKeys: { provider: opts.provider, key: opts.key } };
|
|
2286
2410
|
await fs2.writeFile(
|
|
2287
2411
|
path4.join(novaDir, "config.toml"),
|
|
2288
|
-
|
|
2412
|
+
TOML2.stringify(config),
|
|
2289
2413
|
"utf-8"
|
|
2290
2414
|
);
|
|
2291
2415
|
console.log(`Saved ${opts.provider} config to .nova/config.toml`);
|
package/dist/index.d.ts
CHANGED
|
@@ -53,7 +53,9 @@ declare class ErrorAutoFixer {
|
|
|
53
53
|
private readonly MAX_FIX_ATTEMPTS;
|
|
54
54
|
private lastErrorSignature;
|
|
55
55
|
private cooldownUntil;
|
|
56
|
+
readonly autofixTaskIds: Set<string>;
|
|
56
57
|
constructor(projectPath: string, llmClient: LlmClient, gitManager: IGitManager, eventBus: EventBus, wsServer: WebSocketServer, projectMap: ProjectMap, commitQueue?: CommitQueue | undefined);
|
|
58
|
+
isAutofixTask(taskId: string): boolean;
|
|
57
59
|
/**
|
|
58
60
|
* Process dev server output. Call this for every stdout/stderr chunk.
|
|
59
61
|
*/
|
|
@@ -63,6 +65,9 @@ declare class ErrorAutoFixer {
|
|
|
63
65
|
private attemptAutoFix;
|
|
64
66
|
private fixImageError;
|
|
65
67
|
private fixCompilationError;
|
|
68
|
+
private fixWithLane2;
|
|
69
|
+
private fixWithLane3;
|
|
70
|
+
private extractFilePath;
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
declare function createCli(): Command;
|
package/dist/index.js
CHANGED
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
createCli,
|
|
5
5
|
promptAndScaffold,
|
|
6
6
|
run
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-J573S7XU.js";
|
|
8
8
|
import "./chunk-KE7XWO5N.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigReader,
|
|
11
11
|
runSetup
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-RZGTRPQL.js";
|
|
13
|
+
import "./chunk-ACJAMJVU.js";
|
|
14
14
|
import "./chunk-3RG5ZIWI.js";
|
|
15
15
|
export {
|
|
16
16
|
ConfigReader,
|