@wenathlan/saddle 2.0.162 → 2.0.164

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 CHANGED
@@ -1,4 +1,4 @@
1
- # saddle 2.0.162 — THE ENGINE CONTAINER FILE
1
+ # saddle 2.0.163 — THE ENGINE CONTAINER FILE
2
2
  #
3
3
  # THE FAMILY CONTAINER DOCTRINE, THE SADDLE SHAPE: one versioned container
4
4
  # per engine, built like the site homes (argan, cadria) build theirs — a
@@ -61,20 +61,46 @@
61
61
  # is the sandbox spec surface the console answers, never a host
62
62
  # distribution this container installs.
63
63
  #
64
- # THE ELEVEN-ARCHITECTURE PLATFORM STANDARD (the pr15b law): every
65
- # profile answers the eleven architectures the container standard names —
66
- # the CONTAINERARCHIDS of saddle/containerarch.ts: x64, arm64, armv7,
67
- # riscv64, ppc64le, s390x, 386, mips64le, loong64, wasm32, wasip1 (the
68
- # wasm pair rides the oci artifact shapes wasm32/wasip1 and wasip1/wasm
69
- # the wasm runtimes consume). The build legs follow the pinned node
70
- # base's honest manifest list — the four linux seats it carries
71
- # (linux/amd64 the native x64 leg; linux/arm64, linux/ppc64le and
72
- # linux/s390x ride qemu emulation in the publish workflow). The seven
73
- # seats the node base does not ship (armv7, riscv64, 386, mips64le,
74
- # loong64 and the wasm pair) answer the standard's honest coded absence
75
- # (ARCH_IMAGE_ABSENT), never a pretended build leg — the same honesty
76
- # law the containerarch table keeps for its own pinned base: a leg
77
- # never claims a manifest the base does not carry. The base stage
64
+ # THE OS DISTRIBUTION SEATS the saddle container carries (the osdistrib
65
+ # law, saddle/containerarch.ts — the owner's sentence: "iniciar
66
+ # distribuição do container saddle com por exemplo, grapheneos, omarchy
67
+ # e outros sistemas dentro do saddle"): the container starts its
68
+ # distribution catalog with the seven system seats the OSDISTRIBUTIONS
69
+ # registry pins — grapheneos (a privacy and security hardened version of
70
+ # android), omarchy (the arch linux-based distribution created by dhh),
71
+ # vanilla os (based on ubuntu), maru os (firmware, not an application),
72
+ # the v seat (the vlang platform the dependency catalog pins at 0.5.2,
73
+ # never a guest distribution), the normal linux baseline and android —
74
+ # every seat paired with the architecture legs the eleven-architecture
75
+ # standard already carries (the mobile and firmware seats ride the arm64
76
+ # legs, the desktop and baseline seats ride amd64 and arm64) and bound
77
+ # to the max/balanced/lite engine plan trio the engineplans table owns.
78
+ # The distribution matrix needs NO new build legs: the seats ride the
79
+ # existing arch axis of this file (the amd64 and arm64 legs the pinned
80
+ # base already resolves), so the publish lanes and the build matrix stay
81
+ # untouched — the registry is the catalog the container lanes stamp and
82
+ # the modality system reads (saddle/docs/osdistributions.md). The
83
+ # 50gb-per-plan example the owner's law names stays PLAN CONFIG the
84
+ # devthink plan logic stamps, never a container cap: the engines are
85
+ # unlimited.
86
+ #
87
+ # THE ELEVEN-ARCHITECTURE PLATFORM STANDARD (the pr15 law): every
88
+ # profile answers the eleven architecture seats the container standard
89
+ # names — the CONTAINERARCHIDS of saddle/containerarch.ts (linux-x64,
90
+ # darwin-arm64, windows-x64, linux-arm64, darwin-x64, windows-arm64,
91
+ # linux-x64-musl, linux-riscv64, wasm32, darwin-arm64-v8,
92
+ # windows-x64-gnu). The build legs follow the container-carried seats
93
+ # the pinned node base honestly answers: the amd64 leg serves linux-x64
94
+ # and linux-x64-musl, the arm64 leg serves linux-arm64, and the arm64/v8
95
+ # leg serves the darwin-arm64-v8 abi seat (the arm64 legs ride qemu
96
+ # emulation in the publish workflow). The linux-riscv64 seat the
97
+ # containerarch standard carries on the bash:5 driver base answers the
98
+ # honest coded absence on this node engine base (the pinned base ships
99
+ # no riscv64 manifest), and the six target seats (the darwin and
100
+ # windows seats and wasm32) answer the standard's honest coded absence
101
+ # (ARCH_TARGET_NOT_CONTAINER), never a pretended build leg — the same
102
+ # honesty law the containerarch table keeps for its own pinned base: a
103
+ # leg never claims a manifest the base does not carry. The base stage
78
104
  # declares the TARGETPLATFORM/TARGETARCH automatic build-args (the
