@ai-ecoverse/slicc-kernel 1.174.1 → 1.174.3

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.
@@ -7514,7 +7514,7 @@ var init_version = __esm({
7514
7514
  "src/version.ts"() {
7515
7515
  "use strict";
7516
7516
  init_captured_globals();
7517
- KERNEL_VERSION = true ? "1.174.1" : "0.0.0-dev";
7517
+ KERNEL_VERSION = true ? "1.174.3" : "0.0.0-dev";
7518
7518
  OS_RELEASE = "6.0.0-slicc";
7519
7519
  }
7520
7520
  });
@@ -7513,7 +7513,7 @@ var init_version = __esm({
7513
7513
  "src/version.ts"() {
7514
7514
  "use strict";
7515
7515
  init_captured_globals();
7516
- KERNEL_VERSION = true ? "1.174.1" : "0.0.0-dev";
7516
+ KERNEL_VERSION = true ? "1.174.3" : "0.0.0-dev";
7517
7517
  OS_RELEASE = "6.0.0-slicc";
7518
7518
  }
7519
7519
  });
package/dist/node.js CHANGED
@@ -3702,7 +3702,7 @@ function satisfies(version, range2) {
3702
3702
  }
3703
3703
 
3704
3704
  // src/version.ts
3705
- var KERNEL_VERSION = true ? "1.174.1" : "0.0.0-dev";
3705
+ var KERNEL_VERSION = true ? "1.174.3" : "0.0.0-dev";
3706
3706
  var OS_RELEASE = "6.0.0-slicc";
