@voltx/cli 0.3.4 → 0.3.6
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/README.md +54 -22
- package/dist/build.d.mts +4 -3
- package/dist/build.d.ts +4 -3
- package/dist/build.js +56 -27
- package/dist/build.mjs +1 -2
- package/dist/chunk-2LHDOMF2.mjs +680 -0
- package/dist/chunk-5DVBIJXU.mjs +84 -0
- package/dist/chunk-65PVXS4D.mjs +894 -0
- package/dist/chunk-7JVIEGSA.mjs +141 -0
- package/dist/chunk-A4NA4AJN.mjs +786 -0
- package/dist/chunk-AAAHANST.mjs +839 -0
- package/dist/chunk-AD3WMFZF.mjs +205 -0
- package/dist/chunk-CSSHLVYS.mjs +83 -0
- package/dist/chunk-CWOSNV5O.mjs +150 -0
- package/dist/chunk-EI6XBYKB.mjs +84 -0
- package/dist/chunk-FI2W4L4S.mjs +205 -0
- package/dist/chunk-G2INQCCJ.mjs +907 -0
- package/dist/chunk-H2DTIOEO.mjs +150 -0
- package/dist/chunk-IS2WTE3C.mjs +138 -0
- package/dist/chunk-JECCDBYI.mjs +730 -0
- package/dist/chunk-KX2MRJUO.mjs +795 -0
- package/dist/chunk-LTGMHAZS.mjs +147 -0
- package/dist/chunk-OPO6RUFP.mjs +698 -0
- package/dist/chunk-PWQSKYAM.mjs +682 -0
- package/dist/chunk-Q5XCFN7L.mjs +1026 -0
- package/dist/chunk-QSU6FZC7.mjs +497 -0
- package/dist/chunk-RYWRFHEC.mjs +83 -0
- package/dist/chunk-SU4Q3PTH.mjs +201 -0
- package/dist/chunk-TFVNHM7S.mjs +1028 -0
- package/dist/chunk-UXI3QSDN.mjs +121 -0
- package/dist/chunk-VD3CNPNP.mjs +123 -0
- package/dist/chunk-X6VOAPRJ.mjs +756 -0
- package/dist/cli.js +935 -308
- package/dist/cli.mjs +7 -6
- package/dist/create.d.mts +1 -0
- package/dist/create.d.ts +1 -0
- package/dist/create.js +726 -192
- package/dist/create.mjs +1 -2
- package/dist/dev.d.mts +6 -4
- package/dist/dev.d.ts +6 -4
- package/dist/dev.js +119 -46
- package/dist/dev.mjs +1 -2
- package/dist/generate.js +13 -13
- package/dist/generate.mjs +1 -2
- package/dist/index.js +922 -296
- package/dist/index.mjs +5 -6
- package/dist/start.js +7 -17
- package/dist/start.mjs +1 -2
- package/dist/welcome.mjs +0 -1
- package/package.json +11 -3
package/dist/create.mjs
CHANGED
package/dist/dev.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
interface DevOptions {
|
|
2
2
|
/** Port override (reads from voltx.config.ts or env if not set) */
|
|
3
3
|
port?: number;
|
|
4
|
-
/** Entry file (default:
|
|
4
|
+
/** Entry file (default: server.ts) */
|
|
5
5
|
entry?: string;
|
|
6
6
|
/** Extra directories to watch */
|
|
7
7
|
watch?: string[];
|
|
@@ -9,10 +9,12 @@ interface DevOptions {
|
|
|
9
9
|
clearScreen?: boolean;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* Start the VoltX dev server
|
|
12
|
+
* Start the VoltX dev server.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* Detects whether the project is full-stack (has vite.config.ts or server.ts).
|
|
15
|
+
* - If yes: starts Vite with @hono/vite-dev-server plugin — one process,
|
|
16
|
+
* one port, frontend HMR + backend API routes together.
|
|
17
|
+
* - If no: spawns tsx watch for fast API-only development.
|
|
16
18
|
*/
|
|
17
19
|
declare function runDev(options?: DevOptions): Promise<void>;
|
|
18
20
|
|
package/dist/dev.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
interface DevOptions {
|
|
2
2
|
/** Port override (reads from voltx.config.ts or env if not set) */
|
|
3
3
|
port?: number;
|
|
4
|
-
/** Entry file (default:
|
|
4
|
+
/** Entry file (default: server.ts) */
|
|
5
5
|
entry?: string;
|
|
6
6
|
/** Extra directories to watch */
|
|
7
7
|
watch?: string[];
|
|
@@ -9,10 +9,12 @@ interface DevOptions {
|
|
|
9
9
|
clearScreen?: boolean;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* Start the VoltX dev server
|
|
12
|
+
* Start the VoltX dev server.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* Detects whether the project is full-stack (has vite.config.ts or server.ts).
|
|
15
|
+
* - If yes: starts Vite with @hono/vite-dev-server plugin — one process,
|
|
16
|
+
* one port, frontend HMR + backend API routes together.
|
|
17
|
+
* - If no: spawns tsx watch for fast API-only development.
|
|
16
18
|
*/
|
|
17
19
|
declare function runDev(options?: DevOptions): Promise<void>;
|
|
18
20
|
|
package/dist/dev.js
CHANGED
|
@@ -26,6 +26,7 @@ module.exports = __toCommonJS(dev_exports);
|
|
|
26
26
|
var import_node_child_process = require("child_process");
|
|
27
27
|
var import_node_path = require("path");
|
|
28
28
|
var import_node_fs = require("fs");
|
|
29
|
+
var import_core = require("@voltx/core");
|
|
29
30
|
async function runDev(options = {}) {
|
|
30
31
|
const cwd = process.cwd();
|
|
31
32
|
const {
|
|
@@ -34,7 +35,7 @@ async function runDev(options = {}) {
|
|
|
34
35
|
clearScreen = true
|
|
35
36
|
} = options;
|
|
36
37
|
if (!entry) {
|
|
37
|
-
console.error("[voltx] Could not find entry point. Expected
|
|
38
|
+
console.error("[voltx] Could not find entry point. Expected server.ts or src/index.ts");
|
|
38
39
|
process.exit(1);
|
|
39
40
|
}
|
|
40
41
|
const entryPath = (0, import_node_path.resolve)(cwd, entry);
|
|
@@ -42,56 +43,124 @@ async function runDev(options = {}) {
|
|
|
42
43
|
console.error(`[voltx] Entry file not found: ${entry}`);
|
|
43
44
|
process.exit(1);
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
+
(0, import_core.loadEnv)("development", cwd);
|
|
47
|
+
const hasViteConfig = (0, import_node_fs.existsSync)((0, import_node_path.resolve)(cwd, "vite.config.ts"));
|
|
48
|
+
const hasServerEntry = (0, import_node_fs.existsSync)((0, import_node_path.resolve)(cwd, "server.ts"));
|
|
49
|
+
const isFullStack = hasViteConfig || hasServerEntry;
|
|
50
|
+
if (isFullStack) {
|
|
51
|
+
await startViteDevServer(cwd, port, entry, options);
|
|
52
|
+
} else {
|
|
53
|
+
await startTsxWatch(cwd, port, entry, options);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function startViteDevServer(cwd, port, entry, options) {
|
|
57
|
+
const resolvedPort = port ?? (Number(process.env.PORT) || 3e3);
|
|
58
|
+
printDevBanner(entry, resolvedPort, true);
|
|
59
|
+
const userViteConfig = (0, import_node_path.resolve)(cwd, "vite.config.ts");
|
|
60
|
+
const hasUserViteConfig = (0, import_node_fs.existsSync)(userViteConfig);
|
|
61
|
+
let tempConfigPath = null;
|
|
62
|
+
if (!hasUserViteConfig) {
|
|
63
|
+
tempConfigPath = (0, import_node_path.resolve)(cwd, "vite.config.voltx.ts");
|
|
64
|
+
const viteConfigContent = generateViteConfig(entry, resolvedPort);
|
|
65
|
+
(0, import_node_fs.writeFileSync)(tempConfigPath, viteConfigContent, "utf-8");
|
|
66
|
+
}
|
|
46
67
|
const env = {
|
|
47
68
|
...process.env,
|
|
48
69
|
NODE_ENV: "development"
|
|
49
70
|
};
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
71
|
+
if (port) {
|
|
72
|
+
env.PORT = String(port);
|
|
73
|
+
}
|
|
74
|
+
const viteBin = findBin(cwd, "vite");
|
|
75
|
+
const viteArgs = ["dev"];
|
|
76
|
+
if (tempConfigPath) {
|
|
77
|
+
viteArgs.push("--config", tempConfigPath);
|
|
78
|
+
}
|
|
79
|
+
viteArgs.push("--port", String(resolvedPort));
|
|
80
|
+
let child;
|
|
81
|
+
if (viteBin) {
|
|
82
|
+
child = (0, import_node_child_process.spawn)(viteBin, viteArgs, { cwd, env, stdio: "inherit" });
|
|
83
|
+
} else {
|
|
84
|
+
child = (0, import_node_child_process.spawn)("npx", ["vite", ...viteArgs], { cwd, env, stdio: "inherit" });
|
|
85
|
+
}
|
|
86
|
+
const cleanup = () => {
|
|
87
|
+
if (tempConfigPath && (0, import_node_fs.existsSync)(tempConfigPath)) {
|
|
88
|
+
try {
|
|
89
|
+
(0, import_node_fs.unlinkSync)(tempConfigPath);
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
60
92
|
}
|
|
93
|
+
};
|
|
94
|
+
const signals = ["SIGINT", "SIGTERM"];
|
|
95
|
+
for (const signal of signals) {
|
|
96
|
+
process.on(signal, () => {
|
|
97
|
+
cleanup();
|
|
98
|
+
child.kill(signal);
|
|
99
|
+
});
|
|
61
100
|
}
|
|
101
|
+
child.on("error", (err) => {
|
|
102
|
+
cleanup();
|
|
103
|
+
if (err.code === "ENOENT") {
|
|
104
|
+
console.error("[voltx] vite not found. Install it with: npm install -D vite @hono/vite-dev-server");
|
|
105
|
+
} else {
|
|
106
|
+
console.error("[voltx] Dev server error:", err.message);
|
|
107
|
+
}
|
|
108
|
+
process.exit(1);
|
|
109
|
+
});
|
|
110
|
+
child.on("exit", (code) => {
|
|
111
|
+
cleanup();
|
|
112
|
+
process.exit(code ?? 0);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function generateViteConfig(entry, port) {
|
|
116
|
+
return `// Auto-generated by VoltX \u2014 do not commit this file
|
|
117
|
+
import { defineConfig } from "vite";
|
|
118
|
+
import devServer from "@hono/vite-dev-server";
|
|
119
|
+
|
|
120
|
+
export default defineConfig({
|
|
121
|
+
server: {
|
|
122
|
+
port: ${port},
|
|
123
|
+
},
|
|
124
|
+
plugins: [
|
|
125
|
+
devServer({
|
|
126
|
+
entry: "${entry}",
|
|
127
|
+
exclude: [
|
|
128
|
+
/.*\\.tsx?($|\\?)/,
|
|
129
|
+
/.*\\.(s?css|less)($|\\?)/,
|
|
130
|
+
/.*\\.(svg|png|jpg|jpeg|gif|webp|ico)($|\\?)/,
|
|
131
|
+
/^\\/@.+$/,
|
|
132
|
+
/^\\/favicon\\.svg$/,
|
|
133
|
+
/^\\/node_modules\\/.*/,
|
|
134
|
+
/^\\/src\\/.*/,
|
|
135
|
+
],
|
|
136
|
+
injectClientScript: false,
|
|
137
|
+
}),
|
|
138
|
+
],
|
|
139
|
+
});
|
|
140
|
+
`;
|
|
141
|
+
}
|
|
142
|
+
async function startTsxWatch(cwd, port, entry, options) {
|
|
143
|
+
const resolvedPort = port ?? (Number(process.env.PORT) || 3e3);
|
|
144
|
+
printDevBanner(entry, resolvedPort, false);
|
|
145
|
+
const env = {
|
|
146
|
+
...process.env,
|
|
147
|
+
NODE_ENV: "development"
|
|
148
|
+
};
|
|
62
149
|
if (port) {
|
|
63
150
|
env.PORT = String(port);
|
|
64
151
|
}
|
|
65
|
-
printDevBanner(entry, port);
|
|
66
152
|
const tsxArgs = ["watch"];
|
|
67
|
-
if (clearScreen) {
|
|
153
|
+
if (options.clearScreen ?? true) {
|
|
68
154
|
tsxArgs.push("--clear-screen=false");
|
|
69
155
|
}
|
|
70
|
-
const watchDirs = [
|
|
71
|
-
"src/routes",
|
|
72
|
-
"src/agents",
|
|
73
|
-
"src/tools",
|
|
74
|
-
"src/jobs",
|
|
75
|
-
"src/lib",
|
|
76
|
-
"voltx.config.ts",
|
|
77
|
-
...options.watch ?? []
|
|
78
|
-
];
|
|
79
156
|
tsxArgs.push("--ignore=node_modules", "--ignore=dist", "--ignore=.turbo");
|
|
80
157
|
tsxArgs.push(entry);
|
|
81
|
-
const tsxBin =
|
|
158
|
+
const tsxBin = findBin(cwd, "tsx");
|
|
82
159
|
let child;
|
|
83
160
|
if (tsxBin) {
|
|
84
|
-
child = (0, import_node_child_process.spawn)(tsxBin, tsxArgs, {
|
|
85
|
-
cwd,
|
|
86
|
-
env,
|
|
87
|
-
stdio: "inherit"
|
|
88
|
-
});
|
|
161
|
+
child = (0, import_node_child_process.spawn)(tsxBin, tsxArgs, { cwd, env, stdio: "inherit" });
|
|
89
162
|
} else {
|
|
90
|
-
child = (0, import_node_child_process.spawn)("npx", ["tsx", ...tsxArgs], {
|
|
91
|
-
cwd,
|
|
92
|
-
env,
|
|
93
|
-
stdio: "inherit"
|
|
94
|
-
});
|
|
163
|
+
child = (0, import_node_child_process.spawn)("npx", ["tsx", ...tsxArgs], { cwd, env, stdio: "inherit" });
|
|
95
164
|
}
|
|
96
165
|
const signals = ["SIGINT", "SIGTERM"];
|
|
97
166
|
for (const signal of signals) {
|
|
@@ -102,7 +171,6 @@ async function runDev(options = {}) {
|
|
|
102
171
|
child.on("error", (err) => {
|
|
103
172
|
if (err.code === "ENOENT") {
|
|
104
173
|
console.error("[voltx] tsx not found. Install it with: npm install -D tsx");
|
|
105
|
-
console.error("[voltx] Or run your app directly: npx tsx watch src/index.ts");
|
|
106
174
|
} else {
|
|
107
175
|
console.error("[voltx] Dev server error:", err.message);
|
|
108
176
|
}
|
|
@@ -114,6 +182,8 @@ async function runDev(options = {}) {
|
|
|
114
182
|
}
|
|
115
183
|
function findEntryPoint(cwd) {
|
|
116
184
|
const candidates = [
|
|
185
|
+
"server.ts",
|
|
186
|
+
"server.js",
|
|
117
187
|
"src/index.ts",
|
|
118
188
|
"src/index.js",
|
|
119
189
|
"src/index.mts",
|
|
@@ -129,24 +199,27 @@ function findEntryPoint(cwd) {
|
|
|
129
199
|
}
|
|
130
200
|
return null;
|
|
131
201
|
}
|
|
132
|
-
function
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
202
|
+
function findBin(cwd, name) {
|
|
203
|
+
const paths = [
|
|
204
|
+
(0, import_node_path.join)(cwd, "node_modules", ".bin", name),
|
|
205
|
+
(0, import_node_path.join)(cwd, "..", "node_modules", ".bin", name),
|
|
206
|
+
(0, import_node_path.join)(cwd, "..", "..", "node_modules", ".bin", name)
|
|
207
|
+
];
|
|
208
|
+
for (const p of paths) {
|
|
209
|
+
if ((0, import_node_fs.existsSync)(p)) return p;
|
|
210
|
+
}
|
|
139
211
|
return null;
|
|
140
212
|
}
|
|
141
|
-
function printDevBanner(entry, port) {
|
|
213
|
+
function printDevBanner(entry, port, fullStack) {
|
|
142
214
|
console.log("");
|
|
143
215
|
console.log(" \u26A1 VoltX Dev Server");
|
|
144
216
|
console.log(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
145
217
|
console.log(` Entry: ${entry}`);
|
|
146
|
-
|
|
147
|
-
|
|
218
|
+
console.log(` Port: ${port}`);
|
|
219
|
+
console.log(` Mode: ${fullStack ? "full-stack (Vite + Hono)" : "API-only (tsx watch)"}`);
|
|
220
|
+
if (fullStack) {
|
|
221
|
+
console.log(` HMR: enabled (frontend + backend)`);
|
|
148
222
|
}
|
|
149
|
-
console.log(` Mode: development (hot reload)`);
|
|
150
223
|
console.log(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
151
224
|
console.log("");
|
|
152
225
|
}
|
package/dist/dev.mjs
CHANGED
package/dist/generate.js
CHANGED
|
@@ -49,13 +49,13 @@ async function runGenerate(options) {
|
|
|
49
49
|
}
|
|
50
50
|
function generateRoute(cwd, name, method = "POST") {
|
|
51
51
|
const routePath = name.startsWith("/") ? name.slice(1) : name;
|
|
52
|
-
const filePath = (0, import_node_path.join)(cwd, "
|
|
52
|
+
const filePath = (0, import_node_path.join)(cwd, "api", `${routePath}.ts`);
|
|
53
53
|
if ((0, import_node_fs.existsSync)(filePath)) {
|
|
54
|
-
console.error(`[voltx] Route already exists:
|
|
54
|
+
console.error(`[voltx] Route already exists: api/${routePath}.ts`);
|
|
55
55
|
process.exit(1);
|
|
56
56
|
}
|
|
57
57
|
const upperMethod = method.toUpperCase();
|
|
58
|
-
const urlPath = "/" + routePath;
|
|
58
|
+
const urlPath = "/api/" + routePath;
|
|
59
59
|
const content = `// ${upperMethod} ${urlPath}
|
|
60
60
|
import type { Context } from "@voltx/server";
|
|
61
61
|
|
|
@@ -64,13 +64,13 @@ export async function ${upperMethod}(c: Context) {
|
|
|
64
64
|
}
|
|
65
65
|
`;
|
|
66
66
|
writeFileSafe(filePath, content);
|
|
67
|
-
console.log(` \u2713 Created route:
|
|
67
|
+
console.log(` \u2713 Created route: api/${routePath}.ts`);
|
|
68
68
|
console.log(` ${upperMethod} ${urlPath}`);
|
|
69
69
|
}
|
|
70
70
|
function generateAgent(cwd, name) {
|
|
71
|
-
const filePath = (0, import_node_path.join)(cwd, "
|
|
71
|
+
const filePath = (0, import_node_path.join)(cwd, "agents", `${name}.ts`);
|
|
72
72
|
if ((0, import_node_fs.existsSync)(filePath)) {
|
|
73
|
-
console.error(`[voltx] Agent already exists:
|
|
73
|
+
console.error(`[voltx] Agent already exists: agents/${name}.ts`);
|
|
74
74
|
process.exit(1);
|
|
75
75
|
}
|
|
76
76
|
const content = `// Agent: ${name}
|
|
@@ -92,12 +92,12 @@ export const ${toCamelCase(name)} = createAgent({
|
|
|
92
92
|
});
|
|
93
93
|
`;
|
|
94
94
|
writeFileSafe(filePath, content);
|
|
95
|
-
console.log(` \u2713 Created agent:
|
|
95
|
+
console.log(` \u2713 Created agent: agents/${name}.ts`);
|
|
96
96
|
}
|
|
97
97
|
function generateTool(cwd, name) {
|
|
98
|
-
const filePath = (0, import_node_path.join)(cwd, "
|
|
98
|
+
const filePath = (0, import_node_path.join)(cwd, "tools", `${name}.ts`);
|
|
99
99
|
if ((0, import_node_fs.existsSync)(filePath)) {
|
|
100
|
-
console.error(`[voltx] Tool already exists:
|
|
100
|
+
console.error(`[voltx] Tool already exists: tools/${name}.ts`);
|
|
101
101
|
process.exit(1);
|
|
102
102
|
}
|
|
103
103
|
const content = `// Tool: ${name}
|
|
@@ -119,12 +119,12 @@ export const ${toCamelCase(name)}Tool = {
|
|
|
119
119
|
};
|
|
120
120
|
`;
|
|
121
121
|
writeFileSafe(filePath, content);
|
|
122
|
-
console.log(` \u2713 Created tool:
|
|
122
|
+
console.log(` \u2713 Created tool: tools/${name}.ts`);
|
|
123
123
|
}
|
|
124
124
|
function generateJob(cwd, name) {
|
|
125
|
-
const filePath = (0, import_node_path.join)(cwd, "
|
|
125
|
+
const filePath = (0, import_node_path.join)(cwd, "jobs", `${name}.ts`);
|
|
126
126
|
if ((0, import_node_fs.existsSync)(filePath)) {
|
|
127
|
-
console.error(`[voltx] Job already exists:
|
|
127
|
+
console.error(`[voltx] Job already exists: jobs/${name}.ts`);
|
|
128
128
|
process.exit(1);
|
|
129
129
|
}
|
|
130
130
|
const content = `// Job: ${name}
|
|
@@ -149,7 +149,7 @@ export async function run(ctx: any, data?: Record<string, unknown>) {
|
|
|
149
149
|
}
|
|
150
150
|
`;
|
|
151
151
|
writeFileSafe(filePath, content);
|
|
152
|
-
console.log(` \u2713 Created job:
|
|
152
|
+
console.log(` \u2713 Created job: jobs/${name}.ts`);
|
|
153
153
|
}
|
|
154
154
|
function writeFileSafe(filePath, content) {
|
|
155
155
|
const dir = (0, import_node_path.dirname)(filePath);
|