79
105
  # devthink container's standard arch interface) and stamps the honesty
80
106
  # law into the build log with its arch guard: a leg the base carries
@@ -115,7 +141,7 @@ ARG NODE_BASE_DIGEST
115
141
  # ===== stage: solbuild — the locked npm tree and the console spa =====
116
142
  FROM --platform=$BUILDPLATFORM ${NODE_BASE_TAG}@sha256:${NODE_BASE_DIGEST} AS solbuild
117
143
 
118
- ARG SADDLE_VERSION=2.0.162
144
+ ARG SADDLE_VERSION=2.0.163
119
145
 
120
146
  WORKDIR /app
121
147
 
@@ -143,7 +169,7 @@ RUN npm run web:build:pages \
143
169
  # ===== stage: base — the hardened runtime floor every profile shares =====
144
170
  FROM ${NODE_BASE_TAG}@sha256:${NODE_BASE_DIGEST} AS base
145
171
 
146
- ARG SADDLE_VERSION=2.0.162
172
+ ARG SADDLE_VERSION=2.0.163
147
173
  # the revision stamp the devthink container carries (DEVTHINK_REVISION
148
174
  # there): the publish legs pass the release sha at build time and the
149
175
  # revision label below declares the default-unknown local shape.
@@ -191,19 +217,21 @@ ENV NODE_ENV=production \
191
217
 
192
218
  # the arch-leg guard of the eleven-architecture standard: the pinned
193
219
  # node base resolves the platform of every leg buildx names, and this
194
- # echo layer stamps the honesty law into the build log — the four seats
195
- # the base carries answer their leg line, the legacy builder (no
196
- # platform axis) answers its documented note, and any other seat answers
197
- # the coded refusal before the heavy steps below could run (buildx
198
- # itself fails such a leg at base resolution first; the guard keeps the
199
- # law loud on every builder).
220
+ # echo layer stamps the honesty law into the build log — the two arches
221
+ # the base carries answer their leg line (the amd64 leg serves the
222
+ # linux-x64 and linux-x64-musl seats, the arm64 leg serves the
223
+ # linux-arm64 seat and the darwin-arm64-v8 abi seat through its v8
224
+ # variant), the legacy builder (no platform axis) answers its documented
225
+ # note, and any other arch answers the coded refusal before the heavy
226
+ # steps below could run (buildx itself fails such a leg at base
227
+ # resolution first; the guard keeps the law loud on every builder).
200
228
  RUN case "${TARGETARCH:-}" in \
201
- amd64|arm64|ppc64le|s390x) \
202
- echo "arch leg ${TARGETARCH} of ${TARGETPLATFORM:-<unresolved>}: one of the four seats the pinned node base carries of the eleven-architecture standard" ;; \
229
+ amd64|arm64) \
230
+ echo "arch leg ${TARGETARCH} of ${TARGETPLATFORM:-<unresolved>}: one of the two arches the pinned node base carries — the legs of the container-carried seats of the eleven-architecture standard (linux-x64 and linux-x64-musl on amd64, linux-arm64 and the darwin-arm64-v8 abi seat on arm64)" ;; \
203
231
  "") \
204
232
  echo "arch leg unresolved: the legacy builder carries no platform axis; buildkit answers TARGETARCH per leg" ;; \
205
233
  *) \
206
- echo "the eleven-architecture standard answers the ${TARGETARCH} seat with the honest coded absence (ARCH_IMAGE_ABSENT): the pinned node base carries no such manifest" >&2; \
234
+ echo "the eleven-architecture standard answers the ${TARGETARCH} arch with the honest coded absence (ARCH_TARGET_NOT_CONTAINER for the target seats, ARCH_IMAGE_ABSENT for the riscv64 seat the node engine base does not ship): the pinned node base carries no such manifest" >&2; \
207
235
  exit 1 ;; \
208
236
  esac
209
237
 
package/README.md CHANGED
@@ -31,7 +31,7 @@ domain modules land beside the saddle domains:
31
31
  | `media.ts`, `render.ts`, `quantum.ts`, `tiers.ts` | media pipeline, GPU registry, quantum simulation, tier policy |
32
32
  | `security.ts`, `alternatives.ts` | hardening gates and the alternative-stack catalog |
33
33
  | `index.html`, `App.tsx`, `sol/` | the single SPA shell and the Sol theme (one tsx app with one stylesheet per theme) |
