@gea-ai/cli 0.1.260920-alpha.1 → 0.1.260925-alpha.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/package.json CHANGED
@@ -12,17 +12,32 @@
12
12
  "directory": "packages/gea-cli"
13
13
  },
14
14
  "type": "module",
15
- "version": "0.1.260920-alpha.1",
15
+ "version": "0.1.260925-alpha.0",
16
16
  "bin": {
17
17
  "gea": "gea-launcher.cjs"
18
18
  },
19
19
  "files": [
20
20
  "gea-launcher.cjs",
21
+ "vite.mjs",
22
+ "vite.d.ts",
23
+ "runtime.mjs",
24
+ "runtime.d.ts",
21
25
  "LICENSE"
22
26
  ],
27
+ "exports": {
28
+ "./package.json": "./package.json",
29
+ "./vite": {
30
+ "types": "./vite.d.ts",
31
+ "import": "./vite.mjs"
32
+ },
33
+ "./runtime": {
34
+ "types": "./runtime.d.ts",
35
+ "import": "./runtime.mjs"
36
+ }
37
+ },
23
38
  "name": "@gea-ai/cli",
24
39
  "optionalDependencies": {
25
- "@gea-ai/cli-darwin-arm64": "0.1.260920-alpha.1",
40
+ "@gea-ai/cli-darwin-arm64": "0.1.260925-alpha.0",
26
41
  "@gea-ai/cli-win32-x64": "0.1.260920-alpha.1"
27
42
  },
