@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/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;
|
|
@@ -361,10 +572,11 @@ function validateNodeVersion() {
|
|
|
361
572
|
|
|
362
573
|
// src/commands/create.ts
|
|
363
574
|
import crypto from "crypto";
|
|
575
|
+
import { existsSync } from "fs";
|
|
364
576
|
import fs5 from "fs/promises";
|
|
365
577
|
import path5 from "path";
|
|
366
578
|
import { fileURLToPath } from "url";
|
|
367
|
-
import { createLogger as
|
|
579
|
+
import { createLogger as createLogger6 } from "@revealui/setup/utils";
|
|
368
580
|
import ora2 from "ora";
|
|
369
581
|
|
|
370
582
|
// src/generators/devbox.ts
|
|
@@ -562,70 +774,42 @@ Run the development server:
|
|
|
562
774
|
pnpm dev
|
|
563
775
|
\`\`\`
|
|
564
776
|
|
|
565
|
-
Open [http://localhost:4000](http://localhost:4000) with your browser
|
|
566
|
-
|
|
567
|
-
The web application runs on [http://localhost:3000](http://localhost:3000).
|
|
777
|
+
Open [http://localhost:4000](http://localhost:4000) with your browser.
|
|
568
778
|
|
|
569
|
-
##
|
|
779
|
+
## Requirements
|
|
570
780
|
|
|
571
|
-
### Standard Setup
|
|
572
|
-
|
|
573
|
-
Requirements:
|
|
574
781
|
- Node.js 24.13.0 or higher
|
|
575
|
-
- pnpm 10
|
|
576
|
-
- PostgreSQL 16
|
|
577
|
-
|
|
578
|
-
### Dev Containers
|
|
579
|
-
|
|
580
|
-
Open in VS Code and select "Reopen in Container", or use GitHub Codespaces.
|
|
581
|
-
|
|
582
|
-
### Devbox
|
|
583
|
-
|
|
584
|
-
Install Devbox:
|
|
585
|
-
|
|
586
|
-
\`\`\`bash
|
|
587
|
-
curl -fsSL https://get.jetpack.io/devbox | bash
|
|
588
|
-
\`\`\`
|
|
589
|
-
|
|
590
|
-
Then start the Devbox shell:
|
|
591
|
-
|
|
592
|
-
\`\`\`bash
|
|
593
|
-
devbox shell
|
|
594
|
-
pnpm dev
|
|
595
|
-
\`\`\`
|
|
782
|
+
- pnpm 10 or higher
|
|
783
|
+
- PostgreSQL 16 (or use a hosted provider like [Neon](https://neon.tech))
|
|
596
784
|
|
|
597
785
|
## Project Structure
|
|
598
786
|
|
|
599
787
|
\`\`\`
|
|
600
788
|
${projectConfig.projectName}/
|
|
601
|
-
\u251C\u2500\u2500
|
|
602
|
-
\u2502 \u251C\u2500\u2500
|
|
603
|
-
\u2502 \
|
|
604
|
-
\
|
|
605
|
-
\
|
|
606
|
-
\
|
|
607
|
-
\
|
|
608
|
-
\u251C\u2500\u2500 .devcontainer/ # Dev Container configuration
|
|
609
|
-
\u251C\u2500\u2500 devbox.json # Devbox configuration
|
|
610
|
-
\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)
|
|
611
796
|
\`\`\`
|
|
612
797
|
|
|
613
798
|
## Available Scripts
|
|
614
799
|
|
|
615
|
-
- \`pnpm dev\` - Start development
|
|
800
|
+
- \`pnpm dev\` - Start the development server
|
|
616
801
|
- \`pnpm build\` - Build for production
|
|
617
802
|
- \`pnpm test\` - Run tests
|
|
618
|
-
- \`pnpm lint\` -
|
|
803
|
+
- \`pnpm lint\` - Lint with Biome
|
|
619
804
|
- \`pnpm typecheck\` - Type check
|
|
620
|
-
- \`pnpm db:init\` - Initialize database
|
|
805
|
+
- \`pnpm db:init\` - Initialize the database
|
|
621
806
|
- \`pnpm db:migrate\` - Run migrations
|
|
622
|
-
- \`pnpm db:seed\` - Seed
|
|
807
|
+
- \`pnpm db:seed\` - Seed sample content
|
|
623
808
|
|
|
624
809
|
## Learn More
|
|
625
810
|
|
|
626
|
-
- [RevealUI Documentation](https://
|
|
811
|
+
- [RevealUI Documentation](https://docs.revealui.com)
|
|
627
812
|
- [Next.js Documentation](https://nextjs.org/docs)
|
|
628
|
-
- [Hono Documentation](https://hono.dev)
|
|
629
813
|
|
|
630
814
|
## Template
|
|
631
815
|
|
|
@@ -639,10 +823,10 @@ MIT
|
|
|
639
823
|
}
|
|
640
824
|
|
|
641
825
|
// src/installers/dependencies.ts
|
|
642
|
-
import { createLogger as
|
|
826
|
+
import { createLogger as createLogger4 } from "@revealui/setup/utils";
|
|
643
827
|
import { execa } from "execa";
|
|
644
828
|
import ora from "ora";
|
|
645
|
-
var
|
|
829
|
+
var logger4 = createLogger4({ prefix: "Install" });
|
|
646
830
|
async function installDependencies(projectPath) {
|
|
647
831
|
const spinner = ora("Installing dependencies with pnpm...").start();
|
|
648
832
|
try {
|
|
@@ -653,7 +837,7 @@ async function installDependencies(projectPath) {
|
|
|
653
837
|
spinner.succeed("Dependencies installed successfully");
|
|
654
838
|
} catch (error) {
|
|
655
839
|
spinner.fail("Failed to install dependencies");
|
|
656
|
-
|
|
840
|
+
logger4.error('Please run "pnpm install" manually');
|
|
657
841
|
throw error;
|
|
658
842
|
}
|
|
659
843
|
}
|
|
@@ -667,15 +851,15 @@ async function isPnpmInstalled() {
|
|
|
667
851
|
}
|
|
668
852
|
|
|
669
853
|
// src/utils/git.ts
|
|
670
|
-
import { createLogger as
|
|
854
|
+
import { createLogger as createLogger5 } from "@revealui/setup/utils";
|
|
671
855
|
import { execa as execa2 } from "execa";
|
|
672
|
-
var
|
|
856
|
+
var logger5 = createLogger5({ prefix: "Git" });
|
|
673
857
|
async function initializeGitRepo(projectPath) {
|
|
674
858
|
try {
|
|
675
859
|
await execa2("git", ["init"], { cwd: projectPath });
|
|
676
|
-
|
|
860
|
+
logger5.success("Initialized git repository");
|
|
677
861
|
} catch (error) {
|
|
678
|
-
|
|
862
|
+
logger5.warn("Failed to initialize git repository");
|
|
679
863
|
throw error;
|
|
680
864
|
}
|
|
681
865
|
}
|
|
@@ -683,9 +867,9 @@ async function createInitialCommit(projectPath) {
|
|
|
683
867
|
try {
|
|
684
868
|
await execa2("git", ["add", "."], { cwd: projectPath });
|
|
685
869
|
await execa2("git", ["commit", "-m", "Initial commit from @revealui/cli"], { cwd: projectPath });
|
|
686
|
-
|
|
870
|
+
logger5.success("Created initial commit");
|
|
687
871
|
} catch (error) {
|
|
688
|
-
|
|
872
|
+
logger5.warn("Failed to create initial commit");
|
|
689
873
|
throw error;
|
|
690
874
|
}
|
|
691
875
|
}
|
|
@@ -699,10 +883,10 @@ async function isGitInstalled() {
|
|
|
699
883
|
}
|
|
700
884
|
|
|
701
885
|
// src/commands/create.ts
|
|
702
|
-
var
|
|
886
|
+
var logger6 = createLogger6({ prefix: "Create" });
|
|
703
887
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
704
888
|
var __dirname2 = path5.dirname(__filename2);
|
|
705
|
-
var TEMPLATES_DIR = path5.resolve(__dirname2, "../templates");
|
|
889
|
+
var TEMPLATES_DIR = existsSync(path5.resolve(__dirname2, "../../templates")) ? path5.resolve(__dirname2, "../../templates") : path5.resolve(__dirname2, "../templates");
|
|
706
890
|
function buildEnvLocal(cfg) {
|
|
707
891
|
const lines = [
|
|
708
892
|
"# Generated by @revealui/cli \u2014 fill in the remaining placeholders before running `pnpm dev`",
|
|
@@ -787,6 +971,47 @@ function resolveTemplateName(template) {
|
|
|
787
971
|
};
|
|
788
972
|
return map[template] ?? "starter";
|
|
789
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
|
+
}
|
|
790
1015
|
async function createProject(cfg) {
|
|
791
1016
|
const { project, skipGit = false, skipInstall = false } = cfg;
|
|
792
1017
|
const { projectPath, projectName, template } = project;
|
|
@@ -813,42 +1038,43 @@ async function createProject(cfg) {
|
|
|
813
1038
|
throw err;
|
|
814
1039
|
}
|
|
815
1040
|
await generateReadme(projectPath, project);
|
|
816
|
-
|
|
1041
|
+
logger6.success("README.md generated");
|
|
817
1042
|
if (cfg.devenv.createDevContainer) {
|
|
818
1043
|
await generateDevContainer(projectPath);
|
|
819
|
-
|
|
1044
|
+
logger6.success(".devcontainer/ generated");
|
|
820
1045
|
}
|
|
821
1046
|
if (cfg.devenv.createDevbox) {
|
|
822
1047
|
await generateDevbox(projectPath);
|
|
823
|
-
|
|
1048
|
+
logger6.success("devbox.json generated");
|
|
824
1049
|
}
|
|
1050
|
+
await pullContentRules(projectPath);
|
|
825
1051
|
if (!skipInstall) {
|
|
826
1052
|
const pnpmOk = await isPnpmInstalled();
|
|
827
1053
|
if (!pnpmOk) {
|
|
828
|
-
|
|
1054
|
+
logger6.warn(
|
|
829
1055
|
"pnpm not found \u2014 skipping dependency installation. Run `pnpm install` manually."
|
|
830
1056
|
);
|
|
831
1057
|
} else {
|
|
832
1058
|
await installDependencies(projectPath);
|
|
833
1059
|
}
|
|
834
1060
|
} else {
|
|
835
|
-
|
|
1061
|
+
logger6.info("Skipping dependency installation (--skip-install)");
|
|
836
1062
|
}
|
|
837
1063
|
if (!skipGit) {
|
|
838
1064
|
const gitOk = await isGitInstalled();
|
|
839
1065
|
if (!gitOk) {
|
|
840
|
-
|
|
1066
|
+
logger6.warn("git not found \u2014 skipping repository initialisation.");
|
|
841
1067
|
} else {
|
|
842
1068
|
await initializeGitRepo(projectPath);
|
|
843
1069
|
await createInitialCommit(projectPath);
|
|
844
1070
|
}
|
|
845
1071
|
} else {
|
|
846
|
-
|
|
1072
|
+
logger6.info("Skipping git initialisation (--skip-git)");
|
|
847
1073
|
}
|
|
848
1074
|
}
|
|
849
1075
|
|
|
850
1076
|
// src/commands/create-flow.ts
|
|
851
|
-
var
|
|
1077
|
+
var logger7 = createLogger7({ prefix: "@revealui/cli" });
|
|
852
1078
|
var PRO_TEMPLATES = /* @__PURE__ */ new Set([]);
|
|
853
1079
|
async function checkProLicense() {
|
|
854
1080
|
let key = process.env.REVEALUI_LICENSE_KEY;
|
|
@@ -861,7 +1087,7 @@ async function checkProLicense() {
|
|
|
861
1087
|
}
|
|
862
1088
|
}
|
|
863
1089
|
if (!key) return false;
|
|
864
|
-
const publicKeyPem = process.env.REVEALUI_LICENSE_PUBLIC_KEY;
|
|
1090
|
+
const publicKeyPem = process.env.REVEALUI_LICENSE_PUBLIC_KEY?.replace(/\\n/g, "\n");
|
|
865
1091
|
if (publicKeyPem) {
|
|
866
1092
|
try {
|
|
867
1093
|
const publicKey = await importSPKI(publicKeyPem, "RS256");
|
|
@@ -885,76 +1111,131 @@ async function checkProLicense() {
|
|
|
885
1111
|
return false;
|
|
886
1112
|
}
|
|
887
1113
|
}
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
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.");
|
|
912
1158
|
} else {
|
|
913
|
-
|
|
1159
|
+
logger7.info(` ${message}`);
|
|
914
1160
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
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);
|
|
928
1232
|
}
|
|
929
|
-
logger6.info("[6/8] Configure development environment");
|
|
930
|
-
const devEnvConfig = nonInteractive ? { createDevContainer: false, createDevbox: false } : await promptDevEnvConfig();
|
|
931
|
-
logger6.success(
|
|
932
|
-
`Dev Container: ${devEnvConfig.createDevContainer ? "Yes" : "No"}, Devbox: ${devEnvConfig.createDevbox ? "Yes" : "No"}`
|
|
933
|
-
);
|
|
934
|
-
logger6.info("[7/8] Creating project...");
|
|
935
|
-
await createProject({
|
|
936
|
-
project: projectConfig,
|
|
937
|
-
database: databaseConfig,
|
|
938
|
-
storage: storageConfig,
|
|
939
|
-
payment: paymentConfig,
|
|
940
|
-
devenv: devEnvConfig,
|
|
941
|
-
skipGit: options.skipGit,
|
|
942
|
-
skipInstall: options.skipInstall
|
|
943
|
-
});
|
|
944
|
-
logger6.success("Project created successfully");
|
|
945
|
-
logger6.info("[8/8] Next steps");
|
|
946
|
-
logger6.divider();
|
|
947
|
-
logger6.info(`cd ${projectConfig.projectName}`);
|
|
948
|
-
logger6.info("pnpm install");
|
|
949
|
-
logger6.info("pnpm dev");
|
|
950
|
-
logger6.divider();
|
|
951
|
-
logger6.success(`Project ${projectConfig.projectName} created successfully`);
|
|
952
1233
|
}
|
|
953
1234
|
|
|
954
1235
|
// src/commands/db.ts
|
|
955
1236
|
import fs8 from "fs/promises";
|
|
956
1237
|
import path8 from "path";
|
|
957
|
-
import { createLogger as
|
|
1238
|
+
import { createLogger as createLogger8 } from "@revealui/setup/utils";
|
|
958
1239
|
import { execa as execa4 } from "execa";
|
|
959
1240
|
|
|
960
1241
|
// src/utils/command.ts
|
|
@@ -1066,7 +1347,7 @@ function findWorkspaceRoot(startDir = process.cwd()) {
|
|
|
1066
1347
|
}
|
|
1067
1348
|
|
|
1068
1349
|
// src/commands/db.ts
|
|
1069
|
-
var
|
|
1350
|
+
var logger8 = createLogger8({ prefix: "DB" });
|
|
1070
1351
|
function isPgCtlNotRunningError(error) {
|
|
1071
1352
|
return typeof error === "object" && error !== null && "exitCode" in error && error.exitCode === 3;
|
|
1072
1353
|
}
|
|
@@ -1127,7 +1408,7 @@ async function runDbInitCommand(options = {}) {
|
|
|
1127
1408
|
}
|
|
1128
1409
|
);
|
|
1129
1410
|
await writeLocalDbConfigs(pgdata);
|
|
1130
|
-
|
|
1411
|
+
logger8.success(`PostgreSQL initialized at ${pgdata}`);
|
|
1131
1412
|
}
|
|
1132
1413
|
async function runDbStartCommand() {
|
|
1133
1414
|
const root = getWorkspaceRootOrThrow();
|
|
@@ -1166,7 +1447,7 @@ async function runDbStatusCommand() {
|
|
|
1166
1447
|
});
|
|
1167
1448
|
} catch (error) {
|
|
1168
1449
|
if (isPgCtlNotRunningError(error)) {
|
|
1169
|
-
|
|
1450
|
+
logger8.warn(`PostgreSQL is not running (PGDATA: ${pgdata})`);
|
|
1170
1451
|
return;
|
|
1171
1452
|
}
|
|
1172
1453
|
throw error;
|
|
@@ -1210,7 +1491,7 @@ async function runDbCleanupCommand(options = {}) {
|
|
|
1210
1491
|
}
|
|
1211
1492
|
|
|
1212
1493
|
// src/commands/dev.ts
|
|
1213
|
-
import { createLogger as
|
|
1494
|
+
import { createLogger as createLogger11 } from "@revealui/setup/utils";
|
|
1214
1495
|
import { execa as execa6 } from "execa";
|
|
1215
1496
|
|
|
1216
1497
|
// src/runtime/doctor.ts
|
|
@@ -1346,8 +1627,8 @@ function writeDevConfig(config, startDir = process.cwd()) {
|
|
|
1346
1627
|
}
|
|
1347
1628
|
|
|
1348
1629
|
// src/commands/doctor.ts
|
|
1349
|
-
import { createLogger as
|
|
1350
|
-
var
|
|
1630
|
+
import { createLogger as createLogger9 } from "@revealui/setup/utils";
|
|
1631
|
+
var logger9 = createLogger9({ prefix: "Doctor" });
|
|
1351
1632
|
function getDoctorFixPlan(report) {
|
|
1352
1633
|
const attempted = [];
|
|
1353
1634
|
const skipped = [];
|
|
@@ -1405,7 +1686,7 @@ async function runDoctorCommand(options = {}) {
|
|
|
1405
1686
|
`);
|
|
1406
1687
|
if (options.fix) {
|
|
1407
1688
|
if (fixPlan.attempted.length === 0) {
|
|
1408
|
-
|
|
1689
|
+
logger9.warn("No safe automatic fixes available");
|
|
1409
1690
|
} else {
|
|
1410
1691
|
await applyDoctorFixes(report);
|
|
1411
1692
|
report = await gatherDoctorReport();
|
|
@@ -1414,7 +1695,7 @@ async function runDoctorCommand(options = {}) {
|
|
|
1414
1695
|
}
|
|
1415
1696
|
}
|
|
1416
1697
|
if (report.checks.some((check) => !check.ok)) {
|
|
1417
|
-
|
|
1698
|
+
logger9.warn("Some checks failed");
|
|
1418
1699
|
if (options.strict || options.json || process.env.CI) {
|
|
1419
1700
|
process.exitCode = 1;
|
|
1420
1701
|
}
|
|
@@ -1422,9 +1703,9 @@ async function runDoctorCommand(options = {}) {
|
|
|
1422
1703
|
}
|
|
1423
1704
|
|
|
1424
1705
|
// src/commands/shell.ts
|
|
1425
|
-
import { createLogger as
|
|
1706
|
+
import { createLogger as createLogger10 } from "@revealui/setup/utils";
|
|
1426
1707
|
import { execa as execa5 } from "execa";
|
|
1427
|
-
var
|
|
1708
|
+
var logger10 = createLogger10({ prefix: "Shell" });
|
|
1428
1709
|
async function runShellCommand(options = {}) {
|
|
1429
1710
|
if (!(options.inside || process.env.IN_NIX_SHELL) && await commandExists("nix")) {
|
|
1430
1711
|
const workspaceRoot = findWorkspaceRoot();
|
|
@@ -1469,12 +1750,12 @@ async function runShellCommand(options = {}) {
|
|
|
1469
1750
|
}
|
|
1470
1751
|
process.stdout.write(`${formatDoctorReport(freshReport)}
|
|
1471
1752
|
`);
|
|
1472
|
-
|
|
1753
|
+
logger10.info("Use `revealui doctor --json` for machine-readable status.");
|
|
1473
1754
|
return false;
|
|
1474
1755
|
}
|
|
1475
1756
|
|
|
1476
1757
|
// src/commands/dev.ts
|
|
1477
|
-
var
|
|
1758
|
+
var logger11 = createLogger11({ prefix: "Dev" });
|
|
1478
1759
|
var DEV_PROFILES = {
|
|
1479
1760
|
local: {},
|
|
1480
1761
|
agent: {
|
|
@@ -1600,20 +1881,20 @@ async function runDevUpCommand(options = {}) {
|
|
|
1600
1881
|
process.stdout.write(`${formatDevActions(plan)}
|
|
1601
1882
|
`);
|
|
1602
1883
|
if (plan.dryRun) {
|
|
1603
|
-
|
|
1884
|
+
logger11.info("Dry run only; no migrations or services were started.");
|
|
1604
1885
|
return;
|
|
1605
1886
|
}
|
|
1606
1887
|
if (options.fix) {
|
|
1607
1888
|
await runDoctorCommand({ fix: true });
|
|
1608
1889
|
}
|
|
1609
1890
|
await runDbMigrateCommand();
|
|
1610
|
-
|
|
1891
|
+
logger11.success("Database migration complete");
|
|
1611
1892
|
if (shouldIncludeMcp(resolved.include)) {
|
|
1612
1893
|
const workspaceRoot = findWorkspaceRoot();
|
|
1613
1894
|
if (!workspaceRoot) {
|
|
1614
1895
|
throw new Error("RevealUI workspace root not found");
|
|
1615
1896
|
}
|
|
1616
|
-
|
|
1897
|
+
logger11.info("Validating MCP setup");
|
|
1617
1898
|
await execa6("pnpm", ["setup:mcp"], {
|
|
1618
1899
|
cwd: workspaceRoot,
|
|
1619
1900
|
stdio: "inherit"
|
|
@@ -1624,7 +1905,7 @@ async function runDevUpCommand(options = {}) {
|
|
|
1624
1905
|
if (!workspaceRoot) {
|
|
1625
1906
|
throw new Error("RevealUI workspace root not found");
|
|
1626
1907
|
}
|
|
1627
|
-
|
|
1908
|
+
logger11.info(`Starting dev script: ${resolved.script}`);
|
|
1628
1909
|
await execa6("pnpm", [resolved.script], {
|
|
1629
1910
|
cwd: workspaceRoot,
|
|
1630
1911
|
stdio: "inherit"
|
|
@@ -1682,7 +1963,7 @@ async function runDevProfileSetCommand(profile) {
|
|
|
1682
1963
|
);
|
|
1683
1964
|
}
|
|
1684
1965
|
const configPath = writeDevConfig({ defaultProfile: profile });
|
|
1685
|
-
|
|
1966
|
+
logger11.success(`Default dev profile set to "${profile}" in ${configPath}`);
|
|
1686
1967
|
}
|
|
1687
1968
|
async function runDevProfileShowCommand(options = {}) {
|
|
1688
1969
|
const configuredProfile = getConfiguredProfile() ?? null;
|
|
@@ -1696,10 +1977,10 @@ async function runDevProfileShowCommand(options = {}) {
|
|
|
1696
1977
|
}
|
|
1697
1978
|
|
|
1698
1979
|
// src/cli.ts
|
|
1699
|
-
var
|
|
1980
|
+
var logger12 = createLogger12({ prefix: "CLI" });
|
|
1700
1981
|
function configureCreateCommand(command, legacyName) {
|
|
1701
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) => {
|
|
1702
|
-
|
|
1983
|
+
logger12.header(legacyName ? "Create RevealUI Project" : "RevealUI Create");
|
|
1703
1984
|
await runCreateFlow(projectName, options);
|
|
1704
1985
|
});
|
|
1705
1986
|
return command;
|
|
@@ -1711,6 +1992,17 @@ function createCli() {
|
|
|
1711
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) => {
|
|
1712
1993
|
await runDoctorCommand(options);
|
|
1713
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
|
+
});
|
|
1714
2006
|
const db = program.command("db").description("Manage the local RevealUI database");
|
|
1715
2007
|
db.command("init").description("Initialize the local PostgreSQL data directory").option("--force", "Delete and recreate the local data directory", false).action(async (options) => {
|
|
1716
2008
|
await runDbInitCommand(options);
|