3707
3707
  function procVersion() {
3708
3708
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -4114,6 +4114,27 @@ function binfmtOf(binfmts, path) {
4114
4114
  return best === void 0 ? void 0 : binfmts.get(best);
4115
4115
  }
4116
4116
 
4117
+ // src/cron/clock.ts
4118
+ function clockZone(clock) {
4119
+ return clock?.timeZone ?? (clock?.utc === true ? "UTC" : void 0);
4120
+ }
4121
+ var systemCronClock = {
4122
+ now: () => Date.now(),
4123
+ sleep(until2, signal) {
4124
+ if (signal.aborted) return Promise.resolve();
4125
+ return new Promise((resolve2) => {
4126
+ const done4 = () => {
4127
+ clearTimeout(timer);
4128
+ signal.removeEventListener("abort", done4);
4129
+ resolve2();
4130
+ };
4131
+ const timer = setTimeout(done4, Math.max(0, until2 - Date.now()));
4132
+ timer.unref?.();
4133
+ signal.addEventListener("abort", done4, { once: true });
4134
+ });
4135
+ }
4136
+ };
4137
+
4117
4138
  // src/cron/command.ts
4118
4139
  var CRONTAB_PATH = "/usr/bin/crontab";
4119
4140
  var CRONTAB_COMMAND = {
@@ -4225,6 +4246,94 @@ var CRONTAB_SOURCE = `export default async function crontab(ctx) {
4225
4246
  }
4226
4247
  `;
4227
4248
 
4249
+ // src/time-zone.ts
4250
+ var MINUTE_MS = 6e4;
4251
+ var HOUR_MS = 60 * MINUTE_MS;
4252
+ var BUCKET_MS = 15 * MINUTE_MS;
4253
+ var CACHE_MAX = 4096;
4254
+ var ZERO = /* @__PURE__ */ new Set(["UTC", "Etc/UTC", "Etc/GMT", "GMT", "Etc/Universal", "Etc/Zulu"]);
4255
+ function canonicalZone(name2) {
4256
+ if (typeof name2 !== "string" || name2 === "" || name2.length > 64) return void 0;
4257
+ try {
4258
+ return new Intl.DateTimeFormat("en-US", { timeZone: name2 }).resolvedOptions().timeZone;
4259
+ } catch {
4260
+ return void 0;
4261
+ }
4262
+ }
4263
+ function hostTimeZone() {
4264
+ let name2;
4265
+ try {
4266
+ name2 = new Intl.DateTimeFormat().resolvedOptions().timeZone;
4267
+ } catch {
4268
+ name2 = void 0;
4269
+ }
4270
+ return canonicalZone(name2) ?? "UTC";
4271
+ }
4272
+ function systemTimeZone(given, fallback) {
4273
+ if (given !== void 0) {
4274
+ const zone = canonicalZone(given);
4275
+ if (zone === void 0) throw new Error(`not a time zone: ${String(given)}`);
4276
+ return zone;
4277
+ }
4278
+ return canonicalZone(fallback) ?? hostTimeZone();
4279
+ }
4280
+ var utcZone = { name: "UTC", offset: () => 0 };
4281
+ function hostZone(name2) {
4282
+ return { name: name2, offset: (at) => -new Date(at).getTimezoneOffset() * MINUTE_MS };
4283
+ }
4284
+ function intlZone(name2) {
4285
+ const format = new Intl.DateTimeFormat("en-US", {
4286
+ timeZone: name2,
4287
+ hourCycle: "h23",
4288
+ year: "numeric",
4289
+ month: "numeric",
4290
+ day: "numeric",
4291
+ hour: "numeric",
4292
+ minute: "numeric",
4293
+ second: "numeric"
4294
+ });
4295
+ const exact = (at) => {
4296
+ const parts2 = {};
4297
+ for (const part of format.formatToParts(at)) parts2[part.type] = Number(part.value);
4298
+ const wall = Date.UTC(
4299
+ parts2.year,
4300
+ parts2.month - 1,
4301
+ parts2.day,
4302
+ parts2.hour,
4303
+ parts2.minute,
4304
+ parts2.second
4305
+ );
4306
+ return wall - Math.floor(at / 1e3) * 1e3;
4307
+ };
4308
+ const buckets = /* @__PURE__ */ new Map();
4309
+ return {
4310
+ name: name2,
4311
+ offset(at) {
4312
+ const bucket = Math.floor(at / BUCKET_MS);
4313
+ let known = buckets.get(bucket);
4314
+ if (known === void 0) {
4315
+ const start2 = exact(bucket * BUCKET_MS);
4316
+ known = start2 === exact(bucket * BUCKET_MS + BUCKET_MS - MINUTE_MS) ? start2 : null;
4317
+ if (buckets.size >= CACHE_MAX) buckets.clear();
4318
+ buckets.set(bucket, known);
4319
+ }
4320
+ return known ?? exact(at);
4321
+ }
4322
+ };
4323
+ }
4324
+ var zones = /* @__PURE__ */ new Map();
4325
+ function zoneOf(name2) {
4326
+ if (ZERO.has(name2)) return utcZone;
4327
+ if (name2 === hostTimeZone()) return hostZone(name2);
4328
+ let zone = zones.get(name2);
4329
+ if (!zone) {
4330
+ zone = intlZone(name2);
4331
+ zones.set(name2, zone);
4332
+ }
4333
+ return zone;
4334
+ }
4335
+ var MAX_SHIFT_MS = 3 * HOUR_MS;
4336
+
4228
4337
  // src/cron/schedule.ts
4229
4338
  var MISSED_CAP = 1e5;
4230
4339
  var MACROS = {
@@ -4296,6 +4405,7 @@ function parseSchedule(expression) {
4296
4405
  );
4297
4406
  if (weekdays.delete(7)) weekdays.add(0);
4298
4407
  return {
4408
+ fixed: !parts2[0].startsWith("*") && !parts2[1].startsWith("*"),
4299
4409
  minutes,
4300
4410
  hours,
4301
4411
  days,
@@ -4309,18 +4419,6 @@ function parseWhen(expression) {
4309
4419
  if (expression.trim().toLowerCase() === "@reboot") return { reboot: true };
4310
4420
  return { reboot: false, schedule: parseSchedule(expression) };
4311
4421
  }
4312
- var LOCAL = {
4313
- year: (d) => d.getFullYear(),
4314
- month: (d) => d.getMonth(),
4315
- date: (d) => d.getDate(),
4316
- day: (d) => d.getDay(),
4317
- hours: (d) => d.getHours(),
4318
- minutes: (d) => d.getMinutes(),
4319
- setMonth: (d, month) => d.setMonth(month, 1),
4320
- setDate: (d, date) => d.setDate(date),
4321
- setHours: (d, hours) => d.setHours(hours, 0, 0, 0),
4322
- setMinutes: (d, minutes) => d.setMinutes(minutes, 0, 0)
4323
- };
4324
4422
  var UTC = {
4325
4423
  year: (d) => d.getUTCFullYear(),
4326
4424
  month: (d) => d.getUTCMonth(),
@@ -4333,60 +4431,112 @@ var UTC = {
4333
4431
  setHours: (d, hours) => d.setUTCHours(hours, 0, 0, 0),
4334
4432
  setMinutes: (d, minutes) => d.setUTCMinutes(minutes, 0, 0)
4335
4433
  };
4336
- function dayMatches(schedule, cal, date) {
4337
- const day = schedule.days.has(cal.date(date));
4338
- const weekday = schedule.weekdays.has(cal.day(date));
4434
+ function dayMatches(schedule, date) {
4435
+ const day = schedule.days.has(UTC.date(date));
4436
+ const weekday = schedule.weekdays.has(UTC.day(date));
4339
4437
  if (schedule.anyDay || schedule.anyWeekday) return day && weekday;
4340
4438
  return day || weekday;
4341
4439
  }
4342
4440
  var LIMIT_YEARS = 8;
4343
- function nextFire(schedule, after, utc = false) {
4344
- const cal = utc ? UTC : LOCAL;
4345
- const date = new Date(Math.floor(after / 6e4) * 6e4 + 6e4);
4346
- const limit = cal.year(date) + LIMIT_YEARS;
4347
- while (cal.year(date) <= limit) {
4348
- if (!schedule.months.has(cal.month(date) + 1)) {
4349
- cal.setMonth(date, cal.month(date) + 1);
4350
- cal.setHours(date, 0);
4351
- } else if (!dayMatches(schedule, cal, date)) {
4352
- cal.setDate(date, cal.date(date) + 1);
4353
- cal.setHours(date, 0);
4354
- } else if (!schedule.hours.has(cal.hours(date))) {
4355
- cal.setHours(date, cal.hours(date) + 1);
4356
- } else if (!schedule.minutes.has(cal.minutes(date))) {
4357
- cal.setMinutes(date, cal.minutes(date) + 1);
4441
+ var LIMIT_MS = (LIMIT_YEARS + 1) * 366 * 24 * 60 * MINUTE_MS;
4442
+ var SCAN_MS = 6 * 60 * MINUTE_MS;
4443
+ function nextWall(schedule, from) {
4444
+ const date = new Date(Math.ceil(from / MINUTE_MS) * MINUTE_MS);
4445
+ const limit = UTC.year(date) + LIMIT_YEARS;
4446
+ while (UTC.year(date) <= limit) {
4447
+ if (!schedule.months.has(UTC.month(date) + 1)) {
4448
+ UTC.setMonth(date, UTC.month(date) + 1);
4449
+ UTC.setHours(date, 0);
4450
+ } else if (!dayMatches(schedule, date)) {
4451
+ UTC.setDate(date, UTC.date(date) + 1);
4452
+ UTC.setHours(date, 0);
4453
+ } else if (!schedule.hours.has(UTC.hours(date))) {
4454
+ UTC.setHours(date, UTC.hours(date) + 1);
4455
+ } else if (!schedule.minutes.has(UTC.minutes(date))) {
4456
+ UTC.setMinutes(date, UTC.minutes(date) + 1);
4358
4457
  } else return date.getTime();
4359
4458
  }
4360
4459
  return null;
4361
4460
  }
4362
- function missedFires(schedule, from, until2, utc = false, cap = MISSED_CAP) {
4461
+ function firstChange(zone, from, to, offset) {
4462
+ let lo = from;
4463
+ let hi = to;
4464
+ for (let at = from + SCAN_MS; at < to; at += SCAN_MS) {
4465
+ if (zone.offset(at) !== offset) {
4466
+ hi = at;
4467
+ break;
4468
+ }
4469
+ lo = at;
4470
+ }
4471
+ while (hi - lo > MINUTE_MS) {
4472
+ const mid = lo + Math.floor((hi - lo) / 2 / MINUTE_MS) * MINUTE_MS;
4473
+ if (zone.offset(mid) === offset) lo = mid;
4474
+ else hi = mid;
4475
+ }
4476
+ return hi;
4477
+ }
4478
+ function afterRepeat(zone, at) {
4479
+ const offset = zone.offset(at);
4480
+ const earlier = zone.offset(at - MAX_SHIFT_MS);
4481
+ if (earlier <= offset) return at;
4482
+ const shift = firstChange(zone, at - MAX_SHIFT_MS, at, earlier);
4483
+ const end = shift + (earlier - zone.offset(shift));
4484
+ return Math.max(at, end);
4485
+ }
4486
+ function nextFire(schedule, after, zone = utcZone) {
4487
+ let at = Math.floor(after / MINUTE_MS) * MINUTE_MS + MINUTE_MS;
4488
+ const limit = at + LIMIT_MS;
4489
+ while (at <= limit) {
4490
+ if (schedule.fixed) {
4491
+ const end = afterRepeat(zone, at);
4492
+ if (end > at) {
4493
+ at = end;
4494
+ continue;
4495
+ }
4496
+ }
4497
+ const offset = zone.offset(at);
4498
+ const before = zone.offset(at - MINUTE_MS);
4499
+ if (schedule.fixed && before < offset && offset - before <= MAX_SHIFT_MS) {
4500
+ const skipped = nextWall(schedule, at + before);
4501
+ if (skipped !== null && skipped < at + offset) return at;
4502
+ }
4503
+ const wall = nextWall(schedule, at + offset);
4504
+ if (wall === null) return null;
4505
+ const found = at + (wall - (at + offset));
4506
+ const change = firstChange(zone, at, found, offset);
4507
+ if (change >= found && zone.offset(found) === offset) return found;
4508
+ at = change;
4509
+ }
4510
+ return null;
4511
+ }
4512
+ function missedFires(schedule, from, until2, zone = utcZone, cap = MISSED_CAP) {
4363
4513
  let count2 = 0;
4364
4514
  let last = null;
4365
4515
  let at = from;
4366
4516
  while (count2 < cap) {
4367
- at = nextFire(schedule, at, utc);
4517
+ at = nextFire(schedule, at, zone);
4368
4518
  if (at === null || at > until2) return { count: count2, last, more: false };
4369
4519
  last = at;
4370
4520
  count2++;
4371
4521
  }
4372
- const next3 = nextFire(schedule, last, utc);
4522
+ const next3 = nextFire(schedule, last, zone);
4373
4523
  if (next3 === null || next3 > until2) return { count: count2, last, more: false };
4374
- return { count: count2, last: latestFire(schedule, last, until2, utc), more: true };
4524
+ return { count: count2, last: latestFire(schedule, last, until2, zone), more: true };
4375
4525
  }
4376
- function latestFire(schedule, from, until2, utc = false) {
4526
+ function latestFire(schedule, from, until2, zone = utcZone) {
4377
4527
  let found = from;
4378
4528
  for (let span = 6e4; ; span *= 2) {
4379
4529
  const start2 = Math.max(from, until2 - span);
4380
- const first = nextFire(schedule, start2, utc);
4530
+ const first = nextFire(schedule, start2, zone);
4381
4531
  if (first !== null && first <= until2) {
4382
4532
  found = first;
4383
4533
  break;
4384
4534
  }
4385
4535
  if (start2 === from) return from;
4386
4536
  }
4387
- for (let at = nextFire(schedule, found, utc); at !== null && at <= until2; ) {
4537
+ for (let at = nextFire(schedule, found, zone); at !== null && at <= until2; ) {
4388
4538
  found = at;
4389
- at = nextFire(schedule, at, utc);
4539
+ at = nextFire(schedule, at, zone);
4390
4540
  }
4391
4541
  return found;
4392
4542
  }
@@ -4427,13 +4577,16 @@ function split(text, count2) {
4427
4577
  }
4428
4578
  return [words2, rest2.trim()];
4429
4579
  }
4430
- function jobOf(content, pending, ctx) {
4580
+ function jobOf(content, pending, ctx, env) {
4431
4581
  const fields = content.startsWith("@") ? 1 : 5;
4432
4582
  const parts2 = split(content, fields + (ctx.system ? 1 : 0));
4433
4583
  if (!parts2 || parts2[1] === "") throw new Error("no command");
4434
4584
  const [words2, command] = parts2;
4435
4585
  const schedule = words2.slice(0, fields).join(" ");
4436
4586
  const when = parseWhen(schedule);
4587
+ const zone = env.CRON_TZ;
4588
+ if (zone && !when.reboot && canonicalZone(zone) === void 0)
4589
+ throw new Error(`CRON_TZ: unknown time zone "${zone}"`);
4437
4590
  const user = ctx.system ? words2[fields] : void 0;
4438
4591
  if (user !== void 0 && !USER_NAME.test(user)) throw new Error(`bad user name ${user}`);
4439
4592
  if (pending !== void 0 && !JOB_NAME.test(pending))
@@ -4479,7 +4632,7 @@ function parseCrontab(text, path, system = false) {
4479
4632
  continue;
4480
4633
  }
4481
4634
  try {
4482
- jobs.push({ line, ...jobOf(content, pending, ctx), env: { ...env } });
4635
+ jobs.push({ line, ...jobOf(content, pending, ctx, env), env: { ...env } });
4483
4636
  } catch (err) {
4484
4637
  errors.push({ line, message: err.message });
4485
4638
  }
@@ -5279,24 +5432,6 @@ var UnlinkedKeeper = class {
5279
5432
  }
5280
5433
  };
5281
5434
 
5282
- // src/cron/clock.ts
5283
- var systemCronClock = {
5284
- now: () => Date.now(),
5285
- sleep(until2, signal) {
5286
- if (signal.aborted) return Promise.resolve();
5287
- return new Promise((resolve2) => {
5288
- const done4 = () => {
5289
- clearTimeout(timer);
5290
- signal.removeEventListener("abort", done4);
5291
- resolve2();
5292
- };
5293
- const timer = setTimeout(done4, Math.max(0, until2 - Date.now()));
5294
- timer.unref?.();
5295
- signal.addEventListener("abort", done4, { once: true });
5296
- });
5297
- }
5298
- };
5299
-
5300
5435
  // src/cron/service.ts
5301
5436
  var CRON_DIR = "/var/spool/cron";
5302
5437
  var STAMP_PATH = `${CRON_DIR}/stamp`;
@@ -5308,9 +5443,10 @@ var WAKE_MS = 6e4;
5308
5443
  var BACK_JUMP_MS = 12e4;
5309
5444
  var DEFAULT_SHELL = "/bin/bash";
5310
5445
  var encoder = new TextEncoder();
5311
- var EMPTY_STAMP = JSON.stringify({ jobs: {}, reboot: {} });
5446
+ var EMPTY_STAMP = JSON.stringify({ jobs: {}, reboot: {}, when: {} });
5312
5447
  var messageOf = (err) => err?.message ?? String(err);
5313
5448
  var keyOf2 = ({ source, job }) => `${source} ${job.id}`;
5449
+ var whenOf = ({ job }) => `${job.schedule} ${job.env.CRON_TZ ?? ""}`;
5314
5450
  function tail(bytes, cap = LOG_CAP) {
5315
5451
  return bytes.length > cap ? bytes.slice(bytes.length - cap) : bytes;
5316
5452
  }
@@ -5344,9 +5480,10 @@ function readStamp(text) {
5344
5480
  const parsed2 = JSON.parse(text ?? "");
5345
5481
  const jobs = parsed2.jobs && typeof parsed2.jobs === "object" ? parsed2.jobs : {};
5346
5482
  const reboot = parsed2.reboot && typeof parsed2.reboot === "object" ? parsed2.reboot : {};
5347
- return { jobs: { ...jobs }, reboot: { ...reboot } };
5483
+ const when = parsed2.when && typeof parsed2.when === "object" ? parsed2.when : {};
5484
+ return { jobs: { ...jobs }, reboot: { ...reboot }, when: { ...when } };
5348
5485
  } catch {
5349
- return { jobs: {}, reboot: {} };
5486
+ return { jobs: {}, reboot: {}, when: {} };
5350
5487
  }
5351
5488
  }
5352
5489
  var CronService = class {
@@ -5421,7 +5558,7 @@ var CronService = class {
5421
5558
  const loaded = await this.load();
5422
5559
  const stamp = readStamp(await fs.readFile(STAMP_PATH).catch(() => void 0));
5423
5560
  const now = this.clock.now();
5424
- const utc = this.clock.utc === true;
5561
+ const system = this.host.timeZone;
5425
5562
  const due2 = [];
5426
5563
  const keys = /* @__PURE__ */ new Set();
5427
5564
  let next3 = now + WAKE_MS;
@@ -5435,20 +5572,24 @@ var CronService = class {
5435
5572
  due2.push({ entry, due: now, missed: 0 });
5436
5573
  continue;
5437
5574
  }
5575
+ const zone = zoneOf(entry.job.env.CRON_TZ || system);
5438
5576
  const last = stamp.jobs[key];
5439
- if (typeof last !== "number" || last > now + BACK_JUMP_MS) stamp.jobs[key] = now;
5577
+ const was = stamp.when[key];
5578
+ stamp.when[key] = whenOf(entry);
5579
+ const changed = was !== void 0 && was !== stamp.when[key];
5580
+ if (typeof last !== "number" || changed || last > now + BACK_JUMP_MS) stamp.jobs[key] = now;
5440
5581
  else {
5441
- const missed = missedFires(when.schedule, last, now, utc);
5582
+ const missed = missedFires(when.schedule, last, now, zone);
5442
5583
  if (missed.last !== null) {
5443
5584
  stamp.jobs[key] = now;
5444
5585
  due2.push({ entry, due: missed.last, missed: missed.count - 1 });
5445
5586
  }
5446
5587
  }
5447
- const coming = nextFire(when.schedule, Math.max(now, stamp.jobs[key]), utc);
5588
+ const coming = nextFire(when.schedule, Math.max(now, stamp.jobs[key]), zone);
5448
5589
  if (coming !== null && coming < next3) next3 = coming;
5449
5590
  }
5450
5591
  this.rebooted = true;
5451
- for (const map of [stamp.jobs, stamp.reboot])
5592
+ for (const map of [stamp.jobs, stamp.reboot, stamp.when])
5452
5593
  for (const key of Object.keys(map)) if (!keys.has(key)) delete map[key];
5453
5594
  await this.writeStamp(stamp);
5454
5595
  for (const each of due2) void this.spawn(each);
@@ -11925,14 +12066,14 @@ function attachSyncSabResponder(port, sab, token, opts) {
11925
12066
 
11926
12067
  // src/kernel/cpu-clock.ts
11927
12068
  var SYS_CAP_US = 2e4;
11928
- var LOCAL2 = SAB_CLOCK_OFFSET;
12069
+ var LOCAL = SAB_CLOCK_OFFSET;
11929
12070
  var BLOCKED = 0;
11930
12071
  var IDLE = 1;
11931
12072
  function epochMicros() {
11932
12073
  return Math.floor((performance.timeOrigin + performance.now()) * 1e3);
11933
12074
  }
11934
12075
  function slots(sab) {
11935
- return new BigInt64Array(sab, LOCAL2, SAB_CLOCK_I64);
12076
+ return new BigInt64Array(sab, LOCAL, SAB_CLOCK_I64);
11936
12077
  }
11937
12078
  var rawWait = Atomics.wait.bind(Atomics);
11938
12079
  function localIdle(sab, now) {
@@ -31964,6 +32105,7 @@ var Launcher = class {
31964
32105
  routes;
31965
32106
  resolver;
31966
32107
  hostname;
32108
+ timeZone;
31967
32109
  watchers = new FsWatchers();
31968
32110
  changes = new FileChanges();
31969
32111
  peerHeldPaths = /* @__PURE__ */ new Set();
@@ -32079,9 +32221,11 @@ var Launcher = class {
32079
32221
  const hostname = options.hostname ?? DEFAULT_HOSTNAME;
32080
32222
  if (!isHostname(hostname)) throw new Error(`not a host name: ${String(hostname)}`);
32081
32223
  this.hostname = hostname;
32224
+ this.timeZone = systemTimeZone(options.timeZone, clockZone(options.cron?.clock));
32082
32225
  this.env = {
32083
32226
  ...networkEnv(hostname),
32084
32227
  HOSTNAME: hostname,
32228
+ TZ: this.timeZone,
32085
32229
  SLICC_CDP_URL: this.cdp.url,
32086
32230
  ...this.facades.env(),
32087
32231
  ...options.env
@@ -32191,6 +32335,7 @@ var Launcher = class {
32191
32335
  owners: this.owners,
32192
32336
  lock: options.lock ?? "slicc-kernel-cron",
32193
32337
  bootId: this.bootId,
32338
+ timeZone: this.timeZone,
32194
32339
  ...options.clock ? { clock: options.clock } : {},
32195
32340
  locks: cronLocks(),
32196
32341
  ready: () => this.fstab,
@@ -34210,7 +34355,7 @@ var Launcher = class {
34210
34355
  }
34211
34356
  environment(cwd, extra, account, login2 = false) {
34212
34357
  const env = {
34213
- ...login2 ? { ...networkEnv(this.hostname), HOSTNAME: this.hostname } : this.env,
34358
+ ...login2 ? { ...networkEnv(this.hostname), HOSTNAME: this.hostname, TZ: this.timeZone } : this.env,
34214
34359
  ...userEnv(account, this.pnpmHome),
34215
34360
  PWD: cwd,
34216
34361
  ...extra
@@ -37199,6 +37344,7 @@ function checkedRequests(hook) {
37199
37344
  }
37200
37345
  async function createNodeKernel(options = {}) {
37201
37346
  const hooks = sealedHooks(options.sealed);
37347
+ const timeZone = systemTimeZone(options.timeZone, clockZone(options.cron?.clock));
37202
37348
  const root = options.root ?? memoryRoot();
37203
37349
  const fs = new OpfsFs(root, void 0, void 0, { ranged: isMemoryRoot(root) });
37204
37350
  await fs.reconcile();
@@ -37234,6 +37380,7 @@ async function createNodeKernel(options = {}) {
37234
37380
  ...options.cdp ? { cdp: options.cdp } : {},
37235
37381
  ...options.facades ? { facades: options.facades } : {},
37236
37382
  ...options.hostname !== void 0 ? { hostname: options.hostname } : {},
37383
+ timeZone,
37237
37384
  users: options.users === void 0 ? DEFAULT_USERS : options.users,
37238
37385
  ...options.onDenial ? { onDenial: options.onDenial } : {},
37239
37386
  ...options.protect ? { protect: options.protect } : {},