@amd-gaia/gaia 0.1.0 → 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.
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Binary fetcher for both components (`sidecar` and `tui`).
3
+ *
4
+ * Resolves the current platform → looks the component up in
5
+ * `binaries.lock.json` → downloads it from THAT COMPONENT's base URL
6
+ * (overridable) → **verifies its SHA-256 against the lock and fails loudly on
7
+ * any mismatch** → writes it into a cache dir → `chmod +x` on POSIX.
8
+ *
9
+ * The two components come from different hub lanes: the sidecar from
10
+ * `agents/gaia/<agentVersion>/`, the TUI from `agents/terminal-hub/<tuiVersion>/`
11
+ * (the same binary a core install runs as `gaia tui`). Each entry's base URL
12
+ * comes from its own component, never from a shared top-level one.
13
+ *
14
+ * The SHA verify is the security boundary: a tampered, truncated, or
15
+ * not-yet-published artifact is rejected before it can ever be spawned. There is
16
+ * NO "use it anyway" path, and a placeholder hash in the lock blocks the fetch
17
+ * outright rather than degrading to an unverified download.
18
+ */
19
+ import { type BinaryLock, type ComponentName } from "./platform.js";
20
+ /**
21
+ * Where verified binaries are cached, keyed by agent version so a version bump
22
+ * never reuses the previous release's executables.
23
+ */
24
+ export declare function defaultCacheDir(agentVersion: string): string;
25
+ /** The hub agent id this package installs the sidecar as. */
26
+ export declare const SIDECAR_AGENT_ID = "gaia";
27
+ /** Basename of the hub install record (`gaia.hub.installer.SENTINEL_NAME`). */
28
+ export declare const INSTALLED_SENTINEL_NAME = ".installed";
29
+ /**
30
+ * The daemon's own sidecar cache — `~/.gaia/agents/gaia/`, mirroring
31
+ * `gaia.daemon.sidecars.fetch.default_cache_dir("gaia")`. Staging the verified
32
+ * sidecar here means the daemon's own fetch is a SHA-256 cache hit instead of a
33
+ * second download. This path is a cross-repo contract with the daemon.
34
+ */
35
+ export declare function daemonSidecarCacheDir(agentId?: string): string;
36
+ export interface FetchOptions {
37
+ /** Which binary to fetch. */
38
+ component: ComponentName;
39
+ /** Directory the verified binary is written into. Required. */
40
+ outDir: string;
41
+ /**
42
+ * Override this component's `baseUrl` (e.g. a local mirror). Trailing slash
43
+ * optional. Applies to whichever component is being fetched — the two lanes'
44
+ * filenames never collide, so one flat mirror directory can serve both.
45
+ */
46
+ baseUrl?: string;
47
+ /** Override the platform key (defaults to the current host). */
48
+ platformKey?: string;
49
+ /** Path to the lock file (defaults to the packaged binaries.lock.json). */
50
+ lockPath?: string;
51
+ /** A pre-loaded lock, to avoid re-reading it per component. */
52
+ lock?: BinaryLock;
53
+ /** Fetch override (tests). Defaults to global `fetch`. */
54
+ fetchImpl?: typeof fetch;
55
+ /** Re-download even when a verified binary is already cached. Default false. */
56
+ force?: boolean;
57
+ /** Abort the download after this many ms. Default 300000 (the sidecar is ~200MB). */
58
+ timeoutMs?: number;
59
+ }
60
+ export interface FetchResult {
61
+ component: ComponentName;
62
+ /** Absolute path to the written, verified executable. */
63
+ binaryPath: string;
64
+ /** The platform key resolved. */
65
+ platformKey: string;
66
+ /** The verified SHA-256 (lowercase hex). */
67
+ sha256: string;
68
+ /** Source URL the artifact was downloaded from. */
69
+ url: string;
70
+ /** True when the on-disk binary was reused (hash already matched). */
71
+ cached: boolean;
72
+ }
73
+ /**
74
+ * SHA-256 of a file on disk, or null when it is simply absent. Any other error
75
+ * (a permission problem, a directory in the way) is re-raised: reading it as
76
+ * "no cache" would trigger a re-download that then fails on write with a far
77
+ * less useful message.
78
+ */
79
+ export declare function fileSha256(filePath: string): Promise<string | null>;
80
+ /** Verify an in-memory buffer against an expected SHA-256. */
81
+ export declare function verifySha256(buf: Buffer, expected: string, sourceLabel: string): string;
82
+ /**
83
+ * Fetch + verify + install one component's binary for the current platform.
84
+ *
85
+ * @throws PlatformError unsupported platform / incomplete entry / placeholder hash
86
+ * @throws IntegrityError SHA-256 mismatch
87
+ * @throws Error download/network failure (HTTP status surfaced)
88
+ */
89
+ export declare function fetchBinary(opts: FetchOptions): Promise<FetchResult>;
90
+ export interface FetchAllOptions extends Omit<FetchOptions, "component" | "outDir"> {
91
+ /** Cache dir for the TUI. Defaults to `defaultCacheDir(lock.agentVersion)`. */
92
+ tuiDir?: string;
93
+ /** Cache dir for the sidecar. Defaults to the daemon's `~/.gaia/agents/gaia`. */
94
+ sidecarDir?: string;
95
+ }
96
+ export interface FetchAllResult {
97
+ sidecar: FetchResult;
98
+ tui: FetchResult;
99
+ lock: BinaryLock;
100
+ }
101
+ /**
102
+ * Fetch + verify BOTH binaries. Sequential on purpose: the sidecar is the large
103
+ * download and a failure there should not race a half-finished TUI download.
104
+ *
105
+ * The sidecar lands in the daemon's own cache dir so the daemon — which owns
106
+ * spawning it — finds it already verified instead of downloading it again.
107
+ */
108
+ export declare function fetchAll(opts?: FetchAllOptions): Promise<FetchAllResult>;
109
+ /** Sync existence check, for the lifecycle layer. */
110
+ export declare function binaryExists(binaryPath: string): boolean;
111
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AAWH,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,aAAa,EAQnB,MAAM,eAAe,CAAC;AAIvB;;;GAGG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAEvC,+EAA+E;AAC/E,eAAO,MAAM,uBAAuB,eAAe,CAAC;AAEpD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,SAAmB,GAAG,MAAM,CAExE;AA+DD,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,SAAS,EAAE,aAAa,CAAC;IACzB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,aAAa,CAAC;IACzB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAC;CACjB;AASD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+BzE;AA+DD,8DAA8D;AAC9D,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAoJ1E;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,QAAQ,CAAC;IACjF,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAelF;AAED,qDAAqD;AACrD,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAExD"}
package/dist/fetch.js ADDED
@@ -0,0 +1,369 @@
1
+ // Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
2
+ // SPDX-License-Identifier: MIT
3
+ /**
4
+ * Binary fetcher for both components (`sidecar` and `tui`).
5
+ *
6
+ * Resolves the current platform → looks the component up in
7
+ * `binaries.lock.json` → downloads it from THAT COMPONENT's base URL
8
+ * (overridable) → **verifies its SHA-256 against the lock and fails loudly on
9
+ * any mismatch** → writes it into a cache dir → `chmod +x` on POSIX.
10
+ *
11
+ * The two components come from different hub lanes: the sidecar from
12
+ * `agents/gaia/<agentVersion>/`, the TUI from `agents/terminal-hub/<tuiVersion>/`
13
+ * (the same binary a core install runs as `gaia tui`). Each entry's base URL
14
+ * comes from its own component, never from a shared top-level one.
15
+ *
16
+ * The SHA verify is the security boundary: a tampered, truncated, or
17
+ * not-yet-published artifact is rejected before it can ever be spawned. There is
18
+ * NO "use it anyway" path, and a placeholder hash in the lock blocks the fetch
19
+ * outright rather than degrading to an unverified download.
20
+ */
21
+ import crypto from "node:crypto";
22
+ import fs from "node:fs";
23
+ import fsp from "node:fs/promises";
24
+ import os from "node:os";
25
+ import path from "node:path";
26
+ import { IntegrityError, PlatformError } from "./errors.js";
27
+ import { createLogger } from "./logger.js";
28
+ import { joinUrl } from "./url.js";
29
+ import { componentBaseUrl, componentLock, currentPlatformKey, defaultLockPath, isPlaceholderSha, loadLock, resolveEntry, } from "./platform.js";
30
+ const log = createLogger("fetch");
31
+ /**
32
+ * Where verified binaries are cached, keyed by agent version so a version bump
33
+ * never reuses the previous release's executables.
34
+ */
35
+ export function defaultCacheDir(agentVersion) {
36
+ return path.join(os.homedir(), ".gaia", "npm-cache", `gaia-${agentVersion}`);
37
+ }
38
+ /** The hub agent id this package installs the sidecar as. */
39
+ export const SIDECAR_AGENT_ID = "gaia";
40
+ /** Basename of the hub install record (`gaia.hub.installer.SENTINEL_NAME`). */
41
+ export const INSTALLED_SENTINEL_NAME = ".installed";
42
+ /**
43
+ * The daemon's own sidecar cache — `~/.gaia/agents/gaia/`, mirroring
44
+ * `gaia.daemon.sidecars.fetch.default_cache_dir("gaia")`. Staging the verified
45
+ * sidecar here means the daemon's own fetch is a SHA-256 cache hit instead of a
46
+ * second download. This path is a cross-repo contract with the daemon.
47
+ */
48
+ export function daemonSidecarCacheDir(agentId = SIDECAR_AGENT_ID) {
49
+ return path.join(os.homedir(), ".gaia", "agents", agentId);
50
+ }
51
+ /**
52
+ * Whether this fetch produced a runnable local install worth recording.
53
+ *
54
+ * `--platform` fetches a binary for a DIFFERENT host — a cross-compile staging
55
+ * step, not an install. Recording one would hand the daemon a wrong-arch
56
+ * executable that re-hashes correctly and then fails to exec.
57
+ */
58
+ function installsForThisHost(component, platformKey) {
59
+ return component === "sidecar" && platformKey === currentPlatformKey();
60
+ }
61
+ /**
62
+ * Record a completed install the way `gaia.hub.installer` does.
63
+ *
64
+ * Staging a verified binary is only half the job the CLI claims to do. Without
65
+ * this file the daemon's `_hub_installed_binary` sees no install, and the TUI
66
+ * treats `gaia-agent` as its own stdio child — spawning our REST sidecar over
67
+ * stdio and filling the chat with uvicorn's startup log. With it, the TUI uses
68
+ * daemon transport and the daemon supervises the process and mints its token.
69
+ *
70
+ * Field names and `artifact_kind`/`executable`/`artifact_sha256` are a
71
+ * cross-repo contract with `InstalledAgent.to_dict()`; the daemon re-hashes the
72
+ * binary and raises if it does not match `artifact_sha256`, so this must carry
73
+ * the hash we actually verified.
74
+ */
75
+ async function writeInstalledSentinel(opts) {
76
+ const sentinel = path.join(opts.outDir, INSTALLED_SENTINEL_NAME);
77
+ const record = {
78
+ id: SIDECAR_AGENT_ID,
79
+ version: opts.version,
80
+ language: "python",
81
+ installed_at: new Date().toISOString(),
82
+ artifact_sha256: opts.sha256,
83
+ path: opts.outDir,
84
+ artifact_kind: "binary",
85
+ executable: opts.executable,
86
+ };
87
+ // Temp-then-rename: a truncated sentinel reads as a corrupt install, which
88
+ // looks identical to "never installed".
89
+ const tmp = `${sentinel}.tmp.${process.pid}`;
90
+ try {
91
+ await fsp.writeFile(tmp, `${JSON.stringify(record, null, 2)}\n`, "utf8");
92
+ await fsp.rename(tmp, sentinel);
93
+ }
94
+ catch (e) {
95
+ await fsp.rm(tmp, { force: true }).catch(() => undefined);
96
+ throw new Error(`verified the sidecar at ${opts.outDir} but could not write its ` +
97
+ `${INSTALLED_SENTINEL_NAME} record: ${e.message}. Without it the ` +
98
+ "daemon does not see a completed install and the TUI falls back to running " +
99
+ `the sidecar over stdio. Check write permissions on ${opts.outDir}.`, { cause: e });
100
+ }
101
+ log.debug(`wrote ${sentinel} (v${opts.version})`);
102
+ }
103
+ function sha256Hex(buf) {
104
+ return crypto.createHash("sha256").update(buf).digest("hex");
105
+ }
106
+ /** Read size for incremental hashing — bounded regardless of artifact size. */
107
+ const HASH_CHUNK_BYTES = 1 << 20;
108
+ /**
109
+ * SHA-256 of a file on disk, or null when it is simply absent. Any other error
110
+ * (a permission problem, a directory in the way) is re-raised: reading it as
111
+ * "no cache" would trigger a re-download that then fails on write with a far
112
+ * less useful message.
113
+ */
114
+ export async function fileSha256(filePath) {
115
+ const unreadable = (e) => new Error(`cannot read the cached binary at ${filePath} to check its hash: ${e.message}. ` +
116
+ "Fix the permissions on that path, or pass a different --cache-dir / --sidecar-dir.", { cause: e });
117
+ let fh;
118
+ try {
119
+ fh = await fsp.open(filePath, "r");
120
+ }
121
+ catch (e) {
122
+ if (e.code === "ENOENT")
123
+ return null;
124
+ throw unreadable(e);
125
+ }
126
+ // Chunked, not readFile: this runs on every cache hit, and the sidecar is
127
+ // ~200MB — buffering it whole is the peak the streaming download removed.
128
+ try {
129
+ const hash = crypto.createHash("sha256");
130
+ const buf = Buffer.allocUnsafe(HASH_CHUNK_BYTES);
131
+ for (;;) {
132
+ const { bytesRead } = await fh.read(buf, 0, buf.length, null);
133
+ if (bytesRead === 0)
134
+ break;
135
+ hash.update(buf.subarray(0, bytesRead));
136
+ }
137
+ return hash.digest("hex");
138
+ }
139
+ catch (e) {
140
+ throw unreadable(e);
141
+ }
142
+ finally {
143
+ await fh.close();
144
+ }
145
+ }
146
+ /**
147
+ * Stream a response body to `tmp`, hashing as it goes.
148
+ *
149
+ * Incremental on purpose: the sidecar is ~200MB and `arrayBuffer()` would peak
150
+ * at roughly double that. Awaiting each write applies backpressure.
151
+ */
152
+ async function streamToFile(res, tmp, url) {
153
+ if (!res.body) {
154
+ throw new Error(`download failed: ${url} returned HTTP ${res.status} with no response body. ` +
155
+ "Check the base URL and that the artifact is published for this platform.");
156
+ }
157
+ const hash = crypto.createHash("sha256");
158
+ let bytes = 0;
159
+ let fh;
160
+ try {
161
+ fh = await fsp.open(tmp, "w");
162
+ }
163
+ catch (e) {
164
+ throw new Error(`cannot open ${tmp} to stage the download: ${e.message}. ` +
165
+ "Check write permissions on that directory, or pass a different " +
166
+ "--sidecar-dir / --cache-dir.", { cause: e });
167
+ }
168
+ try {
169
+ for await (const chunk of res.body) {
170
+ hash.update(chunk);
171
+ bytes += chunk.byteLength;
172
+ await fh.write(chunk);
173
+ }
174
+ }
175
+ finally {
176
+ await fh.close();
177
+ }
178
+ return { sha256: hash.digest("hex"), bytes };
179
+ }
180
+ /**
181
+ * Compare an already-computed SHA-256 with the expected one. Throws
182
+ * `IntegrityError` loudly on mismatch — this is the no-silent-fallback gate.
183
+ */
184
+ function assertSha256(actual, expected, sourceLabel) {
185
+ if (actual.toLowerCase() !== expected.toLowerCase()) {
186
+ throw new IntegrityError(`SHA-256 mismatch for ${sourceLabel}:\n` +
187
+ ` expected ${expected}\n` +
188
+ ` actual ${actual}\n` +
189
+ "Refusing to use a binary that does not match binaries.lock.json. " +
190
+ "The download may be corrupt, truncated, or tampered with. Re-run the fetch; " +
191
+ "if it persists, the lock is stale relative to the published artifact — " +
192
+ "report it at https://github.com/amd/gaia/issues.");
193
+ }
194
+ return actual;
195
+ }
196
+ /** Verify an in-memory buffer against an expected SHA-256. */
197
+ export function verifySha256(buf, expected, sourceLabel) {
198
+ return assertSha256(sha256Hex(buf), expected, sourceLabel);
199
+ }
200
+ /**
201
+ * Fetch + verify + install one component's binary for the current platform.
202
+ *
203
+ * @throws PlatformError unsupported platform / incomplete entry / placeholder hash
204
+ * @throws IntegrityError SHA-256 mismatch
205
+ * @throws Error download/network failure (HTTP status surfaced)
206
+ */
207
+ export async function fetchBinary(opts) {
208
+ if (!opts?.outDir) {
209
+ throw new TypeError("fetchBinary requires an outDir to write the binary into");
210
+ }
211
+ if (!opts?.component) {
212
+ throw new TypeError('fetchBinary requires a component ("sidecar" or "tui")');
213
+ }
214
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
215
+ if (typeof fetchImpl !== "function") {
216
+ throw new TypeError("global fetch unavailable — use Node >= 18 or pass fetchImpl");
217
+ }
218
+ const lock = opts.lock ?? loadLock(opts.lockPath ?? defaultLockPath());
219
+ const platformKey = opts.platformKey ?? currentPlatformKey();
220
+ const entry = resolveEntry(lock, opts.component, platformKey);
221
+ // Per-component: the sidecar and the TUI live in different hub lanes at
222
+ // different versions, so there is no single base URL to fall back to.
223
+ const baseUrl = opts.baseUrl ?? componentBaseUrl(lock, opts.component);
224
+ if (isPlaceholderSha(entry.sha256)) {
225
+ throw new PlatformError(`binaries.lock.json has a placeholder sha256 for ${opts.component}/'${platformKey}' ` +
226
+ `(${entry.sha256}), so no verifiable binary is published for it in this build. ` +
227
+ "Fetch is blocked so an unverifiable binary can never be trusted. " +
228
+ "Install a released @amd-gaia/gaia, or build the binary locally " +
229
+ "(hub/agents/gaia/python/packaging for the sidecar, `make -C tui cross-compile` " +
230
+ "for the TUI) and point the lifecycle helpers at it directly.");
231
+ }
232
+ const outDir = path.resolve(opts.outDir);
233
+ await fsp.mkdir(outDir, { recursive: true });
234
+ const binaryPath = path.join(outDir, entry.executable);
235
+ const url = joinUrl(baseUrl, entry.filename);
236
+ if (!opts.force) {
237
+ const existing = await fileSha256(binaryPath);
238
+ if (existing && existing.toLowerCase() === entry.sha256.toLowerCase()) {
239
+ log.debug(`cache hit: ${binaryPath} already matches lock sha256`);
240
+ // Re-apply the exec bit: an interrupted earlier run or a restrictive umask
241
+ // can leave correct bytes that still cannot be spawned.
242
+ if (process.platform !== "win32")
243
+ await fsp.chmod(binaryPath, 0o755);
244
+ // Also on a cache hit: an earlier release staged a verified binary with no
245
+ // sentinel, and those installs would otherwise never repair themselves.
246
+ if (installsForThisHost(opts.component, platformKey)) {
247
+ await writeInstalledSentinel({
248
+ outDir,
249
+ version: componentLock(lock, "sidecar").componentVersion,
250
+ sha256: existing,
251
+ executable: entry.executable,
252
+ });
253
+ }
254
+ return {
255
+ component: opts.component,
256
+ binaryPath,
257
+ platformKey,
258
+ sha256: existing,
259
+ url,
260
+ cached: true,
261
+ };
262
+ }
263
+ }
264
+ log.info(`downloading ${opts.component} for ${platformKey} from ${url}`);
265
+ const timeoutMs = opts.timeoutMs ?? 300_000;
266
+ const controller = new AbortController();
267
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
268
+ // Streamed to a temp file while hashing incrementally: the sidecar is ~200MB
269
+ // and buffering it whole peaks at roughly double that in RSS.
270
+ const tmp = `${binaryPath}.download.${process.pid}`;
271
+ let actualSha;
272
+ let bytes;
273
+ try {
274
+ const res = await fetchImpl(url, {
275
+ headers: { accept: "application/octet-stream" },
276
+ signal: controller.signal,
277
+ });
278
+ if (!res.ok) {
279
+ throw new Error(`download failed: HTTP ${res.status} ${res.statusText} for ${url}. ` +
280
+ "Check the base URL and that the artifact is published for this platform.");
281
+ }
282
+ ({ sha256: actualSha, bytes } = await streamToFile(res, tmp, url));
283
+ }
284
+ catch (e) {
285
+ await fsp.rm(tmp, { force: true }).catch(() => undefined);
286
+ if (e.name === "AbortError") {
287
+ throw new Error(`download timed out after ${timeoutMs}ms for ${url}`);
288
+ }
289
+ throw e;
290
+ }
291
+ finally {
292
+ clearTimeout(timer);
293
+ }
294
+ log.debug(`downloaded ${bytes} bytes`);
295
+ // Verify BEFORE the rename: unverified bytes must never reach the final path.
296
+ let sha;
297
+ try {
298
+ sha = assertSha256(actualSha, entry.sha256, `${opts.component} ${platformKey} (${url})`);
299
+ }
300
+ catch (e) {
301
+ await fsp.rm(tmp, { force: true }).catch(() => undefined);
302
+ throw e;
303
+ }
304
+ try {
305
+ await fsp.rename(tmp, binaryPath);
306
+ }
307
+ catch (e) {
308
+ await fsp.rm(tmp, { force: true }).catch(() => undefined);
309
+ throw new Error(`downloaded and verified the ${opts.component}, but could not move it into place ` +
310
+ `at ${binaryPath}: ${e.message}. ` +
311
+ "The usual cause is that the file is in use — stop any running gaia sidecar " +
312
+ "or TUI (`gaia kill`) and re-run. Otherwise check write permissions on " +
313
+ `${outDir}, or pass a different --sidecar-dir / --cache-dir.`, { cause: e });
314
+ }
315
+ try {
316
+ if (process.platform !== "win32")
317
+ await fsp.chmod(binaryPath, 0o755);
318
+ }
319
+ catch (e) {
320
+ throw new Error(`installed the ${opts.component} at ${binaryPath} but could not make it ` +
321
+ `executable: ${e.message}. Run \`chmod +x ${binaryPath}\`, or ` +
322
+ "pass a --sidecar-dir / --cache-dir you own.", { cause: e });
323
+ }
324
+ if (installsForThisHost(opts.component, platformKey)) {
325
+ await writeInstalledSentinel({
326
+ outDir,
327
+ version: componentLock(lock, "sidecar").componentVersion,
328
+ sha256: sha,
329
+ executable: entry.executable,
330
+ });
331
+ }
332
+ log.info(`installed verified ${opts.component} -> ${binaryPath}`);
333
+ return {
334
+ component: opts.component,
335
+ binaryPath,
336
+ platformKey,
337
+ sha256: sha,
338
+ url,
339
+ cached: false,
340
+ };
341
+ }
342
+ /**
343
+ * Fetch + verify BOTH binaries. Sequential on purpose: the sidecar is the large
344
+ * download and a failure there should not race a half-finished TUI download.
345
+ *
346
+ * The sidecar lands in the daemon's own cache dir so the daemon — which owns
347
+ * spawning it — finds it already verified instead of downloading it again.
348
+ */
349
+ export async function fetchAll(opts = {}) {
350
+ const lock = opts.lock ?? loadLock(opts.lockPath ?? defaultLockPath());
351
+ const platformKey = opts.platformKey ?? currentPlatformKey();
352
+ const common = { ...opts, lock, platformKey };
353
+ const sidecar = await fetchBinary({
354
+ ...common,
355
+ component: "sidecar",
356
+ outDir: opts.sidecarDir ?? daemonSidecarCacheDir(),
357
+ });
358
+ const tui = await fetchBinary({
359
+ ...common,
360
+ component: "tui",
361
+ outDir: opts.tuiDir ?? defaultCacheDir(lock.agentVersion),
362
+ });
363
+ return { sidecar, tui, lock };
364
+ }
365
+ /** Sync existence check, for the lifecycle layer. */
366
+ export function binaryExists(binaryPath) {
367
+ return fs.existsSync(binaryPath);
368
+ }
369
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @amd-gaia/gaia — binary fetcher + process lifecycle for the GAIA flagship
3
+ * agent sidecar and the GAIA terminal UI.
4
+ *
5
+ * The CLI (`npx @amd-gaia/gaia`) is the normal way in. These exports are for
6
+ * integrators who want the pieces:
7
+ *
8
+ * import { fetchAll, startSidecar, shutdown } from "@amd-gaia/gaia";
9
+ *
10
+ * const { sidecar, tui } = await fetchAll(); // both, SHA-256 verified
11
+ * const proc = await startSidecar({ binaryPath: sidecar.binaryPath });
12
+ * const res = await fetch(`${proc.baseUrl}/v1/gaia/query`, { ... });
13
+ * await shutdown(proc);
14
+ */
15
+ export { INSTALLED_SENTINEL_NAME, SIDECAR_AGENT_ID, fetchAll, fetchBinary, verifySha256, fileSha256, binaryExists, defaultCacheDir, daemonSidecarCacheDir, } from "./fetch.js";
16
+ export type { FetchOptions, FetchResult, FetchAllOptions, FetchAllResult, } from "./fetch.js";
17
+ export { AGENT_ID, API_VERSION, DEFAULT_HOST, DEFAULT_PORT, RESERVED_PORT, checkVersion, health, resolveSidecarPath, resolveTuiPath, runTui, shutdown, sidecarExecutableName, spawnSidecar, startSidecar, tuiExecutableName, version, waitForHealth, } from "./lifecycle.js";
18
+ export type { HealthResponse, ResolveOptions, RunTuiOptions, Sidecar, SpawnOptions, StartOptions, VersionCheckOptions, VersionResponse, WaitForHealthOptions, } from "./lifecycle.js";
19
+ export { COMPONENTS, SCHEMA_MAJOR, SUPPORTED_PLATFORMS, SUPPORTED_SIDECAR_PLATFORMS, SUPPORTED_TUI_PLATFORMS, TUI_ARTIFACT_NAMES, componentBaseUrl, componentLock, currentPlatformKey, defaultLockPath, isPlaceholderSha, loadLock, platformsFor, resolveEntry, } from "./platform.js";
20
+ export type { BinaryLock, BinaryLockEntry, ComponentLock, ComponentName, } from "./platform.js";
21
+ export { BinaryNotFoundError, GaiaError, HealthTimeoutError, HttpError, IntegrityError, MalformedResponseError, PlatformError, PortInUseError, SidecarExitedError, VersionMismatchError, } from "./errors.js";
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,eAAe,EACf,qBAAqB,GACtB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,YAAY,EACZ,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,MAAM,EACN,kBAAkB,EAClB,cAAc,EACd,MAAM,EACN,QAAQ,EACR,qBAAqB,EACrB,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,OAAO,EACP,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,cAAc,EACd,cAAc,EACd,aAAa,EACb,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,UAAU,EACV,eAAe,EACf,aAAa,EACb,aAAa,GACd,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,kBAAkB,EAClB,SAAS,EACT,cAAc,EACd,sBAAsB,EACtB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ // Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
2
+ // SPDX-License-Identifier: MIT
3
+ /**
4
+ * @amd-gaia/gaia — binary fetcher + process lifecycle for the GAIA flagship
5
+ * agent sidecar and the GAIA terminal UI.
6
+ *
7
+ * The CLI (`npx @amd-gaia/gaia`) is the normal way in. These exports are for
8
+ * integrators who want the pieces:
9
+ *
10
+ * import { fetchAll, startSidecar, shutdown } from "@amd-gaia/gaia";
11
+ *
12
+ * const { sidecar, tui } = await fetchAll(); // both, SHA-256 verified
13
+ * const proc = await startSidecar({ binaryPath: sidecar.binaryPath });
14
+ * const res = await fetch(`${proc.baseUrl}/v1/gaia/query`, { ... });
15
+ * await shutdown(proc);
16
+ */
17
+ export { INSTALLED_SENTINEL_NAME, SIDECAR_AGENT_ID, fetchAll, fetchBinary, verifySha256, fileSha256, binaryExists, defaultCacheDir, daemonSidecarCacheDir, } from "./fetch.js";
18
+ export { AGENT_ID, API_VERSION, DEFAULT_HOST, DEFAULT_PORT, RESERVED_PORT, checkVersion, health, resolveSidecarPath, resolveTuiPath, runTui, shutdown, sidecarExecutableName, spawnSidecar, startSidecar, tuiExecutableName, version, waitForHealth, } from "./lifecycle.js";
19
+ export { COMPONENTS, SCHEMA_MAJOR, SUPPORTED_PLATFORMS, SUPPORTED_SIDECAR_PLATFORMS, SUPPORTED_TUI_PLATFORMS, TUI_ARTIFACT_NAMES, componentBaseUrl, componentLock, currentPlatformKey, defaultLockPath, isPlaceholderSha, loadLock, platformsFor, resolveEntry, } from "./platform.js";
20
+ export { BinaryNotFoundError, GaiaError, HealthTimeoutError, HttpError, IntegrityError, MalformedResponseError, PlatformError, PortInUseError, SidecarExitedError, VersionMismatchError, } from "./errors.js";
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,+BAA+B;AAC/B;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,eAAe,EACf,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAQpB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,MAAM,EACN,kBAAkB,EAClB,cAAc,EACd,MAAM,EACN,QAAQ,EACR,qBAAqB,EACrB,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,OAAO,EACP,aAAa,GACd,MAAM,gBAAgB,CAAC;AAaxB,OAAO,EACL,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,YAAY,GACb,MAAM,eAAe,CAAC;AAQvB,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,kBAAkB,EAClB,SAAS,EACT,cAAc,EACd,sBAAsB,EACtB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,aAAa,CAAC"}