@ultimat3/cli 15.0.0 → 17.0.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultimat3/cli",
3
- "version": "15.0.0",
3
+ "version": "17.0.0",
4
4
  "description": "The `x` binary: new, dev, build, verify, generate, db, mcp, doctor, deploy",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,34 +37,34 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@babel/core": "^7.28.4",
40
- "@ultimat3/action": "15.0.0",
41
- "@ultimat3/admin": "15.0.0",
42
- "@ultimat3/ai": "15.0.0",
43
- "@ultimat3/auth": "15.0.0",
44
- "@ultimat3/cache": "15.0.0",
45
- "@ultimat3/core": "15.0.0",
46
- "@ultimat3/db": "15.0.0",
47
- "@ultimat3/entity": "15.0.0",
48
- "@ultimat3/flags": "15.0.0",
49
- "@ultimat3/http": "15.0.0",
50
- "@ultimat3/i18n": "15.0.0",
51
- "@ultimat3/jobs": "15.0.0",
52
- "@ultimat3/mail": "15.0.0",
53
- "@ultimat3/manifest": "15.0.0",
54
- "@ultimat3/mcp": "15.0.0",
55
- "@ultimat3/money": "15.0.0",
56
- "@ultimat3/notify": "15.0.0",
57
- "@ultimat3/policy": "15.0.0",
58
- "@ultimat3/pwa": "15.0.0",
59
- "@ultimat3/query": "15.0.0",
60
- "@ultimat3/realtime": "15.0.0",
61
- "@ultimat3/render": "15.0.0",
62
- "@ultimat3/schema": "15.0.0",
63
- "@ultimat3/scraping": "15.0.0",
64
- "@ultimat3/seo": "15.0.0",
65
- "@ultimat3/storage": "15.0.0",
66
- "@ultimat3/testing": "15.0.0",
67
- "@ultimat3/time": "15.0.0",
40
+ "@ultimat3/action": "17.0.0",
41
+ "@ultimat3/admin": "17.0.0",
42
+ "@ultimat3/ai": "17.0.0",
43
+ "@ultimat3/auth": "17.0.0",
44
+ "@ultimat3/cache": "17.0.0",
45
+ "@ultimat3/core": "17.0.0",
46
+ "@ultimat3/db": "17.0.0",
47
+ "@ultimat3/entity": "17.0.0",
48
+ "@ultimat3/flags": "17.0.0",
49
+ "@ultimat3/http": "17.0.0",
50
+ "@ultimat3/i18n": "17.0.0",
51
+ "@ultimat3/jobs": "17.0.0",
52
+ "@ultimat3/mail": "17.0.0",
53
+ "@ultimat3/manifest": "17.0.0",
54
+ "@ultimat3/mcp": "17.0.0",
55
+ "@ultimat3/money": "17.0.0",
56
+ "@ultimat3/notify": "17.0.0",
57
+ "@ultimat3/policy": "17.0.0",
58
+ "@ultimat3/pwa": "17.0.0",
59
+ "@ultimat3/query": "17.0.0",
60
+ "@ultimat3/realtime": "17.0.0",
61
+ "@ultimat3/render": "17.0.0",
62
+ "@ultimat3/schema": "17.0.0",
63
+ "@ultimat3/scraping": "17.0.0",
64
+ "@ultimat3/seo": "17.0.0",
65
+ "@ultimat3/storage": "17.0.0",
66
+ "@ultimat3/testing": "17.0.0",
67
+ "@ultimat3/time": "17.0.0",
68
68
  "babel-preset-solid": "^1.9.15"
69
69
  }
70
70
  }
package/src/dev-roles.ts CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  configuredHttp,
15
15
  createServer,
16
16
  defineHttpConfig,
17
+ MAX_PROXY_HOPS,
17
18
  mergeHttpConfig,
18
19
  } from '@ultimat3/http';
19
20
  import type { OutboxRelay, Scheduler, Worker } from '@ultimat3/jobs';
@@ -188,6 +189,23 @@ function warnIfUnauthenticatable(routes: readonly Route[]): void {
188
189
  );
