@wenathlan/saddle 2.0.163 → 2.0.165

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.165 — 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
@@ -16,9 +16,9 @@
16
16
  # THE THREE VARIANT PROFILES (the saddle-exclusive law: the only app of
17
17
  # the family that ships three) — select with the target flag:
18
18
  #
19
- # docker build --target max -t saddle:2.0.162 .
20
- # docker build --target balanced -t saddle:2.0.162-balanced .
21
- # docker build --target lite -t saddle:2.0.162-lite .
19
+ # docker build --target max -t saddle:2.0.164 .
20
+ # docker build --target balanced -t saddle:2.0.164-balanced .
21
+ # docker build --target lite -t saddle:2.0.164-lite .
22
22
  #
23
23
  # max — the full profile catalog: the epyc 9965 class, 192 vcpu,
24
24
  # 384 threads, 1024 gib ram plan, the b200 gpu plan x8.
@@ -61,16 +61,41 @@
61
61
  # is the sandbox spec surface the console answers, never a host
62
62
  # distribution this container installs.
63
63
  #
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
+ #
64
87
  # THE ELEVEN-ARCHITECTURE PLATFORM STANDARD (the pr15 law): every
65
88
  # profile answers the eleven architecture seats the container standard
66
89
  # names — the CONTAINERARCHIDS of saddle/containerarch.ts (linux-x64,
67
90
  # darwin-arm64, windows-x64, linux-arm64, darwin-x64, windows-arm64,
68
91
  # linux-x64-musl, linux-riscv64, wasm32, darwin-arm64-v8,
69
- # windows-x64-gnu). The build legs follow the container-carried seats
70
- # the pinned node base honestly answers: the amd64 leg serves linux-x64
71
- # and linux-x64-musl, the arm64 leg serves linux-arm64, and the arm64/v8
72
- # leg serves the darwin-arm64-v8 abi seat (the arm64 legs ride qemu
73
- # emulation in the publish workflow). The linux-riscv64 seat the
92
+ # windows-x64-gnu). The build legs follow the four base-carried legs
93
+ # the pinned node base honestly answers (the go-style build index of
94
+ # containerarch.ts): the amd64 leg serves linux-x64 and linux-x64-musl,
95
+ # the arm64 leg serves linux-arm64 and the darwin-arm64-v8 abi seat
96
+ # through its v8 variant, and the ppc64le and s390x legs ride the
97
+ # go-style build index under qemu emulation in the publish workflow.
98
+ # The linux-riscv64 seat the
74
99
  # containerarch standard carries on the bash:5 driver base answers the
75
100
  # honest coded absence on this node engine base (the pinned base ships
76
101
  # no riscv64 manifest), and the six target seats (the darwin and
@@ -118,7 +143,7 @@ ARG NODE_BASE_DIGEST
118
143
  # ===== stage: solbuild — the locked npm tree and the console spa =====
119
144
  FROM --platform=$BUILDPLATFORM ${NODE_BASE_TAG}@sha256:${NODE_BASE_DIGEST} AS solbuild
120
145
 
121
- ARG SADDLE_VERSION=2.0.162
146
+ ARG SADDLE_VERSION=2.0.165
122
147
 
123
148
  WORKDIR /app
124
149
 
@@ -146,7 +171,7 @@ RUN npm run web:build:pages \
146
171
  # ===== stage: base — the hardened runtime floor every profile shares =====
147
172
  FROM ${NODE_BASE_TAG}@sha256:${NODE_BASE_DIGEST} AS base
148
173
 
149
- ARG SADDLE_VERSION=2.0.162
174
+ ARG SADDLE_VERSION=2.0.165
150
175
  # the revision stamp the devthink container carries (DEVTHINK_REVISION
151
176
  # there): the publish legs pass the release sha at build time and the
152
177
  # revision label below declares the default-unknown local shape.
@@ -194,17 +219,19 @@ ENV NODE_ENV=production \
194
219
 
195
220
  # the arch-leg guard of the eleven-architecture standard: the pinned
196
221
  # node base resolves the platform of every leg buildx names, and this
197
- # echo layer stamps the honesty law into the build log — the two arches
198
- # the base carries answer their leg line (the amd64 leg serves the
199
- # linux-x64 and linux-x64-musl seats, the arm64 leg serves the
222
+ # echo layer stamps the honesty law into the build log — the four
223
+ # arches the base carries answer their leg line (the amd64 leg serves
224
+ # the linux-x64 and linux-x64-musl seats, the arm64 leg serves the
200
225
  # linux-arm64 seat and the darwin-arm64-v8 abi seat through its v8
201
- # variant), the legacy builder (no platform axis) answers its documented
226
+ # variant, the ppc64le and s390x legs ride the go-style build index of
227
+ # the containerarch table under qemu emulation), the legacy builder
228
+ # (no platform axis) answers its documented
202
229
  # note, and any other arch answers the coded refusal before the heavy
203
230
  # steps below could run (buildx itself fails such a leg at base
204
231
  # resolution first; the guard keeps the law loud on every builder).
205
232
  RUN case "${TARGETARCH:-}" in \
206
- amd64|arm64) \
207
- 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)" ;; \
233
+ amd64|arm64|ppc64le|s390x) \
234
+ echo "arch leg ${TARGETARCH} of ${TARGETPLATFORM:-<unresolved>}: one of the four arches the pinned node base carries — the build legs of the eleven-architecture standard (linux-x64 and linux-x64-musl on amd64, linux-arm64 and the darwin-arm64-v8 abi seat on arm64, the ppc64le and s390x go-style build-index legs under qemu emulation)" ;; \
208
235
  "") \
209
236
  echo "arch leg unresolved: the legacy builder carries no platform axis; buildkit answers TARGETARCH per leg" ;; \
210
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.163 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.165 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/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; });