@astrale-os/cli 1.0.0-beta.3 → 1.0.0-beta.4
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 +15 -0
- package/dist/astrale.js +445 -344
- package/dist/public/connect-core.js +40 -3
- package/dist/types/lib/admin-target.d.ts +6 -2
- package/dist/types/lib/proc.d.ts +43 -0
- package/dist/types/lib/update.d.ts +101 -0
- package/package.json +1 -1
- package/src/admin/__tests__/binding.test.ts +38 -0
- package/src/admin/binding.ts +9 -159
- package/src/lib/__tests__/admin-target.test.ts +12 -0
- package/src/lib/__tests__/idp.test.ts +9 -4
- package/src/lib/admin-target.ts +21 -2
- package/src/lib/idp.ts +5 -2
package/dist/astrale.js
CHANGED
|
@@ -9738,7 +9738,7 @@ var package_default;
|
|
|
9738
9738
|
var init_package = __esm(() => {
|
|
9739
9739
|
package_default = {
|
|
9740
9740
|
name: "@astrale-os/cli",
|
|
9741
|
-
version: "1.0.0-beta.
|
|
9741
|
+
version: "1.0.0-beta.4",
|
|
9742
9742
|
description: "Astrale CLI — connect to existing Astrale kernels",
|
|
9743
9743
|
keywords: [
|
|
9744
9744
|
"astrale",
|
|
@@ -67208,7 +67208,7 @@ function builtinIdpConfig(name, clientIdOverride, env2 = process.env) {
|
|
|
67208
67208
|
};
|
|
67209
67209
|
}
|
|
67210
67210
|
function workosClientIdFromEnv(env2 = process.env) {
|
|
67211
|
-
return WORKOS_CLIENT_ID_ENV_NAMES.map((name) => env2[name]?.trim()).find((value) => typeof value === "string" && value.length > 0);
|
|
67211
|
+
return WORKOS_CLIENT_ID_ENV_NAMES.map((name) => env2[name]?.trim()).find((value) => typeof value === "string" && value.length > 0) ?? DEFAULT_WORKOS_CLIENT_ID;
|
|
67212
67212
|
}
|
|
67213
67213
|
async function fetchOAuthAuthorizationServerMetadata(issuer) {
|
|
67214
67214
|
const discoveryUrl = new URL("/.well-known/oauth-authorization-server", issuer);
|
|
@@ -67553,7 +67553,7 @@ async function fetchWorkosApplication(args) {
|
|
|
67553
67553
|
function normalizeIssuer(value) {
|
|
67554
67554
|
return value.replace(/\/+$/, "");
|
|
67555
67555
|
}
|
|
67556
|
-
var IdpAudienceMismatchError, OAuthTokenError, OidcMetadataSchema, IdpClientConfigSchema, IdpIndexEntrySchema, IdpStoreSchema, IdpSessionSchema, BUILTIN_WORKOS_IDP_NAME = "workos", DEFAULT_WORKOS_API_HOST = "https://api.workos.com", WORKOS_CLIENT_ID_ENV_NAMES;
|
|
67556
|
+
var IdpAudienceMismatchError, OAuthTokenError, OidcMetadataSchema, IdpClientConfigSchema, IdpIndexEntrySchema, IdpStoreSchema, IdpSessionSchema, BUILTIN_WORKOS_IDP_NAME = "workos", DEFAULT_WORKOS_API_HOST = "https://api.workos.com", DEFAULT_WORKOS_CLIENT_ID = "client_01KC29HET5F3QAQ8GNTPZ7F320", WORKOS_CLIENT_ID_ENV_NAMES;
|
|
67557
67557
|
var init_idp = __esm(() => {
|
|
67558
67558
|
init_webapi();
|
|
67559
67559
|
init_zod2();
|
|
@@ -70394,7 +70394,257 @@ var init_instance2 = __esm(() => {
|
|
|
70394
70394
|
});
|
|
70395
70395
|
});
|
|
70396
70396
|
|
|
70397
|
+
// src/lib/proc.ts
|
|
70398
|
+
import { spawn } from "node:child_process";
|
|
70399
|
+
function run(file2, args = [], opts = {}) {
|
|
70400
|
+
return new Promise((resolve3, reject) => {
|
|
70401
|
+
const child3 = spawn(file2, args, { cwd: opts.cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
70402
|
+
let stdout = "";
|
|
70403
|
+
let stderr = "";
|
|
70404
|
+
child3.stdout?.setEncoding("utf8");
|
|
70405
|
+
child3.stderr?.setEncoding("utf8");
|
|
70406
|
+
child3.stdout?.on("data", (chunk) => {
|
|
70407
|
+
stdout += chunk;
|
|
70408
|
+
});
|
|
70409
|
+
child3.stderr?.on("data", (chunk) => {
|
|
70410
|
+
stderr += chunk;
|
|
70411
|
+
});
|
|
70412
|
+
child3.on("error", reject);
|
|
70413
|
+
child3.on("close", (code) => resolve3({ code: code ?? -1, stdout, stderr }));
|
|
70414
|
+
});
|
|
70415
|
+
}
|
|
70416
|
+
function runInherit(file2, args = [], opts = {}) {
|
|
70417
|
+
return new Promise((resolve3, reject) => {
|
|
70418
|
+
const child3 = spawn(file2, args, { cwd: opts.cwd, stdio: "inherit" });
|
|
70419
|
+
child3.on("error", reject);
|
|
70420
|
+
child3.on("close", (code) => resolve3(code ?? -1));
|
|
70421
|
+
});
|
|
70422
|
+
}
|
|
70423
|
+
function spawnHandle(file2, args = [], opts = {}) {
|
|
70424
|
+
return spawn(file2, args, {
|
|
70425
|
+
cwd: opts.cwd,
|
|
70426
|
+
env: opts.env,
|
|
70427
|
+
detached: opts.detached,
|
|
70428
|
+
stdio: opts.stdio ?? ["ignore", "inherit", "inherit"]
|
|
70429
|
+
});
|
|
70430
|
+
}
|
|
70431
|
+
var init_proc = () => {};
|
|
70432
|
+
|
|
70433
|
+
// src/lib/update.ts
|
|
70434
|
+
import { createHash } from "node:crypto";
|
|
70435
|
+
import { chmod as chmod2, copyFile, mkdir as mkdir6, mkdtemp, readFile as readFile7, rename as rename2, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
70436
|
+
import { tmpdir } from "node:os";
|
|
70437
|
+
import { dirname as dirname6, join as join4 } from "node:path";
|
|
70438
|
+
function detectPlatform() {
|
|
70439
|
+
const os2 = process.platform;
|
|
70440
|
+
const arch = process.arch;
|
|
70441
|
+
if (os2 !== "darwin" && os2 !== "linux") {
|
|
70442
|
+
throw new AstraleError("UNSUPPORTED_PLATFORM", `Unsupported OS "${os2}" — Astrale update supports macOS and Linux.`);
|
|
70443
|
+
}
|
|
70444
|
+
if (arch !== "arm64" && arch !== "x64") {
|
|
70445
|
+
throw new AstraleError("UNSUPPORTED_PLATFORM", `Unsupported CPU architecture "${arch}" — Astrale update supports arm64 and x64.`);
|
|
70446
|
+
}
|
|
70447
|
+
return { os: os2, arch };
|
|
70448
|
+
}
|
|
70449
|
+
function platformKey(platform) {
|
|
70450
|
+
return `${platform.os}-${platform.arch}`;
|
|
70451
|
+
}
|
|
70452
|
+
function isStandaloneBinary() {
|
|
70453
|
+
return Boolean(process.versions.bun);
|
|
70454
|
+
}
|
|
70455
|
+
async function readInstallMetadata(path3 = INSTALL_PATH) {
|
|
70456
|
+
let raw2;
|
|
70457
|
+
try {
|
|
70458
|
+
raw2 = await readFile7(path3, "utf8");
|
|
70459
|
+
} catch {
|
|
70460
|
+
throw isStandaloneBinary() ? new AstraleError("UPDATE_NOT_SCRIPT_INSTALLED", "Astrale was not installed by the official install script.", "Reinstall with: curl -fsSL https://raw.githubusercontent.com/astrale-os/cli/main/install.sh | sh") : new AstraleError("UPDATE_PACKAGE_MANAGED", "This Astrale build is managed by your package manager.", "Update with: npm install -g @astrale-os/cli@latest (or pnpm/bun)");
|
|
70461
|
+
}
|
|
70462
|
+
const parsed = InstallMetadataSchema.safeParse(JSON.parse(raw2));
|
|
70463
|
+
if (!parsed.success) {
|
|
70464
|
+
throw new AstraleError("UPDATE_BAD_INSTALL_METADATA", `Invalid install metadata at ${path3}.`, "Reinstall with: curl -fsSL https://raw.githubusercontent.com/astrale-os/cli/main/install.sh | sh");
|
|
70465
|
+
}
|
|
70466
|
+
return parsed.data;
|
|
70467
|
+
}
|
|
70468
|
+
async function writeInstallMetadata(meta3, path3 = INSTALL_PATH) {
|
|
70469
|
+
await mkdir6(dirname6(path3), { recursive: true });
|
|
70470
|
+
await writeFile2(path3, JSON.stringify(meta3, null, 2) + `
|
|
70471
|
+
`);
|
|
70472
|
+
}
|
|
70473
|
+
function releaseBase(meta3, req) {
|
|
70474
|
+
if (process.env.ASTRALE_UPDATE_BASE)
|
|
70475
|
+
return process.env.ASTRALE_UPDATE_BASE.replace(/\/+$/, "");
|
|
70476
|
+
const repo = meta3.repo || DEFAULT_REPO;
|
|
70477
|
+
if (req.version) {
|
|
70478
|
+
const version2 = req.version.replace(/^cli\/v/, "").replace(/^v/, "");
|
|
70479
|
+
return `https://github.com/${repo}/releases/download/cli/v${version2}`;
|
|
70480
|
+
}
|
|
70481
|
+
return `https://github.com/${repo}/releases/download/${req.channel ?? meta3.channel ?? DEFAULT_UPDATE_CHANNEL}`;
|
|
70482
|
+
}
|
|
70483
|
+
async function fetchManifest(base2) {
|
|
70484
|
+
const raw2 = await readUrlText(`${base2}/manifest.json`);
|
|
70485
|
+
return UpdateManifestSchema.parse(JSON.parse(raw2));
|
|
70486
|
+
}
|
|
70487
|
+
function shouldUpdate(currentVersion, manifestVersion) {
|
|
70488
|
+
return currentVersion !== manifestVersion;
|
|
70489
|
+
}
|
|
70490
|
+
async function updateAstrale(req) {
|
|
70491
|
+
const meta3 = await readInstallMetadata(req.installPath);
|
|
70492
|
+
const currentVersion = meta3.version ?? req.currentVersion;
|
|
70493
|
+
const channel = req.channel ?? meta3.channel ?? DEFAULT_UPDATE_CHANNEL;
|
|
70494
|
+
const platform = req.platform ?? detectPlatform();
|
|
70495
|
+
const key = platformKey(platform);
|
|
70496
|
+
const base2 = releaseBase(meta3, { channel, version: req.version });
|
|
70497
|
+
const manifest = await fetchManifest(base2);
|
|
70498
|
+
const asset = manifest.assets[key];
|
|
70499
|
+
if (!asset) {
|
|
70500
|
+
throw new AstraleError("UPDATE_ASSET_NOT_FOUND", `No Astrale CLI release asset for ${key}.`, `Available platforms: ${Object.keys(manifest.assets).join(", ")}`);
|
|
70501
|
+
}
|
|
70502
|
+
if (!shouldUpdate(currentVersion, manifest.version)) {
|
|
70503
|
+
return {
|
|
70504
|
+
status: "up-to-date",
|
|
70505
|
+
currentVersion,
|
|
70506
|
+
latestVersion: manifest.version,
|
|
70507
|
+
channel: manifest.channel
|
|
70508
|
+
};
|
|
70509
|
+
}
|
|
70510
|
+
if (req.check) {
|
|
70511
|
+
return {
|
|
70512
|
+
status: "available",
|
|
70513
|
+
currentVersion,
|
|
70514
|
+
latestVersion: manifest.version,
|
|
70515
|
+
channel: manifest.channel
|
|
70516
|
+
};
|
|
70517
|
+
}
|
|
70518
|
+
const tmp = await mkdtemp(join4(tmpdir(), "astrale-update-"));
|
|
70519
|
+
try {
|
|
70520
|
+
const archive = join4(tmp, asset.name);
|
|
70521
|
+
await downloadToFile(`${base2}/${asset.name}`, archive);
|
|
70522
|
+
const manifestChecksum = "sha256" in asset ? asset.sha256 : undefined;
|
|
70523
|
+
const expected = manifestChecksum ?? await fetchChecksum(base2, asset.name);
|
|
70524
|
+
const actual = await sha256File(archive);
|
|
70525
|
+
if (actual !== expected.toLowerCase()) {
|
|
70526
|
+
throw new AstraleError("UPDATE_CHECKSUM_MISMATCH", `Checksum mismatch for ${asset.name}.`, `Expected ${expected}; got ${actual}.`);
|
|
70527
|
+
}
|
|
70528
|
+
await extractTarGz(archive, tmp);
|
|
70529
|
+
const nextBin = join4(tmp, "astrale");
|
|
70530
|
+
await chmod2(nextBin, 493);
|
|
70531
|
+
await smokeVersion(nextBin, manifest.binaryVersion ?? manifest.version);
|
|
70532
|
+
const previous = `${meta3.bin}.previous`;
|
|
70533
|
+
const staged = `${meta3.bin}.next`;
|
|
70534
|
+
await copyFile(meta3.bin, previous).catch(() => {
|
|
70535
|
+
return;
|
|
70536
|
+
});
|
|
70537
|
+
await copyFile(nextBin, staged);
|
|
70538
|
+
await chmod2(staged, 493);
|
|
70539
|
+
await rename2(staged, meta3.bin);
|
|
70540
|
+
await writeInstallMetadata({
|
|
70541
|
+
...meta3,
|
|
70542
|
+
channel: manifest.channel,
|
|
70543
|
+
version: manifest.version,
|
|
70544
|
+
installedAt: new Date().toISOString()
|
|
70545
|
+
}, req.installPath);
|
|
70546
|
+
return {
|
|
70547
|
+
status: "updated",
|
|
70548
|
+
previousVersion: currentVersion,
|
|
70549
|
+
currentVersion: manifest.version,
|
|
70550
|
+
channel: manifest.channel,
|
|
70551
|
+
bin: meta3.bin
|
|
70552
|
+
};
|
|
70553
|
+
} finally {
|
|
70554
|
+
await rm(tmp, { recursive: true, force: true });
|
|
70555
|
+
}
|
|
70556
|
+
}
|
|
70557
|
+
async function readUrlText(url3) {
|
|
70558
|
+
if (url3.startsWith("file://")) {
|
|
70559
|
+
return readFile7(new URL(url3), "utf8");
|
|
70560
|
+
}
|
|
70561
|
+
const res = await fetch(url3);
|
|
70562
|
+
if (!res.ok)
|
|
70563
|
+
throw new Error(`GET ${url3} failed: HTTP ${res.status}`);
|
|
70564
|
+
return res.text();
|
|
70565
|
+
}
|
|
70566
|
+
async function downloadToFile(url3, path3) {
|
|
70567
|
+
if (url3.startsWith("file://")) {
|
|
70568
|
+
await copyFile(new URL(url3), path3);
|
|
70569
|
+
return;
|
|
70570
|
+
}
|
|
70571
|
+
const res = await fetch(url3);
|
|
70572
|
+
if (!res.ok)
|
|
70573
|
+
throw new Error(`GET ${url3} failed: HTTP ${res.status}`);
|
|
70574
|
+
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
70575
|
+
await writeFile2(path3, bytes);
|
|
70576
|
+
}
|
|
70577
|
+
async function fetchChecksum(base2, assetName) {
|
|
70578
|
+
const raw2 = await readUrlText(`${base2}/sha256sums.txt`);
|
|
70579
|
+
for (const line of raw2.split(/\r?\n/)) {
|
|
70580
|
+
const [sha, file2] = line.trim().split(/\s+/, 2);
|
|
70581
|
+
if (!sha || !file2)
|
|
70582
|
+
continue;
|
|
70583
|
+
if (file2.replace(/^\*/, "") === assetName && /^[a-fA-F0-9]{64}$/.test(sha))
|
|
70584
|
+
return sha;
|
|
70585
|
+
}
|
|
70586
|
+
throw new AstraleError("UPDATE_CHECKSUM_NOT_FOUND", `Checksum entry not found for ${assetName}.`, `Release base: ${base2}`);
|
|
70587
|
+
}
|
|
70588
|
+
async function sha256File(path3) {
|
|
70589
|
+
const hash2 = createHash("sha256");
|
|
70590
|
+
hash2.update(await readFile7(path3));
|
|
70591
|
+
return hash2.digest("hex");
|
|
70592
|
+
}
|
|
70593
|
+
async function extractTarGz(archive, cwd) {
|
|
70594
|
+
const { code, stderr } = await run("tar", ["-xzf", archive, "-C", cwd]);
|
|
70595
|
+
if (code !== 0) {
|
|
70596
|
+
throw new Error(`Could not extract update archive: ${stderr.trim()}`);
|
|
70597
|
+
}
|
|
70598
|
+
}
|
|
70599
|
+
async function smokeVersion(bin, expectedVersion) {
|
|
70600
|
+
const { code, stdout, stderr } = await run(bin, ["--version"]);
|
|
70601
|
+
if (code !== 0)
|
|
70602
|
+
throw new Error(`Updated binary failed --version: ${stderr.trim()}`);
|
|
70603
|
+
const actual = stdout.trim();
|
|
70604
|
+
if (actual !== expectedVersion) {
|
|
70605
|
+
throw new Error(`Updated binary reported version ${actual}, expected ${expectedVersion}`);
|
|
70606
|
+
}
|
|
70607
|
+
}
|
|
70608
|
+
var DEFAULT_REPO = "astrale-os/cli", DEFAULT_UPDATE_CHANNEL = "beta", InstallMetadataSchema, ManifestAssetSchema, UpdateManifestSchema;
|
|
70609
|
+
var init_update = __esm(() => {
|
|
70610
|
+
init_zod2();
|
|
70611
|
+
init_errors2();
|
|
70612
|
+
init_state();
|
|
70613
|
+
init_proc();
|
|
70614
|
+
InstallMetadataSchema = exports_external2.object({
|
|
70615
|
+
method: exports_external2.literal("script"),
|
|
70616
|
+
channel: exports_external2.string().min(1).default(DEFAULT_UPDATE_CHANNEL),
|
|
70617
|
+
version: exports_external2.string().min(1).optional(),
|
|
70618
|
+
repo: exports_external2.string().min(1).default(DEFAULT_REPO),
|
|
70619
|
+
bin: exports_external2.string().min(1),
|
|
70620
|
+
installedAt: exports_external2.string().optional()
|
|
70621
|
+
});
|
|
70622
|
+
ManifestAssetSchema = exports_external2.object({
|
|
70623
|
+
name: exports_external2.string().min(1),
|
|
70624
|
+
sha256: exports_external2.string().regex(/^[a-fA-F0-9]{64}$/).optional()
|
|
70625
|
+
});
|
|
70626
|
+
UpdateManifestSchema = exports_external2.object({
|
|
70627
|
+
version: exports_external2.string().min(1),
|
|
70628
|
+
binaryVersion: exports_external2.string().min(1).optional(),
|
|
70629
|
+
channel: exports_external2.string().min(1),
|
|
70630
|
+
repo: exports_external2.string().min(1).optional(),
|
|
70631
|
+
assets: exports_external2.record(exports_external2.string(), exports_external2.union([
|
|
70632
|
+
ManifestAssetSchema,
|
|
70633
|
+
exports_external2.string().min(1).transform((name) => ({ name }))
|
|
70634
|
+
]))
|
|
70635
|
+
});
|
|
70636
|
+
});
|
|
70637
|
+
|
|
70397
70638
|
// src/lib/admin-target.ts
|
|
70639
|
+
function defaultAdminTargetForChannel(channel) {
|
|
70640
|
+
return channel === "stable" ? {
|
|
70641
|
+
url: "https://admin.eu.astrale.ai/api",
|
|
70642
|
+
domainIssuer: "https://admin.astrale.ai"
|
|
70643
|
+
} : {
|
|
70644
|
+
url: "https://admin.eu.beta.astrale.ai/api",
|
|
70645
|
+
domainIssuer: "https://admin.beta.astrale.ai"
|
|
70646
|
+
};
|
|
70647
|
+
}
|
|
70398
70648
|
async function resolveAdminTarget(opts, config2, store) {
|
|
70399
70649
|
return resolveAdminTargetFromStore(opts, config2, store ?? await readInstances());
|
|
70400
70650
|
}
|
|
@@ -70486,12 +70736,16 @@ function requireDomainIssuer(value, label) {
|
|
|
70486
70736
|
return value;
|
|
70487
70737
|
throw new AstraleError("ADMIN_DOMAIN_ISSUER_MISSING", `${label} has no Domain issuer for token exchange.`, "Configure domainIssuer or pass --domain-issuer <url>; there is no legacy token fallback.");
|
|
70488
70738
|
}
|
|
70489
|
-
var DEFAULT_ADMIN_TARGET_NAME = "admin", DEFAULT_ADMIN_TARGET_URL
|
|
70739
|
+
var DEFAULT_ADMIN_TARGET_NAME = "admin", DEFAULT_ADMIN_TARGET, DEFAULT_ADMIN_TARGET_URL, DEFAULT_ADMIN_DOMAIN_ISSUER, DEFAULT_ADMIN_TARGET_CONFIG, HttpUrlSchema, AdminTargetConfigSchema, ADMIN_TARGET_OPTIONS;
|
|
70490
70740
|
var init_admin_target = __esm(() => {
|
|
70491
70741
|
init_zod2();
|
|
70492
70742
|
init_errors2();
|
|
70493
70743
|
init_instance2();
|
|
70744
|
+
init_update();
|
|
70494
70745
|
init_validation2();
|
|
70746
|
+
DEFAULT_ADMIN_TARGET = defaultAdminTargetForChannel(DEFAULT_UPDATE_CHANNEL);
|
|
70747
|
+
DEFAULT_ADMIN_TARGET_URL = DEFAULT_ADMIN_TARGET.url;
|
|
70748
|
+
DEFAULT_ADMIN_DOMAIN_ISSUER = DEFAULT_ADMIN_TARGET.domainIssuer;
|
|
70495
70749
|
DEFAULT_ADMIN_TARGET_CONFIG = {
|
|
70496
70750
|
name: DEFAULT_ADMIN_TARGET_NAME,
|
|
70497
70751
|
url: DEFAULT_ADMIN_TARGET_URL,
|
|
@@ -70553,11 +70807,11 @@ var init_admin_target = __esm(() => {
|
|
|
70553
70807
|
});
|
|
70554
70808
|
|
|
70555
70809
|
// src/lib/config.ts
|
|
70556
|
-
import { readFile as
|
|
70557
|
-
import { dirname as
|
|
70810
|
+
import { readFile as readFile8, writeFile as writeFile3, mkdir as mkdir7 } from "node:fs/promises";
|
|
70811
|
+
import { dirname as dirname7 } from "node:path";
|
|
70558
70812
|
async function readConfig() {
|
|
70559
70813
|
try {
|
|
70560
|
-
const raw2 = await
|
|
70814
|
+
const raw2 = await readFile8(CONFIG_PATH, "utf-8");
|
|
70561
70815
|
return AstraleConfigSchema.parse(JSON.parse(raw2));
|
|
70562
70816
|
} catch (e) {
|
|
70563
70817
|
if (e instanceof exports_external2.ZodError || e instanceof SyntaxError) {
|
|
@@ -70567,8 +70821,8 @@ async function readConfig() {
|
|
|
70567
70821
|
}
|
|
70568
70822
|
}
|
|
70569
70823
|
async function writeConfig(config2) {
|
|
70570
|
-
await
|
|
70571
|
-
await
|
|
70824
|
+
await mkdir7(dirname7(CONFIG_PATH), { recursive: true });
|
|
70825
|
+
await writeFile3(CONFIG_PATH, JSON.stringify(config2, null, 2) + `
|
|
70572
70826
|
`);
|
|
70573
70827
|
}
|
|
70574
70828
|
var AstraleConfigSchema, DEFAULT_CONFIG;
|
|
@@ -70754,13 +71008,13 @@ function readline() {
|
|
|
70754
71008
|
function withUpdates(fn2) {
|
|
70755
71009
|
const wrapped = (...args) => {
|
|
70756
71010
|
const store = getStore();
|
|
70757
|
-
let
|
|
71011
|
+
let shouldUpdate2 = false;
|
|
70758
71012
|
const oldHandleChange = store.handleChange;
|
|
70759
71013
|
store.handleChange = () => {
|
|
70760
|
-
|
|
71014
|
+
shouldUpdate2 = true;
|
|
70761
71015
|
};
|
|
70762
71016
|
const returnValue = fn2(...args);
|
|
70763
|
-
if (
|
|
71017
|
+
if (shouldUpdate2) {
|
|
70764
71018
|
oldHandleChange();
|
|
70765
71019
|
}
|
|
70766
71020
|
store.handleChange = oldHandleChange;
|
|
@@ -82156,7 +82410,7 @@ function parseEditorCommand(editor) {
|
|
|
82156
82410
|
}
|
|
82157
82411
|
|
|
82158
82412
|
// node_modules/.pnpm/@inquirer+external-editor@3.0.3_@types+node@22.20.0/node_modules/@inquirer/external-editor/dist/index.js
|
|
82159
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
82413
|
+
import { spawn as spawn2, spawnSync } from "node:child_process";
|
|
82160
82414
|
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
82161
82415
|
import path4 from "node:path";
|
|
82162
82416
|
import os2 from "node:os";
|
|
@@ -82204,7 +82458,7 @@ class ExternalEditor {
|
|
|
82204
82458
|
this.createTempFile();
|
|
82205
82459
|
const promise2 = new Promise((resolve3, reject) => {
|
|
82206
82460
|
try {
|
|
82207
|
-
const editorProcess =
|
|
82461
|
+
const editorProcess = spawn2(this.editor.bin, this.editorArgs(), {
|
|
82208
82462
|
shell: false,
|
|
82209
82463
|
stdio: "inherit"
|
|
82210
82464
|
});
|
|
@@ -83544,51 +83798,15 @@ var init_admin = __esm(() => {
|
|
|
83544
83798
|
};
|
|
83545
83799
|
});
|
|
83546
83800
|
|
|
83547
|
-
// src/lib/proc.ts
|
|
83548
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
83549
|
-
function run(file2, args = [], opts = {}) {
|
|
83550
|
-
return new Promise((resolve3, reject) => {
|
|
83551
|
-
const child3 = spawn2(file2, args, { cwd: opts.cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
83552
|
-
let stdout = "";
|
|
83553
|
-
let stderr = "";
|
|
83554
|
-
child3.stdout?.setEncoding("utf8");
|
|
83555
|
-
child3.stderr?.setEncoding("utf8");
|
|
83556
|
-
child3.stdout?.on("data", (chunk) => {
|
|
83557
|
-
stdout += chunk;
|
|
83558
|
-
});
|
|
83559
|
-
child3.stderr?.on("data", (chunk) => {
|
|
83560
|
-
stderr += chunk;
|
|
83561
|
-
});
|
|
83562
|
-
child3.on("error", reject);
|
|
83563
|
-
child3.on("close", (code) => resolve3({ code: code ?? -1, stdout, stderr }));
|
|
83564
|
-
});
|
|
83565
|
-
}
|
|
83566
|
-
function runInherit(file2, args = [], opts = {}) {
|
|
83567
|
-
return new Promise((resolve3, reject) => {
|
|
83568
|
-
const child3 = spawn2(file2, args, { cwd: opts.cwd, stdio: "inherit" });
|
|
83569
|
-
child3.on("error", reject);
|
|
83570
|
-
child3.on("close", (code) => resolve3(code ?? -1));
|
|
83571
|
-
});
|
|
83572
|
-
}
|
|
83573
|
-
function spawnHandle(file2, args = [], opts = {}) {
|
|
83574
|
-
return spawn2(file2, args, {
|
|
83575
|
-
cwd: opts.cwd,
|
|
83576
|
-
env: opts.env,
|
|
83577
|
-
detached: opts.detached,
|
|
83578
|
-
stdio: opts.stdio ?? ["ignore", "inherit", "inherit"]
|
|
83579
|
-
});
|
|
83580
|
-
}
|
|
83581
|
-
var init_proc = () => {};
|
|
83582
|
-
|
|
83583
83801
|
// src/lib/browser.ts
|
|
83584
|
-
import { mkdir as
|
|
83585
|
-
import { join as
|
|
83802
|
+
import { mkdir as mkdir8, readFile as readFile9, writeFile as writeFile4 } from "node:fs/promises";
|
|
83803
|
+
import { join as join5 } from "node:path";
|
|
83586
83804
|
function profileDirFor(host) {
|
|
83587
|
-
return
|
|
83805
|
+
return join5(BROWSER_DIR, host);
|
|
83588
83806
|
}
|
|
83589
83807
|
async function saveSession(session) {
|
|
83590
|
-
await
|
|
83591
|
-
await
|
|
83808
|
+
await mkdir8(paths3.home, { recursive: true });
|
|
83809
|
+
await writeFile4(BROWSER_SESSION_PATH, `${JSON.stringify(session, null, 2)}
|
|
83592
83810
|
`);
|
|
83593
83811
|
}
|
|
83594
83812
|
async function findAgentBrowser() {
|
|
@@ -83638,15 +83856,15 @@ var BROWSER_DIR, BROWSER_SESSION_PATH, AGENT_BROWSER_REPO = "vercel-labs/agent-b
|
|
|
83638
83856
|
var init_browser = __esm(() => {
|
|
83639
83857
|
init_state();
|
|
83640
83858
|
init_proc();
|
|
83641
|
-
BROWSER_DIR =
|
|
83642
|
-
BROWSER_SESSION_PATH =
|
|
83859
|
+
BROWSER_DIR = join5(paths3.home, "browser");
|
|
83860
|
+
BROWSER_SESSION_PATH = join5(paths3.home, "browser.json");
|
|
83643
83861
|
AUTH_EVAL = "fetch('/auth/me',{credentials:'include'})" + ".then(r=>r.json())" + ".then(j=>({authed:!!j.authenticated,email:j.user&&j.user.email}))" + ".catch(()=>({authed:false}))";
|
|
83644
83862
|
});
|
|
83645
83863
|
|
|
83646
83864
|
// src/lib/skills.ts
|
|
83647
83865
|
import { existsSync, lstatSync, mkdirSync, readlinkSync, symlinkSync } from "node:fs";
|
|
83648
83866
|
import { homedir as homedir2 } from "node:os";
|
|
83649
|
-
import { dirname as
|
|
83867
|
+
import { dirname as dirname8, join as join6 } from "node:path";
|
|
83650
83868
|
async function installSkills() {
|
|
83651
83869
|
const { code, stdout, stderr } = await run("npx", [
|
|
83652
83870
|
"skills",
|
|
@@ -83663,18 +83881,18 @@ function skillSearchDirs() {
|
|
|
83663
83881
|
const dirs = [];
|
|
83664
83882
|
let cur = process.cwd();
|
|
83665
83883
|
for (;; ) {
|
|
83666
|
-
dirs.push(
|
|
83667
|
-
const parent =
|
|
83884
|
+
dirs.push(join6(cur, ".claude", "skills"));
|
|
83885
|
+
const parent = dirname8(cur);
|
|
83668
83886
|
if (parent === cur)
|
|
83669
83887
|
break;
|
|
83670
83888
|
cur = parent;
|
|
83671
83889
|
}
|
|
83672
|
-
dirs.push(
|
|
83890
|
+
dirs.push(join6(homedir2(), ".claude", "skills"));
|
|
83673
83891
|
return dirs;
|
|
83674
83892
|
}
|
|
83675
83893
|
function detectSkill(name) {
|
|
83676
83894
|
for (const dir of skillSearchDirs()) {
|
|
83677
|
-
const file2 =
|
|
83895
|
+
const file2 = join6(dir, name, "SKILL.md");
|
|
83678
83896
|
if (existsSync(file2))
|
|
83679
83897
|
return { installed: true, location: file2 };
|
|
83680
83898
|
}
|
|
@@ -83693,9 +83911,9 @@ function isSymlink(p) {
|
|
|
83693
83911
|
function findAgentsSkillsRoot(fromDir) {
|
|
83694
83912
|
let cur = fromDir;
|
|
83695
83913
|
for (;; ) {
|
|
83696
|
-
if (existsSync(
|
|
83914
|
+
if (existsSync(join6(cur, ".agents", "skills")))
|
|
83697
83915
|
return cur;
|
|
83698
|
-
const parent =
|
|
83916
|
+
const parent = dirname8(cur);
|
|
83699
83917
|
if (parent === cur)
|
|
83700
83918
|
return null;
|
|
83701
83919
|
cur = parent;
|
|
@@ -83705,7 +83923,7 @@ function skillsBridgeStatus(fromDir = process.cwd()) {
|
|
|
83705
83923
|
const root = findAgentsSkillsRoot(fromDir);
|
|
83706
83924
|
if (!root)
|
|
83707
83925
|
return { kind: "none" };
|
|
83708
|
-
const link =
|
|
83926
|
+
const link = join6(root, ".claude", "skills");
|
|
83709
83927
|
if (isSymlink(link)) {
|
|
83710
83928
|
try {
|
|
83711
83929
|
if (readlinkSync(link) === BRIDGE_TARGET)
|
|
@@ -83721,7 +83939,7 @@ function ensureSkillsBridge(fromDir = process.cwd()) {
|
|
|
83721
83939
|
const status = skillsBridgeStatus(fromDir);
|
|
83722
83940
|
if (status.kind !== "unbridged")
|
|
83723
83941
|
return status;
|
|
83724
|
-
mkdirSync(
|
|
83942
|
+
mkdirSync(dirname8(status.link), { recursive: true });
|
|
83725
83943
|
symlinkSync(BRIDGE_TARGET, status.link);
|
|
83726
83944
|
return { kind: "bridged", root: status.root };
|
|
83727
83945
|
}
|
|
@@ -83730,7 +83948,7 @@ var init_skills = __esm(() => {
|
|
|
83730
83948
|
init_browser();
|
|
83731
83949
|
init_proc();
|
|
83732
83950
|
SKILL_INSTALL_HINT = `npx skills add ${ASTRALE_CLI_SKILL_SOURCE} -g`;
|
|
83733
|
-
BRIDGE_TARGET =
|
|
83951
|
+
BRIDGE_TARGET = join6("..", ".agents", "skills");
|
|
83734
83952
|
});
|
|
83735
83953
|
|
|
83736
83954
|
// src/setup/steps/agent-browser.ts
|
|
@@ -83973,9 +84191,9 @@ var init_auth3 = __esm(() => {
|
|
|
83973
84191
|
|
|
83974
84192
|
// src/setup/steps/domain.ts
|
|
83975
84193
|
import { existsSync as existsSync2 } from "node:fs";
|
|
83976
|
-
import { join as
|
|
84194
|
+
import { join as join7 } from "node:path";
|
|
83977
84195
|
function hasDomainProject() {
|
|
83978
|
-
return existsSync2(
|
|
84196
|
+
return existsSync2(join7(process.cwd(), "astrale.config.ts"));
|
|
83979
84197
|
}
|
|
83980
84198
|
var FIX4 = "npx create-astrale-domain <name> --instance <slug>", domainStep;
|
|
83981
84199
|
var init_domain7 = __esm(() => {
|
|
@@ -85940,14 +86158,14 @@ async function boundedResponse(response2, maximum, signal) {
|
|
|
85940
86158
|
signal.removeEventListener("abort", abort);
|
|
85941
86159
|
reader.releaseLock();
|
|
85942
86160
|
}
|
|
85943
|
-
return
|
|
86161
|
+
return join8(chunks, total);
|
|
85944
86162
|
}
|
|
85945
86163
|
function requireExactResponse(response2, expected, label) {
|
|
85946
86164
|
if (response2.redirected || response2.url !== expected) {
|
|
85947
86165
|
throw new ClientError(`${label} did not return the exact requested URL.`);
|
|
85948
86166
|
}
|
|
85949
86167
|
}
|
|
85950
|
-
function
|
|
86168
|
+
function join8(parts2, length) {
|
|
85951
86169
|
if (parts2.length === 1)
|
|
85952
86170
|
return new Uint8Array(parts2[0]);
|
|
85953
86171
|
const output3 = new Uint8Array(length);
|
|
@@ -86751,73 +86969,161 @@ var init_session2 = __esm(() => {
|
|
|
86751
86969
|
init_session();
|
|
86752
86970
|
});
|
|
86753
86971
|
|
|
86754
|
-
//
|
|
86755
|
-
async function
|
|
86756
|
-
|
|
86757
|
-
|
|
86758
|
-
|
|
86972
|
+
// node_modules/.pnpm/@astrale-os+kernel-client@0.6.0-beta.4_typescript@6.0.3/node_modules/@astrale-os/kernel-client/dist/domain/callable.js
|
|
86973
|
+
async function invokeRemote(session, target2, callable, input, options) {
|
|
86974
|
+
return dispatchCallable(session, target2, callable, undefined, input, options);
|
|
86975
|
+
}
|
|
86976
|
+
async function invokeRemoteMethod(session, target2, method, receiver, input, options) {
|
|
86977
|
+
return dispatchCallable(session, target2, method, receiver, input, options);
|
|
86978
|
+
}
|
|
86979
|
+
function bindRemoteMethod(session, target2) {
|
|
86980
|
+
return (method, receiver) => (input) => dispatchCallable(session, target2, method, Path.id(receiver.id), input);
|
|
86981
|
+
}
|
|
86982
|
+
function concreteRootCallables(domain3) {
|
|
86983
|
+
const result = new Map;
|
|
86984
|
+
for (const definition3 of domain3.$.definitions.values()) {
|
|
86985
|
+
if (definition3.kind === "function") {
|
|
86986
|
+
const callable = definition3;
|
|
86987
|
+
result.set(callable.key, callable);
|
|
86988
|
+
continue;
|
|
86989
|
+
}
|
|
86990
|
+
if (definition3.kind !== "class" && definition3.kind !== "interface" || definition3.family !== "node") {
|
|
86991
|
+
continue;
|
|
86992
|
+
}
|
|
86993
|
+
for (const method of definition3.methods.values()) {
|
|
86994
|
+
if (method.definition.inheritance !== "abstract") {
|
|
86995
|
+
const callable = method;
|
|
86996
|
+
result.set(callable.key, callable);
|
|
86997
|
+
}
|
|
86998
|
+
}
|
|
86759
86999
|
}
|
|
86760
|
-
|
|
86761
|
-
|
|
86762
|
-
|
|
86763
|
-
|
|
86764
|
-
|
|
86765
|
-
|
|
86766
|
-
|
|
86767
|
-
const
|
|
86768
|
-
|
|
86769
|
-
|
|
86770
|
-
|
|
86771
|
-
|
|
86772
|
-
|
|
86773
|
-
|
|
86774
|
-
|
|
86775
|
-
|
|
86776
|
-
|
|
86777
|
-
|
|
86778
|
-
|
|
87000
|
+
return result;
|
|
87001
|
+
}
|
|
87002
|
+
async function dispatchCallable(session, target2, callable, receiver, input, controls = {}) {
|
|
87003
|
+
const bound = target2.callables.get(callable.key);
|
|
87004
|
+
if (bound === undefined) {
|
|
87005
|
+
throw new ClientError("Callable is not a concrete member of the bound Domain root.");
|
|
87006
|
+
}
|
|
87007
|
+
const path5 = receiver === undefined ? bound.path : bound.on(Path.from(receiver));
|
|
87008
|
+
const result = await dispatchBound(session, call(path5, input), target2.bound, controls);
|
|
87009
|
+
return requireOutput(bound, result);
|
|
87010
|
+
}
|
|
87011
|
+
function requireOutput(callable, result) {
|
|
87012
|
+
const mode = callable.definition.output.mode;
|
|
87013
|
+
switch (mode) {
|
|
87014
|
+
case "value":
|
|
87015
|
+
if (result.kind === "value")
|
|
87016
|
+
return result.value;
|
|
87017
|
+
break;
|
|
87018
|
+
case "stream":
|
|
87019
|
+
if (result.kind === "stream")
|
|
87020
|
+
return result.stream;
|
|
87021
|
+
break;
|
|
87022
|
+
case "binary":
|
|
87023
|
+
if (result.kind === "binary")
|
|
87024
|
+
return result.value;
|
|
87025
|
+
break;
|
|
87026
|
+
}
|
|
87027
|
+
return resultMismatch(mode, result);
|
|
87028
|
+
}
|
|
87029
|
+
function resultMismatch(expected, result) {
|
|
87030
|
+
if (result.kind === "stream") {
|
|
87031
|
+
result.stream.cancel(`Remote callable declared ${expected} output.`);
|
|
87032
|
+
}
|
|
87033
|
+
throw new ClientError(`Remote callable declared ${expected} output but returned ${result.kind}.`);
|
|
87034
|
+
}
|
|
87035
|
+
var init_callable4 = __esm(() => {
|
|
87036
|
+
init_path4();
|
|
87037
|
+
init_client3();
|
|
87038
|
+
init_errors7();
|
|
87039
|
+
init_session2();
|
|
87040
|
+
});
|
|
87041
|
+
|
|
87042
|
+
// node_modules/.pnpm/@astrale-os+kernel-client@0.6.0-beta.4_typescript@6.0.3/node_modules/@astrale-os/kernel-client/dist/domain/node.js
|
|
87043
|
+
function bindNode(domain3, methodBinder, definitionOrValue, value2) {
|
|
87044
|
+
return value2 === undefined ? domain3.$.wrap(definitionOrValue, methodBinder) : domain3.$.wrap(definitionOrValue, value2, methodBinder);
|
|
87045
|
+
}
|
|
87046
|
+
|
|
87047
|
+
// node_modules/.pnpm/@astrale-os+kernel-client@0.6.0-beta.4_typescript@6.0.3/node_modules/@astrale-os/kernel-client/dist/domain/binding.js
|
|
87048
|
+
function bind(session, schemaOrInstalled, maybeInstalled) {
|
|
87049
|
+
const installed = admitInstalled(maybeInstalled ?? schemaOrInstalled);
|
|
87050
|
+
const published = installed.source.kind === "remote" ? installed.source.publication : undefined;
|
|
87051
|
+
const root = maybeInstalled === undefined ? installed.bundle.root : schemaOrInstalled;
|
|
87052
|
+
if (published !== undefined)
|
|
87053
|
+
requireSchemaPublication(root, published);
|
|
87054
|
+
if (root.origin !== installed.bundle.root.origin || exports_schema.revision(root) !== exports_schema.revision(installed.bundle.root)) {
|
|
87055
|
+
throw new TypeError("Expected Domain schema does not match the installed schema Bundle.");
|
|
87056
|
+
}
|
|
87057
|
+
const domain3 = Domain.fromSchema(root);
|
|
87058
|
+
const invocationTarget = Object.freeze({
|
|
87059
|
+
callables: concreteRootCallables(domain3),
|
|
87060
|
+
bound: Object.freeze({
|
|
87061
|
+
schema: published === undefined ? Object.freeze({ target: installed.target }) : Object.freeze({ revision: exports_schema.revision(root) }),
|
|
87062
|
+
...published === undefined ? {} : { publication: exports_publication.reference(published) }
|
|
87063
|
+
})
|
|
87064
|
+
});
|
|
87065
|
+
const methodBinder = bindRemoteMethod(session, invocationTarget);
|
|
87066
|
+
const invoke = (callable, receiverOrInput, inputOrOptions, options) => ("on" in callable) ? invokeRemoteMethod(session, invocationTarget, callable, receiverOrInput, inputOrOptions, options) : invokeRemote(session, invocationTarget, callable, receiverOrInput, inputOrOptions);
|
|
87067
|
+
const bind2 = (definitionOrValue, value2) => value2 === undefined ? bindNode(domain3, methodBinder, definitionOrValue) : bindNode(domain3, methodBinder, definitionOrValue, value2);
|
|
87068
|
+
const binding6 = {
|
|
86779
87069
|
...domain3,
|
|
86780
87070
|
$: Object.freeze({
|
|
86781
87071
|
...domain3.$,
|
|
86782
|
-
|
|
86783
|
-
publication:
|
|
86784
|
-
invoke
|
|
87072
|
+
installed,
|
|
87073
|
+
...published === undefined ? {} : { publication: published },
|
|
87074
|
+
invoke,
|
|
87075
|
+
bind: bind2
|
|
86785
87076
|
})
|
|
86786
|
-
}
|
|
87077
|
+
};
|
|
87078
|
+
return Object.freeze(binding6);
|
|
86787
87079
|
}
|
|
86788
|
-
|
|
86789
|
-
|
|
86790
|
-
|
|
86791
|
-
return current.invoke(reference3, input, options);
|
|
86792
|
-
const dispatchBound2 = dispatchBound;
|
|
86793
|
-
if (dispatchBound2 === undefined) {
|
|
86794
|
-
throw new TypeError("Client Session cannot invoke an exact Admin publication.");
|
|
87080
|
+
function admitInstalled(input) {
|
|
87081
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
87082
|
+
throw new TypeError("Installed Domain evidence is invalid.");
|
|
86795
87083
|
}
|
|
86796
|
-
|
|
86797
|
-
|
|
86798
|
-
|
|
86799
|
-
|
|
86800
|
-
|
|
86801
|
-
|
|
86802
|
-
|
|
86803
|
-
|
|
86804
|
-
|
|
86805
|
-
|
|
87084
|
+
if (input.state !== "ready" || input.readiness === null) {
|
|
87085
|
+
throw new TypeError("Installed Domain is not ready.");
|
|
87086
|
+
}
|
|
87087
|
+
if (input.source.kind === "remote") {
|
|
87088
|
+
const published = exports_publication.accept(input.source.publication);
|
|
87089
|
+
const acceptedBundle = exports_publication.acceptBundle(published, input.bundle);
|
|
87090
|
+
return Object.freeze({
|
|
87091
|
+
...input,
|
|
87092
|
+
source: Object.freeze({ kind: "remote", publication: published }),
|
|
87093
|
+
bundle: acceptedBundle
|
|
87094
|
+
});
|
|
87095
|
+
}
|
|
87096
|
+
return input;
|
|
86806
87097
|
}
|
|
86807
|
-
function
|
|
86808
|
-
if (
|
|
86809
|
-
|
|
86810
|
-
result.stream.cancel(`Admin callable declared ${expected}.`);
|
|
86811
|
-
throw new TypeError(`Admin callable declared ${expected} output but returned ${result.kind}.`);
|
|
87098
|
+
function requireSchemaPublication(domainSchema, published) {
|
|
87099
|
+
if (domainSchema.origin !== published.origin || exports_schema.revision(domainSchema) !== published.schema.revision) {
|
|
87100
|
+
throw new TypeError("Expected Domain schema does not match the target Publication revision.");
|
|
86812
87101
|
}
|
|
86813
|
-
return result.kind === "stream" ? result.stream : result.value;
|
|
86814
87102
|
}
|
|
86815
|
-
var ADMIN_ORIGIN = "admin.astrale.ai";
|
|
86816
87103
|
var init_binding3 = __esm(() => {
|
|
86817
|
-
|
|
86818
|
-
|
|
86819
|
-
|
|
86820
|
-
|
|
87104
|
+
init_domain3();
|
|
87105
|
+
init_v1();
|
|
87106
|
+
init_dist2();
|
|
87107
|
+
init_callable4();
|
|
87108
|
+
});
|
|
87109
|
+
|
|
87110
|
+
// node_modules/.pnpm/@astrale-os+kernel-client@0.6.0-beta.4_typescript@6.0.3/node_modules/@astrale-os/kernel-client/dist/domain/index.js
|
|
87111
|
+
var init_domain8 = __esm(() => {
|
|
87112
|
+
init_binding3();
|
|
87113
|
+
});
|
|
87114
|
+
|
|
87115
|
+
// src/admin/binding.ts
|
|
87116
|
+
async function bindAdmin(session) {
|
|
87117
|
+
const installed = await session.installed(ADMIN_ORIGIN);
|
|
87118
|
+
const binding6 = bind(session, installed);
|
|
87119
|
+
if (binding6.$.publication?.origin !== ADMIN_ORIGIN || binding6.$.origin !== ADMIN_ORIGIN) {
|
|
87120
|
+
throw new TypeError("Configured Admin target does not serve the Admin Domain.");
|
|
87121
|
+
}
|
|
87122
|
+
return binding6;
|
|
87123
|
+
}
|
|
87124
|
+
var ADMIN_ORIGIN = "admin.astrale.ai";
|
|
87125
|
+
var init_binding4 = __esm(() => {
|
|
87126
|
+
init_domain8();
|
|
86821
87127
|
});
|
|
86822
87128
|
|
|
86823
87129
|
// src/admin/graph/nodes.ts
|
|
@@ -87040,7 +87346,7 @@ var ADMIN_ORIGIN2 = "admin.astrale.ai", PAGE_SIZE = 256, MAXIMUM_INSTANCES = 1e4
|
|
|
87040
87346
|
var init_client4 = __esm(() => {
|
|
87041
87347
|
init_path5();
|
|
87042
87348
|
init_query4();
|
|
87043
|
-
|
|
87349
|
+
init_binding4();
|
|
87044
87350
|
init_graph3();
|
|
87045
87351
|
init_model6();
|
|
87046
87352
|
MAXIMUM_PAGES2 = Math.ceil(MAXIMUM_INSTANCES / PAGE_SIZE) + 1;
|
|
@@ -89123,11 +89429,11 @@ var init_skills2 = __esm(() => {
|
|
|
89123
89429
|
|
|
89124
89430
|
// src/setup/steps/skills-bridge.ts
|
|
89125
89431
|
import { existsSync as existsSync3, readdirSync } from "node:fs";
|
|
89126
|
-
import { join as
|
|
89432
|
+
import { join as join9 } from "node:path";
|
|
89127
89433
|
function countStaged(root) {
|
|
89128
89434
|
try {
|
|
89129
|
-
const dir =
|
|
89130
|
-
return readdirSync(dir).filter((e) => existsSync3(
|
|
89435
|
+
const dir = join9(root, ".agents", "skills");
|
|
89436
|
+
return readdirSync(dir).filter((e) => existsSync3(join9(dir, e, "SKILL.md"))).length;
|
|
89131
89437
|
} catch {
|
|
89132
89438
|
return 0;
|
|
89133
89439
|
}
|
|
@@ -89165,7 +89471,7 @@ var init_skills_bridge = __esm(() => {
|
|
|
89165
89471
|
}
|
|
89166
89472
|
const after = ensureSkillsBridge();
|
|
89167
89473
|
if (after.kind === "bridged") {
|
|
89168
|
-
log.success(`Workspace skills bridged — ${
|
|
89474
|
+
log.success(`Workspace skills bridged — ${join9(after.root, ".agents/skills")} → .claude/skills`);
|
|
89169
89475
|
return "fixed";
|
|
89170
89476
|
}
|
|
89171
89477
|
log.warn("Could not create the skills bridge — create it manually: ln -s ../.agents/skills .claude/skills");
|
|
@@ -89627,18 +89933,18 @@ Examples:
|
|
|
89627
89933
|
|
|
89628
89934
|
// src/lib/sdk-deps.ts
|
|
89629
89935
|
import { existsSync as existsSync4 } from "node:fs";
|
|
89630
|
-
import { join as
|
|
89936
|
+
import { join as join10 } from "node:path";
|
|
89631
89937
|
function inDomainProject(cwd = process.cwd()) {
|
|
89632
|
-
return existsSync4(
|
|
89938
|
+
return existsSync4(join10(cwd, "astrale.config.ts"));
|
|
89633
89939
|
}
|
|
89634
89940
|
function foreignPackageManager(cwd = process.cwd()) {
|
|
89635
|
-
if (existsSync4(
|
|
89941
|
+
if (existsSync4(join10(cwd, "pnpm-lock.yaml")))
|
|
89636
89942
|
return null;
|
|
89637
|
-
if (existsSync4(
|
|
89943
|
+
if (existsSync4(join10(cwd, "package-lock.json")))
|
|
89638
89944
|
return "npm";
|
|
89639
|
-
if (existsSync4(
|
|
89945
|
+
if (existsSync4(join10(cwd, "yarn.lock")))
|
|
89640
89946
|
return "yarn";
|
|
89641
|
-
if (existsSync4(
|
|
89947
|
+
if (existsSync4(join10(cwd, "bun.lockb")) || existsSync4(join10(cwd, "bun.lock")))
|
|
89642
89948
|
return "bun";
|
|
89643
89949
|
return null;
|
|
89644
89950
|
}
|
|
@@ -89683,211 +89989,6 @@ var init_sdk_deps = __esm(() => {
|
|
|
89683
89989
|
init_proc();
|
|
89684
89990
|
});
|
|
89685
89991
|
|
|
89686
|
-
// src/lib/update.ts
|
|
89687
|
-
import { createHash } from "node:crypto";
|
|
89688
|
-
import { chmod as chmod2, copyFile, mkdir as mkdir8, mkdtemp, readFile as readFile9, rename as rename2, rm, writeFile as writeFile4 } from "node:fs/promises";
|
|
89689
|
-
import { tmpdir } from "node:os";
|
|
89690
|
-
import { dirname as dirname8, join as join10 } from "node:path";
|
|
89691
|
-
function detectPlatform() {
|
|
89692
|
-
const os3 = process.platform;
|
|
89693
|
-
const arch = process.arch;
|
|
89694
|
-
if (os3 !== "darwin" && os3 !== "linux") {
|
|
89695
|
-
throw new AstraleError("UNSUPPORTED_PLATFORM", `Unsupported OS "${os3}" — Astrale update supports macOS and Linux.`);
|
|
89696
|
-
}
|
|
89697
|
-
if (arch !== "arm64" && arch !== "x64") {
|
|
89698
|
-
throw new AstraleError("UNSUPPORTED_PLATFORM", `Unsupported CPU architecture "${arch}" — Astrale update supports arm64 and x64.`);
|
|
89699
|
-
}
|
|
89700
|
-
return { os: os3, arch };
|
|
89701
|
-
}
|
|
89702
|
-
function platformKey(platform) {
|
|
89703
|
-
return `${platform.os}-${platform.arch}`;
|
|
89704
|
-
}
|
|
89705
|
-
function isStandaloneBinary() {
|
|
89706
|
-
return Boolean(process.versions.bun);
|
|
89707
|
-
}
|
|
89708
|
-
async function readInstallMetadata(path5 = INSTALL_PATH) {
|
|
89709
|
-
let raw2;
|
|
89710
|
-
try {
|
|
89711
|
-
raw2 = await readFile9(path5, "utf8");
|
|
89712
|
-
} catch {
|
|
89713
|
-
throw isStandaloneBinary() ? new AstraleError("UPDATE_NOT_SCRIPT_INSTALLED", "Astrale was not installed by the official install script.", "Reinstall with: curl -fsSL https://raw.githubusercontent.com/astrale-os/cli/main/install.sh | sh") : new AstraleError("UPDATE_PACKAGE_MANAGED", "This Astrale build is managed by your package manager.", "Update with: npm install -g @astrale-os/cli@latest (or pnpm/bun)");
|
|
89714
|
-
}
|
|
89715
|
-
const parsed = InstallMetadataSchema.safeParse(JSON.parse(raw2));
|
|
89716
|
-
if (!parsed.success) {
|
|
89717
|
-
throw new AstraleError("UPDATE_BAD_INSTALL_METADATA", `Invalid install metadata at ${path5}.`, "Reinstall with: curl -fsSL https://raw.githubusercontent.com/astrale-os/cli/main/install.sh | sh");
|
|
89718
|
-
}
|
|
89719
|
-
return parsed.data;
|
|
89720
|
-
}
|
|
89721
|
-
async function writeInstallMetadata(meta3, path5 = INSTALL_PATH) {
|
|
89722
|
-
await mkdir8(dirname8(path5), { recursive: true });
|
|
89723
|
-
await writeFile4(path5, JSON.stringify(meta3, null, 2) + `
|
|
89724
|
-
`);
|
|
89725
|
-
}
|
|
89726
|
-
function releaseBase(meta3, req) {
|
|
89727
|
-
if (process.env.ASTRALE_UPDATE_BASE)
|
|
89728
|
-
return process.env.ASTRALE_UPDATE_BASE.replace(/\/+$/, "");
|
|
89729
|
-
const repo = meta3.repo || DEFAULT_REPO;
|
|
89730
|
-
if (req.version) {
|
|
89731
|
-
const version2 = req.version.replace(/^cli\/v/, "").replace(/^v/, "");
|
|
89732
|
-
return `https://github.com/${repo}/releases/download/cli/v${version2}`;
|
|
89733
|
-
}
|
|
89734
|
-
return `https://github.com/${repo}/releases/download/${req.channel ?? meta3.channel ?? DEFAULT_UPDATE_CHANNEL}`;
|
|
89735
|
-
}
|
|
89736
|
-
async function fetchManifest(base2) {
|
|
89737
|
-
const raw2 = await readUrlText(`${base2}/manifest.json`);
|
|
89738
|
-
return UpdateManifestSchema.parse(JSON.parse(raw2));
|
|
89739
|
-
}
|
|
89740
|
-
function shouldUpdate(currentVersion, manifestVersion) {
|
|
89741
|
-
return currentVersion !== manifestVersion;
|
|
89742
|
-
}
|
|
89743
|
-
async function updateAstrale(req) {
|
|
89744
|
-
const meta3 = await readInstallMetadata(req.installPath);
|
|
89745
|
-
const currentVersion = meta3.version ?? req.currentVersion;
|
|
89746
|
-
const channel = req.channel ?? meta3.channel ?? DEFAULT_UPDATE_CHANNEL;
|
|
89747
|
-
const platform = req.platform ?? detectPlatform();
|
|
89748
|
-
const key = platformKey(platform);
|
|
89749
|
-
const base2 = releaseBase(meta3, { channel, version: req.version });
|
|
89750
|
-
const manifest = await fetchManifest(base2);
|
|
89751
|
-
const asset = manifest.assets[key];
|
|
89752
|
-
if (!asset) {
|
|
89753
|
-
throw new AstraleError("UPDATE_ASSET_NOT_FOUND", `No Astrale CLI release asset for ${key}.`, `Available platforms: ${Object.keys(manifest.assets).join(", ")}`);
|
|
89754
|
-
}
|
|
89755
|
-
if (!shouldUpdate(currentVersion, manifest.version)) {
|
|
89756
|
-
return {
|
|
89757
|
-
status: "up-to-date",
|
|
89758
|
-
currentVersion,
|
|
89759
|
-
latestVersion: manifest.version,
|
|
89760
|
-
channel: manifest.channel
|
|
89761
|
-
};
|
|
89762
|
-
}
|
|
89763
|
-
if (req.check) {
|
|
89764
|
-
return {
|
|
89765
|
-
status: "available",
|
|
89766
|
-
currentVersion,
|
|
89767
|
-
latestVersion: manifest.version,
|
|
89768
|
-
channel: manifest.channel
|
|
89769
|
-
};
|
|
89770
|
-
}
|
|
89771
|
-
const tmp = await mkdtemp(join10(tmpdir(), "astrale-update-"));
|
|
89772
|
-
try {
|
|
89773
|
-
const archive = join10(tmp, asset.name);
|
|
89774
|
-
await downloadToFile(`${base2}/${asset.name}`, archive);
|
|
89775
|
-
const manifestChecksum = "sha256" in asset ? asset.sha256 : undefined;
|
|
89776
|
-
const expected = manifestChecksum ?? await fetchChecksum(base2, asset.name);
|
|
89777
|
-
const actual = await sha256File(archive);
|
|
89778
|
-
if (actual !== expected.toLowerCase()) {
|
|
89779
|
-
throw new AstraleError("UPDATE_CHECKSUM_MISMATCH", `Checksum mismatch for ${asset.name}.`, `Expected ${expected}; got ${actual}.`);
|
|
89780
|
-
}
|
|
89781
|
-
await extractTarGz(archive, tmp);
|
|
89782
|
-
const nextBin = join10(tmp, "astrale");
|
|
89783
|
-
await chmod2(nextBin, 493);
|
|
89784
|
-
await smokeVersion(nextBin, manifest.binaryVersion ?? manifest.version);
|
|
89785
|
-
const previous = `${meta3.bin}.previous`;
|
|
89786
|
-
const staged = `${meta3.bin}.next`;
|
|
89787
|
-
await copyFile(meta3.bin, previous).catch(() => {
|
|
89788
|
-
return;
|
|
89789
|
-
});
|
|
89790
|
-
await copyFile(nextBin, staged);
|
|
89791
|
-
await chmod2(staged, 493);
|
|
89792
|
-
await rename2(staged, meta3.bin);
|
|
89793
|
-
await writeInstallMetadata({
|
|
89794
|
-
...meta3,
|
|
89795
|
-
channel: manifest.channel,
|
|
89796
|
-
version: manifest.version,
|
|
89797
|
-
installedAt: new Date().toISOString()
|
|
89798
|
-
}, req.installPath);
|
|
89799
|
-
return {
|
|
89800
|
-
status: "updated",
|
|
89801
|
-
previousVersion: currentVersion,
|
|
89802
|
-
currentVersion: manifest.version,
|
|
89803
|
-
channel: manifest.channel,
|
|
89804
|
-
bin: meta3.bin
|
|
89805
|
-
};
|
|
89806
|
-
} finally {
|
|
89807
|
-
await rm(tmp, { recursive: true, force: true });
|
|
89808
|
-
}
|
|
89809
|
-
}
|
|
89810
|
-
async function readUrlText(url3) {
|
|
89811
|
-
if (url3.startsWith("file://")) {
|
|
89812
|
-
return readFile9(new URL(url3), "utf8");
|
|
89813
|
-
}
|
|
89814
|
-
const res = await fetch(url3);
|
|
89815
|
-
if (!res.ok)
|
|
89816
|
-
throw new Error(`GET ${url3} failed: HTTP ${res.status}`);
|
|
89817
|
-
return res.text();
|
|
89818
|
-
}
|
|
89819
|
-
async function downloadToFile(url3, path5) {
|
|
89820
|
-
if (url3.startsWith("file://")) {
|
|
89821
|
-
await copyFile(new URL(url3), path5);
|
|
89822
|
-
return;
|
|
89823
|
-
}
|
|
89824
|
-
const res = await fetch(url3);
|
|
89825
|
-
if (!res.ok)
|
|
89826
|
-
throw new Error(`GET ${url3} failed: HTTP ${res.status}`);
|
|
89827
|
-
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
89828
|
-
await writeFile4(path5, bytes);
|
|
89829
|
-
}
|
|
89830
|
-
async function fetchChecksum(base2, assetName) {
|
|
89831
|
-
const raw2 = await readUrlText(`${base2}/sha256sums.txt`);
|
|
89832
|
-
for (const line of raw2.split(/\r?\n/)) {
|
|
89833
|
-
const [sha, file2] = line.trim().split(/\s+/, 2);
|
|
89834
|
-
if (!sha || !file2)
|
|
89835
|
-
continue;
|
|
89836
|
-
if (file2.replace(/^\*/, "") === assetName && /^[a-fA-F0-9]{64}$/.test(sha))
|
|
89837
|
-
return sha;
|
|
89838
|
-
}
|
|
89839
|
-
throw new AstraleError("UPDATE_CHECKSUM_NOT_FOUND", `Checksum entry not found for ${assetName}.`, `Release base: ${base2}`);
|
|
89840
|
-
}
|
|
89841
|
-
async function sha256File(path5) {
|
|
89842
|
-
const hash2 = createHash("sha256");
|
|
89843
|
-
hash2.update(await readFile9(path5));
|
|
89844
|
-
return hash2.digest("hex");
|
|
89845
|
-
}
|
|
89846
|
-
async function extractTarGz(archive, cwd) {
|
|
89847
|
-
const { code, stderr } = await run("tar", ["-xzf", archive, "-C", cwd]);
|
|
89848
|
-
if (code !== 0) {
|
|
89849
|
-
throw new Error(`Could not extract update archive: ${stderr.trim()}`);
|
|
89850
|
-
}
|
|
89851
|
-
}
|
|
89852
|
-
async function smokeVersion(bin, expectedVersion) {
|
|
89853
|
-
const { code, stdout, stderr } = await run(bin, ["--version"]);
|
|
89854
|
-
if (code !== 0)
|
|
89855
|
-
throw new Error(`Updated binary failed --version: ${stderr.trim()}`);
|
|
89856
|
-
const actual = stdout.trim();
|
|
89857
|
-
if (actual !== expectedVersion) {
|
|
89858
|
-
throw new Error(`Updated binary reported version ${actual}, expected ${expectedVersion}`);
|
|
89859
|
-
}
|
|
89860
|
-
}
|
|
89861
|
-
var DEFAULT_REPO = "astrale-os/cli", DEFAULT_UPDATE_CHANNEL = "beta", InstallMetadataSchema, ManifestAssetSchema, UpdateManifestSchema;
|
|
89862
|
-
var init_update = __esm(() => {
|
|
89863
|
-
init_zod2();
|
|
89864
|
-
init_errors2();
|
|
89865
|
-
init_state();
|
|
89866
|
-
init_proc();
|
|
89867
|
-
InstallMetadataSchema = exports_external2.object({
|
|
89868
|
-
method: exports_external2.literal("script"),
|
|
89869
|
-
channel: exports_external2.string().min(1).default(DEFAULT_UPDATE_CHANNEL),
|
|
89870
|
-
version: exports_external2.string().min(1).optional(),
|
|
89871
|
-
repo: exports_external2.string().min(1).default(DEFAULT_REPO),
|
|
89872
|
-
bin: exports_external2.string().min(1),
|
|
89873
|
-
installedAt: exports_external2.string().optional()
|
|
89874
|
-
});
|
|
89875
|
-
ManifestAssetSchema = exports_external2.object({
|
|
89876
|
-
name: exports_external2.string().min(1),
|
|
89877
|
-
sha256: exports_external2.string().regex(/^[a-fA-F0-9]{64}$/).optional()
|
|
89878
|
-
});
|
|
89879
|
-
UpdateManifestSchema = exports_external2.object({
|
|
89880
|
-
version: exports_external2.string().min(1),
|
|
89881
|
-
binaryVersion: exports_external2.string().min(1).optional(),
|
|
89882
|
-
channel: exports_external2.string().min(1),
|
|
89883
|
-
repo: exports_external2.string().min(1).optional(),
|
|
89884
|
-
assets: exports_external2.record(exports_external2.string(), exports_external2.union([
|
|
89885
|
-
ManifestAssetSchema,
|
|
89886
|
-
exports_external2.string().min(1).transform((name) => ({ name }))
|
|
89887
|
-
]))
|
|
89888
|
-
});
|
|
89889
|
-
});
|
|
89890
|
-
|
|
89891
89992
|
// src/commands/update.ts
|
|
89892
89993
|
var exports_update = {};
|
|
89893
89994
|
__export(exports_update, {
|
|
@@ -93473,7 +93574,7 @@ var ADMIN_ORIGIN3 = "admin.astrale.ai", PAGE_SIZE2 = 256, MAXIMUM_DOMAINS = 1e4,
|
|
|
93473
93574
|
var init_client5 = __esm(() => {
|
|
93474
93575
|
init_path5();
|
|
93475
93576
|
init_query4();
|
|
93476
|
-
|
|
93577
|
+
init_binding4();
|
|
93477
93578
|
init_graph3();
|
|
93478
93579
|
init_model7();
|
|
93479
93580
|
MAXIMUM_PAGES3 = Math.ceil(MAXIMUM_DOMAINS / PAGE_SIZE2) + 1;
|