189
190
  }
190
191
 
192
+ /**
193
+ * How many proxies is too many, and the number is **`@ultimat3/http`'s**, not this file's.
194
+ *
195
+ * `defineHttpConfig` screens the same setting — `assertFiniteCount('trustedProxyHops', …,
196
+ * MAX_PROXY_HOPS)` — and this screen used to say 16 where that one says 64, so one setting had two
197
+ * ceilings and a deployment behind 20 hops was accepted by the library and refused by the boot.
198
+ * Widened rather than narrowed: tightening the library would break a shipped public API, while
199
+ * this end only ever refused topologies http already supports.
200
+ *
201
+ * It was a duplicated literal until 2026-08-26, because `@ultimat3/http` did not export the
202
+ * constant. It does now, so this file IMPORTS it — a downward edge, tier 5 to tier 2 — and there is
203
+ * no second number left to drift. `runtime-overrides.test.ts` still probes both screens for the
204
+ * highest count each accepts, and it is kept rather than deleted: it compares BEHAVIOUR, so it also
205
+ * catches the two disagreeing for a reason a shared constant cannot fix, such as one side gaining a
206
+ * range check the other does not have.
207
+ */
208
+
191
209
  /**
192
210
  * How many proxies append to `x-forwarded-for` between the client and this process, or `null`
193
211
  * when nothing in front of it is trusted.
@@ -207,7 +225,7 @@ export function trustedHopsFromEnv(env: Env): number | null {
207
225
  const hops = Number(raw);
208
226
  // A malformed count is refused rather than defaulted: reading the header at the wrong index is
209
227
  // trusting a value the client typed, which is the failure trusting a proxy exists to avoid.
210
- if (!Number.isInteger(hops) || hops < 1 || hops > 16) {
228
+ if (!Number.isInteger(hops) || hops < 1 || hops > MAX_PROXY_HOPS) {
211
229
  throw new PortInvalidError({ value: raw, name: 'TRUSTED_PROXY_HOPS' });
212
230
  }
213
231
  return hops;
package/src/dev-traces.ts CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  import type { RequestTrace, SpanKind, TimelineSpan } from '@ultimat3/admin/dev';
7
7
  import type { ReadableSpan, SpanExporter } from '@ultimat3/core';
8
+ import { finiteCount } from '@ultimat3/core';
8
9
  // The attribute name is `@ultimat3/db`'s to declare — this reads it rather than restating it, so
9
10
  // renaming it there is a compile error here instead of a panel that silently groups nothing.
10
11
  import { STATEMENT_ATTRIBUTE } from '@ultimat3/db';
@@ -130,7 +131,10 @@ function toTrace(root: ReadableSpan, spans: readonly ReadableSpan[]): RequestTra
130
131
  * root is what keeps a half-finished request, and a job's spans, out of a panel about requests.
131
132
  */
