@wenathlan/saddle 2.1.6 → 2.1.8
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/Dockerfile +170 -66
- package/LICENSE +0 -0
- package/README.md +73 -58
- package/alternatives.ts +0 -0
- package/biome.jsonc +134 -0
- package/boards.json +2 -2
- package/browser.ts +482 -0
- package/cli.ts +274 -0
- package/compute.ts +4 -4
- package/cores.json +2 -2
- package/distribution.ts +731 -0
- package/docker.config +37 -9
- package/docs/.gitkeep +0 -0
- package/docs/actionrecorder.md +0 -0
- package/docs/actionsincident.md +0 -0
- package/docs/alternatives.md +0 -0
- package/docs/architecture.md +0 -0
- package/docs/{architecture-1.8.19.md → architecture1819.md} +0 -0
- package/docs/{architecture-1.8.19.mmd → architecture1819.mmd} +0 -0
- package/docs/artifactavailability.md +2 -2
- package/docs/{artifactresearch-1.8.9.md → artifactresearch189.md} +0 -0
- package/docs/{batches-1816-1820.md → batches1816to1820.md} +0 -0
- package/docs/{brancharchive-2026-08-18.md → brancharchive20260818.md} +0 -0
- package/docs/branchaudit.md +0 -0
- package/docs/browser.md +18 -1
- package/docs/capabilityreport.md +0 -0
- package/docs/comparativeaudit.md +0 -0
- package/docs/consolidation.md +0 -0
- package/docs/{containerplatforms-1.8.17.md → containerplatforms1817.md} +0 -0
- package/docs/{containerplatforms-2.1.0.md → containerplatforms210.md} +1 -1
- package/docs/{documentmap-1.8.12.md → documentmap1812.md} +1 -1
- package/docs/{e2ugh-engine.md → e2ughengine.md} +0 -0
- package/docs/ecosystemplan.md +0 -0
- package/docs/enginearchitecture.md +0 -0
- package/docs/extension.md +13 -2
- package/docs/featureaudit.md +0 -0
- package/docs/{flatbuildresearch-1.8.11.md → flatbuildresearch1811.md} +0 -0
- package/docs/gapmatrix.md +0 -0
- package/docs/hardware.md +0 -0
- package/docs/libraryapi.md +1 -1
- package/docs/{licenseaudit-1.8.12.md → licenseaudit1812.md} +0 -0
- package/docs/logs/examplesession.json +54 -0
- package/docs/memoryengine.md +0 -0
- package/docs/{mobileconversionresearch-1.8.10.md → mobileconversionresearch1810.md} +0 -0
- package/docs/modes.md +0 -0
- package/docs/{nativeidentityresearch-1.8.11.md → nativeidentityresearch1811.md} +0 -0
- package/docs/{native-wrappers.md → nativewrappers.md} +0 -0
- package/docs/ninetymodalities.md +191 -0
- package/docs/optimization.md +0 -0
- package/docs/packageaudit185.md +0 -0
- package/docs/performance.md +0 -0
- package/docs/{planning.1.8.18.md → planning1818.md} +0 -0
- package/docs/{planning.1.8.19.md → planning1819.md} +0 -0
- package/docs/planningengine.md +186 -0
- package/docs/planningninety.md +391 -0
- package/docs/platformpipelineaudit.md +0 -0
- package/docs/platformpipelines.md +0 -0
- package/docs/productindex.md +0 -0
- package/docs/registryresearch.md +0 -0
- package/docs/release.md +0 -0
- package/docs/release17notes.md +0 -0
- package/docs/release181notes.md +0 -0
- package/docs/release182notes.md +0 -0
- package/docs/release184notes.md +0 -0
- package/docs/release185notes.md +0 -0
- package/docs/release18notes.md +0 -0
- package/docs/releaseassets.md +0 -0
- package/docs/{releasenotes-1.8.12.md → releasenotes1812.md} +0 -0
- package/docs/{releasenotes-1.8.13.md → releasenotes1813.md} +2 -2
- package/docs/{releasenotes-1.8.14.md → releasenotes1814.md} +1 -1
- package/docs/{releasenotes-1.8.15.md → releasenotes1815.md} +0 -0
- package/docs/{releasenotes-1.8.16.md → releasenotes1816.md} +0 -0
- package/docs/{releasenotes-1.8.17.md → releasenotes1817.md} +0 -0
- package/docs/{releasenotes-1.8.18.md → releasenotes1818.md} +0 -0
- package/docs/{releasenotes-1.8.19.md → releasenotes1819.md} +0 -0
- package/docs/{reorganization-1.8.8.md → reorganization188.md} +0 -0
- package/docs/{reorganization-1.8.9.md → reorganization189.md} +0 -0
- package/docs/{repo-analysis-1.8.21.json → repoanalysis1821.json} +0 -0
- package/docs/{repo-candidates-1.8.21.jsonl → repocandidates1821.jsonl} +0 -0
- package/docs/{repo-research-1.8.16.md → reporesearch1816.md} +0 -0
- package/docs/{repo-research-1.8.21.md → reporesearch1821.md} +0 -0
- package/docs/{repo-selected-1.8.21.json → reposelected1821.json} +0 -0
- package/docs/{repo-synthesis-1.8.16.md → reposynthesis1816.md} +1 -1
- package/docs/{repo-synthesis-1.8.21.md → reposynthesis1821.md} +0 -0
- package/docs/{research-1.8.18-isolation.md → research1818isolation.md} +0 -0
- package/docs/{research-1.8.19-virtual-browser.md → research1819virtualbrowser.md} +0 -0
- package/docs/roadmapp2p3.md +0 -0
- package/docs/s3compatible.md +0 -0
- package/docs/{scanningresearch-1.8.11.md → scanningresearch1811.md} +0 -0
- package/docs/security.md +0 -0
- package/docs/{securityaudit-1.8.7.md → securityaudit187.md} +0 -0
- package/docs/{securityreferences-1.8.11.md → securityreferences1811.md} +0 -0
- package/docs/{securityresearch-1.8.11.md → securityresearch1811.md} +0 -0
- package/docs/{signingresearch-1.8.12.md → signingresearch1812.md} +0 -0
- package/docs/signingwithoutcertificates.md +0 -0
- package/docs/signpathapplication.md +0 -0
- package/docs/sitemap.md +0 -0
- package/docs/{tauri-glib-risk-1.8.11.md → tauriglibrisk1811.md} +0 -0
- package/docs/todo.md +2 -2
- package/docs/{todo-1.8.15.md → todo1815.md} +1 -1
- package/docs/{todo-1.8.16.md → todo1816.md} +5 -5
- package/docs/{todo-1.8.18.md → todo1818.md} +0 -0
- package/docs/{todo-1.8.19.md → todo1819.md} +0 -0
- package/docs/{toolchainresearch-1.8.9.md → toolchainresearch189.md} +0 -0
- package/docs/toolchains.md +0 -0
- package/docs/usage.md +0 -0
- package/docs/viability.md +0 -0
- package/docs/virtualization.md +0 -0
- package/docs/{web-duplicatecleanup.md → webduplicatecleanup.md} +0 -0
- package/docs/{web-ideas.md → webideas.md} +0 -0
- package/docs/{workflowimprovements-2026-08-19.md → workflowimprovements20260819.md} +0 -0
- package/docs/workflowinputs.md +0 -0
- package/docs/workflowoperations.md +0 -0
- package/docs/workloadlaw.md +104 -0
- package/execution.ts +677 -0
- package/foundation.ts +314 -0
- package/gpumonitor.cpp +0 -0
- package/gpus.json +1 -1
- package/index.ts +38 -29
- package/isolation.ts +84 -0
- package/modalityregistry.ts +1493 -0
- package/{dist/modes.js → modes.ts} +79 -62
- package/mttg.config +1 -1
- package/orchestrator.ts +54 -17
- package/package.json +245 -146
- package/passage.config +0 -0
- package/performance.ts +0 -0
- package/processors.json +1 -1
- package/qemu.config +2 -2
- package/qemubridge.py +0 -0
- package/quantum.ts +0 -0
- package/render.ts +0 -0
- package/sandbox.ts +2035 -0
- package/scheduler.ts +1 -1
- package/security.ts +0 -0
- package/server.ts +52 -0
- package/tiers.ts +9 -3
- package/tsconfig.json +22 -13
- package/virtual.ts +1105 -0
- package/virtualcpu.ts +1 -0
- package/virtualgpu.ts +2 -1
- package/virtualhardware.c +0 -0
- package/virtualhardware.json +2 -2
- package/virtualization.ts +1 -1
- package/virtualizationcore.cpp +0 -0
- package/virtualmemory.ts +0 -0
- package/vm.config.json +2 -2
- package/workloadlaw.ts +293 -0
- package/biome.json +0 -151
- package/dist/acquisition.d.ts +0 -359
- package/dist/acquisition.d.ts.map +0 -1
- package/dist/acquisition.js +0 -629
- package/dist/acquisition.js.map +0 -1
- package/dist/alternatives.d.ts +0 -509
- package/dist/alternatives.d.ts.map +0 -1
- package/dist/alternatives.js +0 -951
- package/dist/alternatives.js.map +0 -1
- package/dist/automation.d.ts +0 -426
- package/dist/automation.d.ts.map +0 -1
- package/dist/automation.js +0 -561
- package/dist/automation.js.map +0 -1
- package/dist/browser.d.ts +0 -562
- package/dist/browser.d.ts.map +0 -1
- package/dist/browser.js +0 -1057
- package/dist/browser.js.map +0 -1
- package/dist/cli.d.ts +0 -17
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -169
- package/dist/cli.js.map +0 -1
- package/dist/communication.d.ts +0 -192
- package/dist/communication.d.ts.map +0 -1
- package/dist/communication.js +0 -418
- package/dist/communication.js.map +0 -1
- package/dist/compute.d.ts +0 -1161
- package/dist/compute.d.ts.map +0 -1
- package/dist/compute.js +0 -2273
- package/dist/compute.js.map +0 -1
- package/dist/distribution.d.ts +0 -529
- package/dist/distribution.d.ts.map +0 -1
- package/dist/distribution.js +0 -811
- package/dist/distribution.js.map +0 -1
- package/dist/docs/example-localjob.d.ts +0 -2
- package/dist/docs/example-localjob.d.ts.map +0 -1
- package/dist/docs/example-localjob.js +0 -15
- package/dist/docs/example-localjob.js.map +0 -1
- package/dist/docs/example-publicapi.d.ts +0 -2
- package/dist/docs/example-publicapi.d.ts.map +0 -1
- package/dist/docs/example-publicapi.js +0 -7
- package/dist/docs/example-publicapi.js.map +0 -1
- package/dist/execution.d.ts +0 -530
- package/dist/execution.d.ts.map +0 -1
- package/dist/execution.js +0 -761
- package/dist/execution.js.map +0 -1
- package/dist/format.d.ts +0 -19
- package/dist/format.d.ts.map +0 -1
- package/dist/format.js +0 -60
- package/dist/format.js.map +0 -1
- package/dist/foundation.d.ts +0 -176
- package/dist/foundation.d.ts.map +0 -1
- package/dist/foundation.js +0 -309
- package/dist/foundation.js.map +0 -1
- package/dist/index.d.ts +0 -735
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -1020
- package/dist/index.js.map +0 -1
- package/dist/integration.d.ts +0 -236
- package/dist/integration.d.ts.map +0 -1
- package/dist/integration.js +0 -236
- package/dist/integration.js.map +0 -1
- package/dist/intelligence.d.ts +0 -94
- package/dist/intelligence.d.ts.map +0 -1
- package/dist/intelligence.js +0 -145
- package/dist/intelligence.js.map +0 -1
- package/dist/isolation.d.ts +0 -129
- package/dist/isolation.d.ts.map +0 -1
- package/dist/isolation.js +0 -96
- package/dist/isolation.js.map +0 -1
- package/dist/media.d.ts +0 -344
- package/dist/media.d.ts.map +0 -1
- package/dist/media.js +0 -986
- package/dist/media.js.map +0 -1
- package/dist/modes.d.ts +0 -359
- package/dist/modes.d.ts.map +0 -1
- package/dist/modes.js.map +0 -1
- package/dist/operations.d.ts +0 -67
- package/dist/operations.d.ts.map +0 -1
- package/dist/operations.js +0 -94
- package/dist/operations.js.map +0 -1
- package/dist/orchestrator.d.ts +0 -1339
- package/dist/orchestrator.d.ts.map +0 -1
- package/dist/orchestrator.js +0 -4308
- package/dist/orchestrator.js.map +0 -1
- package/dist/packager/targetcli.js +0 -4
- package/dist/performance.d.ts +0 -416
- package/dist/performance.d.ts.map +0 -1
- package/dist/performance.js +0 -827
- package/dist/performance.js.map +0 -1
- package/dist/quantum.d.ts +0 -810
- package/dist/quantum.d.ts.map +0 -1
- package/dist/quantum.js +0 -2073
- package/dist/quantum.js.map +0 -1
- package/dist/render.d.ts +0 -381
- package/dist/render.d.ts.map +0 -1
- package/dist/render.js +0 -1073
- package/dist/render.js.map +0 -1
- package/dist/scheduler.d.ts +0 -596
- package/dist/scheduler.d.ts.map +0 -1
- package/dist/scheduler.js +0 -1259
- package/dist/scheduler.js.map +0 -1
- package/dist/security.d.ts +0 -501
- package/dist/security.d.ts.map +0 -1
- package/dist/security.js +0 -1170
- package/dist/security.js.map +0 -1
- package/dist/server.d.ts +0 -21
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -52
- package/dist/server.js.map +0 -1
- package/dist/tiers.d.ts +0 -1002
- package/dist/tiers.d.ts.map +0 -1
- package/dist/tiers.js +0 -2165
- package/dist/tiers.js.map +0 -1
- package/dist/virtual.d.ts +0 -641
- package/dist/virtual.d.ts.map +0 -1
- package/dist/virtual.js +0 -1285
- package/dist/virtual.js.map +0 -1
- package/dist/virtualcpu.d.ts +0 -316
- package/dist/virtualcpu.d.ts.map +0 -1
- package/dist/virtualcpu.js +0 -1180
- package/dist/virtualcpu.js.map +0 -1
- package/dist/virtualgpu.d.ts +0 -345
- package/dist/virtualgpu.d.ts.map +0 -1
- package/dist/virtualgpu.js +0 -1000
- package/dist/virtualgpu.js.map +0 -1
- package/dist/virtualization.d.ts +0 -607
- package/dist/virtualization.d.ts.map +0 -1
- package/dist/virtualization.js +0 -1187
- package/dist/virtualization.js.map +0 -1
- package/dist/virtualmemory.d.ts +0 -818
- package/dist/virtualmemory.d.ts.map +0 -1
- package/dist/virtualmemory.js +0 -1796
- package/dist/virtualmemory.js.map +0 -1
- package/dist/vitest.config.d.ts +0 -3
- package/dist/vitest.config.d.ts.map +0 -1
- package/dist/vitest.config.js +0 -26
- package/dist/vitest.config.js.map +0 -1
- package/dist/webscrape.d.ts +0 -720
- package/dist/webscrape.d.ts.map +0 -1
- package/dist/webscrape.js +0 -2697
- package/dist/webscrape.js.map +0 -1
- package/docs/CONVERSA.txt +0 -1523
- package/docs/architecture-1.8.19.png +0 -0
- package/docs/assets/architecture.svg +0 -45
- package/docs/assets/saddlemark.svg +0 -13
- package/docs/example-localjob.ts +0 -15
- package/docs/example-publicapi.ts +0 -7
- package/docs/saddle.archive.1.8.17.tar.gz.gpg +0 -0
- package/media.ts +0 -1337
- package/web/manifest.json +0 -30
- package/web/readme.md +0 -383
- package/web/tsconfig.json +0 -25
package/cli.ts
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* cli.ts — the saddle command-line entry point.
|
|
4
|
+
*
|
|
5
|
+
* This file is the v2.0.0 grand-merge consolidation of the former nested
|
|
6
|
+
* folders of the repository (cli) into the single
|
|
7
|
+
* root-level domain file of the e2ugh family standard: one optimized
|
|
8
|
+
* TypeScript file per correlated domain, ordinal sections, JSDoc on every
|
|
9
|
+
* block, intra-domain imports dissolved, cross-domain imports rewritten to
|
|
10
|
+
* ./<domain>.js. Every capability of every source file is preserved here;
|
|
11
|
+
* the pure re-export barrels (none in this domain) folded their surface into this file directly.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { mkdtemp, readFile } from "node:fs/promises";
|
|
15
|
+
import { tmpdir } from "node:os";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
import { argv } from "node:process";
|
|
18
|
+
import { eventbus } from "./foundation.ts";
|
|
19
|
+
import { localmemory, localstorage } from "./virtual.ts";
|
|
20
|
+
import { engine, inprocess, scheduler } from "./execution.ts";
|
|
21
|
+
import { mcpserver } from "./integration.ts";
|
|
22
|
+
import { modecatalog } from "./modes.ts";
|
|
23
|
+
import { creategrid, defaultplan, dockerrun, multiplex, planlint, plantoml, qemucommand, type plan } from "./index.ts";
|
|
24
|
+
import {
|
|
25
|
+
compilewithbabel,
|
|
26
|
+
dockerdescriptor,
|
|
27
|
+
interpretsh,
|
|
28
|
+
interpretyaml,
|
|
29
|
+
interpretyml,
|
|
30
|
+
runscript,
|
|
31
|
+
runscriptbackground,
|
|
32
|
+
scriptRunStatus,
|
|
33
|
+
type ScriptPlan,
|
|
34
|
+
} from "./scriptlanes.ts";
|
|
35
|
+
|
|
36
|
+
/* ════════════════════════════════════════════════════════════════════ */
|
|
37
|
+
/* Section 1: cli/main.ts — the saddle command-line entry point (the bin "saddle" resolves to this source through the source-is-library law (node 26 strips the types, the shebang hands the file to the runtime)). */
|
|
38
|
+
/* ════════════════════════════════════════════════════════════════════ */
|
|
39
|
+
/**
|
|
40
|
+
* the cli keeps local execution explicit and leaves remote dispatch to adapters.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/** Runs one CLI command and keeps external services behind adapters. */
|
|
44
|
+
export async function main(args = argv.slice(2)) {
|
|
45
|
+
const command = args[0] ?? "help";
|
|
46
|
+
/* Help stays short and lists only stable local commands. */
|
|
47
|
+
if (["help", "--help", "-h"].includes(command)) { console.log("saddle <command>\n\ncommands\n help\n modes\n plan [qemu|docker|toml]\n vm [qemu|docker|toml]\n vmlint\n gpus\n runexample\n script <run|background|status|docker|compile> [file|runid]\n mcp"); return; }
|
|
48
|
+
if (command === "modes") { console.log(JSON.stringify(modecatalog(), null, 2)); return; }
|
|
49
|
+
if (command === "plan") { await renderplan(args[1]); return; }
|
|
50
|
+
/* The vm/vmlint/gpus triad makes the nominal npm aliases (vm:create, */
|
|
51
|
+
/* vm:validate, gpu:list) real: they map to the live engine surface — */
|
|
52
|
+
/* the plan renderer, the planlint validator, and the gpus.json catalog. */
|
|
53
|
+
if (command === "vm") { await renderplan(args[1] ?? "qemu"); return; }
|
|
54
|
+
if (command === "vmlint") { await rendervmlint(); return; }
|
|
55
|
+
if (command === "gpus") { await rendergpus(); return; }
|
|
56
|
+
if (command === "runexample") {
|
|
57
|
+
const root = await mkdtemp(join(tmpdir(), "saddlecli"));
|
|
58
|
+
const events = eventbus();
|
|
59
|
+
const run = engine({ storage: localstorage(root), memory: localmemory(), scheduler: scheduler([inprocess()]), events });
|
|
60
|
+
const result = await run.run({ name: "cliexample", input: { hello: "saddle" } }, ({ job }) => ({ jobid: job.id, ok: true, message: "storage to working set to result" }));
|
|
61
|
+
console.log(JSON.stringify({ jobid: result.job.id, artifact: result.artifact, events: events.all().length }, null, 2));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (command === "script") { await renderscript(args[1], args[2]); return; }
|
|
65
|
+
if (command === "mcp") { const server = mcpserver(); console.log(JSON.stringify({ tools: server.listtools() }, null, 2)); return; }
|
|
66
|
+
throw new Error(`unknown command: ${command}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* ════════════════════════════════════════════════════════════════════ */
|
|
70
|
+
/* Section 2: the plan renderer — the architect CLI absorbed from the e2ugh */
|
|
71
|
+
/* engine entry (index.ts); the former `e2ugh` bin folds into the single */
|
|
72
|
+
/* `saddle` bin at the 2.0.0 grand merge. */
|
|
73
|
+
/* ════════════════════════════════════════════════════════════════════ */
|
|
74
|
+
/**
|
|
75
|
+
* Renders one machine plan (defaulting to defaultplan, overridden by the
|
|
76
|
+
* optional vm.config.toml regex fields) preceded by the MTTG multiplex
|
|
77
|
+
* header — the absorbed e2ugh engine CLI entry, byte-compatible with the
|
|
78
|
+
* former `node ./index.ts` invocation through the single saddle bin.
|
|
79
|
+
*
|
|
80
|
+
* @param format the render format: qemu (default), docker or toml.
|
|
81
|
+
*/
|
|
82
|
+
async function renderplan(format = "qemu") {
|
|
83
|
+
try {
|
|
84
|
+
let candidate: plan = { ...defaultplan };
|
|
85
|
+
try {
|
|
86
|
+
const raw = await readFile("vm.config.toml", "utf8");
|
|
87
|
+
const vcpus = /vcpus = (\d+)/.exec(raw)?.[1];
|
|
88
|
+
const mem = /gib = (\d+)/.exec(raw)?.[1];
|
|
89
|
+
const mttg = /virtual_threads = (\d+)/.exec(raw)?.[1];
|
|
90
|
+
if (vcpus !== undefined) {
|
|
91
|
+
candidate = { ...candidate, vcpus: Number(vcpus) };
|
|
92
|
+
}
|
|
93
|
+
if (mem !== undefined) {
|
|
94
|
+
candidate = { ...candidate, memorygib: Number(mem) };
|
|
95
|
+
}
|
|
96
|
+
if (mttg !== undefined) {
|
|
97
|
+
candidate = { ...candidate, mttgthreads: Number(mttg), mttg: true };
|
|
98
|
+
}
|
|
99
|
+
} catch {
|
|
100
|
+
/* catcher: vm.config.toml is optional; defaults stay */
|
|
101
|
+
}
|
|
102
|
+
const grid = creategrid(undefined, candidate.mttgthreads);
|
|
103
|
+
const header = `# multiplex ${multiplex(grid).toFixed(1)}x on ${grid.host} host threads\n`;
|
|
104
|
+
const body =
|
|
105
|
+
format === "docker"
|
|
106
|
+
? dockerrun(candidate)
|
|
107
|
+
: format === "toml"
|
|
108
|
+
? plantoml(candidate)
|
|
109
|
+
: qemucommand(candidate);
|
|
110
|
+
process.stdout.write(`${header}${body}\n`);
|
|
111
|
+
for (const note of planlint(candidate)) {
|
|
112
|
+
process.stderr.write(`# ${note}\n`);
|
|
113
|
+
}
|
|
114
|
+
} catch (error) {
|
|
115
|
+
process.stderr.write(
|
|
116
|
+
`planner failed: ${error instanceof Error ? error.message : String(error)}\n`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Validates the effective machine plan (defaults overridden by the optional
|
|
123
|
+
* vm.config.toml fields) through planlint and prints only the advisory
|
|
124
|
+
* notes — the engine behind the nominal `vm:validate` npm alias: exit code
|
|
125
|
+
* stays zero because the notes are advisory, never fatal.
|
|
126
|
+
*/
|
|
127
|
+
async function rendervmlint() {
|
|
128
|
+
let candidate: plan = { ...defaultplan };
|
|
129
|
+
try {
|
|
130
|
+
const raw = await readFile("vm.config.toml", "utf8");
|
|
131
|
+
const vcpus = /vcpus = (\d+)/.exec(raw)?.[1];
|
|
132
|
+
const mem = /gib = (\d+)/.exec(raw)?.[1];
|
|
133
|
+
const mttg = /virtual_threads = (\d+)/.exec(raw)?.[1];
|
|
134
|
+
if (vcpus !== undefined) candidate = { ...candidate, vcpus: Number(vcpus) };
|
|
135
|
+
if (mem !== undefined) candidate = { ...candidate, memorygib: Number(mem) };
|
|
136
|
+
if (mttg !== undefined) candidate = { ...candidate, mttgthreads: Number(mttg), mttg: true };
|
|
137
|
+
} catch {
|
|
138
|
+
/* catcher: vm.config.toml is optional; defaults stay */
|
|
139
|
+
}
|
|
140
|
+
const notes = planlint(candidate);
|
|
141
|
+
console.log(`vcpus ${candidate.vcpus} memorygib ${candidate.memorygib} — ${notes.length} note(s)`);
|
|
142
|
+
for (const note of notes) {
|
|
143
|
+
console.log(`# ${note}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Lists the GPU catalog of the engine (gpus.json — the catalog the
|
|
149
|
+
* orchestrator resolves GPU requests against) — the engine behind the
|
|
150
|
+
* nominal `gpu:list` npm alias.
|
|
151
|
+
*/
|
|
152
|
+
async function rendergpus() {
|
|
153
|
+
const catalog = JSON.parse(await readFile("gpus.json", "utf8")) as { gpus: Array<Record<string, unknown>> };
|
|
154
|
+
console.log(`${catalog.gpus.length} gpus`);
|
|
155
|
+
for (const gpu of catalog.gpus) {
|
|
156
|
+
const name = String(gpu.name ?? gpu.model ?? "unknown");
|
|
157
|
+
const profiles = Array.isArray(gpu.profiles) ? (gpu.profiles as unknown[]).length : 0;
|
|
158
|
+
console.log(profiles > 0 ? `${name} (${profiles} mig profiles)` : name);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* ══════════════════════════════════════════════════════════════════ */
|
|
163
|
+
/* Section 3: the script lanes renderer — the sh/yml/yaml execution */
|
|
164
|
+
/* surface of the engine lane (PR15): run, background, status, docker */
|
|
165
|
+
/* and compile ride the very scriptlanes.ts functions the webserver */
|
|
166
|
+
/* routes serve, so the bin and the api speak one lane. */
|
|
167
|
+
/* ══════════════════════════════════════════════════════════════════ */
|
|
168
|
+
/**
|
|
169
|
+
* the script lanes renderer: every descriptor subcommand reads one
|
|
170
|
+
* file whose extension picks the interpretation lane and answers the
|
|
171
|
+
* honest result — no faked exit codes, no silent skips.
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
/** the poll pause the background renderer waits with (the same cadence
|
|
175
|
+
* the script lanes test polls the detached record with). */
|
|
176
|
+
const scriptpause = (milliseconds: number) => new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* interprets one descriptor file into a script plan: the extension
|
|
180
|
+
* picks the lane — .sh wraps the raw script as one direct step,
|
|
181
|
+
* .yml and .yaml ride the house yaml subset (both spellings one lane,
|
|
182
|
+
* the plan declares the babel compile lane). a missing file or an
|
|
183
|
+
* unknown extension refuses honestly instead of guessing.
|
|
184
|
+
*
|
|
185
|
+
* @param target the descriptor file path.
|
|
186
|
+
* @returns the interpreted plan.
|
|
187
|
+
*/
|
|
188
|
+
async function scriptplanfromfile(target: string): Promise<ScriptPlan> {
|
|
189
|
+
if (target.length === 0) {
|
|
190
|
+
throw new Error("the script subcommand requires a descriptor file (.sh, .yml or .yaml)");
|
|
191
|
+
}
|
|
192
|
+
const text = await readFile(target, "utf8");
|
|
193
|
+
if (target.endsWith(".sh")) return interpretsh(text);
|
|
194
|
+
if (target.endsWith(".yml")) return interpretyml(text);
|
|
195
|
+
if (target.endsWith(".yaml")) return interpretyaml(text);
|
|
196
|
+
throw new Error(`the descriptor extension of "${target}" is not one the script lanes speak (.sh, .yml, .yaml)`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Renders one script lanes subcommand: run executes the plan
|
|
201
|
+
* server-side with the enforced per-step deadlines and prints the
|
|
202
|
+
* honest per-step result (a failed plan exits 1); background kicks the
|
|
203
|
+
* plan detached through the house job queue, prints the launch answer
|
|
204
|
+
* and observes the record settle through the run status (the registry
|
|
205
|
+
* lives in this process, the poll reads it the way the api consumer
|
|
206
|
+
* does); status reads the observable record of one runid — honestly
|
|
207
|
+
* refusing a runid another process launched (SCRIPT_RUN_NOT_FOUND,
|
|
208
|
+
* the one-shot cli never carried that registry); docker emits the
|
|
209
|
+
* docker-ready descriptor of the plan; compile validates the babel
|
|
210
|
+
* roundtrip and prints the compiled plan.
|
|
211
|
+
*
|
|
212
|
+
* @param subcommand the script subcommand (run, background, status, docker, compile).
|
|
213
|
+
* @param target the descriptor file path (or the runid for status).
|
|
214
|
+
*/
|
|
215
|
+
async function renderscript(subcommand = "help", target = "") {
|
|
216
|
+
if (["help", "--help", "-h"].includes(subcommand)) {
|
|
217
|
+
console.log(
|
|
218
|
+
"saddle script <run|background|status|docker|compile> [file|runid]" +
|
|
219
|
+
"\n\n run <file> execute the plan server-side and print the honest per-step result" +
|
|
220
|
+
"\n background <file> kick the plan detached and observe the record settle" +
|
|
221
|
+
"\n status <runid> read the observable record of one background run" +
|
|
222
|
+
"\n docker <file> emit the docker-ready descriptor of the plan" +
|
|
223
|
+
"\n compile <file> ride the babel compile roundtrip and print the compiled plan",
|
|
224
|
+
);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
if (subcommand === "run") {
|
|
229
|
+
const plan = await scriptplanfromfile(target);
|
|
230
|
+
const result = await runscript(plan);
|
|
231
|
+
console.log(JSON.stringify({ source: plan.source, compiledvia: plan.compiledvia, ...result }, null, 2));
|
|
232
|
+
if (result.status === "failed") process.exitCode = 1;
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (subcommand === "background") {
|
|
236
|
+
const plan = await scriptplanfromfile(target);
|
|
237
|
+
const launch = runscriptbackground(plan);
|
|
238
|
+
console.log(JSON.stringify({ runid: launch.runid, status: launch.status, source: plan.source }, null, 2));
|
|
239
|
+
let record = scriptRunStatus(launch.runid);
|
|
240
|
+
const deadlineat = Date.now() + 60000;
|
|
241
|
+
while (record.status !== "succeeded" && record.status !== "failed" && Date.now() < deadlineat) {
|
|
242
|
+
await scriptpause(50);
|
|
243
|
+
record = scriptRunStatus(launch.runid);
|
|
244
|
+
}
|
|
245
|
+
console.log(JSON.stringify(record, null, 2));
|
|
246
|
+
if (record.status === "failed") process.exitCode = 1;
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
if (subcommand === "status") {
|
|
250
|
+
if (target.length === 0) throw new Error("the status subcommand requires a runid");
|
|
251
|
+
console.log(JSON.stringify(scriptRunStatus(target), null, 2));
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
if (subcommand === "docker") {
|
|
255
|
+
const plan = await scriptplanfromfile(target);
|
|
256
|
+
const descriptor = dockerdescriptor(plan);
|
|
257
|
+
process.stdout.write(descriptor.dockerfile);
|
|
258
|
+
process.stdout.write(`# entrypoint (docker run): ${descriptor.entrypoint}\n`);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (subcommand === "compile") {
|
|
262
|
+
const plan = await scriptplanfromfile(target);
|
|
263
|
+
const compiled = await compilewithbabel(plan);
|
|
264
|
+
console.log(JSON.stringify(compiled, null, 2));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
throw new Error(`unknown script subcommand: ${subcommand}`);
|
|
268
|
+
} catch (error) {
|
|
269
|
+
process.stderr.write(`script lane failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
270
|
+
process.exitCode = 1;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (import.meta.url === `file://${argv[1]}`) main().catch((error) => { console.error(error); process.exitCode = 1; });
|
package/compute.ts
CHANGED
|
@@ -2554,7 +2554,7 @@ export function buildvmcrdmanifest(opts?: {
|
|
|
2554
2554
|
'metadata:',
|
|
2555
2555
|
` name: ${plural}.${group}`,
|
|
2556
2556
|
'spec:',
|
|
2557
|
-
|
|
2557
|
+
` group: ${group}`,
|
|
2558
2558
|
' scope: Namespaced',
|
|
2559
2559
|
' names:',
|
|
2560
2560
|
` plural: ${plural}`,
|
|
@@ -2562,7 +2562,7 @@ export function buildvmcrdmanifest(opts?: {
|
|
|
2562
2562
|
` kind: ${kind}`,
|
|
2563
2563
|
' shortNames: [vm, evm]',
|
|
2564
2564
|
' versions:',
|
|
2565
|
-
|
|
2565
|
+
` - name: ${version}`,
|
|
2566
2566
|
' served: true',
|
|
2567
2567
|
' storage: true',
|
|
2568
2568
|
' subresources:',
|
|
@@ -2618,8 +2618,8 @@ export function buildvmcrdmanifest(opts?: {
|
|
|
2618
2618
|
'',
|
|
2619
2619
|
].join('\n');
|
|
2620
2620
|
const sample = [
|
|
2621
|
-
|
|
2622
|
-
|
|
2621
|
+
`apiVersion: ${group}/${version}`,
|
|
2622
|
+
`kind: ${kind}`,
|
|
2623
2623
|
'metadata:',
|
|
2624
2624
|
' name: demo-vm',
|
|
2625
2625
|
' namespace: saddle',
|
package/cores.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"metadata": {
|
|
3
3
|
"id": "cores.json",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.0.127",
|
|
5
5
|
"date": "2026-08-22",
|
|
6
6
|
"datestamp": "2026-08-22T00:00:00Z",
|
|
7
7
|
"observer": "third person observer notes the hybrid core inventory reflects production silicon as of 2026-08-22",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
]
|
|
37
37
|
},
|
|
38
38
|
"stack": {
|
|
39
|
-
"node": "26.
|
|
39
|
+
"node": "26.12.0 Current",
|
|
40
40
|
"nodeAlt": "24.19.0 LTS",
|
|
41
41
|
"typescript": "7.0.2",
|
|
42
42
|
"python": "3.14.7",
|