@revealui/cli 0.3.3 → 0.4.0
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/cli.js +445 -154
- package/dist/cli.js.map +1 -1
- package/dist/index.js +445 -154
- package/dist/index.js.map +1 -1
- package/package.json +16 -8
- package/templates/basic-blog/next.config.mjs +1 -3
- package/templates/basic-blog/package.json +1 -1
- package/templates/e-commerce/next.config.mjs +1 -3
- package/templates/e-commerce/package.json +1 -1
- package/templates/portfolio/next.config.mjs +1 -3
- package/templates/portfolio/package.json +1 -1
- package/templates/starter/next.config.mjs +1 -3
- package/templates/starter/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,20 +1,231 @@
|
|
|
1
1
|
// src/cli.ts
|
|
2
|
-
import { createLogger as
|
|
2
|
+
import { createLogger as createLogger12 } from "@revealui/setup/utils";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
|
|
5
|
+
// src/commands/agent.ts
|
|
6
|
+
import { createInterface } from "readline";
|
|
7
|
+
import { createLogger } from "@revealui/setup/utils";
|
|
8
|
+
var logger = createLogger({ prefix: "agent" });
|
|
9
|
+
async function runAgentStatusCommand() {
|
|
10
|
+
const { available, provider, model, projectRoot } = await detectProvider();
|
|
11
|
+
logger.info(`Provider: ${provider}`);
|
|
12
|
+
logger.info(`Model: ${model}`);
|
|
13
|
+
logger.info(`Project root: ${projectRoot}`);
|
|
14
|
+
logger.info(`Available: ${available ? "yes" : "no"}`);
|
|
15
|
+
if (!available) {
|
|
16
|
+
logger.warn("No LLM provider detected. Start BitNet, Ollama, or set GROQ_API_KEY.");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function runAgentHeadlessCommand(prompt) {
|
|
20
|
+
const deps = await loadProDeps();
|
|
21
|
+
if (!deps) return;
|
|
22
|
+
const { StreamingAgentRuntime, createLLMClientFromEnv, createCodingTools } = deps;
|
|
23
|
+
const projectRoot = process.cwd();
|
|
24
|
+
const tools = createCodingTools({ projectRoot });
|
|
25
|
+
const llmClient = createLLMClientFromEnv();
|
|
26
|
+
const agent = {
|
|
27
|
+
id: "revealui-coding-agent",
|
|
28
|
+
name: "RevealUI Coding Agent",
|
|
29
|
+
instructions: buildMinimalInstructions(),
|
|
30
|
+
tools,
|
|
31
|
+
config: {},
|
|
32
|
+
getContext: () => ({ projectRoot, workingDirectory: projectRoot })
|
|
33
|
+
};
|
|
34
|
+
const task = {
|
|
35
|
+
id: `task-${Date.now()}`,
|
|
36
|
+
type: "headless-prompt",
|
|
37
|
+
description: prompt
|
|
38
|
+
};
|
|
39
|
+
const runtime = new StreamingAgentRuntime({
|
|
40
|
+
maxIterations: 10,
|
|
41
|
+
timeout: 12e4
|
|
42
|
+
});
|
|
43
|
+
try {
|
|
44
|
+
for await (const chunk of runtime.streamTask(agent, task, llmClient)) {
|
|
45
|
+
switch (chunk.type) {
|
|
46
|
+
case "text":
|
|
47
|
+
if (chunk.content) process.stdout.write(chunk.content);
|
|
48
|
+
break;
|
|
49
|
+
case "tool_call_start":
|
|
50
|
+
if (chunk.toolCall) {
|
|
51
|
+
process.stderr.write(`
|
|
52
|
+
[tool] ${chunk.toolCall.name}
|
|
53
|
+
`);
|
|
54
|
+
}
|
|
55
|
+
break;
|
|
56
|
+
case "tool_call_result":
|
|
57
|
+
if (chunk.toolResult?.content) {
|
|
58
|
+
process.stderr.write(` \u2192 ${chunk.toolResult.content}
|
|
59
|
+
`);
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
62
|
+
case "error":
|
|
63
|
+
process.stderr.write(`
|
|
64
|
+
[error] ${chunk.error}
|
|
65
|
+
`);
|
|
66
|
+
break;
|
|
67
|
+
case "done":
|
|
68
|
+
process.stdout.write("\n");
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} finally {
|
|
73
|
+
await runtime.cleanup();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function runAgentReplCommand() {
|
|
77
|
+
const deps = await loadProDeps();
|
|
78
|
+
if (!deps) return;
|
|
79
|
+
const { StreamingAgentRuntime, createLLMClientFromEnv, createCodingTools } = deps;
|
|
80
|
+
const projectRoot = process.cwd();
|
|
81
|
+
const tools = createCodingTools({ projectRoot });
|
|
82
|
+
const llmClient = createLLMClientFromEnv();
|
|
83
|
+
const agent = {
|
|
84
|
+
id: "revealui-coding-agent",
|
|
85
|
+
name: "RevealUI Coding Agent",
|
|
86
|
+
instructions: buildMinimalInstructions(),
|
|
87
|
+
tools,
|
|
88
|
+
config: {},
|
|
89
|
+
getContext: () => ({ projectRoot, workingDirectory: projectRoot })
|
|
90
|
+
};
|
|
91
|
+
logger.info('RevealUI Agent (type "exit" or Ctrl+C to quit)');
|
|
92
|
+
const rl = createInterface({
|
|
93
|
+
input: process.stdin,
|
|
94
|
+
output: process.stdout,
|
|
95
|
+
prompt: "\n> "
|
|
96
|
+
});
|
|
97
|
+
rl.prompt();
|
|
98
|
+
rl.on("line", async (line) => {
|
|
99
|
+
const input = line.trim();
|
|
100
|
+
if (!input) {
|
|
101
|
+
rl.prompt();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (input === "exit" || input === "quit") {
|
|
105
|
+
rl.close();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const task = {
|
|
109
|
+
id: `task-${Date.now()}`,
|
|
110
|
+
type: "repl-prompt",
|
|
111
|
+
description: input
|
|
112
|
+
};
|
|
113
|
+
const runtime = new StreamingAgentRuntime({
|
|
114
|
+
maxIterations: 10,
|
|
115
|
+
timeout: 12e4
|
|
116
|
+
});
|
|
117
|
+
try {
|
|
118
|
+
for await (const chunk of runtime.streamTask(agent, task, llmClient)) {
|
|
119
|
+
switch (chunk.type) {
|
|
120
|
+
case "text":
|
|
121
|
+
if (chunk.content) process.stdout.write(chunk.content);
|
|
122
|
+
break;
|
|
123
|
+
case "tool_call_start":
|
|
124
|
+
if (chunk.toolCall) {
|
|
125
|
+
process.stderr.write(`
|
|
126
|
+
[tool] ${chunk.toolCall.name}
|
|
127
|
+
`);
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
case "tool_call_result":
|
|
131
|
+
if (chunk.toolResult?.content) {
|
|
132
|
+
process.stderr.write(` \u2192 ${chunk.toolResult.content}
|
|
133
|
+
`);
|
|
134
|
+
}
|
|
135
|
+
break;
|
|
136
|
+
case "error":
|
|
137
|
+
process.stderr.write(`
|
|
138
|
+
[error] ${chunk.error}
|
|
139
|
+
`);
|
|
140
|
+
break;
|
|
141
|
+
case "done":
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
} catch (err) {
|
|
146
|
+
logger.error(err instanceof Error ? err.message : String(err));
|
|
147
|
+
} finally {
|
|
148
|
+
await runtime.cleanup();
|
|
149
|
+
}
|
|
150
|
+
rl.prompt();
|
|
151
|
+
});
|
|
152
|
+
rl.on("close", () => {
|
|
153
|
+
process.exit(0);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
async function loadProDeps() {
|
|
157
|
+
const aiRuntimePath = "@revealui/ai/orchestration/streaming-runtime";
|
|
158
|
+
const aiClientPath = "@revealui/ai/llm/client";
|
|
159
|
+
const aiToolsPath = "@revealui/ai/tools/coding";
|
|
160
|
+
try {
|
|
161
|
+
const [runtimeMod, clientMod, toolsMod] = await Promise.all([
|
|
162
|
+
import(aiRuntimePath),
|
|
163
|
+
import(aiClientPath),
|
|
164
|
+
import(aiToolsPath)
|
|
165
|
+
]);
|
|
166
|
+
return {
|
|
167
|
+
StreamingAgentRuntime: runtimeMod.StreamingAgentRuntime,
|
|
168
|
+
createLLMClientFromEnv: clientMod.createLLMClientFromEnv,
|
|
169
|
+
createCodingTools: toolsMod.createCodingTools
|
|
170
|
+
};
|
|
171
|
+
} catch {
|
|
172
|
+
logger.error(
|
|
173
|
+
"Pro packages not found. Install @revealui/ai to use the agent.\n npm install @revealui/ai"
|
|
174
|
+
);
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async function detectProvider() {
|
|
179
|
+
const projectRoot = process.cwd();
|
|
180
|
+
if (process.env.BITNET_BASE_URL) {
|
|
181
|
+
try {
|
|
182
|
+
const res = await fetch(`${process.env.BITNET_BASE_URL}/v1/models`, {
|
|
183
|
+
signal: AbortSignal.timeout(2e3)
|
|
184
|
+
});
|
|
185
|
+
if (res.ok) {
|
|
186
|
+
return { available: true, provider: "bitnet", model: "bitnet-b1.58-2B-4T", projectRoot };
|
|
187
|
+
}
|
|
188
|
+
} catch {
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const ollamaUrl = process.env.OLLAMA_BASE_URL ?? "http://localhost:11434";
|
|
192
|
+
try {
|
|
193
|
+
const res = await fetch(`${ollamaUrl}/api/tags`, {
|
|
194
|
+
signal: AbortSignal.timeout(2e3)
|
|
195
|
+
});
|
|
196
|
+
if (res.ok) {
|
|
197
|
+
return { available: true, provider: "ollama", model: "llama3.2:3b", projectRoot };
|
|
198
|
+
}
|
|
199
|
+
} catch {
|
|
200
|
+
}
|
|
201
|
+
if (process.env.GROQ_API_KEY) {
|
|
202
|
+
return { available: true, provider: "groq", model: "llama-3.3-70b-versatile", projectRoot };
|
|
203
|
+
}
|
|
204
|
+
return { available: false, provider: "none", model: "none", projectRoot };
|
|
205
|
+
}
|
|
206
|
+
function buildMinimalInstructions() {
|
|
207
|
+
return [
|
|
208
|
+
"You are the RevealUI coding agent. You help with software development tasks in this project.",
|
|
209
|
+
"Use the available tools to read, write, edit, search, and execute commands.",
|
|
210
|
+
"Always read files before modifying them. Prefer surgical edits over full rewrites.",
|
|
211
|
+
"Follow project conventions discovered via the project_context tool.",
|
|
212
|
+
"Be concise and direct. Show your work through tool usage, not verbose explanations."
|
|
213
|
+
].join("\n");
|
|
214
|
+
}
|
|
215
|
+
|
|
5
216
|
// src/commands/create-flow.ts
|
|
6
217
|
import { readFileSync } from "fs";
|
|
7
218
|
import { homedir } from "os";
|
|
8
219
|
import { join } from "path";
|
|
9
|
-
import { createLogger as
|
|
220
|
+
import { createLogger as createLogger7 } from "@revealui/setup/utils";
|
|
10
221
|
import { importSPKI, jwtVerify } from "jose";
|
|
11
222
|
|
|
12
223
|
// src/prompts/database.ts
|
|
13
224
|
import inquirer from "inquirer";
|
|
14
225
|
|
|
15
226
|
// src/validators/credentials.ts
|
|
16
|
-
import { createLogger } from "@revealui/setup/utils";
|
|
17
|
-
var
|
|
227
|
+
import { createLogger as createLogger2 } from "@revealui/setup/utils";
|
|
228
|
+
var logger2 = createLogger2({ prefix: "Validator" });
|
|
18
229
|
async function validateStripeKey(key) {
|
|
19
230
|
if (!(key.startsWith("sk_test_") || key.startsWith("sk_live_"))) {
|
|
20
231
|
return {
|
|
@@ -54,7 +265,7 @@ async function validateSupabaseUrl(url) {
|
|
|
54
265
|
try {
|
|
55
266
|
const parsed = new URL(url);
|
|
56
267
|
if (!parsed.hostname.includes("supabase")) {
|
|
57
|
-
|
|
268
|
+
logger2.warn("URL does not appear to be a Supabase URL");
|
|
58
269
|
}
|
|
59
270
|
return { valid: true };
|
|
60
271
|
} catch {
|
|
@@ -342,18 +553,18 @@ async function promptStorageConfig() {
|
|
|
342
553
|
}
|
|
343
554
|
|
|
344
555
|
// src/validators/node-version.ts
|
|
345
|
-
import { createLogger as
|
|
346
|
-
var
|
|
556
|
+
import { createLogger as createLogger3 } from "@revealui/setup/utils";
|
|
557
|
+
var logger3 = createLogger3({ prefix: "Setup" });
|
|
347
558
|
var REQUIRED_NODE_VERSION = "24.13.0";
|
|
348
559
|
function validateNodeVersion() {
|
|
349
560
|
const currentVersion = process.version.slice(1);
|
|
350
561
|
const [currentMajor, currentMinor] = currentVersion.split(".").map(Number);
|
|
351
562
|
const [requiredMajor, requiredMinor] = REQUIRED_NODE_VERSION.split(".").map(Number);
|
|
352
563
|
if (currentMajor < requiredMajor || currentMajor === requiredMajor && currentMinor < requiredMinor) {
|
|
353
|
-
|
|
564
|
+
logger3.error(
|
|
354
565
|
`Node.js ${REQUIRED_NODE_VERSION} or higher is required. You have ${currentVersion}.`
|
|
355
566
|
);
|
|
356
|
-
|
|
567
|
+
logger3.info("Please upgrade Node.js: https://nodejs.org/");
|
|
357
568
|
return false;
|
|
358
569
|
}
|
|
359
570
|
return true;
|
|
@@ -365,7 +576,7 @@ import { existsSync } from "fs";
|
|
|
365
576
|
import fs5 from "fs/promises";
|
|
366
577
|
import path5 from "path";
|
|
367
578
|
import { fileURLToPath } from "url";
|
|
368
|
-
import { createLogger as
|
|
579
|
+
import { createLogger as createLogger6 } from "@revealui/setup/utils";
|
|
369
580
|
import ora2 from "ora";
|
|
370
581
|
|
|
371
582
|
// src/generators/devbox.ts
|
|
@@ -563,70 +774,42 @@ Run the development server:
|
|
|
563
774
|
pnpm dev
|
|
564
775
|
\`\`\`
|
|
565
776
|
|
|
566
|
-
Open [http://localhost:4000](http://localhost:4000) with your browser
|
|
567
|
-
|
|
568
|
-
The web application runs on [http://localhost:3000](http://localhost:3000).
|
|
777
|
+
Open [http://localhost:4000](http://localhost:4000) with your browser.
|
|
569
778
|
|
|
570
|
-
##
|
|
779
|
+
## Requirements
|
|
571
780
|
|
|
572
|
-
### Standard Setup
|
|
573
|
-
|
|
574
|
-
Requirements:
|
|
575
781
|
- Node.js 24.13.0 or higher
|
|
576
|
-
- pnpm 10
|
|
577
|
-
- PostgreSQL 16
|
|
578
|
-
|
|
579
|
-
### Dev Containers
|
|
580
|
-
|
|
581
|
-
Open in VS Code and select "Reopen in Container", or use GitHub Codespaces.
|
|
582
|
-
|
|
583
|
-
### Devbox
|
|
584
|
-
|
|
585
|
-
Install Devbox:
|
|
586
|
-
|
|
587
|
-
\`\`\`bash
|
|
588
|
-
curl -fsSL https://get.jetpack.io/devbox | bash
|
|
589
|
-
\`\`\`
|
|
590
|
-
|
|
591
|
-
Then start the Devbox shell:
|
|
592
|
-
|
|
593
|
-
\`\`\`bash
|
|
594
|
-
devbox shell
|
|
595
|
-
pnpm dev
|
|
596
|
-
\`\`\`
|
|
782
|
+
- pnpm 10 or higher
|
|
783
|
+
- PostgreSQL 16 (or use a hosted provider like [Neon](https://neon.tech))
|
|
597
784
|
|
|
598
785
|
## Project Structure
|
|
599
786
|
|
|
600
787
|
\`\`\`
|
|
601
788
|
${projectConfig.projectName}/
|
|
602
|
-
\u251C\u2500\u2500
|
|
603
|
-
\u2502 \u251C\u2500\u2500
|
|
604
|
-
\u2502 \
|
|
605
|
-
\
|
|
606
|
-
\
|
|
607
|
-
\
|
|
608
|
-
\
|
|
609
|
-
\u251C\u2500\u2500 .devcontainer/ # Dev Container configuration
|
|
610
|
-
\u251C\u2500\u2500 devbox.json # Devbox configuration
|
|
611
|
-
\u2514\u2500\u2500 .env.development.local # Environment variables
|
|
789
|
+
\u251C\u2500\u2500 src/
|
|
790
|
+
\u2502 \u251C\u2500\u2500 app/ # Next.js App Router pages
|
|
791
|
+
\u2502 \u251C\u2500\u2500 collections/ # RevealUI collection definitions
|
|
792
|
+
\u2502 \u2514\u2500\u2500 seed.ts # Database seed script
|
|
793
|
+
\u251C\u2500\u2500 revealui.config.ts # RevealUI configuration
|
|
794
|
+
\u251C\u2500\u2500 next.config.mjs # Next.js configuration
|
|
795
|
+
\u2514\u2500\u2500 .env.local # Environment variables (git-ignored)
|
|
612
796
|
\`\`\`
|
|
613
797
|
|
|
614
798
|
## Available Scripts
|
|
615
799
|
|
|
616
|
-
- \`pnpm dev\` - Start development
|
|
800
|
+
- \`pnpm dev\` - Start the development server
|
|
617
801
|
- \`pnpm build\` - Build for production
|
|
618
802
|
- \`pnpm test\` - Run tests
|
|
619
|
-
- \`pnpm lint\` -
|
|
803
|
+
- \`pnpm lint\` - Lint with Biome
|
|
620
804
|
- \`pnpm typecheck\` - Type check
|
|
621
|
-
- \`pnpm db:init\` - Initialize database
|
|
805
|
+
- \`pnpm db:init\` - Initialize the database
|
|
622
806
|
- \`pnpm db:migrate\` - Run migrations
|
|
623
|
-
- \`pnpm db:seed\` - Seed
|
|
807
|
+
- \`pnpm db:seed\` - Seed sample content
|
|
624
808
|
|
|
625
809
|
## Learn More
|
|
626
810
|
|
|
627
|
-
- [RevealUI Documentation](https://
|
|
811
|
+
- [RevealUI Documentation](https://docs.revealui.com)
|
|
628
812
|
- [Next.js Documentation](https://nextjs.org/docs)
|
|
629
|
-
- [Hono Documentation](https://hono.dev)
|
|
630
813
|
|
|
631
814
|
## Template
|
|
632
815
|
|
|
@@ -640,10 +823,10 @@ MIT
|
|
|
640
823
|
}
|
|
641
824
|
|
|
642
825
|
// src/installers/dependencies.ts
|
|
643
|
-
import { createLogger as
|
|
826
|
+
import { createLogger as createLogger4 } from "@revealui/setup/utils";
|
|
644
827
|
import { execa } from "execa";
|
|
645
828
|
import ora from "ora";
|
|
646
|
-
var
|
|
829
|
+
var logger4 = createLogger4({ prefix: "Install" });
|
|
647
830
|
async function installDependencies(projectPath) {
|
|
648
831
|
const spinner = ora("Installing dependencies with pnpm...").start();
|
|
649
832
|
try {
|
|
@@ -654,7 +837,7 @@ async function installDependencies(projectPath) {
|
|
|
654
837
|
spinner.succeed("Dependencies installed successfully");
|
|
655
838
|
} catch (error) {
|
|
656
839
|
spinner.fail("Failed to install dependencies");
|
|
657
|
-
|
|
840
|
+
logger4.error('Please run "pnpm install" manually');
|
|
658
841
|
throw error;
|
|
659
842
|
}
|
|
660
843
|
}
|
|
@@ -668,15 +851,15 @@ async function isPnpmInstalled() {
|
|
|
668
851
|
}
|
|
669
852
|
|
|
670
853
|
// src/utils/git.ts
|
|
671
|
-
import { createLogger as
|
|
854
|
+
import { createLogger as createLogger5 } from "@revealui/setup/utils";
|
|
672
855
|
import { execa as execa2 } from "execa";
|
|
673
|
-
var
|
|
856
|
+
var logger5 = createLogger5({ prefix: "Git" });
|
|
674
857
|
async function initializeGitRepo(projectPath) {
|
|
675
858
|
try {
|
|
676
859
|
await execa2("git", ["init"], { cwd: projectPath });
|
|
677
|
-
|
|
860
|
+
logger5.success("Initialized git repository");
|
|
678
861
|
} catch (error) {
|
|
679
|
-
|
|
862
|
+
logger5.warn("Failed to initialize git repository");
|
|
680
863
|
throw error;
|
|
681
864
|
}
|
|
682
865
|
}
|
|
@@ -684,9 +867,9 @@ async function createInitialCommit(projectPath) {
|
|
|
684
867
|
try {
|
|
685
868
|
await execa2("git", ["add", "."], { cwd: projectPath });
|
|
686
869
|
await execa2("git", ["commit", "-m", "Initial commit from @revealui/cli"], { cwd: projectPath });
|
|
687
|
-
|
|
870
|
+
logger5.success("Created initial commit");
|
|
688
871
|
} catch (error) {
|
|
689
|
-
|
|
872
|
+
logger5.warn("Failed to create initial commit");
|
|
690
873
|
throw error;
|
|
691
874
|
}
|
|
692
875
|
}
|
|
@@ -700,7 +883,7 @@ async function isGitInstalled() {
|
|
|
700
883
|
}
|
|
701
884
|
|
|
702
885
|
// src/commands/create.ts
|
|
703
|
-
var
|
|
886
|
+
var logger6 = createLogger6({ prefix: "Create" });
|
|
704
887
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
705
888
|
var __dirname2 = path5.dirname(__filename2);
|
|
706
889
|
var TEMPLATES_DIR = existsSync(path5.resolve(__dirname2, "../../templates")) ? path5.resolve(__dirname2, "../../templates") : path5.resolve(__dirname2, "../templates");
|
|
@@ -788,6 +971,47 @@ function resolveTemplateName(template) {
|
|
|
788
971
|
};
|
|
789
972
|
return map[template] ?? "starter";
|
|
790
973
|
}
|
|
974
|
+
async function pullContentRules(projectPath) {
|
|
975
|
+
const baseUrl = process.env.REVEALUI_RULES_URL ?? "https://raw.githubusercontent.com/RevealUIStudio/editor-configs/main/harnesses";
|
|
976
|
+
const spinner = ora2("Pulling AI coding rules...").start();
|
|
977
|
+
try {
|
|
978
|
+
const manifestRes = await fetch(`${baseUrl}/manifest.json`, {
|
|
979
|
+
signal: AbortSignal.timeout(1e4)
|
|
980
|
+
});
|
|
981
|
+
if (!manifestRes.ok) {
|
|
982
|
+
spinner.info("AI rules not available \u2014 skipping");
|
|
983
|
+
return;
|
|
984
|
+
}
|
|
985
|
+
const manifest = await manifestRes.json();
|
|
986
|
+
const generatorId = "claude-code";
|
|
987
|
+
const ossDefs = manifest.definitions.filter((d) => d.tier === "oss");
|
|
988
|
+
let written = 0;
|
|
989
|
+
for (const def of ossDefs) {
|
|
990
|
+
const paths = def.generatorPaths[generatorId] ?? [];
|
|
991
|
+
for (const relPath of paths) {
|
|
992
|
+
try {
|
|
993
|
+
const fileRes = await fetch(`${baseUrl}/generators/${generatorId}/${relPath}`, {
|
|
994
|
+
signal: AbortSignal.timeout(5e3)
|
|
995
|
+
});
|
|
996
|
+
if (!fileRes.ok) continue;
|
|
997
|
+
const content = await fileRes.text();
|
|
998
|
+
const absolutePath = path5.join(projectPath, relPath);
|
|
999
|
+
await fs5.mkdir(path5.dirname(absolutePath), { recursive: true });
|
|
1000
|
+
await fs5.writeFile(absolutePath, content, "utf-8");
|
|
1001
|
+
written++;
|
|
1002
|
+
} catch {
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
if (written > 0) {
|
|
1007
|
+
spinner.succeed(`Pulled ${written} AI coding rules`);
|
|
1008
|
+
} else {
|
|
1009
|
+
spinner.info("No AI rules pulled");
|
|
1010
|
+
}
|
|
1011
|
+
} catch {
|
|
1012
|
+
spinner.info("AI rules not available \u2014 skipping");
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
791
1015
|
async function createProject(cfg) {
|
|
792
1016
|
const { project, skipGit = false, skipInstall = false } = cfg;
|
|
793
1017
|
const { projectPath, projectName, template } = project;
|
|
@@ -814,42 +1038,43 @@ async function createProject(cfg) {
|
|
|
814
1038
|
throw err;
|
|
815
1039
|
}
|
|
816
1040
|
await generateReadme(projectPath, project);
|
|
817
|
-
|
|
1041
|
+
logger6.success("README.md generated");
|
|
818
1042
|
if (cfg.devenv.createDevContainer) {
|
|
819
1043
|
await generateDevContainer(projectPath);
|
|
820
|
-
|
|
1044
|
+
logger6.success(".devcontainer/ generated");
|
|
821
1045
|
}
|
|
822
1046
|
if (cfg.devenv.createDevbox) {
|
|
823
1047
|
await generateDevbox(projectPath);
|
|
824
|
-
|
|
1048
|
+
logger6.success("devbox.json generated");
|
|
825
1049
|
}
|
|
1050
|
+
await pullContentRules(projectPath);
|
|
826
1051
|
if (!skipInstall) {
|
|
827
1052
|
const pnpmOk = await isPnpmInstalled();
|
|
828
1053
|
if (!pnpmOk) {
|
|
829
|
-
|
|
1054
|
+
logger6.warn(
|
|
830
1055
|
"pnpm not found \u2014 skipping dependency installation. Run `pnpm install` manually."
|
|
831
1056
|
);
|
|
832
1057
|
} else {
|
|
833
1058
|
await installDependencies(projectPath);
|
|
834
1059
|
}
|
|
835
1060
|
} else {
|
|
836
|
-
|
|
1061
|
+
logger6.info("Skipping dependency installation (--skip-install)");
|
|
837
1062
|
}
|
|
838
1063
|
if (!skipGit) {
|
|
839
1064
|
const gitOk = await isGitInstalled();
|
|
840
1065
|
if (!gitOk) {
|
|
841
|
-
|
|
1066
|
+
logger6.warn("git not found \u2014 skipping repository initialisation.");
|
|
842
1067
|
} else {
|
|
843
1068
|
await initializeGitRepo(projectPath);
|
|
844
1069
|
await createInitialCommit(projectPath);
|
|
845
1070
|
}
|
|
846
1071
|
} else {
|
|
847
|
-
|
|
1072
|
+
logger6.info("Skipping git initialisation (--skip-git)");
|
|
848
1073
|
}
|
|
849
1074
|
}
|
|
850
1075
|
|
|
851
1076
|
// src/commands/create-flow.ts
|
|
852
|
-
var
|
|
1077
|
+
var logger7 = createLogger7({ prefix: "@revealui/cli" });
|
|
853
1078
|
var PRO_TEMPLATES = /* @__PURE__ */ new Set([]);
|
|
854
1079
|
async function checkProLicense() {
|
|
855
1080
|
let key = process.env.REVEALUI_LICENSE_KEY;
|
|
@@ -862,7 +1087,7 @@ async function checkProLicense() {
|
|
|
862
1087
|
}
|
|
863
1088
|
}
|
|
864
1089
|
if (!key) return false;
|
|
865
|
-
const publicKeyPem = process.env.REVEALUI_LICENSE_PUBLIC_KEY;
|
|
1090
|
+
const publicKeyPem = process.env.REVEALUI_LICENSE_PUBLIC_KEY?.replace(/\\n/g, "\n");
|
|
866
1091
|
if (publicKeyPem) {
|
|
867
1092
|
try {
|
|
868
1093
|
const publicKey = await importSPKI(publicKeyPem, "RS256");
|
|
@@ -886,76 +1111,131 @@ async function checkProLicense() {
|
|
|
886
1111
|
return false;
|
|
887
1112
|
}
|
|
888
1113
|
}
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1114
|
+
function printBanner() {
|
|
1115
|
+
logger7.divider();
|
|
1116
|
+
logger7.info(" RevealUI \u2014 B.O.S.S.");
|
|
1117
|
+
logger7.info(" Build your business, not your boilerplate.");
|
|
1118
|
+
logger7.divider();
|
|
1119
|
+
logger7.info("");
|
|
1120
|
+
}
|
|
1121
|
+
function printPostCreateSummary(projectName) {
|
|
1122
|
+
logger7.divider();
|
|
1123
|
+
logger7.success("Your RevealUI project is ready!");
|
|
1124
|
+
logger7.info("");
|
|
1125
|
+
logger7.info(" Quick start:");
|
|
1126
|
+
logger7.info(` cd ${projectName}`);
|
|
1127
|
+
logger7.info(" pnpm install");
|
|
1128
|
+
logger7.info(" pnpm dev");
|
|
1129
|
+
logger7.info("");
|
|
1130
|
+
logger7.info(" What was created:");
|
|
1131
|
+
logger7.info(` ./${projectName}/ \u2014 project root`);
|
|
1132
|
+
logger7.info(` ./${projectName}/.env.local \u2014 environment variables (edit before pnpm dev)`);
|
|
1133
|
+
logger7.info(` ./${projectName}/README.md \u2014 getting started guide`);
|
|
1134
|
+
logger7.info("");
|
|
1135
|
+
logger7.info(" Helpful links:");
|
|
1136
|
+
logger7.info(" Docs: https://docs.revealui.com");
|
|
1137
|
+
logger7.info(" GitHub: https://github.com/RevealUIStudio/revealui");
|
|
1138
|
+
logger7.info(" Support: support@revealui.com");
|
|
1139
|
+
logger7.divider();
|
|
1140
|
+
}
|
|
1141
|
+
function formatCreateError(err) {
|
|
1142
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1143
|
+
const code = err instanceof Error && "code" in err ? err.code : void 0;
|
|
1144
|
+
logger7.error("Project creation failed.");
|
|
1145
|
+
logger7.info("");
|
|
1146
|
+
if (code === "EACCES") {
|
|
1147
|
+
logger7.info(" Permission denied. Try:");
|
|
1148
|
+
logger7.info(" - Running from a directory you own");
|
|
1149
|
+
logger7.info(" - Checking folder permissions with `ls -la`");
|
|
1150
|
+
} else if (code === "ENOENT") {
|
|
1151
|
+
logger7.info(" A required file or directory was not found.");
|
|
1152
|
+
logger7.info(" - Check that you are in the correct directory");
|
|
1153
|
+
logger7.info(" - Try running `revealui doctor` to diagnose your environment");
|
|
1154
|
+
} else if (code === "ENOSPC") {
|
|
1155
|
+
logger7.info(" Disk full. Free up space and try again.");
|
|
1156
|
+
} else if (message.includes("fetch") || message.includes("ENOTFOUND") || message.includes("ETIMEDOUT")) {
|
|
1157
|
+
logger7.info(" Network error. Check your internet connection and try again.");
|
|
913
1158
|
} else {
|
|
914
|
-
|
|
1159
|
+
logger7.info(` ${message}`);
|
|
915
1160
|
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
1161
|
+
logger7.info("");
|
|
1162
|
+
logger7.info(" Troubleshooting:");
|
|
1163
|
+
logger7.info(" revealui doctor \u2014 diagnose your environment");
|
|
1164
|
+
logger7.info(" https://docs.revealui.com/docs/TROUBLESHOOTING");
|
|
1165
|
+
logger7.info(" support@revealui.com \u2014 we are here to help");
|
|
1166
|
+
logger7.divider();
|
|
1167
|
+
}
|
|
1168
|
+
async function runCreateFlow(projectName, options) {
|
|
1169
|
+
printBanner();
|
|
1170
|
+
try {
|
|
1171
|
+
logger7.info("[1/8] Validating Node.js version...");
|
|
1172
|
+
if (!validateNodeVersion()) {
|
|
1173
|
+
process.exit(1);
|
|
1174
|
+
}
|
|
1175
|
+
logger7.success(`Node.js version: ${process.version}`);
|
|
1176
|
+
logger7.info("[2/8] Configure your project");
|
|
1177
|
+
const projectConfig = await promptProjectConfig(projectName, options.template, options.yes);
|
|
1178
|
+
logger7.success(`Project: ${projectConfig.projectName}`);
|
|
1179
|
+
logger7.success(`Template: ${projectConfig.template}`);
|
|
1180
|
+
if (PRO_TEMPLATES.has(projectConfig.template)) {
|
|
1181
|
+
if (!await checkProLicense()) {
|
|
1182
|
+
logger7.error(`The "${projectConfig.template}" template requires a RevealUI Pro license.`);
|
|
1183
|
+
logger7.info("Get Pro at https://revealui.com/pricing");
|
|
1184
|
+
logger7.info("Set your license key: export REVEALUI_LICENSE_KEY=<your-key>");
|
|
1185
|
+
process.exit(2);
|
|
1186
|
+
}
|
|
1187
|
+
logger7.success("Pro license verified");
|
|
1188
|
+
}
|
|
1189
|
+
const nonInteractive = options.yes === true;
|
|
1190
|
+
logger7.info("[3/8] Configure database");
|
|
1191
|
+
const databaseConfig = nonInteractive ? { provider: "skip" } : await promptDatabaseConfig();
|
|
1192
|
+
if (databaseConfig.provider !== "skip") {
|
|
1193
|
+
logger7.success(`Database: ${databaseConfig.provider}`);
|
|
1194
|
+
} else {
|
|
1195
|
+
logger7.info("Database configuration skipped");
|
|
1196
|
+
}
|
|
1197
|
+
logger7.info("[4/8] Configure storage");
|
|
1198
|
+
const storageConfig = nonInteractive ? { provider: "skip" } : await promptStorageConfig();
|
|
1199
|
+
if (storageConfig.provider !== "skip") {
|
|
1200
|
+
logger7.success(`Storage: ${storageConfig.provider}`);
|
|
1201
|
+
} else {
|
|
1202
|
+
logger7.info("Storage configuration skipped");
|
|
1203
|
+
}
|
|
1204
|
+
logger7.info("[5/8] Configure payments");
|
|
1205
|
+
const paymentConfig = nonInteractive ? { enabled: false } : await promptPaymentConfig();
|
|
1206
|
+
if (paymentConfig.enabled) {
|
|
1207
|
+
logger7.success("Stripe configured");
|
|
1208
|
+
} else {
|
|
1209
|
+
logger7.info("Payments disabled");
|
|
1210
|
+
}
|
|
1211
|
+
logger7.info("[6/8] Configure development environment");
|
|
1212
|
+
const devEnvConfig = nonInteractive ? { createDevContainer: false, createDevbox: false } : await promptDevEnvConfig();
|
|
1213
|
+
logger7.success(
|
|
1214
|
+
`Dev Container: ${devEnvConfig.createDevContainer ? "Yes" : "No"}, Devbox: ${devEnvConfig.createDevbox ? "Yes" : "No"}`
|
|
1215
|
+
);
|
|
1216
|
+
logger7.info("[7/8] Creating project...");
|
|
1217
|
+
await createProject({
|
|
1218
|
+
project: projectConfig,
|
|
1219
|
+
database: databaseConfig,
|
|
1220
|
+
storage: storageConfig,
|
|
1221
|
+
payment: paymentConfig,
|
|
1222
|
+
devenv: devEnvConfig,
|
|
1223
|
+
skipGit: options.skipGit,
|
|
1224
|
+
skipInstall: options.skipInstall
|
|
1225
|
+
});
|
|
1226
|
+
logger7.success("Project created successfully");
|
|
1227
|
+
logger7.info("[8/8] Done!");
|
|
1228
|
+
printPostCreateSummary(projectConfig.projectName);
|
|
1229
|
+
} catch (err) {
|
|
1230
|
+
formatCreateError(err);
|
|
1231
|
+
process.exit(1);
|
|
929
1232
|
}
|
|
930
|
-
logger6.info("[6/8] Configure development environment");
|
|
931
|
-
const devEnvConfig = nonInteractive ? { createDevContainer: false, createDevbox: false } : await promptDevEnvConfig();
|
|
932
|
-
logger6.success(
|
|
933
|
-
`Dev Container: ${devEnvConfig.createDevContainer ? "Yes" : "No"}, Devbox: ${devEnvConfig.createDevbox ? "Yes" : "No"}`
|
|
934
|
-
);
|
|
935
|
-
logger6.info("[7/8] Creating project...");
|
|
936
|
-
await createProject({
|
|
937
|
-
project: projectConfig,
|
|
938
|
-
database: databaseConfig,
|
|
939
|
-
storage: storageConfig,
|
|
940
|
-
payment: paymentConfig,
|
|
941
|
-
devenv: devEnvConfig,
|
|
942
|
-
skipGit: options.skipGit,
|
|
943
|
-
skipInstall: options.skipInstall
|
|
944
|
-
});
|
|
945
|
-
logger6.success("Project created successfully");
|
|
946
|
-
logger6.info("[8/8] Next steps");
|
|
947
|
-
logger6.divider();
|
|
948
|
-
logger6.info(`cd ${projectConfig.projectName}`);
|
|
949
|
-
logger6.info("pnpm install");
|
|
950
|
-
logger6.info("pnpm dev");
|
|
951
|
-
logger6.divider();
|
|
952
|
-
logger6.success(`Project ${projectConfig.projectName} created successfully`);
|
|
953
1233
|
}
|
|
954
1234
|
|
|
955
1235
|
// src/commands/db.ts
|
|
956
1236
|
import fs8 from "fs/promises";
|
|
957
1237
|
import path8 from "path";
|
|
958
|
-
import { createLogger as
|
|
1238
|
+
import { createLogger as createLogger8 } from "@revealui/setup/utils";
|
|
959
1239
|
import { execa as execa4 } from "execa";
|
|
960
1240
|
|
|
961
1241
|
// src/utils/command.ts
|
|
@@ -1067,7 +1347,7 @@ function findWorkspaceRoot(startDir = process.cwd()) {
|
|
|
1067
1347
|
}
|
|
1068
1348
|
|
|
1069
1349
|
// src/commands/db.ts
|
|
1070
|
-
var
|
|
1350
|
+
var logger8 = createLogger8({ prefix: "DB" });
|
|
1071
1351
|
function isPgCtlNotRunningError(error) {
|
|
1072
1352
|
return typeof error === "object" && error !== null && "exitCode" in error && error.exitCode === 3;
|
|
1073
1353
|
}
|
|
@@ -1128,7 +1408,7 @@ async function runDbInitCommand(options = {}) {
|
|
|
1128
1408
|
}
|
|
1129
1409
|
);
|
|
1130
1410
|
await writeLocalDbConfigs(pgdata);
|
|
1131
|
-
|
|
1411
|
+
logger8.success(`PostgreSQL initialized at ${pgdata}`);
|
|
1132
1412
|
}
|
|
1133
1413
|
async function runDbStartCommand() {
|
|
1134
1414
|
const root = getWorkspaceRootOrThrow();
|
|
@@ -1167,7 +1447,7 @@ async function runDbStatusCommand() {
|
|
|
1167
1447
|
});
|
|
1168
1448
|
} catch (error) {
|
|
1169
1449
|
if (isPgCtlNotRunningError(error)) {
|
|
1170
|
-
|
|
1450
|
+
logger8.warn(`PostgreSQL is not running (PGDATA: ${pgdata})`);
|
|
1171
1451
|
return;
|
|
1172
1452
|
}
|
|
1173
1453
|
throw error;
|
|
@@ -1211,7 +1491,7 @@ async function runDbCleanupCommand(options = {}) {
|
|
|
1211
1491
|
}
|
|
1212
1492
|
|
|
1213
1493
|
// src/commands/dev.ts
|
|
1214
|
-
import { createLogger as
|
|
1494
|
+
import { createLogger as createLogger11 } from "@revealui/setup/utils";
|
|
1215
1495
|
import { execa as execa6 } from "execa";
|
|
1216
1496
|
|
|
1217
1497
|
// src/runtime/doctor.ts
|
|
@@ -1347,8 +1627,8 @@ function writeDevConfig(config, startDir = process.cwd()) {
|
|
|
1347
1627
|
}
|
|
1348
1628
|
|
|
1349
1629
|
// src/commands/doctor.ts
|
|
1350
|
-
import { createLogger as
|
|
1351
|
-
var
|
|
1630
|
+
import { createLogger as createLogger9 } from "@revealui/setup/utils";
|
|
1631
|
+
var logger9 = createLogger9({ prefix: "Doctor" });
|
|
1352
1632
|
function getDoctorFixPlan(report) {
|
|
1353
1633
|
const attempted = [];
|
|
1354
1634
|
const skipped = [];
|
|
@@ -1406,7 +1686,7 @@ async function runDoctorCommand(options = {}) {
|
|
|
1406
1686
|
`);
|
|
1407
1687
|
if (options.fix) {
|
|
1408
1688
|
if (fixPlan.attempted.length === 0) {
|
|
1409
|
-
|
|
1689
|
+
logger9.warn("No safe automatic fixes available");
|
|
1410
1690
|
} else {
|
|
1411
1691
|
await applyDoctorFixes(report);
|
|
1412
1692
|
report = await gatherDoctorReport();
|
|
@@ -1415,7 +1695,7 @@ async function runDoctorCommand(options = {}) {
|
|
|
1415
1695
|
}
|
|
1416
1696
|
}
|
|
1417
1697
|
if (report.checks.some((check) => !check.ok)) {
|
|
1418
|
-
|
|
1698
|
+
logger9.warn("Some checks failed");
|
|
1419
1699
|
if (options.strict || options.json || process.env.CI) {
|
|
1420
1700
|
process.exitCode = 1;
|
|
1421
1701
|
}
|
|
@@ -1423,9 +1703,9 @@ async function runDoctorCommand(options = {}) {
|
|
|
1423
1703
|
}
|
|
1424
1704
|
|
|
1425
1705
|
// src/commands/shell.ts
|
|
1426
|
-
import { createLogger as
|
|
1706
|
+
import { createLogger as createLogger10 } from "@revealui/setup/utils";
|
|
1427
1707
|
import { execa as execa5 } from "execa";
|
|
1428
|
-
var
|
|
1708
|
+
var logger10 = createLogger10({ prefix: "Shell" });
|
|
1429
1709
|
async function runShellCommand(options = {}) {
|
|
1430
1710
|
if (!(options.inside || process.env.IN_NIX_SHELL) && await commandExists("nix")) {
|
|
1431
1711
|
const workspaceRoot = findWorkspaceRoot();
|
|
@@ -1470,12 +1750,12 @@ async function runShellCommand(options = {}) {
|
|
|
1470
1750
|
}
|
|
1471
1751
|
process.stdout.write(`${formatDoctorReport(freshReport)}
|
|
1472
1752
|
`);
|
|
1473
|
-
|
|
1753
|
+
logger10.info("Use `revealui doctor --json` for machine-readable status.");
|
|
1474
1754
|
return false;
|
|
1475
1755
|
}
|
|
1476
1756
|
|
|
1477
1757
|
// src/commands/dev.ts
|
|
1478
|
-
var
|
|
1758
|
+
var logger11 = createLogger11({ prefix: "Dev" });
|
|
1479
1759
|
var DEV_PROFILES = {
|
|
1480
1760
|
local: {},
|
|
1481
1761
|
agent: {
|
|
@@ -1601,20 +1881,20 @@ async function runDevUpCommand(options = {}) {
|
|
|
1601
1881
|
process.stdout.write(`${formatDevActions(plan)}
|
|
1602
1882
|
`);
|
|
1603
1883
|
if (plan.dryRun) {
|
|
1604
|
-
|
|
1884
|
+
logger11.info("Dry run only; no migrations or services were started.");
|
|
1605
1885
|
return;
|
|
1606
1886
|
}
|
|
1607
1887
|
if (options.fix) {
|
|
1608
1888
|
await runDoctorCommand({ fix: true });
|
|
1609
1889
|
}
|
|
1610
1890
|
await runDbMigrateCommand();
|
|
1611
|
-
|
|
1891
|
+
logger11.success("Database migration complete");
|
|
1612
1892
|
if (shouldIncludeMcp(resolved.include)) {
|
|
1613
1893
|
const workspaceRoot = findWorkspaceRoot();
|
|
1614
1894
|
if (!workspaceRoot) {
|
|
1615
1895
|
throw new Error("RevealUI workspace root not found");
|
|
1616
1896
|
}
|
|
1617
|
-
|
|
1897
|
+
logger11.info("Validating MCP setup");
|
|
1618
1898
|
await execa6("pnpm", ["setup:mcp"], {
|
|
1619
1899
|
cwd: workspaceRoot,
|
|
1620
1900
|
stdio: "inherit"
|
|
@@ -1625,7 +1905,7 @@ async function runDevUpCommand(options = {}) {
|
|
|
1625
1905
|
if (!workspaceRoot) {
|
|
1626
1906
|
throw new Error("RevealUI workspace root not found");
|
|
1627
1907
|
}
|
|
1628
|
-
|
|
1908
|
+
logger11.info(`Starting dev script: ${resolved.script}`);
|
|
1629
1909
|
await execa6("pnpm", [resolved.script], {
|
|
1630
1910
|
cwd: workspaceRoot,
|
|
1631
1911
|
stdio: "inherit"
|
|
@@ -1683,7 +1963,7 @@ async function runDevProfileSetCommand(profile) {
|
|
|
1683
1963
|
);
|
|
1684
1964
|
}
|
|
1685
1965
|
const configPath = writeDevConfig({ defaultProfile: profile });
|
|
1686
|
-
|
|
1966
|
+
logger11.success(`Default dev profile set to "${profile}" in ${configPath}`);
|
|
1687
1967
|
}
|
|
1688
1968
|
async function runDevProfileShowCommand(options = {}) {
|
|
1689
1969
|
const configuredProfile = getConfiguredProfile() ?? null;
|
|
@@ -1697,10 +1977,10 @@ async function runDevProfileShowCommand(options = {}) {
|
|
|
1697
1977
|
}
|
|
1698
1978
|
|
|
1699
1979
|
// src/cli.ts
|
|
1700
|
-
var
|
|
1980
|
+
var logger12 = createLogger12({ prefix: "CLI" });
|
|
1701
1981
|
function configureCreateCommand(command, legacyName) {
|
|
1702
1982
|
command.description("Create a new RevealUI project").argument("[project-name]", "Name of the project").option("-t, --template <name>", "Template to use (basic-blog, e-commerce, portfolio)").option("--skip-git", "Skip git initialization", false).option("--skip-install", "Skip dependency installation", false).option("-y, --yes", "Skip all prompts and use defaults", false).action(async (projectName, options) => {
|
|
1703
|
-
|
|
1983
|
+
logger12.header(legacyName ? "Create RevealUI Project" : "RevealUI Create");
|
|
1704
1984
|
await runCreateFlow(projectName, options);
|
|
1705
1985
|
});
|
|
1706
1986
|
return command;
|
|
@@ -1712,6 +1992,17 @@ function createCli() {
|
|
|
1712
1992
|
program.command("doctor").description("Check RevealUI workspace and developer environment health").option("--json", "Output machine-readable JSON", false).option("--fix", "Apply safe automatic fixes when possible", false).option("--strict", "Exit nonzero when checks fail", false).action(async (options) => {
|
|
1713
1993
|
await runDoctorCommand(options);
|
|
1714
1994
|
});
|
|
1995
|
+
const agent = program.command("agent").description("RevealUI coding agent (powered by local or cloud LLMs)");
|
|
1996
|
+
agent.option("-p, --prompt <text>", "Run a single prompt in headless mode").action(async (options) => {
|
|
1997
|
+
if (options.prompt) {
|
|
1998
|
+
await runAgentHeadlessCommand(options.prompt);
|
|
1999
|
+
} else {
|
|
2000
|
+
await runAgentReplCommand();
|
|
2001
|
+
}
|
|
2002
|
+
});
|
|
2003
|
+
agent.command("status").description("Show agent status: model, provider, project root").action(async () => {
|
|
2004
|
+
await runAgentStatusCommand();
|
|
2005
|
+
});
|
|
1715
2006
|
const db = program.command("db").description("Manage the local RevealUI database");
|
|
1716
2007
|
db.command("init").description("Initialize the local PostgreSQL data directory").option("--force", "Delete and recreate the local data directory", false).action(async (options) => {
|
|
1717
2008
|
await runDbInitCommand(options);
|