@ai-ecoverse/slicc-kernel 1.74.0 → 1.75.1

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.
@@ -1998,7 +1998,7 @@ function ptyStat(path) {
1998
1998
  ctime: now
1999
1999
  };
2000
2000
  }
2001
- function sealedStat() {
2001
+ function sealedStat(minor = 250) {
2002
2002
  const now = /* @__PURE__ */ new Date();
2003
2003
  return {
2004
2004
  dev: 22,
@@ -2007,7 +2007,7 @@ function sealedStat() {
2007
2007
  nlink: 1,
2008
2008
  uid: 0,
2009
2009
  gid: 0,
2010
- rdev: 10 << 8 | 250,
2010
+ rdev: 10 << 8 | minor,
2011
2011
  size: 0,
2012
2012
  blksize: 4096,
2013
2013
  blocks: 0,
@@ -2019,7 +2019,7 @@ function sealedStat() {
2019
2019
  function nonblocking(stream) {
2020
2020
  return (stream.flags & O_NONBLOCK) !== 0 ? { nonblock: true } : void 0;
2021
2021
  }
2022
- var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, SEALED_PATH, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC2, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
2022
+ var POLLIN, POLLOUT, POLLERR, POLLHUP, POLLRDNORM, POLLWRNORM, TCSETSF, O_NONBLOCK, SOCKET_MODE, PTY_PATH, TTY_PATH, TTY_NAME, SEALED_PATH, STRERROR, CLIPBOARD_PATH, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC2, KILLED_BY_SIGPIPE, ProcessExit, SyscallError, KernelStreams;
2023
2023
  var init_kernel_streams = __esm({
2024
2024
  "src/process/kernel-streams.ts"() {
2025
2025
  "use strict";
@@ -2037,6 +2037,16 @@ var init_kernel_streams = __esm({
2037
2037
  TTY_PATH = /^\/dev\/tty\d+$/;
2038
2038
  TTY_NAME = /^tty\d+$/;
2039
2039
  SEALED_PATH = "/dev/sealed";
2040
+ STRERROR = {
2041
+ EACCES: "Permission denied",
2042
+ EIO: "I/O error",
2043
+ ENOTSUP: "Not supported",
2044
+ EOPNOTSUPP: "Not supported",
2045
+ EFBIG: "File too large",
2046
+ EILSEQ: "Illegal byte sequence",
2047
+ EINTR: "Interrupted system call"
2048
+ };
2049
+ CLIPBOARD_PATH = "/dev/clipboard";
2040
2050
  O_CREAT = 64;
2041
2051
  O_EXCL = 128;
2042
2052
  O_NOCTTY = 256;
@@ -2112,10 +2122,64 @@ var init_kernel_streams = __esm({
2112
2122
  }
2113
2123
  listSealed() {
2114
2124
  const { analyzePath, mkdev, makedev } = this.Fs;
2115
- if (!this.sys.openSealed || !analyzePath || !mkdev || !makedev) return;
2116
- if (analyzePath.call(this.Fs, SEALED_PATH).exists) return;
2125
+ if (!analyzePath || !mkdev || !makedev) return;
2126
+ const nodes = [
2127
+ [SEALED_PATH, 250, this.sys.openSealed],
2128
+ [CLIPBOARD_PATH, 251, this.sys.openClipboard]
2129
+ ];
2130
+ for (const [path, minor, present] of nodes) {
2131
+ if (!present || analyzePath.call(this.Fs, path).exists) continue;
2132
+ try {
2133
+ mkdev.call(this.Fs, path, makedev.call(this.Fs, 10, minor));
2134
+ } catch {
2135
+ }
2136
+ }
2137
+ }
2138
+ reporting = /* @__PURE__ */ new Set();
2139
+ reportClose(kfd) {
2140
+ this.reporting.add(kfd);
2141
+ }
2142
+ quitting = false;
2143
+ atExit = false;
2144
+ failedAtExit = false;
2145
+ committed = /* @__PURE__ */ new Set();
2146
+ exiting() {
2147
+ this.atExit = true;
2148
+ return () => {
2149
+ this.atExit = false;
2150
+ };
2151
+ }
2152
+ commitStdout() {
2153
+ const kfd = this.Fs.getStream(1)?.sliccKernelFd;
2154
+ if (kfd === void 0 || !this.reporting.delete(kfd)) return;
2155
+ this.committed.add(kfd);
2156
+ try {
2157
+ this.sys.close(kfd);
2158
+ } catch (e) {
2159
+ if (e instanceof SyscallError) this.stdoutFailed(e.code);
2160
+ }
2161
+ }
2162
+ exitStatus(status2) {
2163
+ return this.failedAtExit && status2 === 0 ? 1 : status2;
2164
+ }
2165
+ reportedClose(stream, kfd) {
2117
2166
  try {
2118
- mkdev.call(this.Fs, SEALED_PATH, makedev.call(this.Fs, 10, 250));
2167
+ this.sys.close(kfd);
2168
+ } catch (e) {
2169
+ if (this.quitting && stream.fd === 1 && e instanceof SyscallError) this.stdoutFailed(e.code);
2170
+ this.call(() => {
2171
+ throw e;
2172
+ });
2173
+ }
2174
+ }
2175
+ stdoutFailed(code2) {
2176
+ this.failedAtExit = true;
2177
+ const stderr = this.Fs.getStream(2)?.sliccKernelFd;
2178
+ if (stderr === void 0) return;
2179
+ const line = `${this.options.program ?? "program"}: write error: ${STRERROR[code2] ?? code2}
2180
+ `;
2181
+ try {
2182
+ this.sys.write(stderr, new TextEncoder().encode(line));
2119
2183
  } catch {
2120
2184
  }
2121
2185
  }
@@ -2218,7 +2282,7 @@ var init_kernel_streams = __esm({
2218
2282
  if (device2 !== void 0 && TTY_PATH.test(device2) && !this.terminalExists(device2)) {
2219
2283
  throw new this.Fs.ErrnoError(wasiErrno("ENOENT"));
2220
2284
  }
2221
- const pty = this.openPty(open, path, flags, mode) ?? this.openSealed(open, path, flags, mode);
2285
+ const pty = this.openPty(open, path, flags, mode) ?? this.openSealed(open, path, flags, mode) ?? this.openClipboard(open, path, flags, mode);
2222
2286
  if (pty) return pty;
2223
2287
  this.refuseExclusiveLink(path, flags);
2224
2288
  const stream = this.openRacing(open, path, flags, mode);
@@ -2284,6 +2348,14 @@ var init_kernel_streams = __esm({
2284
2348
  const kfd = this.call(() => openSealed.call(this.sys));
2285
2349
  return this.vessel(open, kfd, { path, flags, mode }, false);
2286
2350
  }
2351
+ openClipboard(open, path, flags, mode) {
2352
+ const { openClipboard } = this.sys;
2353
+ if (path !== CLIPBOARD_PATH || !openClipboard) return void 0;
2354
+ const kfd = this.call(() => openClipboard.call(this.sys, flags & 3));
2355
+ const stream = this.vessel(open, kfd, { path, flags, mode }, false);
2356
+ this.reportClose(kfd);
2357
+ return stream;
2358
+ }
2287
2359
  vessel(open, kfd, at, terminal) {
2288
2360
  let stream;
2289
2361
  try {
@@ -2308,6 +2380,7 @@ var init_kernel_streams = __esm({
2308
2380
  if (typeof original !== "function") continue;
2309
2381
  fs[name2] = (path, ...rest2) => {
2310
2382
  if (path === SEALED_PATH && this.sys.openSealed) return sealedStat();
2383
+ if (path === CLIPBOARD_PATH && this.sys.openClipboard) return sealedStat(251);
2311
2384
  const owned = this.ownedTty(path);
2312
2385
  if (owned && isPtyPath(path)) return this.owned(path, ptyStat(path));
2313
2386
  if (!isPtyPath(path)) {
@@ -2448,6 +2521,7 @@ var init_kernel_streams = __esm({
2448
2521
  this.refs.set(kfd, (this.refs.get(kfd) ?? 0) + 1);
2449
2522
  },
2450
2523
  close: (stream) => {
2524
+ if (this.atExit && stream.fd === 2 && this.reporting.size > 0) this.commitStdout();
2451
2525
  try {
2452
2526
  base.close?.(stream);
2453
2527
  } catch {
@@ -2458,6 +2532,11 @@ var init_kernel_streams = __esm({
2458
2532
  return;
2459
2533
  }
2460
2534
  this.refs.delete(kfd);
2535
+ if (this.committed.size > 0 && this.committed.delete(kfd)) return;
2536
+ if (this.reporting.size > 0 && this.reporting.delete(kfd)) {
2537
+ this.reportedClose(stream, kfd);
2538
+ return;
2539
+ }
2461
2540
  try {
2462
2541
  this.sys.close(kfd);
2463
2542
  } catch {
@@ -3308,7 +3387,7 @@ function place(Fs, stream, fd) {
3308
3387
  function placeholder(Fs, streams, entry) {
3309
3388
  if (entry.kind === "socket") return streams.socketStream(entry.flags ?? O_RDWR);
3310
3389
  if (entry.kind === "tty") return Fs.open("/dev/tty", O_RDWR);
3311
- if (entry.kind === "stream") return Fs.open("/dev/null", O_RDWR);
3390
+ if (entry.kind === "stream" || entry.kind === "clipboard") return Fs.open("/dev/null", O_RDWR);
3312
3391
  Fs.mkdirTree(PLACEHOLDER_DIR);
3313
3392
  return Fs.open(`${PLACEHOLDER_DIR}/${entry.fd}`, O_RDWR | O_CREAT3);
3314
3393
  }
@@ -3332,6 +3411,7 @@ function placeKernelStream(Fs, streams, entry) {
3332
3411
  streams.sizeFromKernel(stream, entry.kernel);
3333
3412
  } else if (entry.kind === "socket") streams.attachSocket(stream, entry.kernel);
3334
3413
  else streams.attach(stream, entry.kernel, entry.kind === "tty");
3414
+ if (entry.kind === "clipboard") streams.reportClose(entry.kernel);
3335
3415
  if (entry.kind === "tty") streams.nameTerminal(stream);
3336
3416
  if (entry.kind === "stream") {
3337
3417
  asFifo(stream, streams, entry.desc !== void 0 ? `d${entry.desc}` : `k${entry.kernel}`);
@@ -4491,6 +4571,9 @@ function kernelSys(transport) {
4491
4571
  openSealed() {
4492
4572
  return json2(call2({ op: "fd-open-sealed" }, "fd-open-sealed"));
4493
4573
  },
4574
+ openClipboard(flags) {
4575
+ return json2(call2({ op: "fd-open-clipboard", flags }, "fd-open-clipboard"));
4576
+ },
4494
4577
  ptyNumbers() {
4495
4578
  return json2(call2({ op: "pty-list" }, "pty-list"));
4496
4579
  },
@@ -4647,6 +4730,8 @@ async function runWasmProcess(init, port2, deps = {}) {
4647
4730
  let failed5;
4648
4731
  let memory;
4649
4732
  let exports;
4733
+ let atExit = () => () => {
4734
+ };
4650
4735
  const initialized = new Promise((resolve, reject) => {
4651
4736
  ready = resolve;
4652
4737
  failed5 = reject;
@@ -4688,7 +4773,10 @@ async function runWasmProcess(init, port2, deps = {}) {
4688
4773
  memory = wasmMemory(instance, imports);
4689
4774
  exports = instance.exports;
4690
4775
  publishMemory(init.sab, memory?.buffer.byteLength ?? 0);
4691
- done(instance, init.program.module);
4776
+ done(
4777
+ withExitHook(instance, () => atExit()),
4778
+ init.program.module
4779
+ );
4692
4780
  }, failed5);
4693
4781
  return {};
4694
4782
  },
@@ -4721,9 +4809,17 @@ async function runWasmProcess(init, port2, deps = {}) {
4721
4809
  const sigpipe = () => running.sliccSigpipe?.() === 1;
4722
4810
  const restartable = () => signals.restartable();
4723
4811
  const owners = init.owners ? { owners: true } : {};
4724
- const streams = new KernelStreams(running.FS, sys, { sigpipe, restartable, ...owners });
4812
+ const streams = new KernelStreams(running.FS, sys, {
4813
+ sigpipe,
4814
+ restartable,
4815
+ ...owners,
4816
+ program: init.argv0
4817
+ });
4725
4818
  trackCloseOnExec(running.FS);
4726
- quietQuit(running.FS);
4819
+ quietQuit(running.FS, (on) => {
4820
+ streams.quitting = on;
4821
+ });
4822
+ atExit = () => streams.exiting();
4727
4823
  useMounts(running.FS, init.env, true);
4728
4824
  useZeroDevices(running.FS);
4729
4825
  useProcfs(running.FS, sys, init.pid);
@@ -4769,7 +4865,7 @@ async function runWasmProcess(init, port2, deps = {}) {
4769
4865
  restartable
4770
4866
  });
4771
4867
  try {
4772
- return runMain(running, init);
4868
+ return streams.exitStatus(runMain(running, init));
4773
4869
  } finally {
4774
4870
  try {
4775
4871
  vfs.flush();
@@ -4777,10 +4873,27 @@ async function runWasmProcess(init, port2, deps = {}) {
4777
4873
  }
4778
4874
  }
4779
4875
  }
4780
- function quietQuit(Fs) {
4876
+ function withExitHook(instance, begin) {
4877
+ const funcs = instance.exports.__funcs_on_exit;
4878
+ if (typeof funcs !== "function") return instance;
4879
+ const run = funcs;
4880
+ const exported = Object.assign(/* @__PURE__ */ Object.create(null), instance.exports, {
4881
+ __funcs_on_exit: () => {
4882
+ const end = begin();
4883
+ try {
4884
+ run();
4885
+ } finally {
4886
+ end();
4887
+ }
4888
+ }
4889
+ });
4890
+ return { exports: exported };
4891
+ }
4892
+ function quietQuit(Fs, quitting) {
4781
4893
  const { quit, close } = Fs;
4782
4894
  if (!quit) return;
4783
4895
  Fs.quit = () => {
4896
+ quitting?.(true);
4784
4897
  Fs.close = (stream) => {
4785
4898
  try {
4786
4899
  close.call(Fs, stream);
@@ -4790,6 +4903,7 @@ function quietQuit(Fs) {
4790
4903
  try {
4791
4904
  quit.call(Fs);
4792
4905
  } finally {
4906
+ quitting?.(false);
4793
4907
  Fs.close = close;
4794
4908
  }
4795
4909
  };
@@ -4842,7 +4956,7 @@ var init_process_runtime = __esm({
4842
4956
  O_ACCMODE4 = 3;
4843
4957
  O_DIRECTORY = 65536;
4844
4958
  accessMode = (access) => access === "read" ? O_RDONLY : access === "write" ? O_WRONLY3 : O_RDWR3;
4845
- PLACED = /* @__PURE__ */ new Set(["stream", "file", "socket"]);
4959
+ PLACED = /* @__PURE__ */ new Set(["stream", "file", "socket", "clipboard"]);
4846
4960
  GLUE_TRAILER = [
4847
4961
  "if (typeof ENV !== 'undefined') Object.assign(ENV, Module.sliccEnv);",
4848
4962
  "const __sliccTake = (name, value) => {",
@@ -5610,7 +5724,7 @@ function promoteRequest(fd, f, handed) {
5610
5724
  ...f.buffer.handle !== void 0 ? { handle: f.buffer.handle } : {}
5611
5725
  };
5612
5726
  }
5613
- var SYNTHETIC_DIRS2, O_NONBLOCK2, O_WRONLY4, O_RDWR4, O_APPEND, SEALED_PATH2, WasiFds, GEN;
5727
+ var SYNTHETIC_DIRS2, O_NONBLOCK2, O_WRONLY4, O_RDWR4, O_APPEND, SEALED_PATH2, CLIPBOARD_PATH2, WasiFds, GEN;
5614
5728
  var init_wasi_fds = __esm({
5615
5729
  "src/process/wasi/wasi-fds.ts"() {
5616
5730
  "use strict";
@@ -5624,6 +5738,7 @@ var init_wasi_fds = __esm({
5624
5738
  O_RDWR4 = 2;
5625
5739
  O_APPEND = 1024;
5626
5740
  SEALED_PATH2 = "/dev/sealed";
5741
+ CLIPBOARD_PATH2 = "/dev/clipboard";
5627
5742
  WasiFds = class {
5628
5743
  table = /* @__PURE__ */ new Map();
5629
5744
  buffers = /* @__PURE__ */ new Map();
@@ -5924,9 +6039,12 @@ var init_wasi_fds = __esm({
5924
6039
  const e = this.get(fd);
5925
6040
  this.table.delete(fd);
5926
6041
  this.cloexec.delete(fd);
5927
- this.kernel.sys.close(fd);
5928
- this.release(e);
5929
- this.bump();
6042
+ try {
6043
+ this.kernel.sys.close(fd);
6044
+ } finally {
6045
+ this.release(e);
6046
+ this.bump();
6047
+ }
5930
6048
  }
5931
6049
  renumber(from, to, keep = false) {
5932
6050
  const e = this.get(from);
@@ -6089,8 +6207,8 @@ var init_wasi_fds = __esm({
6089
6207
  const joined2 = path.startsWith("/") ? path : `${this.dir(dirfd).path}/${path}`;
6090
6208
  return joined2.split("/").includes("..") ? physical(this.fs, joined2) : normalize(joined2);
6091
6209
  }
6092
- openKernelDevice(path, oflags, fdflags) {
6093
- const { openSealed, openTty } = this.kernel.sys;
6210
+ openKernelDevice(path, oflags, fdflags, rights) {
6211
+ const { openSealed, openClipboard, openTty } = this.kernel.sys;
6094
6212
  const nonblock = (fdflags & FDFLAGS.NONBLOCK) !== 0;
6095
6213
  let fd;
6096
6214
  let kind;
@@ -6099,6 +6217,9 @@ var init_wasi_fds = __esm({
6099
6217
  if (oflags & OFLAGS.CREAT && oflags & OFLAGS.EXCL) throw new WasiError("EEXIST");
6100
6218
  fd = openSealed.call(this.kernel.sys);
6101
6219
  kind = "sealed";
6220
+ } else if (path === CLIPBOARD_PATH2 && openClipboard) {
6221
+ fd = this.openClipboard(openClipboard, oflags, rights);
6222
+ kind = "clipboard";
6102
6223
  } else if (path === "/dev/tty" || /^\/dev\/tty\d+$/.test(path)) {
6103
6224
  fd = openTty?.call(this.kernel.sys, path === "/dev/tty" ? void 0 : path);
6104
6225
  if (fd === void 0) throw new WasiError("ENXIO");
@@ -6108,10 +6229,17 @@ var init_wasi_fds = __esm({
6108
6229
  this.bump();
6109
6230
  return fd;
6110
6231
  }
6232
+ openClipboard(openClipboard, oflags, rights) {
6233
+ if (oflags & OFLAGS.DIRECTORY) throw new WasiError("ENOTDIR");
6234
+ if (oflags & OFLAGS.CREAT && oflags & OFLAGS.EXCL) throw new WasiError("EEXIST");
6235
+ const want = wantOf2(oflags, rights);
6236
+ const flags = want === 6 ? O_RDWR4 : want === 2 ? O_WRONLY4 : 0;
6237
+ return openClipboard.call(this.kernel.sys, flags);
6238
+ }
6111
6239
  open(path, oflags, rights, fdflags) {
6112
6240
  const device2 = deviceOf(path);
6113
6241
  if (device2) return this.install({ type: "device", device: device2 });
6114
- const kernelDevice = this.openKernelDevice(path, oflags, fdflags);
6242
+ const kernelDevice = this.openKernelDevice(path, oflags, fdflags, rights);
6115
6243
  if (kernelDevice !== void 0) return kernelDevice;
6116
6244
  const alias = stdioAlias(path);
6117
6245
  if (alias !== void 0) return this.reopen(alias);
@@ -6554,6 +6682,7 @@ function kernelFiletype(kind) {
6554
6682
  switch (kind) {
6555
6683
  case "tty":
6556
6684
  case "sealed":
6685
+ case "clipboard":
6557
6686
  return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: false };
6558
6687
  case "device":
6559
6688
  return { filetype: FILETYPE.CHARACTER_DEVICE, seeks: true };
@@ -6711,7 +6840,7 @@ var init_wasi_host = __esm({
6711
6840
  const e = fds.get(fd);
6712
6841
  if (e.type === "device") return ROOT_IDS;
6713
6842
  const kind = e.type === "kernel" ? fds.kind(fd, e) : "file";
6714
- if (kind === "sealed") return ROOT_IDS;
6843
+ if (kind === "sealed" || kind === "clipboard") return ROOT_IDS;
6715
6844
  if (kind !== "file") return void 0;
6716
6845
  try {
6717
6846
  return this.o.fs.stat(pathOf(fd));
@@ -6768,12 +6897,12 @@ var init_wasi_host = __esm({
6768
6897
  fd_mode: (fd, out) => {
6769
6898
  const e = fds.get(fd);
6770
6899
  const kind = e.type === "kernel" ? fds.kind(fd, e) : void 0;
6771
- const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" ? SEALED_MODE : modeOf(this.o.fs.stat(pathOf(fd)));
6900
+ const mode = kind === "stream" ? S_IFIFO | 384 : kind === "sealed" || kind === "clipboard" ? SEALED_MODE : modeOf(this.o.fs.stat(pathOf(fd)));
6772
6901
  mem.view().setUint32(out, mode, true);
6773
6902
  },
6774
6903
  path_mode: (dirfd, p, l, flags, out) => {
6775
6904
  const path = at(dirfd, p, l);
6776
- if (path === SEALED_PATH2 && this.o.kernel.sys.openSealed)
6905
+ if (this.synthetic(path) && deviceOf(path) === void 0)
6777
6906
  return void mem.view().setUint32(out, SEALED_MODE, true);
6778
6907
  const st = flags & AT_SYMLINK_NOFOLLOW2 ? this.o.fs.lstat(path) : this.o.fs.stat(path);
6779
6908
  mem.view().setUint32(out, modeOf(st), true);
@@ -7276,7 +7405,7 @@ var init_wasi_host = __esm({
7276
7405
  return gone ? { ...out, nlink: 0n } : out;
7277
7406
  }
7278
7407
  synthetic(path) {
7279
- return deviceOf(path) !== void 0 || path === SEALED_PATH2 && !!this.o.kernel.sys.openSealed;
7408
+ return deviceOf(path) !== void 0 || path === SEALED_PATH2 && !!this.o.kernel.sys.openSealed || path === CLIPBOARD_PATH2 && !!this.o.kernel.sys.openClipboard;
7280
7409
  }
7281
7410
  pathFilestat(path, lookup2) {
7282
7411
  if (this.synthetic(path)) {
@@ -10873,6 +11002,11 @@ var init_async_sab = __esm({
10873
11002
  });
10874
11003
 
10875
11004
  // src/process/js/js-kernel.ts
11005
+ function callError(result, op) {
11006
+ const { errno: errno2, message: message2 } = result;
11007
+ const detailed = typeof message2 === "string" && message2 !== errno2 && DETAILED.has(op);
11008
+ return new JsCallError(errno2, detailed ? `${op}: ${message2}` : op);
11009
+ }
10876
11010
  function untilAborted(work, signal) {
10877
11011
  if (!signal) return work;
10878
11012
  return new Promise((resolve) => {
@@ -10889,7 +11023,7 @@ function caughtOf(handlers) {
10889
11023
  for (const sig of handlers.keys()) caught |= sigbit(sig);
10890
11024
  return caught;
10891
11025
  }
10892
- var JsCallError, JsKernel;
11026
+ var JsCallError, DETAILED, JsKernel;
10893
11027
  var init_js_kernel = __esm({
10894
11028
  "src/process/js/js-kernel.ts"() {
10895
11029
  "use strict";
@@ -10904,6 +11038,12 @@ var init_js_kernel = __esm({
10904
11038
  this.code = code2;
10905
11039
  }
10906
11040
  };
11041
+ DETAILED = /* @__PURE__ */ new Set([
11042
+ "fd-read",
11043
+ "fd-write",
11044
+ "fd-close",
11045
+ "fd-open-clipboard"
11046
+ ]);
10907
11047
  JsKernel = class {
10908
11048
  header;
10909
11049
  transport;
@@ -10930,7 +11070,7 @@ var init_js_kernel = __esm({
10930
11070
  }
10931
11071
  async call(req) {
10932
11072
  const result = await this.raw(req);
10933
- if (!result.ok) throw new JsCallError(result.errno, req.op);
11073
+ if (!result.ok) throw callError(result, req.op);
10934
11074
  return result;
10935
11075
  }
10936
11076
  async json(req) {
@@ -10946,7 +11086,7 @@ var init_js_kernel = __esm({
10946
11086
  const id = await this.submit(req, track);
10947
11087
  const result = await this.settled(id, signal);
10948
11088
  if (result.ok) return result;
10949
- if (result.errno !== "EINTR") throw new JsCallError(result.errno, req.op);
11089
+ if (result.errno !== "EINTR") throw callError(result, req.op);
10950
11090
  }
10951
11091
  }
10952
11092
  acks = [];
@@ -11326,6 +11466,7 @@ function* lookup(abs) {
11326
11466
  const name2 = abs.slice("/dev/".length);
11327
11467
  if (DEVICES2.includes(name2)) return { kind: "device" };
11328
11468
  if (name2 === "tty") return { kind: "tty" };
11469
+ if (name2 === "clipboard") return { kind: "clipboard" };
11329
11470
  const std = STDIO3.indexOf(name2);
11330
11471
  if (std >= 0) return { kind: "link", target: `${SELF_FD}/${std}`, fd: std };
11331
11472
  if (name2 === "fd") return { kind: "link", target: SELF_FD };
@@ -11369,7 +11510,8 @@ function* fdStat(fd, path) {
11369
11510
  return yield* pathStat(file.path);
11370
11511
  }
11371
11512
  if (info.terminal) return yield* terminalStat(info.terminal);
11372
- if (info.kind === "device" || info.kind === "tty") return nodeStat(CHAR | 438);
11513
+ if (info.kind === "device" || info.kind === "tty" || info.kind === "clipboard")
11514
+ return nodeStat(CHAR | 438);
11373
11515
  if (info.kind === "socket") return nodeStat(49663);
11374
11516
  return nodeStat(4480);
11375
11517
  }
@@ -11379,6 +11521,7 @@ function* fdTarget(fd, path) {
11379
11521
  if (info.kind === "file") return (yield { op: "fd-vfs-stat", fd }).path;
11380
11522
  if (info.terminal) return info.terminal;
11381
11523
  if (info.meta && "device" in info.meta) return `/dev/${info.meta.device}`;
11524
+ if (info.kind === "clipboard") return "/dev/clipboard";
11382
11525
  return `${info.kind === "socket" ? "socket" : "pipe"}:[${fd}]`;
11383
11526
  }
11384
11527
  function linkStat(target) {
@@ -11391,6 +11534,7 @@ function* devStat(abs, follow2) {
11391
11534
  return nodeStat(node.mode);
11392
11535
  case "device":
11393
11536
  case "tty":
11537
+ case "clipboard":
11394
11538
  return nodeStat(CHAR | 438);
11395
11539
  case "terminal":
11396
11540
  return yield* terminalStat(node.name);
@@ -11425,7 +11569,7 @@ function* devReaddir(abs) {
11425
11569
  if (node.kind !== "dir") throw new JsCallError("ENOTDIR", abs);
11426
11570
  const names = yield { op: "fd-tty-names" };
11427
11571
  const ttys = names.filter((n) => /^\/dev\/tty\d+$/.test(n)).map((n) => n.slice(5));
11428
- return [...DEVICES2, "tty", "fd", ...STDIO3, ...ttys].sort();
11572
+ return [...DEVICES2, "clipboard", "tty", "fd", ...STDIO3, ...ttys].sort();
11429
11573
  }
11430
11574
  function* aliasOf(fd, abs, o) {
11431
11575
  const info = yield* fdInfo(fd, abs);
@@ -11454,6 +11598,11 @@ function* opened(abs, o) {
11454
11598
  return { fd: yield openRequest(abs, { ...o, create: false }), file: false };
11455
11599
  case "tty":
11456
11600
  return { fd: yield { op: "fd-open-tty" }, file: false };
11601
+ case "clipboard": {
11602
+ const write2 = o.write === true || o.append === true || o.truncate === true;
11603
+ const flags = write2 ? o.read === true ? 2 : 1 : 0;
11604
+ return { fd: yield { op: "fd-open-clipboard", flags }, file: false };
11605
+ }
11457
11606
  case "terminal": {
11458
11607
  const req = node.pts === void 0 ? { op: "fd-open-tty", name: node.name } : { op: "pty-slave-open", n: node.pts, noctty: true };
11459
11608
  return { fd: yield req, file: false };
@@ -12496,7 +12645,7 @@ var init_js_sync = __esm({
12496
12645
  }
12497
12646
  call(req) {
12498
12647
  const result = this.raw(req);
12499
- if (!result.ok) throw new JsCallError(result.errno, req.op);
12648
+ if (!result.ok) throw callError(result, req.op);
12500
12649
  return result;
12501
12650
  }
12502
12651
  json(req) {
@@ -12511,7 +12660,7 @@ var init_js_sync = __esm({
12511
12660
  for (; ; ) {
12512
12661
  const result = this.raw(req);
12513
12662
  if (result.ok) return result;
12514
- if (result.errno !== "EINTR") throw new JsCallError(result.errno, req.op);
12663
+ if (result.errno !== "EINTR") throw callError(result, req.op);
12515
12664
  }
12516
12665
  }
12517
12666
  };
@@ -13103,7 +13252,7 @@ async function receiveSome(kernel, fd, max, signal) {
13103
13252
  signal.throwIfAborted();
13104
13253
  const r = await kernel.raw({ op: "fd-read", fd, max, nonblock: true });
13105
13254
  if (r.ok) return r.kind === "bytes" ? r.bytes : new Uint8Array(0);
13106
- if (r.errno !== "EAGAIN") throw new JsCallError(r.errno, "fd-read");
13255
+ if (r.errno !== "EAGAIN") throw callError(r, "fd-read");
13107
13256
  await kernel.blocking({ op: "fd-select", read: [fd], write: [], timeoutMs: -1 }, signal);
13108
13257
  }
13109
13258
  }
@@ -13112,7 +13261,7 @@ async function sendSome(kernel, fd, body, signal) {
13112
13261
  signal.throwIfAborted();
13113
13262
  const r = await kernel.raw({ op: "fd-write", fd, body, nonblock: true });
13114
13263
  if (r.ok) return written(r, body.length);
13115
- if (r.errno !== "EAGAIN") throw new JsCallError(r.errno, "fd-write");
13264
+ if (r.errno !== "EAGAIN") throw callError(r, "fd-write");
13116
13265
  await kernel.blocking({ op: "fd-select", read: [], write: [fd], timeoutMs: -1 }, signal);
13117
13266
  }
13118
13267
  }