@amd-gaia/agent-ui 0.21.2 → 0.22.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/dist/assets/{browser-B1LxEoD3.js → browser-CmSowSA-.js} +1 -1
- package/dist/assets/index-B31DMoxr.css +1 -0
- package/dist/assets/index-lScW7mUY.js +72 -0
- package/dist/index.html +2 -2
- package/main-safety-net.cjs +13 -3
- package/main.cjs +3 -0
- package/package.json +3 -3
- package/services/agent-seeder.cjs +256 -14
- package/services/backend-installer.cjs +141 -63
- package/dist/assets/index-BaBSHxtq.js +0 -72
- package/dist/assets/index-CGT9a3El.css +0 -1
|
@@ -77,25 +77,27 @@ const INSTALL_RETRY_BACKOFF_MS = 3000;
|
|
|
77
77
|
// `curl | sh` path is retained only as an unpackaged-dev fallback so
|
|
78
78
|
// contributors running from source keep working.
|
|
79
79
|
//
|
|
80
|
-
// When bumping uv, update
|
|
80
|
+
// When bumping uv, update:
|
|
81
81
|
// - .github/workflows/build-installers.yml (tarball .tar.gz SHA256 — archive)
|
|
82
|
-
// - BUNDLED_UV_SHA256 below (extracted
|
|
83
|
-
// These are two different digests: the workflow verifies the downloaded
|
|
84
|
-
// archive against upstream's published .sha256, then extracts the `uv` binary
|
|
85
|
-
// which is what `ensureUv()` hashes at runtime.
|
|
82
|
+
// - BUNDLED_UV_SHA256 below (extracted binary SHA256, linux-x64/win-x64 only)
|
|
86
83
|
//
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
//
|
|
84
|
+
// IMPORTANT: per-platform verification strategy differs:
|
|
85
|
+
// - linux-x64 / win-x64: BUNDLED_UV_SHA256 pins the raw extracted-binary
|
|
86
|
+
// digest (no post-build modification) — deterministic across CI runs.
|
|
87
|
+
// - mac-arm64: NOT pinned here. electron-builder code-signs the bundled uv
|
|
88
|
+
// during packaging (ad-hoc `identity=-` when no Developer ID cert is
|
|
89
|
+
// configured, which is every CI build today), and ad-hoc codesign output
|
|
90
|
+
// depends on the codesign/Xcode toolchain baked into the GitHub-hosted
|
|
91
|
+
// `macos-latest` runner image — which floats and is NOT reproducible
|
|
92
|
+
// across CI runs (observed: macos-15-arm64 vs macos-26-arm64 images
|
|
93
|
+
// produced two different digests for byte-identical source). A fixed
|
|
94
|
+
// SHA256 pin is therefore not deterministic on macOS and would fail
|
|
95
|
+
// ~half of CI runs and brick first-launch on user machines whenever the
|
|
96
|
+
// runner image rolls. Instead, ensureUv() and the dmg-structural-smoke
|
|
97
|
+
// test both run `codesign --verify --strict` against the bundled binary
|
|
98
|
+
// — this validates the on-disk signature is intact/untampered without
|
|
99
|
+
// depending on the exact signing bytes, and still fails loud on
|
|
100
|
+
// corruption or an actually-invalid signature.
|
|
99
101
|
const BUNDLED_UV_VERSION = "0.5.14";
|
|
100
102
|
const BUNDLED_UV_SHA256 = {
|
|
101
103
|
"linux-x64": "0e05d828b5708e8a927724124db3746396afddad6273c47283d7c562dc795bd6",
|
|
@@ -103,9 +105,12 @@ const BUNDLED_UV_SHA256 = {
|
|
|
103
105
|
// build step. The placeholder MUST be replaced in CI before packaging
|
|
104
106
|
// so runtime verification remains strict.
|
|
105
107
|
"win-x64": "055d55eec85a91cfb5e9c8bc7f6463f9883866796c5bcb205fbcdfed9c088c88",
|
|
106
|
-
// mac-arm64:
|
|
107
|
-
//
|
|
108
|
-
|
|
108
|
+
// mac-arm64: intentionally absent. See the comment block above — the
|
|
109
|
+
// post-codesign digest is not deterministic across CI runner images, so
|
|
110
|
+
// mac-arm64 is verified via codesignVerify() (identity/signature validity)
|
|
111
|
+
// instead of a fixed SHA256 pin. bundledUvPlatformKey() still returns
|
|
112
|
+
// "mac-arm64"; callers must not treat a missing entry here as "unpinned
|
|
113
|
+
// platform" for darwin — see ensureUv()/installBundledUv().
|
|
109
114
|
};
|
|
110
115
|
|
|
111
116
|
const MANAGED_UV_DIR = path.join(GAIA_HOME, "bin");
|
|
@@ -924,6 +929,27 @@ function sha256File(filePath) {
|
|
|
924
929
|
});
|
|
925
930
|
}
|
|
926
931
|
|
|
932
|
+
/**
|
|
933
|
+
* Verify a macOS binary's code signature is structurally intact via
|
|
934
|
+
* `codesign --verify --strict`. Used in place of a fixed SHA256 pin for
|
|
935
|
+
* mac-arm64 (see the BUNDLED_UV_SHA256 comment) — ad-hoc-signed binaries
|
|
936
|
+
* (identity=-, which is every CI build today) pass this check, but a
|
|
937
|
+
* corrupted, tampered, or actually-unsigned binary fails it. This does NOT
|
|
938
|
+
* depend on the specific bytes any given codesign/Xcode toolchain produces,
|
|
939
|
+
* so it is stable across GitHub-hosted runner image rollovers where a fixed
|
|
940
|
+
* digest pin is not.
|
|
941
|
+
*
|
|
942
|
+
* @param {string} binPath
|
|
943
|
+
* @returns {{ ok: boolean, output: string }}
|
|
944
|
+
*/
|
|
945
|
+
function codesignVerify(binPath) {
|
|
946
|
+
const result = spawnSync("codesign", ["--verify", "--strict", binPath], {
|
|
947
|
+
encoding: "utf8",
|
|
948
|
+
});
|
|
949
|
+
const output = `${result.stdout || ""}${result.stderr || ""}`.trim();
|
|
950
|
+
return { ok: result.status === 0, output };
|
|
951
|
+
}
|
|
952
|
+
|
|
927
953
|
/**
|
|
928
954
|
* Resolve the bundled uv binary path inside the Electron resources dir.
|
|
929
955
|
* Returns null if this isn't an Electron-packaged runtime (no
|
|
@@ -945,15 +971,22 @@ function findBundledUvResource() {
|
|
|
945
971
|
}
|
|
946
972
|
|
|
947
973
|
/**
|
|
948
|
-
* Atomically install the bundled uv into ~/.gaia/bin/uv after verifying
|
|
949
|
-
*
|
|
974
|
+
* Atomically install the bundled uv into ~/.gaia/bin/uv after verifying it.
|
|
975
|
+
* Returns the installed path.
|
|
950
976
|
*
|
|
951
|
-
*
|
|
952
|
-
*
|
|
977
|
+
* Verification strategy differs by platform (see the BUNDLED_UV_SHA256
|
|
978
|
+
* comment): mac-arm64 uses `codesign --verify --strict` (darwin only —
|
|
979
|
+
* post-codesign SHA256 is not deterministic across CI runner images);
|
|
980
|
+
* linux-x64 / win-x64 use the SHA256 pin in BUNDLED_UV_SHA256, which IS
|
|
981
|
+
* deterministic for those platforms (no post-build re-signing).
|
|
982
|
+
*
|
|
983
|
+
* Writes to `uv.tmp-<pid>-<rand>` with mode 0o700, verifies, `chmod +x`,
|
|
984
|
+
* then `fs.rename()` (atomic on same filesystem).
|
|
953
985
|
*/
|
|
954
986
|
async function installBundledUv(sourcePath, platformKey) {
|
|
987
|
+
const isDarwin = platformKey === "mac-arm64";
|
|
955
988
|
const expected = BUNDLED_UV_SHA256[platformKey];
|
|
956
|
-
if (!expected || expected.startsWith("<")) {
|
|
989
|
+
if (!isDarwin && (!expected || expected.startsWith("<"))) {
|
|
957
990
|
// Enforce strict verification: builds MUST populate the expected SHA
|
|
958
991
|
// for packaged binaries. Failing fast prevents shipping an unverified
|
|
959
992
|
// uv binary which would be a supply-chain regression.
|
|
@@ -989,18 +1022,39 @@ async function installBundledUv(sourcePath, platformKey) {
|
|
|
989
1022
|
rs.pipe(ws);
|
|
990
1023
|
});
|
|
991
1024
|
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
`
|
|
999
|
-
|
|
1000
|
-
);
|
|
1001
|
-
|
|
1025
|
+
if (isDarwin) {
|
|
1026
|
+
// chmod BEFORE codesign --verify: codesign needs the execute bit to
|
|
1027
|
+
// resolve the binary's designated requirement on some toolchains.
|
|
1028
|
+
try {
|
|
1029
|
+
fs.chmodSync(tmpPath, 0o700);
|
|
1030
|
+
} catch (err) {
|
|
1031
|
+
log(`Warning: chmod on tmp uv failed: ${err.message}`);
|
|
1032
|
+
}
|
|
1033
|
+
const { ok, output } = codesignVerify(tmpPath);
|
|
1034
|
+
if (!ok) {
|
|
1035
|
+
try { fs.unlinkSync(tmpPath); } catch { /* ignore */ }
|
|
1036
|
+
throw new InstallError(
|
|
1037
|
+
`Bundled uv failed code signature verification (codesign --verify --strict): ${output || "no output"}`,
|
|
1038
|
+
{
|
|
1039
|
+
stage: STAGES.ENSURE_UV,
|
|
1040
|
+
suggestion:
|
|
1041
|
+
"The AppImage/installer may be corrupt. Re-download from https://amd-gaia.ai and try again.",
|
|
1042
|
+
}
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
log("Bundled uv passed codesign --verify --strict");
|
|
1046
|
+
} else {
|
|
1047
|
+
let actual;
|
|
1048
|
+
try {
|
|
1049
|
+
actual = await sha256File(tmpPath);
|
|
1050
|
+
} catch (err) {
|
|
1051
|
+
try { fs.unlinkSync(tmpPath); } catch { /* ignore */ }
|
|
1052
|
+
throw new InstallError(
|
|
1053
|
+
`Could not hash copied uv binary: ${err.message}`,
|
|
1054
|
+
{ stage: STAGES.ENSURE_UV }
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
1002
1057
|
|
|
1003
|
-
if (expected) {
|
|
1004
1058
|
if (actual !== expected) {
|
|
1005
1059
|
try { fs.unlinkSync(tmpPath); } catch { /* ignore */ }
|
|
1006
1060
|
throw new InstallError(
|
|
@@ -1012,14 +1066,12 @@ async function installBundledUv(sourcePath, platformKey) {
|
|
|
1012
1066
|
}
|
|
1013
1067
|
);
|
|
1014
1068
|
}
|
|
1015
|
-
} else {
|
|
1016
|
-
log("No expected SHA registered for bundled uv; installed binary will not be verified locally.");
|
|
1017
|
-
}
|
|
1018
1069
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1070
|
+
try {
|
|
1071
|
+
if (!IS_WINDOWS) fs.chmodSync(tmpPath, 0o700);
|
|
1072
|
+
} catch (err) {
|
|
1073
|
+
log(`Warning: chmod on tmp uv failed: ${err.message}`);
|
|
1074
|
+
}
|
|
1023
1075
|
}
|
|
1024
1076
|
|
|
1025
1077
|
try {
|
|
@@ -1057,9 +1109,11 @@ function addManagedBinToPath() {
|
|
|
1057
1109
|
|
|
1058
1110
|
/**
|
|
1059
1111
|
* Ensure `uv` is available. Preference order (per issue #782 / T3):
|
|
1060
|
-
* 1. Managed copy at ~/.gaia/bin/uv
|
|
1112
|
+
* 1. Managed copy at ~/.gaia/bin/uv already verified (warm-install fast path):
|
|
1113
|
+
* SHA256 pin on linux-x64/win-x64, `codesign --verify --strict` on mac-arm64.
|
|
1061
1114
|
* 2. Bundled binary in process.resourcesPath/vendor/uv/<platform>/uv:
|
|
1062
|
-
* copy atomically to ~/.gaia/bin/uv with
|
|
1115
|
+
* copy atomically to ~/.gaia/bin/uv with the same platform-appropriate
|
|
1116
|
+
* verification.
|
|
1063
1117
|
* 3. DEV-ONLY fallback (app.isPackaged === false OR no resourcesPath):
|
|
1064
1118
|
* the original `curl | sh` from astral.sh. Not a shipped-user path.
|
|
1065
1119
|
* 4. System `uv` on PATH (last resort — unverified version).
|
|
@@ -1071,10 +1125,20 @@ async function ensureUv({ onProgress, isPackaged } = {}) {
|
|
|
1071
1125
|
report(STAGES.ENSURE_UV, 0, "Checking uv (Python package manager)");
|
|
1072
1126
|
|
|
1073
1127
|
const platformKey = bundledUvPlatformKey();
|
|
1128
|
+
const isDarwin = platformKey === "mac-arm64";
|
|
1074
1129
|
const expectedSha = platformKey ? BUNDLED_UV_SHA256[platformKey] : null;
|
|
1075
1130
|
|
|
1076
|
-
// Fast path: warm install already on disk
|
|
1077
|
-
if (
|
|
1131
|
+
// Fast path: warm install already on disk and still passes verification.
|
|
1132
|
+
if (isDarwin && fs.existsSync(MANAGED_UV_BIN)) {
|
|
1133
|
+
const { ok, output } = codesignVerify(MANAGED_UV_BIN);
|
|
1134
|
+
if (ok) {
|
|
1135
|
+
log(`Managed uv at ${MANAGED_UV_BIN} passed codesign --verify --strict — reusing`);
|
|
1136
|
+
addManagedBinToPath();
|
|
1137
|
+
report(STAGES.ENSURE_UV, 100, "uv ready (cached)");
|
|
1138
|
+
return;
|
|
1139
|
+
}
|
|
1140
|
+
log(`Managed uv failed codesign verification (${output || "no output"}) — replacing`);
|
|
1141
|
+
} else if (expectedSha && fs.existsSync(MANAGED_UV_BIN)) {
|
|
1078
1142
|
try {
|
|
1079
1143
|
const actual = await sha256File(MANAGED_UV_BIN);
|
|
1080
1144
|
if (actual === expectedSha) {
|
|
@@ -1097,22 +1161,36 @@ async function ensureUv({ onProgress, isPackaged } = {}) {
|
|
|
1097
1161
|
report(STAGES.ENSURE_UV, 30, "Installing bundled uv");
|
|
1098
1162
|
log(`Using bundled uv from ${bundled}`);
|
|
1099
1163
|
|
|
1100
|
-
// Verify the source resource
|
|
1101
|
-
//
|
|
1102
|
-
//
|
|
1103
|
-
//
|
|
1104
|
-
//
|
|
1105
|
-
// build-time error
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1164
|
+
// Verify the source resource before copying — catches installer
|
|
1165
|
+
// corruption before we touch the user's home. mac-arm64 uses
|
|
1166
|
+
// codesign --verify --strict (see BUNDLED_UV_SHA256 comment for why a
|
|
1167
|
+
// fixed digest isn't viable there); other platforms use the SHA256 pin,
|
|
1168
|
+
// which CI must have populated — a missing/placeholder value is a
|
|
1169
|
+
// build-time error, rejected at runtime here.
|
|
1170
|
+
if (isDarwin) {
|
|
1171
|
+
const { ok, output } = codesignVerify(bundled);
|
|
1172
|
+
if (!ok) {
|
|
1173
|
+
throw new InstallError(
|
|
1174
|
+
`Bundled uv resource failed code signature verification (codesign --verify --strict): ${output || "no output"}`,
|
|
1175
|
+
{
|
|
1176
|
+
stage: STAGES.ENSURE_UV,
|
|
1177
|
+
suggestion:
|
|
1178
|
+
"The installer appears to be corrupt. Re-download GAIA from https://amd-gaia.ai and try again.",
|
|
1179
|
+
}
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
} else {
|
|
1183
|
+
const srcHash = await sha256File(bundled);
|
|
1184
|
+
if (srcHash !== expectedSha) {
|
|
1185
|
+
throw new InstallError(
|
|
1186
|
+
`Bundled uv resource SHA256 mismatch (expected ${expectedSha}, got ${srcHash}).`,
|
|
1187
|
+
{
|
|
1188
|
+
stage: STAGES.ENSURE_UV,
|
|
1189
|
+
suggestion:
|
|
1190
|
+
"The installer appears to be corrupt. Re-download GAIA from https://amd-gaia.ai and try again.",
|
|
1191
|
+
}
|
|
1192
|
+
);
|
|
1193
|
+
}
|
|
1116
1194
|
}
|
|
1117
1195
|
await installBundledUv(bundled, platformKey);
|
|
1118
1196
|
addManagedBinToPath();
|