@amd-gaia/gaia 0.1.0 → 0.1.1
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/CHANGELOG.md +93 -0
- package/LICENSE +21 -0
- package/README.md +200 -6
- package/SKILL.md +473 -0
- package/SPEC.md +393 -0
- package/binaries.lock.json +78 -0
- package/dist/cli.d.ts +41 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +368 -0
- package/dist/cli.js.map +1 -0
- package/dist/errors.d.ts +32 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +42 -0
- package/dist/errors.js.map +1 -0
- package/dist/fetch.d.ts +110 -0
- package/dist/fetch.d.ts.map +1 -0
- package/dist/fetch.js +217 -0
- package/dist/fetch.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle.d.ts +145 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +397 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/logger.d.ts +13 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +30 -0
- package/dist/logger.js.map +1 -0
- package/dist/platform.d.ts +100 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +202 -0
- package/dist/platform.js.map +1 -0
- package/dist/url.d.ts +4 -0
- package/dist/url.d.ts.map +1 -0
- package/dist/url.js +22 -0
- package/dist/url.js.map +1 -0
- package/package.json +66 -15
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
// Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
/**
|
|
4
|
+
* Process lifecycle for the two binaries this package installs.
|
|
5
|
+
*
|
|
6
|
+
* **Sidecar** — locate the frozen binary, spawn it, poll `GET /health`, check the
|
|
7
|
+
* contract version via `GET /version`, and shut it down killing the whole process
|
|
8
|
+
* tree. Tree-kill matters: a PyInstaller one-file build spawns a child uvicorn
|
|
9
|
+
* process that `child.kill()` on the parent does NOT reap, leaving the port held.
|
|
10
|
+
*
|
|
11
|
+
* **TUI** — exec it with stdio inherited and propagate its exit code, so the
|
|
12
|
+
* terminal UI owns the terminal completely.
|
|
13
|
+
*
|
|
14
|
+
* Note on who spawns the sidecar in the normal `gaia` flow: the GAIA daemon does.
|
|
15
|
+
* The TUI reaches agents through the daemon's relay and deliberately never holds a
|
|
16
|
+
* sidecar bearer token, so `gaia run` stages the *verified* sidecar binary into the
|
|
17
|
+
* daemon's cache and lets the daemon own its process. The helpers below are the
|
|
18
|
+
* direct path — used by `gaia serve` and by programmatic integrators who want the
|
|
19
|
+
* REST surface without a daemon.
|
|
20
|
+
*/
|
|
21
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
22
|
+
import fs from "node:fs";
|
|
23
|
+
import path from "node:path";
|
|
24
|
+
import { BinaryNotFoundError, HealthTimeoutError, HttpError, VersionMismatchError, } from "./errors.js";
|
|
25
|
+
import { createLogger } from "./logger.js";
|
|
26
|
+
import { currentPlatformKey } from "./platform.js";
|
|
27
|
+
const log = createLogger("lifecycle");
|
|
28
|
+
export const DEFAULT_HOST = "127.0.0.1";
|
|
29
|
+
/** Matches `gaia_agent_gaia.server.DEFAULT_PORT`. NEVER 4001 (repo-reserved). */
|
|
30
|
+
export const DEFAULT_PORT = 8141;
|
|
31
|
+
/** Repo-wide reserved port. Nothing here may ever bind it. */
|
|
32
|
+
export const RESERVED_PORT = 4001;
|
|
33
|
+
/** The apiVersion this package is built against (`server.py: API_VERSION`). */
|
|
34
|
+
export const API_VERSION = "2.12";
|
|
35
|
+
/** The agent id in the sidecar's route prefix (`/v1/gaia/...`). */
|
|
36
|
+
export const AGENT_ID = "gaia";
|
|
37
|
+
/** Basename the sidecar executable is written as (matches the lock). */
|
|
38
|
+
export function sidecarExecutableName(platform = process.platform) {
|
|
39
|
+
return platform === "win32" ? "gaia-agent.exe" : "gaia-agent";
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Basename the TUI executable is written as. Deliberately `gaia-tui`, not
|
|
43
|
+
* `gaia`: npm installs its own `gaia` bin shim, and a same-named executable in a
|
|
44
|
+
* cache dir on PATH would shadow it.
|
|
45
|
+
*/
|
|
46
|
+
export function tuiExecutableName(platform = process.platform) {
|
|
47
|
+
return platform === "win32" ? "gaia-tui.exe" : "gaia-tui";
|
|
48
|
+
}
|
|
49
|
+
/** Resolve a fetched binary's path, failing loudly if it is not there. */
|
|
50
|
+
function resolveIn(opts, fallback, what) {
|
|
51
|
+
if (!opts?.resourcesDir) {
|
|
52
|
+
throw new TypeError("resolve requires { resourcesDir }");
|
|
53
|
+
}
|
|
54
|
+
const full = path.resolve(opts.resourcesDir, opts.executable ?? fallback);
|
|
55
|
+
if (!fs.existsSync(full)) {
|
|
56
|
+
throw new BinaryNotFoundError(`${what} binary not found at ${full} (platform ${currentPlatformKey()}). ` +
|
|
57
|
+
"Run the fetch step first: `npx @amd-gaia/gaia fetch`.");
|
|
58
|
+
}
|
|
59
|
+
return full;
|
|
60
|
+
}
|
|
61
|
+
export function resolveSidecarPath(opts) {
|
|
62
|
+
return resolveIn(opts, sidecarExecutableName(), "gaia-agent sidecar");
|
|
63
|
+
}
|
|
64
|
+
export function resolveTuiPath(opts) {
|
|
65
|
+
return resolveIn(opts, tuiExecutableName(), "gaia-tui");
|
|
66
|
+
}
|
|
67
|
+
// --- Auto-cleanup: reap orphaned sidecars when the parent process goes away ---
|
|
68
|
+
// The sidecar is spawned detached (its own process group), so a parent Ctrl+C,
|
|
69
|
+
// crash, or plain exit does NOT propagate to it — without this it keeps running
|
|
70
|
+
// and holds its port. Handlers are installed once and SIGKILL the tree
|
|
71
|
+
// synchronously on the way out. A hard SIGKILL of the parent is the one case no
|
|
72
|
+
// in-process handler can catch.
|
|
73
|
+
const liveSidecars = new Set();
|
|
74
|
+
let cleanupInstalled = false;
|
|
75
|
+
const CLEANUP_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
76
|
+
function killTreeSync(sidecar) {
|
|
77
|
+
const { child } = sidecar;
|
|
78
|
+
if (child.pid === undefined)
|
|
79
|
+
return;
|
|
80
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
81
|
+
return;
|
|
82
|
+
try {
|
|
83
|
+
if (process.platform === "win32") {
|
|
84
|
+
spawnSync("taskkill", ["/PID", String(child.pid), "/T", "/F"], { stdio: "ignore" });
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
process.kill(-child.pid, "SIGKILL");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
/* already gone */
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function reapAllSync() {
|
|
95
|
+
for (const s of liveSidecars)
|
|
96
|
+
killTreeSync(s);
|
|
97
|
+
liveSidecars.clear();
|
|
98
|
+
}
|
|
99
|
+
function crashHandler(err) {
|
|
100
|
+
reapAllSync();
|
|
101
|
+
try {
|
|
102
|
+
// Synchronous write — console.error can truncate on a piped stderr before
|
|
103
|
+
// process.exit flushes.
|
|
104
|
+
fs.writeSync(2, `${err instanceof Error ? (err.stack ?? err.message) : String(err)}\n`);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
/* stderr unavailable */
|
|
108
|
+
}
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
function installCleanupHandlers() {
|
|
112
|
+
if (cleanupInstalled)
|
|
113
|
+
return;
|
|
114
|
+
cleanupInstalled = true;
|
|
115
|
+
process.on("exit", reapAllSync);
|
|
116
|
+
process.on("uncaughtException", (err) => {
|
|
117
|
+
reapAllSync();
|
|
118
|
+
if (process.listenerCount("uncaughtException") === 1)
|
|
119
|
+
crashHandler(err);
|
|
120
|
+
});
|
|
121
|
+
process.on("unhandledRejection", (err) => {
|
|
122
|
+
reapAllSync();
|
|
123
|
+
if (process.listenerCount("unhandledRejection") === 1)
|
|
124
|
+
crashHandler(err);
|
|
125
|
+
});
|
|
126
|
+
for (const sig of CLEANUP_SIGNALS) {
|
|
127
|
+
const handler = () => {
|
|
128
|
+
reapAllSync();
|
|
129
|
+
// Sole listener → restore the default disposition and re-raise so the
|
|
130
|
+
// process still terminates (Ctrl+C).
|
|
131
|
+
if (process.listenerCount(sig) === 1) {
|
|
132
|
+
process.removeListener(sig, handler);
|
|
133
|
+
process.kill(process.pid, sig);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
process.on(sig, handler);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function registerForCleanup(sidecar) {
|
|
140
|
+
installCleanupHandlers();
|
|
141
|
+
liveSidecars.add(sidecar);
|
|
142
|
+
sidecar.child.once("exit", () => liveSidecars.delete(sidecar));
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Spawn the frozen sidecar. Does NOT wait for readiness — call `waitForHealth`
|
|
146
|
+
* (or `startSidecar`, which does both).
|
|
147
|
+
*/
|
|
148
|
+
export function spawnSidecar(opts) {
|
|
149
|
+
if (!opts?.binaryPath) {
|
|
150
|
+
throw new TypeError("spawnSidecar requires { binaryPath }");
|
|
151
|
+
}
|
|
152
|
+
if (!fs.existsSync(opts.binaryPath)) {
|
|
153
|
+
throw new BinaryNotFoundError(`binary does not exist: ${opts.binaryPath}`);
|
|
154
|
+
}
|
|
155
|
+
const host = opts.host ?? DEFAULT_HOST;
|
|
156
|
+
const port = opts.port ?? DEFAULT_PORT;
|
|
157
|
+
if (port === RESERVED_PORT) {
|
|
158
|
+
throw new RangeError(`port ${RESERVED_PORT} is reserved and must never be used`);
|
|
159
|
+
}
|
|
160
|
+
const args = ["--host", host, "--port", String(port)];
|
|
161
|
+
if (opts.extraArgs?.length)
|
|
162
|
+
args.push(...opts.extraArgs);
|
|
163
|
+
log.info(`spawning ${opts.binaryPath} ${args.join(" ")}`);
|
|
164
|
+
const child = spawn(opts.binaryPath, args, {
|
|
165
|
+
// detached on POSIX → the child leads its own process group so we can signal
|
|
166
|
+
// the whole tree. Windows has different detach semantics; we use taskkill /T.
|
|
167
|
+
detached: process.platform !== "win32",
|
|
168
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
169
|
+
env: { ...process.env, ...(opts.env ?? {}) },
|
|
170
|
+
});
|
|
171
|
+
child.stdout?.on("data", (d) => log.debug(`[sidecar stdout] ${String(d).trimEnd()}`));
|
|
172
|
+
child.stderr?.on("data", (d) => log.debug(`[sidecar stderr] ${String(d).trimEnd()}`));
|
|
173
|
+
child.on("exit", (code, signal) => log.debug(`sidecar exited code=${code} signal=${signal}`));
|
|
174
|
+
child.on("error", (e) => log.error(`sidecar process error: ${e.message}`));
|
|
175
|
+
const sidecar = { child, host, port, baseUrl: `http://${host}:${port}` };
|
|
176
|
+
if (opts.autoCleanup !== false)
|
|
177
|
+
registerForCleanup(sidecar);
|
|
178
|
+
return sidecar;
|
|
179
|
+
}
|
|
180
|
+
async function getJson(url, timeoutMs) {
|
|
181
|
+
const controller = new AbortController();
|
|
182
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
183
|
+
try {
|
|
184
|
+
const res = await fetch(url, {
|
|
185
|
+
headers: { accept: "application/json" },
|
|
186
|
+
signal: controller.signal,
|
|
187
|
+
});
|
|
188
|
+
const text = await res.text();
|
|
189
|
+
if (!res.ok)
|
|
190
|
+
throw new HttpError(res.status, url, text);
|
|
191
|
+
return JSON.parse(text);
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
194
|
+
clearTimeout(timer);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/** `GET /health` — liveness only; it does not mean a model is loaded. */
|
|
198
|
+
export function health(baseUrl, timeoutMs = 1000) {
|
|
199
|
+
return getJson(`${baseUrl}/health`, timeoutMs);
|
|
200
|
+
}
|
|
201
|
+
/** `GET /version` — the contract probe (`{ apiVersion, agentVersion }`). */
|
|
202
|
+
export function version(baseUrl, timeoutMs = 5000) {
|
|
203
|
+
return getJson(`${baseUrl}/version`, timeoutMs);
|
|
204
|
+
}
|
|
205
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
206
|
+
/**
|
|
207
|
+
* Poll `GET /health` until the sidecar reports ok, or throw `HealthTimeoutError`.
|
|
208
|
+
* Never silently assumes ready.
|
|
209
|
+
*/
|
|
210
|
+
export async function waitForHealth(baseUrl, opts = {}) {
|
|
211
|
+
const timeoutMs = opts.timeoutMs ?? 60_000;
|
|
212
|
+
const intervalMs = opts.intervalMs ?? 250;
|
|
213
|
+
const deadline = Date.now() + timeoutMs;
|
|
214
|
+
let lastErr = "";
|
|
215
|
+
let attempts = 0;
|
|
216
|
+
while (Date.now() < deadline) {
|
|
217
|
+
if (opts.signal?.aborted) {
|
|
218
|
+
throw new HealthTimeoutError(`health wait for ${baseUrl} was aborted after ${attempts} probe(s) ` +
|
|
219
|
+
"(the process being probed exited).");
|
|
220
|
+
}
|
|
221
|
+
attempts++;
|
|
222
|
+
try {
|
|
223
|
+
const h = await health(baseUrl, intervalMs * 4);
|
|
224
|
+
if (h.status === "ok") {
|
|
225
|
+
log.debug(`sidecar healthy after ${attempts} probe(s)`);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
lastErr = `unexpected health status: ${JSON.stringify(h)}`;
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
lastErr = e.message;
|
|
232
|
+
}
|
|
233
|
+
await sleep(intervalMs);
|
|
234
|
+
}
|
|
235
|
+
throw new HealthTimeoutError(`the gaia sidecar at ${baseUrl} did not become healthy within ${timeoutMs}ms ` +
|
|
236
|
+
`(${attempts} probes). Last error: ${lastErr}. ` +
|
|
237
|
+
"Re-run with DEBUG=gaia to see the sidecar's own output, and check the port is free.");
|
|
238
|
+
}
|
|
239
|
+
/** Parse "2.12" → 2 (major). Throws on a non-numeric major. */
|
|
240
|
+
function majorOf(v) {
|
|
241
|
+
const major = Number.parseInt(String(v).split(".")[0] ?? "", 10);
|
|
242
|
+
if (Number.isNaN(major)) {
|
|
243
|
+
throw new VersionMismatchError(`cannot parse apiVersion major from '${v}'`);
|
|
244
|
+
}
|
|
245
|
+
return major;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Fetch `/version` and refuse a sidecar whose apiVersion MAJOR differs from what
|
|
249
|
+
* this package expects. A major bump is a breaking contract change; a higher
|
|
250
|
+
* minor (same major) is a backward-compatible addition and is accepted.
|
|
251
|
+
*/
|
|
252
|
+
export async function checkVersion(baseUrl, opts = {}) {
|
|
253
|
+
const expected = opts.expectedApiVersion ?? API_VERSION;
|
|
254
|
+
const info = await version(baseUrl);
|
|
255
|
+
const expectedMajor = majorOf(expected);
|
|
256
|
+
const actualMajor = majorOf(info.apiVersion);
|
|
257
|
+
if (actualMajor !== expectedMajor) {
|
|
258
|
+
throw new VersionMismatchError(`incompatible gaia sidecar apiVersion: it reports '${info.apiVersion}' ` +
|
|
259
|
+
`(major ${actualMajor}) but this package expects major ${expectedMajor} ` +
|
|
260
|
+
`('${expected}'). A major bump is a breaking contract change. ` +
|
|
261
|
+
"Upgrade @amd-gaia/gaia to a version matching the sidecar.");
|
|
262
|
+
}
|
|
263
|
+
log.debug(`version OK: apiVersion=${info.apiVersion} agentVersion=${info.agentVersion}`);
|
|
264
|
+
return info;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Shut the sidecar down, killing the whole process tree. Resolves once the
|
|
268
|
+
* process has exited (or immediately if it already had).
|
|
269
|
+
*/
|
|
270
|
+
export async function shutdown(sidecar, timeoutMs = 5000) {
|
|
271
|
+
const { child } = sidecar;
|
|
272
|
+
liveSidecars.delete(sidecar); // an explicit shutdown owns the lifecycle now
|
|
273
|
+
if (child.exitCode !== null || child.signalCode !== null || child.pid === undefined) {
|
|
274
|
+
log.debug("shutdown: sidecar already exited");
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const pid = child.pid;
|
|
278
|
+
log.info(`shutting down sidecar pid=${pid} (tree-kill)`);
|
|
279
|
+
const exited = new Promise((resolve) => {
|
|
280
|
+
child.once("exit", () => resolve());
|
|
281
|
+
});
|
|
282
|
+
if (process.platform === "win32") {
|
|
283
|
+
const killer = spawn("taskkill", ["/PID", String(pid), "/T", "/F"], {
|
|
284
|
+
stdio: "ignore",
|
|
285
|
+
});
|
|
286
|
+
killer.on("error", (e) => log.error(`taskkill failed: ${e.message}`));
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
try {
|
|
290
|
+
process.kill(-pid, "SIGTERM"); // negative pid → the whole process group
|
|
291
|
+
}
|
|
292
|
+
catch (e) {
|
|
293
|
+
log.debug(`SIGTERM to group failed (${e.message}); trying direct`);
|
|
294
|
+
try {
|
|
295
|
+
child.kill("SIGTERM");
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
/* already gone */
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const raceExit = async (ms) => {
|
|
303
|
+
let t;
|
|
304
|
+
const timer = new Promise((resolve) => {
|
|
305
|
+
t = setTimeout(() => resolve("timeout"), ms);
|
|
306
|
+
});
|
|
307
|
+
return Promise.race([exited.then(() => "exited"), timer]).finally(() => clearTimeout(t));
|
|
308
|
+
};
|
|
309
|
+
if ((await raceExit(timeoutMs)) === "timeout") {
|
|
310
|
+
log.warn(`sidecar did not exit within ${timeoutMs}ms; forcing`);
|
|
311
|
+
if (process.platform !== "win32") {
|
|
312
|
+
try {
|
|
313
|
+
process.kill(-pid, "SIGKILL");
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
/* gone */
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
// Bound the final wait too. On Windows there is no second escalation after
|
|
320
|
+
// taskkill, so an unbounded await here would hang Ctrl+C forever.
|
|
321
|
+
if ((await raceExit(timeoutMs)) === "timeout") {
|
|
322
|
+
throw new Error(`the gaia sidecar (pid ${pid}) did not exit after a forced kill. ` +
|
|
323
|
+
"Kill it manually — " +
|
|
324
|
+
(process.platform === "win32"
|
|
325
|
+
? `taskkill /PID ${pid} /T /F`
|
|
326
|
+
: `kill -9 -${pid}`) +
|
|
327
|
+
` — or the port it holds stays bound.`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
log.info("sidecar shut down");
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Spawn → wait for health → (optionally) version-check. On any failure the
|
|
334
|
+
* sidecar is shut down before rethrowing, so a failed start never leaks a
|
|
335
|
+
* process.
|
|
336
|
+
*/
|
|
337
|
+
export async function startSidecar(opts) {
|
|
338
|
+
const sidecar = spawnSidecar(opts);
|
|
339
|
+
// A sidecar that dies immediately (missing runtime lib, port already bound)
|
|
340
|
+
// must not make the caller wait out the full health timeout.
|
|
341
|
+
const died = new AbortController();
|
|
342
|
+
sidecar.child.once("exit", () => died.abort());
|
|
343
|
+
try {
|
|
344
|
+
await waitForHealth(sidecar.baseUrl, {
|
|
345
|
+
timeoutMs: opts.healthTimeoutMs,
|
|
346
|
+
signal: died.signal,
|
|
347
|
+
});
|
|
348
|
+
if (opts.verifyVersion ?? true) {
|
|
349
|
+
await checkVersion(sidecar.baseUrl, {
|
|
350
|
+
expectedApiVersion: opts.expectedApiVersion,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
return sidecar;
|
|
354
|
+
}
|
|
355
|
+
catch (e) {
|
|
356
|
+
log.error(`startSidecar failed (${e.message}); shutting down`);
|
|
357
|
+
await shutdown(sidecar).catch(() => undefined);
|
|
358
|
+
throw e;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Run the TUI in the foreground with stdio inherited and resolve with its exit
|
|
363
|
+
* code. A signal-terminated TUI resolves as 128 + signum, the shell convention,
|
|
364
|
+
* so a Ctrl+C is distinguishable from a clean exit 0.
|
|
365
|
+
*/
|
|
366
|
+
export function runTui(opts) {
|
|
367
|
+
if (!opts?.binaryPath) {
|
|
368
|
+
throw new TypeError("runTui requires { binaryPath }");
|
|
369
|
+
}
|
|
370
|
+
if (!fs.existsSync(opts.binaryPath)) {
|
|
371
|
+
throw new BinaryNotFoundError(`gaia-tui binary does not exist: ${opts.binaryPath}`);
|
|
372
|
+
}
|
|
373
|
+
return new Promise((resolve, reject) => {
|
|
374
|
+
const child = spawn(opts.binaryPath, opts.args ?? [], {
|
|
375
|
+
stdio: "inherit",
|
|
376
|
+
env: { ...process.env, ...(opts.env ?? {}) },
|
|
377
|
+
});
|
|
378
|
+
child.on("error", (e) => reject(new BinaryNotFoundError(`could not launch the TUI at ${opts.binaryPath}: ${e.message}`)));
|
|
379
|
+
child.on("exit", (code, signal) => {
|
|
380
|
+
if (signal) {
|
|
381
|
+
resolve(128 + (SIGNUM[signal] ?? 0));
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
resolve(code ?? 0);
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
// Only the signals a foreground TUI realistically dies from; anything else maps
|
|
389
|
+
// to 128, which still reads as "terminated by a signal".
|
|
390
|
+
const SIGNUM = {
|
|
391
|
+
SIGHUP: 1,
|
|
392
|
+
SIGINT: 2,
|
|
393
|
+
SIGQUIT: 3,
|
|
394
|
+
SIGKILL: 9,
|
|
395
|
+
SIGTERM: 15,
|
|
396
|
+
};
|
|
397
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal namespaced logger. Debug output is OFF by default and enabled via the
|
|
3
|
+
* `DEBUG` env var (substring match on `gaia`, or `*`). Everything goes to stderr
|
|
4
|
+
* so it never corrupts stdout — which the TUI owns once it is exec'd.
|
|
5
|
+
*/
|
|
6
|
+
export interface Logger {
|
|
7
|
+
debug(msg: string, ...rest: unknown[]): void;
|
|
8
|
+
info(msg: string, ...rest: unknown[]): void;
|
|
9
|
+
warn(msg: string, ...rest: unknown[]): void;
|
|
10
|
+
error(msg: string, ...rest: unknown[]): void;
|
|
11
|
+
}
|
|
12
|
+
export declare function createLogger(namespace: string): Logger;
|
|
13
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAOH,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC7C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAC9C;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAgBtD"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
/**
|
|
4
|
+
* Minimal namespaced logger. Debug output is OFF by default and enabled via the
|
|
5
|
+
* `DEBUG` env var (substring match on `gaia`, or `*`). Everything goes to stderr
|
|
6
|
+
* so it never corrupts stdout — which the TUI owns once it is exec'd.
|
|
7
|
+
*/
|
|
8
|
+
function debugEnabled() {
|
|
9
|
+
const d = (typeof process !== "undefined" && process.env?.["DEBUG"]) || "";
|
|
10
|
+
return d === "*" || d.includes("gaia");
|
|
11
|
+
}
|
|
12
|
+
export function createLogger(namespace) {
|
|
13
|
+
const tag = `[gaia:${namespace}]`;
|
|
14
|
+
return {
|
|
15
|
+
debug(msg, ...rest) {
|
|
16
|
+
if (debugEnabled())
|
|
17
|
+
console.error(`${tag} ${msg}`, ...rest);
|
|
18
|
+
},
|
|
19
|
+
info(msg, ...rest) {
|
|
20
|
+
console.error(`${tag} ${msg}`, ...rest);
|
|
21
|
+
},
|
|
22
|
+
warn(msg, ...rest) {
|
|
23
|
+
console.error(`${tag} WARN ${msg}`, ...rest);
|
|
24
|
+
},
|
|
25
|
+
error(msg, ...rest) {
|
|
26
|
+
console.error(`${tag} ERROR ${msg}`, ...rest);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,+BAA+B;AAC/B;;;;GAIG;AAEH,SAAS,YAAY;IACnB,MAAM,CAAC,GAAG,CAAC,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3E,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC;AASD,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,MAAM,GAAG,GAAG,SAAS,SAAS,GAAG,CAAC;IAClC,OAAO;QACL,KAAK,CAAC,GAAG,EAAE,GAAG,IAAI;YAChB,IAAI,YAAY,EAAE;gBAAE,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI;YACf,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI;YACf,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,SAAS,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC/C,CAAC;QACD,KAAK,CAAC,GAAG,EAAE,GAAG,IAAI;YAChB,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,UAAU,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAChD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform/arch resolution and binary-lock loading.
|
|
3
|
+
*
|
|
4
|
+
* The lock file (`binaries.lock.json`, shipped in the published package) is the
|
|
5
|
+
* single source of truth for which artifacts to download for the current host
|
|
6
|
+
* and what their SHA-256 must be. Platform keys are
|
|
7
|
+
* `${process.platform}-${process.arch}`.
|
|
8
|
+
*
|
|
9
|
+
* The lock is keyed by COMPONENT first (`sidecar` and `tui`), because
|
|
10
|
+
* `npx @amd-gaia/gaia` needs both and they differ in three ways: platform
|
|
11
|
+
* coverage (the Go TUI cross-compiles to arm64 Linux/Windows, the frozen Python
|
|
12
|
+
* sidecar does not), version, and — since schemaVersion 3.0 — the hub lane they
|
|
13
|
+
* are published in.
|
|
14
|
+
*
|
|
15
|
+
* The two lanes:
|
|
16
|
+
*
|
|
17
|
+
* sidecar agents/gaia/<agentVersion>/ built by this package's release
|
|
18
|
+
* tui agents/terminal-hub/<tuiVersion>/ the `terminal-hub` component,
|
|
19
|
+
* published by the core release
|
|
20
|
+
*
|
|
21
|
+
* The TUI is therefore the SAME binary as `gaia tui` from a core install — this
|
|
22
|
+
* package consumes it rather than building a second copy, so the two can never
|
|
23
|
+
* drift in behaviour or version. Each component carries its own `baseUrl`, which
|
|
24
|
+
* is what schemaVersion 2.0's single top-level `baseUrl` could not express.
|
|
25
|
+
*
|
|
26
|
+
* The terminal-hub lane spells its Windows artifacts `win-x64` / `win-arm64`,
|
|
27
|
+
* while Node's `process.platform` gives `win32`. That difference is carried by
|
|
28
|
+
* the entry's `filename` (data), never by a code path — see `TUI_ARTIFACT_NAMES`.
|
|
29
|
+
*/
|
|
30
|
+
/** The two binaries `npx @amd-gaia/gaia` needs. */
|
|
31
|
+
export declare const COMPONENTS: readonly ["sidecar", "tui"];
|
|
32
|
+
export type ComponentName = (typeof COMPONENTS)[number];
|
|
33
|
+
/** The lock schema this package reads. Loading any other major fails loudly. */
|
|
34
|
+
export declare const SCHEMA_MAJOR = 3;
|
|
35
|
+
/** One component+platform artifact entry in the lock file. */
|
|
36
|
+
export interface BinaryLockEntry {
|
|
37
|
+
/** Artifact filename as published under the component's base URL. */
|
|
38
|
+
filename: string;
|
|
39
|
+
/** Lowercase hex SHA-256 of the downloaded artifact. */
|
|
40
|
+
sha256: string;
|
|
41
|
+
/** Size in bytes (informational; not enforced). */
|
|
42
|
+
size?: number;
|
|
43
|
+
/** Basename the executable is written as on disk (with platform ext). */
|
|
44
|
+
executable: string;
|
|
45
|
+
}
|
|
46
|
+
/** One component's lane: where it is published, at what version, for which platforms. */
|
|
47
|
+
export interface ComponentLock {
|
|
48
|
+
/** The component's own released version — not necessarily `agentVersion`. */
|
|
49
|
+
componentVersion: string;
|
|
50
|
+
/** Download base URL for THIS component. Overridable at fetch time. */
|
|
51
|
+
baseUrl: string;
|
|
52
|
+
platforms: Record<string, BinaryLockEntry>;
|
|
53
|
+
}
|
|
54
|
+
/** The whole lock file (`binaries.lock.json`), schemaVersion 3.x. */
|
|
55
|
+
export interface BinaryLock {
|
|
56
|
+
schemaVersion: string;
|
|
57
|
+
agentVersion: string;
|
|
58
|
+
components: Record<string, ComponentLock>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Platform keys the sidecar publishes for. PyInstaller freezes on the host it
|
|
62
|
+
* runs on and there is no arm64 Linux/Windows CI runner for it, so this is a
|
|
63
|
+
* strict subset of the TUI's coverage.
|
|
64
|
+
*/
|
|
65
|
+
export declare const SUPPORTED_SIDECAR_PLATFORMS: readonly ["win32-x64", "darwin-arm64", "darwin-x64", "linux-x64"];
|
|
66
|
+
/** Platform keys the TUI publishes for (Go cross-compiles all six). */
|
|
67
|
+
export declare const SUPPORTED_TUI_PLATFORMS: readonly ["win32-x64", "win32-arm64", "darwin-arm64", "darwin-x64", "linux-x64", "linux-arm64"];
|
|
68
|
+
/** Every platform key at least one component publishes for. */
|
|
69
|
+
export declare const SUPPORTED_PLATFORMS: readonly ["win32-x64", "win32-arm64", "darwin-arm64", "darwin-x64", "linux-x64", "linux-arm64"];
|
|
70
|
+
/**
|
|
71
|
+
* npm platform key → the artifact name the terminal-hub lane publishes.
|
|
72
|
+
*
|
|
73
|
+
* The mapping exists for exactly one reason: terminal-hub names its Windows
|
|
74
|
+
* builds `win-x64` / `win-arm64` (Go's GOOS vocabulary), while our keys come
|
|
75
|
+
* from `process.platform`, which says `win32`. Everything else is identical.
|
|
76
|
+
* This table is the assertion, not the lookup — the lock's `filename` is what
|
|
77
|
+
* the fetcher uses, and `test/lock.test.ts` checks the two agree, so a hub-side
|
|
78
|
+
* rename shows up as a failing test rather than a 404 on a user's first run.
|
|
79
|
+
*/
|
|
80
|
+
export declare const TUI_ARTIFACT_NAMES: Record<string, string>;
|
|
81
|
+
/** Resolve the current host's platform key, e.g. "win32-x64". */
|
|
82
|
+
export declare function currentPlatformKey(platform?: NodeJS.Platform, arch?: string): string;
|
|
83
|
+
/** Locate `binaries.lock.json` (package root, one level up from dist/ or src/). */
|
|
84
|
+
export declare function defaultLockPath(): string;
|
|
85
|
+
/** Load and minimally validate the lock file. */
|
|
86
|
+
export declare function loadLock(lockPath?: string): BinaryLock;
|
|
87
|
+
/** One component's lane, failing loudly when the lock does not declare it. */
|
|
88
|
+
export declare function componentLock(lock: BinaryLock, component: ComponentName): ComponentLock;
|
|
89
|
+
/** The download base URL for one component. */
|
|
90
|
+
export declare function componentBaseUrl(lock: BinaryLock, component: ComponentName): string;
|
|
91
|
+
/** The platform keys a component publishes for, per the lock. */
|
|
92
|
+
export declare function platformsFor(lock: BinaryLock, component: ComponentName): string[];
|
|
93
|
+
/**
|
|
94
|
+
* Resolve one component's lock entry for a platform key, failing loudly when the
|
|
95
|
+
* component has no build for it (e.g. the sidecar on linux-arm64).
|
|
96
|
+
*/
|
|
97
|
+
export declare function resolveEntry(lock: BinaryLock, component: ComponentName, platformKey: string): BinaryLockEntry;
|
|
98
|
+
/** True when an entry's sha256 is the not-yet-published placeholder sentinel. */
|
|
99
|
+
export declare function isPlaceholderSha(sha256: string): boolean;
|
|
100
|
+
//# sourceMappingURL=platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAQH,mDAAmD;AACnD,eAAO,MAAM,UAAU,6BAA8B,CAAC;AACtD,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAExD,gFAAgF;AAChF,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,gBAAgB,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC5C;AAED,qEAAqE;AACrE,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC3C;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,mEAK9B,CAAC;AAEX,uEAAuE;AACvE,eAAO,MAAM,uBAAuB,iGAO1B,CAAC;AAEX,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,iGAA0B,CAAC;AAE3D;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOrD,CAAC;AAEF,iEAAiE;AACjE,wBAAgB,kBAAkB,CAChC,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,IAAI,GAAE,MAAqB,GAC1B,MAAM,CAER;AAED,mFAAmF;AACnF,wBAAgB,eAAe,IAAI,MAAM,CAGxC;AAED,iDAAiD;AACjD,wBAAgB,QAAQ,CAAC,QAAQ,GAAE,MAA0B,GAAG,UAAU,CA2DzE;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,GAAG,aAAa,CASvF;AAED,+CAA+C;AAC/C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,GAAG,MAAM,CASnF;AAED,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,GAAG,MAAM,EAAE,CAEjF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,aAAa,EACxB,WAAW,EAAE,MAAM,GAClB,eAAe,CAqCjB;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD"}
|