28
43
  "os": [
package/runtime.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function geaInstallation(environment?: NodeJS.ProcessEnv): { cli: string; runtime: string; systemWorkers: string };
2
+ export declare function developmentEnvironment(root: string): NodeJS.ProcessEnv;
package/runtime.mjs ADDED
@@ -0,0 +1,48 @@
1
+ // src/vite-env.ts
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { createRequire } from "node:module";
4
+ import { dirname, join, resolve } from "node:path";
5
+ import { parseEnv } from "node:util";
6
+ function developmentEnvironment(root) {
7
+ const file = join(root, ".dev.vars");
8
+ return {
9
+ ...existsSync(file) ? parseEnv(readFileSync(file, "utf8")) : {},
10
+ ...process.env
11
+ };
12
+ }
13
+ function geaInstallation(environment = process.env) {
14
+ let distributionRoot = environment.GEA_CLI_DISTRIBUTION_ROOT;
15
+ if (!distributionRoot && (!environment.GEA_CLI_BINARY || !environment.GEA_WORKER_RUNTIME_BINARY || !environment.WORKER_RUNTIME_SYSTEM_WORKER_ROOT)) {
16
+ const cliRequire = createRequire(import.meta.url);
17
+ const target = process.platform === "darwin" && process.arch === "arm64" ? "darwin-arm64" : process.platform === "win32" && process.arch === "x64" ? "win32-x64" : null;
18
+ if (!target)
19
+ throw new Error(
20
+ "Set GEA_CLI_BINARY, GEA_WORKER_RUNTIME_BINARY and WORKER_RUNTIME_SYSTEM_WORKER_ROOT for this platform."
21
+ );
22
+ distributionRoot = dirname(
23
+ cliRequire.resolve(`@gea-ai/cli-${target}/package.json`)
24
+ );
25
+ }
26
+ const cli = environment.GEA_CLI_BINARY ?? join(
27
+ distributionRoot,
28
+ process.platform === "win32" ? "gea-windows-x64.exe" : "gea-darwin-arm64"
29
+ );
30
+ const runtime = environment.GEA_WORKER_RUNTIME_BINARY ?? join(
31
+ distributionRoot,
32
+ process.platform === "win32" ? "gea-worker-runtime.exe" : "gea-worker-runtime"
33
+ );
34
+ const systemWorkers = environment.WORKER_RUNTIME_SYSTEM_WORKER_ROOT ?? join(distributionRoot, "system-workers");
35
+ for (const path of [cli, runtime, join(systemWorkers, "filesystem.mjs")]) {
36
+ if (!existsSync(path))
37
+ throw new Error(`GEA installation is incomplete: ${path}`);
38
+ }
39
+ return {
40
+ cli: resolve(cli),
41
+ runtime: resolve(runtime),
42
+ systemWorkers: resolve(systemWorkers)
43
+ };
44
+ }
45
+ export {
46
+ developmentEnvironment,
47
+ geaInstallation
48
+ };
package/vite.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function geaWorker(): import("vite").Plugin;
package/vite.mjs ADDED
@@ -0,0 +1,255 @@
1
+ // src/vite.ts
2
+ import { spawn } from "node:child_process";
3
+ import { once } from "node:events";
4
+ import { createServer, request as proxyRequest } from "node:http";
5
+
6
+ // src/vite-env.ts
7
+ import { existsSync, readFileSync } from "node:fs";
8
+ import { createRequire } from "node:module";
9
+ import { dirname, join, resolve } from "node:path";
10
+ import { parseEnv } from "node:util";
11
+ function developmentEnvironment(root) {
12
+ const file = join(root, ".dev.vars");
13
+ return {
14
+ ...existsSync(file) ? parseEnv(readFileSync(file, "utf8")) : {},
15
+ ...process.env
16
+ };
17
+ }
18
+ function geaInstallation(environment = process.env) {
19
+ let distributionRoot = environment.GEA_CLI_DISTRIBUTION_ROOT;
20
+ if (!distributionRoot && (!environment.GEA_CLI_BINARY || !environment.GEA_WORKER_RUNTIME_BINARY || !environment.WORKER_RUNTIME_SYSTEM_WORKER_ROOT)) {
21
+ const cliRequire = createRequire(import.meta.url);
22
+ const target = process.platform === "darwin" && process.arch === "arm64" ? "darwin-arm64" : process.platform === "win32" && process.arch === "x64" ? "win32-x64" : null;
23
+ if (!target)
24
+ throw new Error(
25
+ "Set GEA_CLI_BINARY, GEA_WORKER_RUNTIME_BINARY and WORKER_RUNTIME_SYSTEM_WORKER_ROOT for this platform."
26
+ );
27
+ distributionRoot = dirname(
28
+ cliRequire.resolve(`@gea-ai/cli-${target}/package.json`)
29
+ );
30
+ }
31
+ const cli = environment.GEA_CLI_BINARY ?? join(
32
+ distributionRoot,
33
+ process.platform === "win32" ? "gea-windows-x64.exe" : "gea-darwin-arm64"
34
+ );
35
+ const runtime = environment.GEA_WORKER_RUNTIME_BINARY ?? join(
36
+ distributionRoot,
37
+ process.platform === "win32" ? "gea-worker-runtime.exe" : "gea-worker-runtime"
38
+ );
39
+ const systemWorkers = environment.WORKER_RUNTIME_SYSTEM_WORKER_ROOT ?? join(distributionRoot, "system-workers");
40
+ for (const path of [cli, runtime, join(systemWorkers, "filesystem.mjs")]) {
41
+ if (!existsSync(path))
42
+ throw new Error(`GEA installation is incomplete: ${path}`);
43
+ }
44
+ return {
45
+ cli: resolve(cli),
46
+ runtime: resolve(runtime),
47
+ systemWorkers: resolve(systemWorkers)
48
+ };
49
+ }
50
+
51
+ // src/vite.ts
52
+ async function reservePort() {
53
+ const listener = createServer();
54
+ listener.listen(0, "127.0.0.1");
55
+ await once(listener, "listening");
56
+ const address = listener.address();
57
+ if (!address || typeof address === "string")
58
+ throw new Error("Could not allocate development port.");
59
+ await new Promise((resolve2) => listener.close(() => resolve2()));
60
+ return address.port;
61
+ }
62
+ function geaWorker() {
63
+ let stopWorker;
64
+ return {
65
+ async closeBundle() {
66
+ await stopWorker?.();
67
+ },
68
+ name: "gea-worker",
69
+ enforce: "pre",
70
+ transform(code, id) {
71
+ if (id.endsWith(".md"))
72
+ return { code: `export default ${JSON.stringify(code)};`, map: null };
73
+ },
74
+ config() {
75
+ return {
76
+ environments: {
77
+ ssr: {
78
+ resolve: {
79
+ noExternal: true,
80
+ external: [
81
+ "@gea-ai/agent-sdk",
82
+ "ai",
83
+ "cloudflare:workers",
84
+ "node:async_hooks",
85
+ "node:stream",
86
+ "node:stream/web"
87
+ ],
88
+ conditions: ["workerd", "worker", "browser"]
89
+ },
90
+ build: {
91
+ rollupOptions: {
92
+ input: "worker.ts",
93
+ external: [
94
+ /^@gea-ai\/agent-sdk(?:\/|$)/,
95
+ "ai",
96
+ "cloudflare:workers",
97
+ "node:async_hooks",
98
+ "node:stream",
99
+ "node:stream/web"
100
+ ],
101
+ output: {
102
+ inlineDynamicImports: true,
103
+ entryFileNames: "index.js"
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
109
+ };
110
+ },
111
+ async configureServer(server) {
112
+ const environment = developmentEnvironment(server.config.root);
113
+ const installation = geaInstallation(environment);
114
+ const port = await reservePort();
115
+ const apiPort = await reservePort();
116
+ const origin = `http://127.0.0.1:${port}`;
117
+ const agentEnvironment = environment.AGENT_ENVIRONMENT ?? "local";
118
+ if (agentEnvironment === "local" && server.config.server.host !== "127.0.0.1")
119
+ throw new Error(
120
+ "Local Agents API development must bind Vite to 127.0.0.1."
121
+ );
122
+ const child = spawn(
123
+ installation.cli,
124
+ [
125
+ "agent",
126
+ "dev",
127
+ "--json",
128
+ JSON.stringify({
129
+ cwd: server.config.root,
130
+ host: "127.0.0.1",
131
+ port,
132
+ apiPort,
133
+ vite: false
134
+ })
135
+ ],
136
+ {
137
+ cwd: server.config.root,
138
+ env: {
139
+ ...environment,
140
+ APP_ORIGIN: environment.APP_ORIGIN ?? `http://127.0.0.1:${server.config.server.port ?? 4e3}`,
141
+ AGENT_ENVIRONMENT: agentEnvironment,
142
+ ...agentEnvironment === "local" ? { LOCAL_AGENTS_API_URL: `http://127.0.0.1:${apiPort}` } : {},
143
+ NODE_ENV: "production",
144
+ GEA_WORKER_RUNTIME_BINARY: installation.runtime,
145
+ WORKER_RUNTIME_SYSTEM_WORKER_ROOT: installation.systemWorkers
146
+ },
147
+ stdio: ["ignore", "pipe", "pipe"]
148
+ }
149
+ );
150
+ let output = "";
151
+ let stopping;
152
+ const stop = () => stopping ??= (async () => {
153
+ if (!child.pid || child.exitCode !== null || child.signalCode !== null)
154
+ return;
155
+ const exited = once(child, "exit");
156
+ child.kill("SIGTERM");
157
+ await exited;
158
+ })();
159
+ stopWorker = stop;
160
+ const restart = server.restart.bind(server);
161
+ server.restart = async (force) => {
162
+ await stop();
163
+ await restart(force);
164
+ };
165
+ server.httpServer?.once("close", () => {
166
+ void stop();
167
+ });
168
+ child.stdout.on("data", (chunk) => process.stdout.write(chunk));
169
+ child.stderr.on("data", (chunk) => {
170
+ process.stderr.write(chunk);
171
+ output += chunk;
172
+ const lines = output.split("\n");
173
+ output = lines.pop();
174
+ if (lines.some(
175
+ (line) => line.startsWith("[gea] Agent Worker reloaded at deployment ") || line === "[gea] Agent Worker Runtime restarted."
176
+ ))
177
+ server.ws.send({ type: "full-reload" });
178
+ });
179
+ let startupError;
180
+ child.once("error", (error) => {
181
+ startupError = error;
182
+ });
183
+ try {
184
+ const deadline = Date.now() + 6e4;
185
+ while (true) {
186
+ if (startupError) throw startupError;
187
+ if (child.exitCode !== null || child.signalCode !== null)
188
+ throw new Error(
189
+ "GEA development process exited. See its output above."
190
+ );
191
+ try {
192
+ const response = await fetch(`${origin}/gea/agents/run`, {
193
+ method: "OPTIONS"
194
+ });
195
+ await response.body?.cancel();
196
+ if (response.ok) break;
197
+ } catch {
198
+ }
199
+ if (Date.now() > deadline)
200
+ throw new Error("GEA development startup timed out.");
201
+ await new Promise((resolve2) => setTimeout(resolve2, 200));
202
+ }
203
+ } catch (error) {
204
+ await stop();
205
+ throw error;
206
+ }
207
+ server.middlewares.use((request, response, next) => {
208
+ const pathname = new URL(request.url ?? "/", origin).pathname;
209
+ if (pathname.startsWith("/@vite/") || pathname.startsWith("/@id/") || pathname.startsWith("/node_modules/") && pathname.endsWith("/vite/dist/client/env.mjs"))
210
+ return next();
211
+ const upstream = proxyRequest(
212
+ new URL(request.url ?? "/", origin),
213
+ {
214
+ method: request.method,
215
+ headers: {
216
+ ...request.headers,
217
+ "x-forwarded-host": request.headers.host ?? "",
218
+ "x-forwarded-proto": "http"
219
+ }
220
+ },
221
+ (incoming) => {
222
+ incoming.on("error", (error) => response.destroy(error));
223
+ const html = incoming.headers["content-type"]?.includes("text/html");
224
+ const headers = { ...incoming.headers };
225
+ if (html) delete headers["content-length"];
226
+ response.writeHead(incoming.statusCode ?? 502, headers);
227
+ if (!html) return void incoming.pipe(response);
228
+ const chunks = [];
229
+ incoming.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
230
+ incoming.on(
231
+ "end",
232
+ () => response.end(
233
+ Buffer.concat(chunks).toString("utf8").replace(
234
+ "</head>",
235
+ '<script type="module" src="/@vite/client"></script></head>'
236
+ )
237
+ )
238
+ );
239
+ }
240
+ );
241
+ upstream.on("error", (error) => {
242
+ if (response.headersSent) response.destroy(error);
243
+ else response.writeHead(502).end("GEA Worker is unavailable.");
244
+ });
245
+ response.once("close", () => {
246
+ if (!response.writableEnded) upstream.destroy();
247
+ });
248
+ request.pipe(upstream);
249
+ });
250
+ }
251
+ };
252
+ }
253
+ export {
254
+ geaWorker
255
+ };