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