34
- | `server.ts`, `sandbox.ts` | the zero-dependency self-hosted API of the 2.0.162 grand-merge envelope (`node server.ts`; the api answers its version at `/api/v1/health`) and the browser-pure engine port |
34
+ | `server.ts`, `sandbox.ts` | the zero-dependency self-hosted API of the 2.0.164 grand-merge envelope (`node server.ts`; the api answers its version at `/api/v1/health`) and the browser-pure engine port |
35
35
  | `vercel.json`, `netlify.toml` | the platform deploy adapters beside the surface they publish (the caddy ghost stays out of the tree) |
36
36
  | `specs/*` package exports | processors, gpus, cores, boards and the qemu/mttg/passage/docker envelopes |
37
37
 
package/biome.jsonc CHANGED
File without changes
package/cli.ts CHANGED
@@ -14,7 +14,8 @@
14
14
  import { mkdtemp, readFile } from "node:fs/promises";
15
15
  import { tmpdir } from "node:os";
16
16
  import { join } from "node:path";
17
- import { argv } from "node:process";
17
+ import { argv, stdin, stdout } from "node:process";
18
+ import { createInterface } from "node:readline/promises";
18
19
  import { eventbus } from "./foundation.ts";
19
20
  import { localmemory, localstorage } from "./virtual.ts";
20
21
  import { engine, inprocess, scheduler } from "./execution.ts";
