mirror of
https://github.com/aphrody-labs/bun-distribution.git
synced 2026-10-13 23:56:39 +00:00
feat: expose unified product server from bun os CLI
This commit is contained in:
1 parent
ca4b5549fc
commit
020ecaea9e
3 files changed
+97
-73
No files matched your search
+17
-2
@@ -4,6 +4,7 @@
|
||||
flowchart TD
|
||||
UI[Aphrody shell] --> SDK[Bun Tauri v3 / CEF]
|
||||
UI --> Backend[Bun backend]
|
||||
Product[Standalone product API] --> Workspace
|
||||
Backend --> Workspace[Native library orchestration]
|
||||
Workspace --> Sources[Pinned library submodules]
|
||||
Backend --> Video[Typed video adapter]
|
||||
@@ -18,11 +19,17 @@ flowchart TD
|
||||
Infra[Aphrody Infra] --> Apps
|
||||
Infra --> Control[Rust deployment controller]
|
||||
Forge[Git forge and runner] --> Factory
|
||||
Infra --> Forge
|
||||
Forge --> Portal[source.aphrody.app]
|
||||
Sources --> Crates[Flat pinned crates / root Cargo workspace]
|
||||
```
|
||||
|
||||
- `apps/desktop`: Aphrody shell, built and served by Bun.
|
||||
- `packages/workspace`: app identity, config, provenance, source coverage,
|
||||
native execution, asset manifests and the app transport.
|
||||
- `packages/bun-workspace`: app identity, config, provenance, source coverage,
|
||||
native execution, asset manifests and shared process ownership.
|
||||
- `packages/workspace`: OS CLI and adapters consuming that shared owner.
|
||||
- `packages/bun-app-host`: product server, common authenticated API transport,
|
||||
standalone compilation and executable qualification.
|
||||
- `packages/bun-video-project`: exact JSON, bounded native operations and runtime availability.
|
||||
- `packages/bun-artifacts`: target manifests, standalone compilation and verified
|
||||
native payload extraction.
|
||||
@@ -51,4 +58,12 @@ Provider credentials, sessions, datasets and model weights remain isolated.
|
||||
|
||||
Aphrody Infra owns host, service, route and activation policy. Komodo actuates
|
||||
deployment; Gitea and its runner host Git and execute the same Bun factory.
|
||||
The root `bun-os` CLI routes `server` commands to the same app-host CLI owner.
|
||||
Just coordinates setup, shared quality, Cargo, apps, product server and vendor
|
||||
without implementing another build pipeline. The root owns `node_modules`,
|
||||
`target`, `build` and `install`.
|
||||
|
||||
Source, artifact, CI and public service qualification are recorded separately.
|
||||
The complete 239-repository Labs inventory and resumable mirror admission live
|
||||
in Aphrody Infra. The embedded product catalog is a pinned distribution
|
||||
snapshot, not a claim that every mirror or native application is qualified.
|
||||
@@ -6,8 +6,8 @@ import { productCatalog } from "./build.ts";
|
||||
import { startProduct } from "./product.ts";
|
||||
import { verifyProduct } from "./verify.ts";
|
||||
|
||||
if (import.meta.main) {
|
||||
const [action = "help", root = repositoryRoot, receipt] = Bun.argv.slice(2);
|
||||
export async function runProductCLI(args: readonly string[]): Promise<void> {
|
||||
const [action = "help", root = repositoryRoot, receipt] = args;
|
||||
if (action === "help" || action === "--help")
|
||||
console.log("Aphrody / Bun server: cli.ts serve [ROOT] | verify [BINARY] [RECEIPT] | --version");
|
||||
else if (action === "--version") console.log("Aphrody / Bun server 1.4.4");
|
||||
@@ -26,3 +26,5 @@ if (import.meta.main) {
|
||||
console.log(JSON.stringify(await verifyProduct(binary, receipt ? resolve(receipt) : binary + ".json")));
|
||||
} else throw new Error("Use serve, verify or --version.");
|
||||
}
|
||||
|
||||
if (import.meta.main) await runProductCLI(Bun.argv.slice(2));
|
||||
+76
-69
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bun
|
||||
import { resolve } from "node:path";
|
||||
import { parseArgs } from "node:util";
|
||||
import { runProductCLI } from "../packages/bun-app-host/src/cli.ts";
|
||||
import {
|
||||
assembleSources,
|
||||
buildImage,
|
||||
@@ -14,6 +15,7 @@ import {
|
||||
} from "./distribution.ts";
|
||||
|
||||
const usage = `Bun OS factory
|
||||
server serve [ROOT] | verify [BINARY] [RECEIPT] | --version
|
||||
plan [--profile full|perf] [--target linux-x64|linux-arm64|windows-x64|macos-arm64|wasm]
|
||||
sources --out DIR [--config FILE]
|
||||
stage --out DIR --runtime FILE --receipt FILE --profile full|perf --target TARGET
|
||||
@@ -26,77 +28,82 @@ Sources contain committed, pinned files and every locked submodule; protected st
|
||||
WASM builds libm3's portable API. Native Bun/JSC and the Linux compositor require their native targets.`;
|
||||
|
||||
try {
|
||||
const { positionals, values } = parseArgs({
|
||||
args: Bun.argv.slice(2),
|
||||
allowPositionals: true,
|
||||
options: {
|
||||
help: { type: "boolean", short: "h" },
|
||||
profile: { type: "string", default: "perf" },
|
||||
target: { type: "string", default: "linux-x64" },
|
||||
out: { type: "string" },
|
||||
config: { type: "string" },
|
||||
runtime: { type: "string" },
|
||||
receipt: { type: "string" },
|
||||
material: { type: "string" },
|
||||
tag: { type: "string" },
|
||||
},
|
||||
});
|
||||
if (values.help || !positionals.length) {
|
||||
console.log(usage);
|
||||
process.exit(0);
|
||||
}
|
||||
if (positionals.length !== 1) throw new Error("Expected one factory command");
|
||||
if (values.profile !== "full" && values.profile !== "perf") throw new Error("Unknown distribution profile");
|
||||
const profile: Profile = values.profile;
|
||||
if (!["linux-x64", "linux-arm64", "windows-x64", "macos-arm64", "wasm"].includes(values.target!))
|
||||
throw new Error("Unknown target");
|
||||
const target = values.target as Target;
|
||||
const required = (name: "out" | "runtime" | "receipt" | "material" | "tag") => {
|
||||
const value = values[name];
|
||||
if (!value) throw new Error(`Missing --${name}`);
|
||||
return value;
|
||||
};
|
||||
let config: Config = {};
|
||||
if (values.config) {
|
||||
const file = resolve(values.config);
|
||||
config = await Bun.file(file).json();
|
||||
for (const [id, path] of Object.entries(config.checkouts ?? {})) config.checkouts![id] = resolve(file, "..", path);
|
||||
if (config.sourceExport) {
|
||||
if (config.sourceExport.cache) config.sourceExport.cache = resolve(file, "..", config.sourceExport.cache);
|
||||
for (const [id, path] of Object.entries(config.sourceExport.repositories ?? {}))
|
||||
config.sourceExport.repositories![id] = resolve(file, "..", path);
|
||||
config.sourceExport.protectedRoots = config.sourceExport.protectedRoots?.map(path => resolve(file, "..", path));
|
||||
if (Bun.argv[2] === "server") {
|
||||
await runProductCLI(Bun.argv.slice(3));
|
||||
} else {
|
||||
const { positionals, values } = parseArgs({
|
||||
args: Bun.argv.slice(2),
|
||||
allowPositionals: true,
|
||||
options: {
|
||||
help: { type: "boolean", short: "h" },
|
||||
profile: { type: "string", default: "perf" },
|
||||
target: { type: "string", default: "linux-x64" },
|
||||
out: { type: "string" },
|
||||
config: { type: "string" },
|
||||
runtime: { type: "string" },
|
||||
receipt: { type: "string" },
|
||||
material: { type: "string" },
|
||||
tag: { type: "string" },
|
||||
},
|
||||
});
|
||||
if (values.help || !positionals.length) {
|
||||
console.log(usage);
|
||||
process.exit(0);
|
||||
}
|
||||
if (positionals.length !== 1) throw new Error("Expected one factory command");
|
||||
if (values.profile !== "full" && values.profile !== "perf") throw new Error("Unknown distribution profile");
|
||||
const profile: Profile = values.profile;
|
||||
if (!["linux-x64", "linux-arm64", "windows-x64", "macos-arm64", "wasm"].includes(values.target!))
|
||||
throw new Error("Unknown target");
|
||||
const target = values.target as Target;
|
||||
const required = (name: "out" | "runtime" | "receipt" | "material" | "tag") => {
|
||||
const value = values[name];
|
||||
if (!value) throw new Error(`Missing --${name}`);
|
||||
return value;
|
||||
};
|
||||
let config: Config = {};
|
||||
if (values.config) {
|
||||
const file = resolve(values.config);
|
||||
config = await Bun.file(file).json();
|
||||
for (const [id, path] of Object.entries(config.checkouts ?? {}))
|
||||
config.checkouts![id] = resolve(file, "..", path);
|
||||
if (config.sourceExport) {
|
||||
if (config.sourceExport.cache) config.sourceExport.cache = resolve(file, "..", config.sourceExport.cache);
|
||||
for (const [id, path] of Object.entries(config.sourceExport.repositories ?? {}))
|
||||
config.sourceExport.repositories![id] = resolve(file, "..", path);
|
||||
config.sourceExport.protectedRoots = config.sourceExport.protectedRoots?.map(path => resolve(file, "..", path));
|
||||
}
|
||||
}
|
||||
let result: unknown;
|
||||
switch (positionals[0]) {
|
||||
case "plan":
|
||||
result = await plan(profile, target, config);
|
||||
break;
|
||||
case "sources":
|
||||
result = await assembleSources(resolve(required("out")), config);
|
||||
break;
|
||||
case "stage":
|
||||
if (target === "wasm") throw new Error("Use the wasm command for the portable library target");
|
||||
await stageRuntime(
|
||||
resolve(required("out")),
|
||||
resolve(required("runtime")),
|
||||
resolve(required("receipt")),
|
||||
profile,
|
||||
target,
|
||||
);
|
||||
result = { staged: true, profile, target };
|
||||
break;
|
||||
case "wasm":
|
||||
result = await buildWasm(resolve(required("out")), config);
|
||||
break;
|
||||
case "image":
|
||||
result = await buildImage(resolve(required("out")), profile, target, required("tag"));
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown command ${positionals[0]}; run ${packageRoot}/src/cli.ts --help`);
|
||||
}
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
}
|
||||
let result: unknown;
|
||||
switch (positionals[0]) {
|
||||
case "plan":
|
||||
result = await plan(profile, target, config);
|
||||
break;
|
||||
case "sources":
|
||||
result = await assembleSources(resolve(required("out")), config);
|
||||
break;
|
||||
case "stage":
|
||||
if (target === "wasm") throw new Error("Use the wasm command for the portable library target");
|
||||
await stageRuntime(
|
||||
resolve(required("out")),
|
||||
resolve(required("runtime")),
|
||||
resolve(required("receipt")),
|
||||
profile,
|
||||
target,
|
||||
);
|
||||
result = { staged: true, profile, target };
|
||||
break;
|
||||
case "wasm":
|
||||
result = await buildWasm(resolve(required("out")), config);
|
||||
break;
|
||||
case "image":
|
||||
result = await buildImage(resolve(required("out")), profile, target, required("tag"));
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown command ${positionals[0]}; run ${packageRoot}/src/cli.ts --help`);
|
||||
}
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
} catch (error) {
|
||||
console.error(error instanceof Error ? error.message : String(error));
|
||||
process.exitCode = 1;
|
||||
|
||||
Reference in new issue
Block a user