@aixyz/cli 0.1.2 → 0.2.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/README.md +11 -1
- package/bin.ts +14 -6
- package/build/AixyzConfigPlugin.ts +29 -2
- package/build/AixyzServerPlugin.ts +30 -4
- package/build/index.ts +79 -4
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -34,12 +34,22 @@ aixyz-cli dev --port 8080
|
|
|
34
34
|
|
|
35
35
|
### `aixyz-cli build`
|
|
36
36
|
|
|
37
|
-
Build the agent for
|
|
37
|
+
Build the agent for deployment.
|
|
38
|
+
|
|
39
|
+
**Default behavior:** Bundles into a single file for Bun Runtime at `./.aixyz/output/server.js`
|
|
38
40
|
|
|
39
41
|
```bash
|
|
40
42
|
aixyz-cli build
|
|
41
43
|
```
|
|
42
44
|
|
|
45
|
+
**With --vercel flag or VERCEL=1:** Build for Vercel deployment using the [Build Output API v3](https://vercel.com/docs/build-output-api/v3) at `.vercel/output/`
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
aixyz-cli build --vercel
|
|
49
|
+
# or automatically detected on Vercel
|
|
50
|
+
VERCEL=1 aixyz-cli build
|
|
51
|
+
```
|
|
52
|
+
|
|
43
53
|
## License
|
|
44
54
|
|
|
45
55
|
MIT
|
package/bin.ts
CHANGED
|
@@ -27,27 +27,35 @@ program
|
|
|
27
27
|
|
|
28
28
|
program
|
|
29
29
|
.command("build")
|
|
30
|
-
.description("Build the aixyz agent
|
|
30
|
+
.description("Build the aixyz agent")
|
|
31
|
+
.option("--vercel", "Build for Vercel deployment with serverless function output")
|
|
31
32
|
.addHelpText(
|
|
32
33
|
"after",
|
|
33
34
|
`
|
|
34
35
|
Details:
|
|
35
|
-
Bundles your aixyz agent
|
|
36
|
+
Bundles your aixyz agent for deployment.
|
|
37
|
+
|
|
38
|
+
Default behavior:
|
|
39
|
+
Bundles into a single executable file for Bun Runtime at ./.aixyz/output/server.js
|
|
40
|
+
|
|
41
|
+
With --vercel flag or VERCEL=1 env:
|
|
42
|
+
Generates Vercel Build Output API v3 structure at .vercel/output/
|
|
43
|
+
(Automatically detected when deploying to Vercel)
|
|
36
44
|
|
|
37
45
|
The build process:
|
|
38
46
|
1. Loads aixyz.config.ts from the current directory
|
|
39
47
|
2. Detects entrypoint (app/server.ts or auto-generates from app/agent.ts + app/tools/)
|
|
40
|
-
3.
|
|
48
|
+
3. Bundles the application
|
|
41
49
|
4. Copies static assets from public/ (if present)
|
|
42
50
|
|
|
43
|
-
Output is written to .vercel/output/ in the current directory.
|
|
44
|
-
|
|
45
51
|
Prerequisites:
|
|
46
52
|
- An aixyz.config.ts with a default export
|
|
47
53
|
- An entrypoint at app/server.ts, or app/agent.ts + app/tools/ for auto-generation
|
|
48
54
|
|
|
49
55
|
Examples:
|
|
50
|
-
$ aixyz build
|
|
56
|
+
$ aixyz build # Build for Bun Runtime (default)
|
|
57
|
+
$ aixyz build --vercel # Build for Vercel deployment
|
|
58
|
+
$ VERCEL=1 aixyz build # Auto-detected Vercel build`,
|
|
51
59
|
)
|
|
52
60
|
.action(handleAction(build));
|
|
53
61
|
|
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
import { getAixyzConfig } from "@aixyz/config";
|
|
2
2
|
import type { BunPlugin } from "bun";
|
|
3
|
+
import boxen from "boxen";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
|
|
6
|
+
function label(text: string): string {
|
|
7
|
+
return chalk.dim(text.padEnd(14));
|
|
8
|
+
}
|
|
3
9
|
|
|
4
10
|
export function AixyzConfigPlugin(): BunPlugin {
|
|
5
11
|
const materialized = getAixyzConfig();
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
const maxLen = Math.max(materialized.url.length, materialized.x402.payTo.length);
|
|
14
|
+
const description =
|
|
15
|
+
materialized.description.length > maxLen
|
|
16
|
+
? materialized.description.slice(0, maxLen - 1) + "…"
|
|
17
|
+
: materialized.description;
|
|
18
|
+
|
|
19
|
+
const lines = [
|
|
20
|
+
`${label("Name")}${materialized.name}`,
|
|
21
|
+
`${label("Description")}${description}`,
|
|
22
|
+
`${label("URL")}${materialized.url}`,
|
|
23
|
+
`${label("Version")}${materialized.version}`,
|
|
24
|
+
`${label("x402 PayTo")}${materialized.x402.payTo}`,
|
|
25
|
+
`${label("x402 Network")}${materialized.x402.network}`,
|
|
26
|
+
];
|
|
27
|
+
console.log(
|
|
28
|
+
boxen(lines.join("\n"), {
|
|
29
|
+
padding: { left: 1, right: 1, top: 0, bottom: 0 },
|
|
30
|
+
borderStyle: "round",
|
|
31
|
+
borderColor: "green",
|
|
32
|
+
title: "aixyz.config.ts",
|
|
33
|
+
titleAlignment: "left",
|
|
34
|
+
}),
|
|
35
|
+
);
|
|
9
36
|
|
|
10
37
|
return {
|
|
11
38
|
name: "aixyz-config",
|
|
@@ -2,7 +2,7 @@ import type { BunPlugin } from "bun";
|
|
|
2
2
|
import { existsSync, mkdirSync, readdirSync, writeFileSync } from "fs";
|
|
3
3
|
import { resolve, relative, basename, join } from "path";
|
|
4
4
|
|
|
5
|
-
export function AixyzServerPlugin(entrypoint: string): BunPlugin {
|
|
5
|
+
export function AixyzServerPlugin(entrypoint: string, mode: "vercel" | "standalone"): BunPlugin {
|
|
6
6
|
return {
|
|
7
7
|
name: "aixyz-entrypoint",
|
|
8
8
|
setup(build) {
|
|
@@ -10,9 +10,28 @@ export function AixyzServerPlugin(entrypoint: string): BunPlugin {
|
|
|
10
10
|
if (args.path !== entrypoint) return;
|
|
11
11
|
|
|
12
12
|
const source = await Bun.file(args.path).text();
|
|
13
|
-
const transformed = source.replace(/export\s+default\s+(\w+)\s*;/, "export default $1.express;");
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
if (mode === "vercel") {
|
|
15
|
+
// For Vercel, export server.express for serverless function
|
|
16
|
+
const transformed = source.replace(/export\s+default\s+(\w+)\s*;/, "export default $1.express;");
|
|
17
|
+
return { contents: transformed, loader: "ts" };
|
|
18
|
+
} else {
|
|
19
|
+
// For standalone, keep the server export but add startup code
|
|
20
|
+
// TODO(@fuxingloh): use Bun.serve later.
|
|
21
|
+
const transformed = source.replace(
|
|
22
|
+
/export\s+default\s+(\w+)\s*;/,
|
|
23
|
+
`export default $1;
|
|
24
|
+
|
|
25
|
+
// Auto-start server when run directly
|
|
26
|
+
if (import.meta.main) {
|
|
27
|
+
const port = parseInt(process.env.PORT || "3000", 10);
|
|
28
|
+
$1.express.listen(port, () => {
|
|
29
|
+
console.log(\`Server listening on port \${port}\`);
|
|
30
|
+
});
|
|
31
|
+
}`,
|
|
32
|
+
);
|
|
33
|
+
return { contents: transformed, loader: "ts" };
|
|
34
|
+
}
|
|
16
35
|
});
|
|
17
36
|
},
|
|
18
37
|
};
|
|
@@ -47,6 +66,13 @@ function generateServer(appDir: string, entrypointDir: string): string {
|
|
|
47
66
|
|
|
48
67
|
imports.push('import { AixyzServer } from "aixyz/server";');
|
|
49
68
|
|
|
69
|
+
const hasAccepts = existsSync(resolve(appDir, "accepts.ts"));
|
|
70
|
+
if (hasAccepts) {
|
|
71
|
+
imports.push(`import { facilitator } from "${importPrefix}/accepts";`);
|
|
72
|
+
} else {
|
|
73
|
+
imports.push('import { facilitator } from "aixyz/accepts";');
|
|
74
|
+
}
|
|
75
|
+
|
|
50
76
|
const hasAgent = existsSync(resolve(appDir, "agent.ts"));
|
|
51
77
|
if (hasAgent) {
|
|
52
78
|
imports.push('import { useA2A } from "aixyz/server/adapters/a2a";');
|
|
@@ -74,7 +100,7 @@ function generateServer(appDir: string, entrypointDir: string): string {
|
|
|
74
100
|
}
|
|
75
101
|
}
|
|
76
102
|
|
|
77
|
-
body.push("const server = new AixyzServer();");
|
|
103
|
+
body.push("const server = new AixyzServer(facilitator);");
|
|
78
104
|
body.push("await server.initialize();");
|
|
79
105
|
body.push("server.unstable_withIndexPage();");
|
|
80
106
|
|
package/build/index.ts
CHANGED
|
@@ -2,12 +2,87 @@ import { resolve } from "path";
|
|
|
2
2
|
import { existsSync, mkdirSync, cpSync, rmSync } from "fs";
|
|
3
3
|
import { AixyzConfigPlugin } from "./AixyzConfigPlugin";
|
|
4
4
|
import { AixyzServerPlugin, getEntrypointMayGenerate } from "./AixyzServerPlugin";
|
|
5
|
+
import { loadEnvConfig } from "@next/env";
|
|
6
|
+
import chalk from "chalk";
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
interface BuildOptions {
|
|
9
|
+
vercel?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function build(options: BuildOptions = {}): Promise<void> {
|
|
13
|
+
// Auto-detect Vercel environment
|
|
14
|
+
const isVercel = options.vercel || process.env.VERCEL === "1";
|
|
8
15
|
|
|
16
|
+
const cwd = process.cwd();
|
|
17
|
+
loadEnvConfig(cwd, false);
|
|
9
18
|
const entrypoint = getEntrypointMayGenerate(cwd, "build");
|
|
10
19
|
|
|
20
|
+
if (isVercel) {
|
|
21
|
+
console.log(chalk.cyan("▶") + " Building for " + chalk.bold("Vercel") + "...");
|
|
22
|
+
await buildVercel(entrypoint);
|
|
23
|
+
} else {
|
|
24
|
+
console.log(chalk.cyan("▶") + " Building for " + chalk.bold("Bun Runtime") + "...");
|
|
25
|
+
await buildBun(entrypoint);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function buildBun(entrypoint: string): Promise<void> {
|
|
30
|
+
const cwd = process.cwd();
|
|
31
|
+
|
|
32
|
+
const outputDir = resolve(cwd, ".aixyz/output");
|
|
33
|
+
rmSync(outputDir, { recursive: true, force: true });
|
|
34
|
+
mkdirSync(outputDir, { recursive: true });
|
|
35
|
+
|
|
36
|
+
// Build as a single bundled file for Bun Runtime
|
|
37
|
+
const result = await Bun.build({
|
|
38
|
+
entrypoints: [entrypoint],
|
|
39
|
+
outdir: outputDir,
|
|
40
|
+
naming: "server.js",
|
|
41
|
+
target: "bun",
|
|
42
|
+
format: "esm",
|
|
43
|
+
sourcemap: "linked",
|
|
44
|
+
plugins: [AixyzConfigPlugin(), AixyzServerPlugin(entrypoint, "standalone")],
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (!result.success) {
|
|
48
|
+
console.error("Build failed:");
|
|
49
|
+
for (const log of result.logs) {
|
|
50
|
+
console.error(log);
|
|
51
|
+
}
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Write package.json for ESM support
|
|
56
|
+
await Bun.write(resolve(outputDir, "package.json"), JSON.stringify({ type: "module" }, null, 2));
|
|
57
|
+
|
|
58
|
+
// Copy static assets (public/ → .aixyz/output/public/)
|
|
59
|
+
const publicDir = resolve(cwd, "public");
|
|
60
|
+
if (existsSync(publicDir)) {
|
|
61
|
+
const destPublicDir = resolve(outputDir, "public");
|
|
62
|
+
cpSync(publicDir, destPublicDir, { recursive: true });
|
|
63
|
+
console.log("Copied public/ →", destPublicDir);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const iconFile = resolve(cwd, "app/icon.png");
|
|
67
|
+
if (existsSync(iconFile)) {
|
|
68
|
+
cpSync(iconFile, resolve(outputDir, "icon.png"));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Log summary
|
|
72
|
+
console.log("");
|
|
73
|
+
console.log("Build complete! Output:");
|
|
74
|
+
console.log(" .aixyz/output/server.js");
|
|
75
|
+
console.log(" .aixyz/output/package.json");
|
|
76
|
+
if (existsSync(publicDir) || existsSync(iconFile)) {
|
|
77
|
+
console.log(" .aixyz/output/public/ and assets");
|
|
78
|
+
}
|
|
79
|
+
console.log("");
|
|
80
|
+
console.log("To run: bun .aixyz/output/server.js");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function buildVercel(entrypoint: string): Promise<void> {
|
|
84
|
+
const cwd = process.cwd();
|
|
85
|
+
|
|
11
86
|
const outputDir = resolve(cwd, ".vercel/output");
|
|
12
87
|
rmSync(outputDir, { recursive: true, force: true });
|
|
13
88
|
|
|
@@ -22,7 +97,7 @@ export async function build(): Promise<void> {
|
|
|
22
97
|
target: "bun",
|
|
23
98
|
format: "esm",
|
|
24
99
|
sourcemap: "linked",
|
|
25
|
-
plugins: [AixyzConfigPlugin(), AixyzServerPlugin(entrypoint)],
|
|
100
|
+
plugins: [AixyzConfigPlugin(), AixyzServerPlugin(entrypoint, "vercel")],
|
|
26
101
|
});
|
|
27
102
|
|
|
28
103
|
if (!result.success) {
|
|
@@ -85,6 +160,6 @@ export async function build(): Promise<void> {
|
|
|
85
160
|
console.log("");
|
|
86
161
|
console.log("Build complete! Output:");
|
|
87
162
|
console.log(" .vercel/output/config.json");
|
|
88
|
-
console.log(" .vercel/output/functions/index.func/
|
|
163
|
+
console.log(" .vercel/output/functions/index.func/server.js");
|
|
89
164
|
console.log(" .vercel/output/static/");
|
|
90
165
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aixyz/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI for building and deploying aixyz agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@aixyz/config": "workspace:*",
|
|
34
34
|
"@next/env": "^16.1.6",
|
|
35
|
-
"
|
|
35
|
+
"boxen": "^8.0.0",
|
|
36
|
+
"chalk": "^5.0.0",
|
|
37
|
+
"commander": "^14.0.3"
|
|
36
38
|
},
|
|
37
39
|
"engines": {
|
|
38
40
|
"bun": ">=1.3.0"
|