@wenathlan/saddle 2.0.154 → 2.0.155

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.
Files changed (307) hide show
  1. package/Dockerfile +112 -41
  2. package/README.md +58 -59
  3. package/browser.ts +482 -0
  4. package/cli.ts +274 -0
  5. package/distribution.ts +731 -0
  6. package/docker.config +29 -8
  7. package/docs/artifactavailability.md +2 -2
  8. package/docs/browser.md +18 -1
  9. package/docs/{containerplatforms.2.1.0.md → containerplatforms210.md} +1 -1
  10. package/docs/{documentmap.1.8.12.md → documentmap1812.md} +1 -1
  11. package/docs/extension.md +13 -2
  12. package/docs/libraryapi.md +1 -1
  13. package/docs/{ninety.modalities.md → ninetymodalities.md} +87 -4
  14. package/docs/{planning.ninety.md → planningninety.md} +6 -6
  15. package/docs/{releasenotes.1.8.13.md → releasenotes1813.md} +2 -2
  16. package/docs/{releasenotes.1.8.14.md → releasenotes1814.md} +1 -1
  17. package/docs/{repo.synthesis.1.8.16.md → reposynthesis1816.md} +1 -1
  18. package/docs/todo.md +2 -2
  19. package/docs/{todo.1.8.15.md → todo1815.md} +1 -1
  20. package/docs/{todo.1.8.16.md → todo1816.md} +5 -5
  21. package/execution.ts +677 -0
  22. package/foundation.ts +314 -0
  23. package/index.ts +35 -27
  24. package/isolation.ts +84 -0
  25. package/modes.ts +170 -0
  26. package/mttg.config +1 -1
  27. package/orchestrator.ts +49 -15
  28. package/package.json +90 -75
  29. package/qemu.config +2 -2
  30. package/sandbox.ts +2094 -0
  31. package/scheduler.ts +1 -1
  32. package/server.ts +52 -0
  33. package/tsconfig.json +11 -12
  34. package/virtual.ts +1105 -0
  35. package/virtualgpu.ts +1 -1
  36. package/virtualization.ts +1 -1
  37. package/workloadlaw.ts +293 -0
  38. package/dist/App.d.ts +0 -5
  39. package/dist/App.js +0 -52
  40. package/dist/Sol/Sol.d.ts +0 -3
  41. package/dist/Sol/Sol.js +0 -46
  42. package/dist/Sol/agentbrowser/agentbrowser.d.ts +0 -9
  43. package/dist/Sol/agentbrowser/agentbrowser.js +0 -121
  44. package/dist/Sol/architecture/architecture.d.ts +0 -9
  45. package/dist/Sol/architecture/architecture.js +0 -93
  46. package/dist/Sol/compute/compute.d.ts +0 -9
  47. package/dist/Sol/compute/compute.js +0 -22
  48. package/dist/Sol/console/console.d.ts +0 -15
  49. package/dist/Sol/console/console.js +0 -292
  50. package/dist/Sol/dashboard/dashboard.d.ts +0 -10
  51. package/dist/Sol/dashboard/dashboard.js +0 -181
  52. package/dist/Sol/docs/docs.d.ts +0 -9
  53. package/dist/Sol/docs/docs.js +0 -28
  54. package/dist/Sol/home/home.d.ts +0 -35
  55. package/dist/Sol/home/home.js +0 -239
  56. package/dist/Sol/integrations/integrations.d.ts +0 -9
  57. package/dist/Sol/integrations/integrations.js +0 -83
  58. package/dist/Sol/intro/intro.d.ts +0 -7
  59. package/dist/Sol/intro/intro.js +0 -102
  60. package/dist/Sol/login/login.d.ts +0 -16
  61. package/dist/Sol/login/login.js +0 -49
  62. package/dist/Sol/notfound/notfound.d.ts +0 -9
  63. package/dist/Sol/notfound/notfound.js +0 -15
  64. package/dist/Sol/onboarding/onboarding.d.ts +0 -25
  65. package/dist/Sol/onboarding/onboarding.js +0 -60
  66. package/dist/Sol/playground/playground.d.ts +0 -9
  67. package/dist/Sol/playground/playground.js +0 -127
  68. package/dist/Sol/register/register.d.ts +0 -16
  69. package/dist/Sol/register/register.js +0 -193
  70. package/dist/Sol/shell/Shell.d.ts +0 -124
  71. package/dist/Sol/shell/Shell.js +0 -335
  72. package/dist/Sol/wingets/ComputeBootladder.d.ts +0 -6
  73. package/dist/Sol/wingets/ComputeBootladder.js +0 -71
  74. package/dist/Sol/wingets/ComputeModalitycatalog.d.ts +0 -7
  75. package/dist/Sol/wingets/ComputeModalitycatalog.js +0 -71
  76. package/dist/Sol/wingets/ConsoleApibadge.d.ts +0 -7
  77. package/dist/Sol/wingets/ConsoleApibadge.js +0 -5
  78. package/dist/Sol/wingets/ConsoleEdgelaw.d.ts +0 -6
  79. package/dist/Sol/wingets/ConsoleEdgelaw.js +0 -36
  80. package/dist/Sol/wingets/ConsoleEventstimeline.d.ts +0 -19
  81. package/dist/Sol/wingets/ConsoleEventstimeline.js +0 -12
  82. package/dist/Sol/wingets/ConsoleSnapshotcontrols.d.ts +0 -8
  83. package/dist/Sol/wingets/ConsoleSnapshotcontrols.js +0 -8
  84. package/dist/Sol/wingets/ConsoleSpecpanel.d.ts +0 -21
  85. package/dist/Sol/wingets/ConsoleSpecpanel.js +0 -75
  86. package/dist/Sol/wingets/ConsoleTerminal.d.ts +0 -22
  87. package/dist/Sol/wingets/ConsoleTerminal.js +0 -77
  88. package/dist/Sol/wingets/DashboardAccountpanel.d.ts +0 -18
  89. package/dist/Sol/wingets/DashboardAccountpanel.js +0 -65
  90. package/dist/Sol/wingets/DashboardAdminpanel.d.ts +0 -6
  91. package/dist/Sol/wingets/DashboardAdminpanel.js +0 -90
  92. package/dist/Sol/wingets/DashboardAuditlog.d.ts +0 -8
  93. package/dist/Sol/wingets/DashboardAuditlog.js +0 -50
  94. package/dist/Sol/wingets/DashboardCreatesandboxform.d.ts +0 -10
  95. package/dist/Sol/wingets/DashboardCreatesandboxform.js +0 -71
  96. package/dist/Sol/wingets/DashboardEventstimeline.d.ts +0 -8
  97. package/dist/Sol/wingets/DashboardEventstimeline.js +0 -83
  98. package/dist/Sol/wingets/DashboardGlobalsandboxestable.d.ts +0 -8
  99. package/dist/Sol/wingets/DashboardGlobalsandboxestable.js +0 -57
  100. package/dist/Sol/wingets/DashboardMeshnodestable.d.ts +0 -8
  101. package/dist/Sol/wingets/DashboardMeshnodestable.js +0 -103
  102. package/dist/Sol/wingets/DashboardSandboxlist.d.ts +0 -10
  103. package/dist/Sol/wingets/DashboardSandboxlist.js +0 -163
  104. package/dist/Sol/wingets/DashboardUserstable.d.ts +0 -8
  105. package/dist/Sol/wingets/DashboardUserstable.js +0 -78
  106. package/dist/Sol/wingets/HomeEntrygate.d.ts +0 -23
  107. package/dist/Sol/wingets/HomeEntrygate.js +0 -73
  108. package/dist/Sol/wingets/HomeMetricstrip.d.ts +0 -9
  109. package/dist/Sol/wingets/HomeMetricstrip.js +0 -4
  110. package/dist/Sol/wingets/HomeRuntimediagram.d.ts +0 -1
  111. package/dist/Sol/wingets/HomeRuntimediagram.js +0 -22
  112. package/dist/Sol/wingets/LoginForm.d.ts +0 -19
  113. package/dist/Sol/wingets/LoginForm.js +0 -141
  114. package/dist/Sol/wingets/RegisterPasswordconfirm.d.ts +0 -13
  115. package/dist/Sol/wingets/RegisterPasswordconfirm.js +0 -16
  116. package/dist/Sol/wingets/RegisterPasswordmeter.d.ts +0 -19
  117. package/dist/Sol/wingets/RegisterPasswordmeter.js +0 -65
  118. package/dist/Sol/wingets/RegisterUsernamerules.d.ts +0 -11
  119. package/dist/Sol/wingets/RegisterUsernamerules.js +0 -16
  120. package/dist/Sol/wingets/index.d.ts +0 -39
  121. package/dist/Sol/wingets/index.js +0 -39
  122. package/dist/alternatives.d.ts +0 -508
  123. package/dist/alternatives.js +0 -950
  124. package/dist/api.d.ts +0 -154
  125. package/dist/api.js +0 -174
  126. package/dist/auth.d.ts +0 -268
  127. package/dist/auth.js +0 -476
  128. package/dist/automation.d.ts +0 -425
  129. package/dist/automation.js +0 -566
  130. package/dist/browser.d.ts +0 -561
  131. package/dist/browser.js +0 -1058
  132. package/dist/capacitor.config.d.ts +0 -45
  133. package/dist/capacitor.config.js +0 -48
  134. package/dist/catalog.d.ts +0 -43
  135. package/dist/catalog.js +0 -44
  136. package/dist/cli.d.ts +0 -16
  137. package/dist/cli.js +0 -168
  138. package/dist/communication.d.ts +0 -181
  139. package/dist/communication.js +0 -376
  140. package/dist/compute.d.ts +0 -1160
  141. package/dist/compute.js +0 -2272
  142. package/dist/dashboardlib.d.ts +0 -58
  143. package/dist/dashboardlib.js +0 -161
  144. package/dist/db.d.ts +0 -569
  145. package/dist/db.js +0 -1080
  146. package/dist/distribution.d.ts +0 -528
  147. package/dist/distribution.js +0 -810
  148. package/dist/drizzle.config.d.ts +0 -20
  149. package/dist/drizzle.config.js +0 -18
  150. package/dist/edgelandes.d.ts +0 -70
  151. package/dist/edgelandes.host.d.ts +0 -26
  152. package/dist/edgelandes.host.js +0 -1089
  153. package/dist/edgelandes.inproc.d.ts +0 -27
  154. package/dist/edgelandes.inproc.js +0 -952
  155. package/dist/edgelandes.js +0 -1133
  156. package/dist/edgelandes.ninety.d.ts +0 -31
  157. package/dist/edgelandes.ninety.js +0 -174
  158. package/dist/edgelandes.virtual.d.ts +0 -25
  159. package/dist/edgelandes.virtual.js +0 -629
  160. package/dist/edgeplane.d.ts +0 -121
  161. package/dist/edgeplane.js +0 -341
  162. package/dist/examplelocaljob.d.ts +0 -1
  163. package/dist/examplelocaljob.js +0 -14
  164. package/dist/execution.d.ts +0 -529
  165. package/dist/execution.js +0 -760
  166. package/dist/family.d.ts +0 -16
  167. package/dist/family.js +0 -42
  168. package/dist/familyurl.d.ts +0 -21
  169. package/dist/familyurl.js +0 -24
  170. package/dist/format.d.ts +0 -18
  171. package/dist/format.js +0 -59
  172. package/dist/foundation.d.ts +0 -172
  173. package/dist/foundation.js +0 -312
  174. package/dist/index.d.ts +0 -735
  175. package/dist/index.js +0 -1020
  176. package/dist/integration.d.ts +0 -235
  177. package/dist/integration.js +0 -228
  178. package/dist/intelligence.d.ts +0 -93
  179. package/dist/intelligence.js +0 -144
  180. package/dist/isolation.d.ts +0 -128
  181. package/dist/isolation.js +0 -95
  182. package/dist/labels.d.ts +0 -665
  183. package/dist/labels.js +0 -707
  184. package/dist/localauth.d.ts +0 -127
  185. package/dist/localauth.js +0 -413
  186. package/dist/media.d.ts +0 -343
  187. package/dist/media.js +0 -985
  188. package/dist/mesh.d.ts +0 -177
  189. package/dist/mesh.js +0 -468
  190. package/dist/modalityregistry.d.ts +0 -109
  191. package/dist/modalityregistry.js +0 -1386
  192. package/dist/modes.d.ts +0 -358
  193. package/dist/modes.js +0 -133
  194. package/dist/onboardingstate.d.ts +0 -79
  195. package/dist/onboardingstate.js +0 -282
  196. package/dist/orchestrator.d.ts +0 -1338
  197. package/dist/orchestrator.js +0 -4310
  198. package/dist/packager/targetcli.js +0 -4
  199. package/dist/paths.d.ts +0 -2
  200. package/dist/paths.js +0 -14
  201. package/dist/performance.d.ts +0 -415
  202. package/dist/performance.js +0 -826
  203. package/dist/quantum.d.ts +0 -809
  204. package/dist/quantum.js +0 -2072
  205. package/dist/render.d.ts +0 -380
  206. package/dist/render.js +0 -1072
  207. package/dist/runall.d.ts +0 -2
  208. package/dist/runall.js +0 -39
  209. package/dist/runtimeprobe.d.ts +0 -4
  210. package/dist/runtimeprobe.js +0 -8
  211. package/dist/sandbox.d.ts +0 -355
  212. package/dist/sandbox.js +0 -1721
  213. package/dist/sandboxenvprofile.d.ts +0 -29
  214. package/dist/sandboxenvprofile.js +0 -89
  215. package/dist/sandboxprofile.d.ts +0 -137
  216. package/dist/sandboxprofile.js +0 -241
  217. package/dist/sandboxqueue.d.ts +0 -108
  218. package/dist/sandboxqueue.js +0 -201
  219. package/dist/sandboxquota.d.ts +0 -121
  220. package/dist/sandboxquota.js +0 -236
  221. package/dist/scheduler.d.ts +0 -595
  222. package/dist/scheduler.js +0 -1258
  223. package/dist/scriptlanes.d.ts +0 -182
  224. package/dist/scriptlanes.js +0 -660
  225. package/dist/scripts.buildengine.d.ts +0 -1
  226. package/dist/scripts.buildengine.js +0 -39
  227. package/dist/scripts.securitygate.d.ts +0 -1
  228. package/dist/scripts.securitygate.js +0 -68
  229. package/dist/scripts.validateflatnative.d.ts +0 -1
  230. package/dist/scripts.validateflatnative.js +0 -72
  231. package/dist/security.d.ts +0 -500
  232. package/dist/security.js +0 -1169
  233. package/dist/seedcatalog.d.ts +0 -13
  234. package/dist/seedcatalog.js +0 -46
  235. package/dist/server.d.ts +0 -20
  236. package/dist/server.js +0 -53
  237. package/dist/speccatalog.d.ts +0 -31
  238. package/dist/speccatalog.js +0 -163
  239. package/dist/tiers.d.ts +0 -1001
  240. package/dist/tiers.js +0 -2169
  241. package/dist/utils.d.ts +0 -2
  242. package/dist/utils.js +0 -5
  243. package/dist/vaulthandoff.d.ts +0 -141
  244. package/dist/vaulthandoff.js +0 -444
  245. package/dist/virtual.d.ts +0 -640
  246. package/dist/virtual.js +0 -1284
  247. package/dist/virtualcpu.d.ts +0 -315
  248. package/dist/virtualcpu.js +0 -1180
  249. package/dist/virtualgpu.d.ts +0 -344
  250. package/dist/virtualgpu.js +0 -1000
  251. package/dist/virtualization.d.ts +0 -606
  252. package/dist/virtualization.js +0 -1186
  253. package/dist/virtualmemory.d.ts +0 -817
  254. package/dist/virtualmemory.js +0 -1795
  255. package/dist/vite.config.d.ts +0 -3
  256. package/dist/vite.config.js +0 -48
  257. package/dist/vitest.config.d.ts +0 -2
  258. package/dist/vitest.config.js +0 -25
  259. package/dist/webserver.d.ts +0 -166
  260. package/dist/webserver.js +0 -2226
  261. package/dist/workloadlaw.d.ts +0 -133
  262. package/dist/workloadlaw.js +0 -193
  263. package/manifest.json +0 -20
  264. package/media.ts +0 -1337
  265. /package/docs/{architecture.1.8.19.md → architecture1819.md} +0 -0
  266. /package/docs/{architecture.1.8.19.mmd → architecture1819.mmd} +0 -0
  267. /package/docs/{artifactresearch.1.8.9.md → artifactresearch189.md} +0 -0
  268. /package/docs/{batches.1816.to.1820.md → batches1816to1820.md} +0 -0
  269. /package/docs/{brancharchive.2026.08.18.md → brancharchive20260818.md} +0 -0
  270. /package/docs/{containerplatforms.1.8.17.md → containerplatforms1817.md} +0 -0
  271. /package/docs/{e2ugh.engine.md → e2ughengine.md} +0 -0
  272. /package/docs/{flatbuildresearch.1.8.11.md → flatbuildresearch1811.md} +0 -0
  273. /package/docs/{licenseaudit.1.8.12.md → licenseaudit1812.md} +0 -0
  274. /package/docs/{mobileconversionresearch.1.8.10.md → mobileconversionresearch1810.md} +0 -0
  275. /package/docs/{nativeidentityresearch.1.8.11.md → nativeidentityresearch1811.md} +0 -0
  276. /package/docs/{native.wrappers.md → nativewrappers.md} +0 -0
  277. /package/docs/{planning.1.8.18.md → planning1818.md} +0 -0
  278. /package/docs/{planning.1.8.19.md → planning1819.md} +0 -0
  279. /package/docs/{planning.engine.md → planningengine.md} +0 -0
  280. /package/docs/{releasenotes.1.8.12.md → releasenotes1812.md} +0 -0
  281. /package/docs/{releasenotes.1.8.15.md → releasenotes1815.md} +0 -0
  282. /package/docs/{releasenotes.1.8.16.md → releasenotes1816.md} +0 -0
  283. /package/docs/{releasenotes.1.8.17.md → releasenotes1817.md} +0 -0
  284. /package/docs/{releasenotes.1.8.18.md → releasenotes1818.md} +0 -0
  285. /package/docs/{releasenotes.1.8.19.md → releasenotes1819.md} +0 -0
  286. /package/docs/{reorganization.1.8.8.md → reorganization188.md} +0 -0
  287. /package/docs/{reorganization.1.8.9.md → reorganization189.md} +0 -0
  288. /package/docs/{repo.analysis.1.8.21.json → repoanalysis1821.json} +0 -0
  289. /package/docs/{repo.candidates.1.8.21.jsonl → repocandidates1821.jsonl} +0 -0
  290. /package/docs/{repo.research.1.8.16.md → reporesearch1816.md} +0 -0
  291. /package/docs/{repo.research.1.8.21.md → reporesearch1821.md} +0 -0
  292. /package/docs/{repo.selected.1.8.21.json → reposelected1821.json} +0 -0
  293. /package/docs/{repo.synthesis.1.8.21.md → reposynthesis1821.md} +0 -0
  294. /package/docs/{research.1.8.18.isolation.md → research1818isolation.md} +0 -0
  295. /package/docs/{research.1.8.19.virtual.browser.md → research1819virtualbrowser.md} +0 -0
  296. /package/docs/{scanningresearch.1.8.11.md → scanningresearch1811.md} +0 -0
  297. /package/docs/{securityaudit.1.8.7.md → securityaudit187.md} +0 -0
  298. /package/docs/{securityreferences.1.8.11.md → securityreferences1811.md} +0 -0
  299. /package/docs/{securityresearch.1.8.11.md → securityresearch1811.md} +0 -0
  300. /package/docs/{signingresearch.1.8.12.md → signingresearch1812.md} +0 -0
  301. /package/docs/{tauri.glib.risk.1.8.11.md → tauriglibrisk1811.md} +0 -0
  302. /package/docs/{todo.1.8.18.md → todo1818.md} +0 -0
  303. /package/docs/{todo.1.8.19.md → todo1819.md} +0 -0
  304. /package/docs/{toolchainresearch.1.8.9.md → toolchainresearch189.md} +0 -0
  305. /package/docs/{web.duplicatecleanup.md → webduplicatecleanup.md} +0 -0
  306. /package/docs/{web.ideas.md → webideas.md} +0 -0
  307. /package/docs/{workflowimprovements.2026.08.19.md → workflowimprovements20260819.md} +0 -0
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; });