@@ -44,7 +45,8 @@ import {
44
45
  export async function main(args = argv.slice(2)) {
45
46
  const command = args[0] ?? "help";
46
47
  /* 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 (["help", "--help", "-h"].includes(command)) { console.log("saddle <command>\n\ncommands\n help\n chat\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; }
49
+ if (command === "chat") { await renderchat(); return; }
48
50
  if (command === "modes") { console.log(JSON.stringify(modecatalog(), null, 2)); return; }
49
51
  if (command === "plan") { await renderplan(args[1]); return; }
50
52
  /* The vm/vmlint/gpus triad makes the nominal npm aliases (vm:create, */
@@ -271,4 +273,99 @@ async function renderscript(subcommand = "help", target = "") {
271
273
  }
272
274
  }
273
275
 
276
+ /* ════════════════════════════════════════════════════════════════════ */
277
+ /* Section 4: the chat console — the pr13 creation workspace seat: the */
278
+ /* same windows 11 chat console the family clibin seats render, with */
279
+ /* the same tokens, the same titlebar and the same dpi ladder (native */
280
+ /* detection, 1x / 1.5x / 2x / 3x, never xdpi — the difference from */
281
+ /* the web / desktop surface is only the responsiveness). */
282
+ /* ════════════════════════════════════════════════════════════════════ */
283
+
284
+ /** the chat accent of the prompt and the titlebar name (ansi 117 — the family accent #a3d7e6). */
285
+ const CHATACCENT = "\x1b[38;5;117m" as const;
286
+ /** the focus ink of the active top rule (ansi 75 — the family focus #4cc2ff). */
287
+ const CHATFOCUS = "\x1b[38;5;75m" as const;
288
+ /** the hover red of the unknown-command rows (ansi 203 — rgb(232, 17, 35)). */
289
+ const CHATHOVER = "\x1b[38;5;203m" as const;
290
+ /** the dim ink of the description rows (the minimal text law). */
291
+ const CHATINK = "\x1b[2m" as const;
292
+ /** the reset token that closes every colored run. */
293
+ const CHATRESET = "\x1b[0m" as const;
294
+ /** the single glyph of the rules and the rails. */
295
+ const CHATBAR = "─" as const;
296
+ /** the engine ownership one-liner of the seat, quoted from the README. */
297
+ const CHATENGINE = "storage-backed jobs, ninety sandbox modalities and portable runners — the master engine of virtualization (README)" as const;
298
+ /** the scale ladder the native detection resolves (the automatic scaling law). */
299
+ const CHATSCALESTEPS = [1, 1.5, 2, 3] as const;
300
+
301
+ /** the dpi frame the chat chrome renders inside: the resolved scale seat, the terminal columns and the rail length the titlebar draws. */
302
+ interface chatframe {
303
+ /** the scale seat of the ladder (1, 1.5, 2 or 3). */
304
+ scale: number;
305
+ /** the columns the terminal answers (windows terminal, conpty, xterm, tmux — every pty reports them). */
306
+ columns: number;
307
+ /** the titlebar rail length in cells (the pixel rail folded to the grid and clamped so the line never wraps). */
308
+ rail: number;
309
+ }
310
+
311
+ /** resolves the dpi frame natively, zero dependencies: the columns come from stdout (every windows and linux terminal answers them), the scale seat from the column ladder — the explicit SADDLE_DPI environment override wins first (the native scaling knob). */
312
+ function chatdetectframe(): chatframe {
313
+ const columns = Number.isFinite(stdout.columns) && Number(stdout.columns) > 0 ? Number(stdout.columns) : 80;
314
+ const override = Number(process.env.SADDLE_DPI ?? "");
315
+ const scale =
316
+ Number.isFinite(override) && override > 0 && CHATSCALESTEPS.includes(override as (typeof CHATSCALESTEPS)[number])
317
+ ? override
318
+ : columns >= 200
319
+ ? 3
320
+ : columns >= 160
321
+ ? 2
322
+ : columns >= 120
323
+ ? 1.5
324
+ : 1;
325
+ const rail = Math.max(4, Math.min(Math.round(24 * scale), columns - "saddle".length - 16));
326
+ return { scale, columns, rail };
327
+ }
328
+
329
+ /** runs the chat console: the titlebar, the top rule, the ❯ prompt and the dispatch (help, version, dpi, engine, exit) — the same chat look the web / desktop surfaces carry, an eof on stdin closing the console the same way exit does. */
330
+ async function renderchat(): Promise<void> {
331
+ const frame = chatdetectframe();
332
+ let seatversion = "0.0.0";
333
+ try {
334
+ seatversion = String((JSON.parse(await readFile(new URL("./package.json", import.meta.url), "utf8")) as { version?: string }).version ?? "0.0.0");
335
+ } catch {
336
+ /* the guarded best-effort read answers the zero literal the version row prints */
337
+ }
338
+ const rl = createInterface({ input: stdin, output: stdout });
339
+ let eof = false;
340
+ rl.on("close", () => { eof = true; });
341
+ const rule = CHATBAR.repeat(Math.max(3, Math.round(3 * frame.scale)));
342
+ console.log(`${CHATACCENT}┌ saddle ─ cli${CHATRESET} ${CHATINK}${CHATBAR.repeat(frame.rail)} ─ ❐ ✕${CHATRESET}`);
343
+ console.log(`${CHATFOCUS}${rule} saddle ${rule}${CHATRESET}`);
344
+ console.log(`${CHATACCENT}saddle${CHATRESET} ${CHATINK}v${seatversion}${CHATRESET}`);
345
+ console.log(`${CHATINK}the saddle console — same design as web / desktop, only the DPI differs. type help.${CHATRESET}`);
346
+ rl.setPrompt(`${CHATACCENT}❯${CHATRESET} `);
347
+ rl.prompt();
348
+ for await (const raw of rl) {
349
+ const line = raw.trim();
350
+ const command = line.length > 0 ? line.split(/\s+/)[0]!.toLowerCase() : "";
351
+ if (command === "exit") rl.close();
352
+ else if (command === "help") {
353
+ console.log(`${CHATINK}commands${CHATRESET}`);
354
+ console.log(` help ${CHATINK}this list${CHATRESET}`);
355
+ console.log(` version ${CHATINK}the package version, read from package.json at runtime${CHATRESET}`);
356
+ console.log(` dpi ${CHATINK}the resolved dpi seat of this terminal (scale, columns, rail)${CHATRESET}`);
357
+ console.log(` engine ${CHATINK}the engine ownership one-liner of the app${CHATRESET}`);
358
+ console.log(` exit ${CHATINK}close the console${CHATRESET}`);
359
+ }
360
+ else if (command === "version") console.log(`${CHATACCENT}saddle${CHATRESET} ${seatversion}`);
361
+ else if (command === "dpi") console.log(`${CHATACCENT}saddle${CHATRESET} ${CHATINK}dpi seat ${frame.scale}x on ${frame.columns} columns — rail ${frame.rail} cells, ladder 1x / 1.5x / 2x / 3x${CHATRESET}`);
362
+ else if (command === "engine") console.log(`${CHATINK}${CHATENGINE}${CHATRESET}`);
363
+ else if (command.length > 0) console.log(`${CHATHOVER}✕${CHATRESET} ${CHATINK}unknown command: ${command} — type help${CHATRESET}`);
364
+ if (command === "exit") break;
365
+ /* the prompt is cosmetic chrome: a piped stdin that already reached eof skips it, the buffered lines still answer. */
366
+ if (!eof) rl.prompt();
367
+ }
368
+ console.log(`${CHATINK}saddle console closed.${CHATRESET}`);
369
+ }
370
+
274
371
  if (import.meta.url === `file://${argv[1]}`) main().catch((error) => { console.error(error); process.exitCode = 1; });