132
133
  export function createTraceRecorder(options: { limit?: number } = {}): TraceRecorder {
133
- const limit = options.limit ?? DEFAULT_LIMIT;
134
+ // `byTrace.size > NaN` is false on every pass, so an unchecked limit does not widen the buffer —
135
+ // it deletes the eviction loop, and a dev session then holds every span of every request it has
136
+ // ever seen. At least 1: a recorder that retains nothing is what `/_x/timeline` reads.
137
+ const limit = finiteCount('createTraceRecorder', 'limit', options.limit ?? DEFAULT_LIMIT, 1);
134
138
  // Insertion-ordered: the oldest trace id is the first key, which is the one eviction drops.
135
139
  const byTrace = new Map<string, ReadableSpan[]>();
136
140
 
package/src/e2e-page.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  // e2e test drives and `@ultimat3/scraping` owns the only driver that can drive one, and neither
3
3
  // may import the other — so the join is here, in the one package allowed to know about both.
4
4
 
5
+ import { finiteCount } from '@ultimat3/core';
5
6
  import type { LocatorLike, PageLike } from '@ultimat3/testing';
6
7
  import { E2eServiceWorkerAbsentError } from './e2e-errors';
7
8
  import { evaluateClosure } from './e2e-evaluate';
@@ -30,6 +31,9 @@ export interface E2ePageOptions {
30
31
  readonly serviceWorkerTimeoutMs?: number | undefined;
31
32
  }
32
33
 
34
+ /** Named once, so both refusals below name the call an app's test preload actually makes. */
35
+ const SUBJECT = 'installE2eDriver';
36
+
33
37
  export const DEFAULT_E2E_TIMEOUT_MS = 30_000;
34
38
  export const DEFAULT_SERVICE_WORKER_TIMEOUT_MS = 10_000;
35
39
 
@@ -82,8 +86,18 @@ const serviceWorkerExpression = (timeoutMs: number): string =>
82
86
  */
83
87
  export function e2ePage(options: E2ePageOptions): PageLike {
84
88
  const page = options.page;
85
- const timeout = options.timeoutMs ?? DEFAULT_E2E_TIMEOUT_MS;
86
- const swTimeout = options.serviceWorkerTimeoutMs ?? DEFAULT_SERVICE_WORKER_TIMEOUT_MS;
89
+ // Both are screened HERE, at construction, and not where they land: `timeout` is handed to a
90
+ // driver that reads it as a deadline, and `swTimeout` is INTERPOLATED into the in-page source,
91
+ // where `setTimeout(fn, NaN)` is `setTimeout(fn, 0)` — so a NaN budget makes every
92
+ // `waitForServiceWorker()` refuse a worker that really did take control. A misdiagnosis reported
93
+ // as a test failure is worse than the failure. Floor 0, because a driver reads `timeout: 0` as
94
+ // "no deadline" and that is a value an app is entitled to declare.
95
+ const timeout = finiteCount(SUBJECT, 'timeoutMs', options.timeoutMs ?? DEFAULT_E2E_TIMEOUT_MS);
96
+ const swTimeout = finiteCount(
97
+ SUBJECT,
98
+ 'serviceWorkerTimeoutMs',
99
+ options.serviceWorkerTimeoutMs ?? DEFAULT_SERVICE_WORKER_TIMEOUT_MS,
100
+ );
87
101
  const absolute = (url: string): string => new URL(url, options.baseUrl).toString();
88
102
  const locate = (selection: E2eSelection): LocatorLike => e2eLocator(page, selection);
89
103
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  // why: no Bun native joins a path; `Bun.write` and `Bun.file` both take one already joined.
7
7
  import { join } from 'node:path';
8
+ import { finiteCount } from '@ultimat3/core';
8
9
  import type { ScrapeDriver, ScrapeSession } from '@ultimat3/scraping';
9
10
  import { systemScrapeClock } from '@ultimat3/scraping';
10
11
  import type { IslandShotTarget, IslandStatesManifest, IslandViewport } from '@ultimat3/testing';
@@ -157,6 +158,7 @@ async function captureOne(
157
158
  options: IslandShotRun,
158
159
  server: ShotServer,
159
160
  target: IslandShotTarget,
161
+ floor: number,
160
162
  ): Promise<IslandStateShot> {
161
163
  const url = new URL(`${ISLAND_HARNESS_PATH}${target.query}`, server.url).toString();
162
164
  let session: ScrapeSession | undefined;
@@ -203,7 +205,6 @@ async function captureOne(
203
205
  // Never `fullPage`: the frame is the state's own declared viewport, and a full-page capture
204
206
  // would grow with whatever the component scrolled.
205
207
  const bytes = await page.screenshot({ fullPage: false });
206
- const floor = options.minBytes ?? MIN_SHOT_BYTES;
207
208
  if (bytes.byteLength < floor) {
208
209
  throw new IslandUnphotographableError({
209
210
  island: target.island,
@@ -257,6 +258,11 @@ export async function runIslandShot(options: IslandShotRun): Promise<IslandArtif
257
258
  const targets = islandShotTargets(options.manifest).filter(
258
259
  (target) => chosen === null || chosen.has(target.state),
259
260
  );
261
+ // Before the boot, and before a browser: `bytes.byteLength < NaN` is false for every picture, so
262
+ // an unchecked floor does not lower the backstop — it removes it, and "produced nothing and
263
+ // exited 0" is the one outcome a reader cannot tell from success. 0 stays legal and is what
264
+ // `island-shot.test.ts` passes: the fake driver answers an 8-byte PNG signature.
265
+ const floor = finiteCount('runIslandShot', 'minBytes', options.minBytes ?? MIN_SHOT_BYTES);
260
266
  const server = await options.boot();
261
267
  const shots: IslandStateShot[] = [];
262
268
  const failures: unknown[] = [];
@@ -266,7 +272,7 @@ export async function runIslandShot(options: IslandShotRun): Promise<IslandArtif
266
272
  // the app CAN produce plus a named reason for each one it cannot, and the missing-shot gate
267
273
  // below is what turns those reasons into a non-zero exit.
268
274
  try {
269
- shots.push(await captureOne(options, server, target));
275
+ shots.push(await captureOne(options, server, target, floor));
270
276
  } catch (error) {
271
277
  failures.push(error);
272
278
  }
@@ -3,6 +3,7 @@
3
3
  // `docker/helm`'s HPAs read a number instead of `<unknown>`.
4
4
 
5
5
  import {
6
+ finiteCount,
6
7
  logger,
7
8
  METRICS_CONTENT_TYPE,
8
9
  METRICS_PATH,
@@ -78,7 +79,11 @@ export interface MetricsEndpoint {
78
79
  * signal at the moment of load is worse than no autoscaler.
79
80
  */
80
81
  export function startMetricsEndpoint(options: MetricsEndpointOptions = {}): MetricsEndpoint {
81
- const port = options.port ?? DEFAULT_METRICS_PORT;
82
+ // Screened here rather than left to `Bun.serve`, which refuses a `NaN` with a bare `RangeError`
83
+ // — no code, no `fix:` — at exactly the boot path the refusal below exists to stop reporting
84
+ // that way. Floor 0, because 0 asks the kernel for a free port and `dev-roles.ts` passes it for
85
+ // an ephemeral boot; the ceiling stays Bun's, which names the range it refuses.
86
+ const port = finiteCount('startMetricsEndpoint', 'port', options.port ?? DEFAULT_METRICS_PORT);
82
87
  // `startRoles` opens this FIRST, before any role, so `Bun.serve`'s own bare `Error` was what a
83
88
  // second `x dev` on one machine reported: no code, no fix, at the boot path this package owns.
84
89
  // The return type is inferred, keeping `Bun.serve`'s own shape stated once.
@@ -5,7 +5,7 @@
5
5
  // by wiring, not by design.
6
6
 
7
7
  import type { Actor, Clock } from '@ultimat3/core';
8
- import { systemClock } from '@ultimat3/core';
8
+ import { finiteCount, systemClock } from '@ultimat3/core';
9
9
  import type { HttpConfig } from '@ultimat3/http';
10
10
  import {
11
11
  configuredAuthenticator,
@@ -102,7 +102,13 @@ export function syncAuthenticator(
102
102
  // this per connection otherwise.
103
103
  const config = upgradeConfig(buildId);
104
104
  const clock = options.clock ?? systemClock;
105
- const ttlMs = options.ttlMs ?? SYNC_GRANT_TTL_MS;
105
+ // A credential lifetime, screened where it is declared. `expiresAt` is `now + ttlMs`, and
106
+ // `GrantBook.expired()` asks `expiresAt <= now` — false for every `now` when the sum is `NaN`,
107
+ // so the grant never reaches a sweep and the socket keeps a revoked actor's authority for as
108
+ // long as the tab is open. That is the hole this whole file was written to close, and a `??`
109
+ // does not close it: `NaN` is not nullish. At least 1ms — a window that has already shut when
110
+ // the grant is minted is not a window.
111
+ const ttlMs = finiteCount('syncAuthenticator', 'ttlMs', options.ttlMs ?? SYNC_GRANT_TTL_MS, 1);
106
112
 
107
113
  const resolve = async (credential: Credential): Promise<SyncGrant | null> => {
108
114
  const request = new Request(credential.url, {