@ai-ecoverse/slicc-kernel 1.174.2 → 1.175.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.
@@ -3118,7 +3118,7 @@ var init_version = __esm({
3118
3118
  "src/version.ts"() {
3119
3119
  "use strict";
3120
3120
  init_captured_globals();
3121
- KERNEL_VERSION = true ? "1.174.2" : "0.0.0-dev";
3121
+ KERNEL_VERSION = true ? "1.175.0" : "0.0.0-dev";
3122
3122
  OS_RELEASE = "6.0.0-slicc";
3123
3123
  }
3124
3124
  });
@@ -29,7 +29,7 @@ export type { EmbedderHook, EmbedderKindPolicy, EmbedderReply, EmbedderRequest,
29
29
  export type { RouteTable } from './kernel/net/routes.js';
30
30
  export { SEALED_FETCH_VERSION, type SealedFetchHook, type SealedFetchRequest, type SealedOption, } from './kernel/net/sealed-fetch.js';
31
31
  export type { NetworkUplink, ResolveAnswer, ResolveFamily, UplinkTraits, } from './kernel/net/uplink.js';
32
- export type { SealedAbortReason, SealedCaller, SealedHook, SealedRequest, } from './kernel/sealed.js';
32
+ export type { SealedAbortReason, SealedCaller, SealedHook, SealedRequest, SealedRequester, } from './kernel/sealed.js';
33
33
  export type { ConnectorStamp } from './kernel/socket.js';
34
34
  export type { HostfsEvent, HostfsGrant, HostfsGrantHook, HostfsPortGrant, HostfsTransport, } from './mount/hostfs.js';
35
35
  export { serveHostfsPort } from './mount/hostfs.js';
@@ -542,6 +542,7 @@ export declare class WasmProcess {
542
542
  private stampClipboards;
543
543
  connectorStamp(): Promise<SealedCaller>;
544
544
  private sealedCaller;
545
+ private sealedRequester;
545
546
  private guarded;
546
547
  private ttyOwner;
547
548
  private terminalByName;
@@ -1,4 +1,5 @@
1
1
  import type { UsersMode } from '../fs/types.js';
2
+ import type { SudoStdin } from '../sudo.js';
2
3
  import type { Cred } from './cred.js';
3
4
  import { TicketBook } from './exec-ticket.js';
4
5
  import { type OpenAccess, OpenFile, type PollState } from './fd-table.js';
@@ -8,6 +9,10 @@ import { type SessionAnchorFields, type SessionFields } from './sealed-session.j
8
9
  export declare const SEALED_PATH = "/dev/sealed";
9
10
  export declare const SEALED_MAX_BYTES: number;
10
11
  export declare const SEALED_TIMEOUT_MS = 10000;
12
+ export declare const SEALED_ASK_TIMEOUT_MS = 305000;
13
+ export declare const SEALED_NAME: RegExp;
14
+ export declare const SEALED_NAME_MAX = 128;
15
+ export declare const SEALED_PROMPT_MAX = 200;
11
16
  export declare const SEALED_OPS: ReadonlySet<string>;
12
17
  export interface SealedCaller {
13
18
  pid: number;
@@ -32,7 +37,17 @@ export type SealedRequest = {
32
37
  export type SealedHook = (req: SealedRequest, options: {
33
38
  signal: AbortSignal;
34
39
  }) => Promise<object>;
35
- export type SealedAbortReason = 'replaced' | 'timeout' | 'withdrawn';
40
+ export type SealedAbortReason = 'expired' | 'replaced' | 'timeout' | 'withdrawn';
41
+ export interface SealedProcessFacts {
42
+ exe: string;
43
+ argv: string[];
44
+ cwd: string;
45
+ tty: string | null;
46
+ }
47
+ export interface SealedRequester extends SealedProcessFacts {
48
+ stdin: SudoStdin;
49
+ }
50
+ export type SealedRequesterOf = () => Promise<SealedRequester | undefined>;
36
51
  export declare function parseSealed(bytes: Uint8Array): Record<string, unknown>;
37
52
  declare class SealedChannel {
38
53
  private reply;
@@ -41,7 +56,9 @@ declare class SealedChannel {
41
56
  private readonly broker;
42
57
  readonly access: OpenAccess;
43
58
  constructor(broker: SealedBroker, access: OpenAccess);
44
- send(bytes: Uint8Array, caller: SealedCaller, gone: AbortSignal): number;
59
+ send(bytes: Uint8Array, caller: SealedCaller, gone: AbortSignal, requester?: SealedRequesterOf): number;
60
+ private asking;
61
+ private stopped;
45
62
  private answer;
46
63
  private drop;
47
64
  read(max: number, signal?: AbortSignal): Promise<Uint8Array>;
@@ -71,7 +88,9 @@ export declare class SealedBroker {
71
88
  readonly tagOf: (pid: number) => readonly string[] | undefined;
72
89
  readonly tickets: TicketBook;
73
90
  readonly sessions: SessionScrubs;
91
+ askTimeoutMs: number;
74
92
  userOf: (uid: number) => Promise<string | undefined>;
93
+ factsOf: (pid: number) => Promise<SealedProcessFacts | undefined>;
75
94
  constructor(hook: SealedHook | undefined, users: UsersMode, timeoutMs?: number, tagOf?: (pid: number) => readonly string[] | undefined);
76
95
  stamp(ids: {
77
96
  pid: number;
@@ -143,6 +143,7 @@ export interface RunResult {
143
143
  }
144
144
  interface Target {
145
145
  abi: Abi;
146
+ command?: string;
146
147
  glue: string;
147
148
  wasm: string;
148
149
  argv0: string;
@@ -198,6 +199,8 @@ export declare class Launcher {
198
199
  private readonly orphans;
199
200
  private readonly described;
200
201
  private readonly creds;
202
+ private readonly programs;
203
+ private readonly cwdPaths;
201
204
  private readonly tags;
202
205
  private readonly sessions;
203
206
  private readonly tagBases;
@@ -404,6 +407,7 @@ export declare class Launcher {
404
407
  private running;
405
408
  private decide;
406
409
  private heldFor;
410
+ private processFacts;
407
411
  private chdirHeld;
408
412
  private forker;
409
413
  private keySignal;
@@ -28,7 +28,7 @@ export type { ConnectOptions, Ended, KernelGroups, KernelIntegrity, KernelSealed
28
28
  export type { ClipboardHook, ClipboardStamp } from './kernel/clipboard.js';
29
29
  export type { EmbedderHook, EmbedderKindPolicy, EmbedderReply, EmbedderRequest, EmbedderStamp, } from './kernel/embedder.js';
30
30
  export { SEALED_FETCH_VERSION, type SealedFetchHook, type SealedFetchRequest, type SealedOption, } from './kernel/net/sealed-fetch.js';
31
- export type { SealedAbortReason, SealedCaller, SealedHook, SealedRequest, } from './kernel/sealed.js';
31
+ export type { SealedAbortReason, SealedCaller, SealedHook, SealedRequest, SealedRequester, } from './kernel/sealed.js';
32
32
  export type { ConnectorStamp } from './kernel/socket.js';
33
33
  export type { HostfsEvent, HostfsGrant, HostfsGrantHook, HostfsPortGrant, HostfsTransport, } from './mount/hostfs.js';
34
34
  export { serveHostfsPort } from './mount/hostfs.js';
@@ -0,0 +1,4 @@
1
+ import type { Command } from './commands.js';
2
+ export declare const SEALED_BIN = "/usr/bin/sealed";
3
+ export declare const SEALED_COMMAND: Command;
4
+ export declare const SEALED_SOURCE = "export default async function sealed(ctx) {\n const USAGE = \"usage: sealed ask NAME [--prompt TEXT] [--reveal] [--replace]\\n sealed placeholder NAME\\n sealed list [--json]\\n\";\n const NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;\n const EXIT = { EINVAL: 2, EACCES: 3, EAGAIN: 4, ETIMEDOUT: 124 };\n const say = (fd, text) => ctx.write(fd, text).catch(() => undefined);\n const fail = async (status, text) => {\n await say(2, \"sealed: \" + text + \"\\n\");\n return status;\n };\n const usage = async (text) => {\n if (text !== undefined) await say(2, \"sealed: \" + text + \"\\n\");\n await say(2, USAGE);\n return 2;\n };\n const [action, ...args] = ctx.argv.slice(1);\n if (action === undefined || action === \"-h\" || action === \"--help\") return usage();\n let name;\n let prompt;\n let reveal = false;\n let replace = false;\n let asJson = false;\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (action === \"ask\" && arg === \"--prompt\") {\n prompt = args[++i];\n if (prompt === undefined) return usage(\"--prompt needs a text\");\n } else if (action === \"ask\" && arg.startsWith(\"--prompt=\")) prompt = arg.slice(9);\n else if (action === \"ask\" && arg === \"--reveal\") reveal = true;\n else if (action === \"ask\" && arg === \"--replace\") replace = true;\n else if (action === \"list\" && arg === \"--json\") asJson = true;\n else if (action !== \"list\" && name === undefined && !arg.startsWith(\"-\")) name = arg;\n else return usage(\"unexpected argument \" + JSON.stringify(arg));\n }\n let request;\n if (action === \"ask\" || action === \"placeholder\") {\n if (name === undefined) return usage(\"a NAME is needed\");\n if (name.length > 128 || !NAME.test(name)) return fail(2, JSON.stringify(name) + \" is not a valid name\");\n if (prompt !== undefined && [...prompt].length > 200) return fail(2, \"the prompt is longer than 200 characters\");\n request = action === \"ask\"\n ? { v: 1, op: \"ask\", name, ...(prompt !== undefined ? { prompt } : {}), reveal, replace }\n : { v: 1, op: \"placeholder\", name };\n } else if (action === \"list\") request = { v: 1, op: \"list\" };\n else return usage(\"unknown command \" + JSON.stringify(action));\n let reply;\n try {\n reply = await exchange(request);\n } catch (err) {\n const code = err && err.code ? err.code : String(err);\n return fail(EXIT[code] ?? 1, \"/dev/sealed: \" + code);\n }\n if (reply.error !== undefined) {\n const code = String(reply.error && reply.error.code);\n const message = reply.error && reply.error.message ? reply.error.message : code;\n return fail(EXIT[code] ?? 1, (name !== undefined ? name + \": \" : \"\") + message);\n }\n const newline = (await ctx.isatty(1).catch(() => false)) ? \"\\n\" : \"\";\n if (action === \"list\") {\n const secrets = Array.isArray(reply.secrets) ? reply.secrets : [];\n if (asJson) {\n await say(1, JSON.stringify(secrets) + \"\\n\");\n return 0;\n }\n await say(1, secrets.map((s) => s.name + \"\\t\" + s.placeholder + \"\\t\" + s.state + \"\\n\").join(\"\"));\n return 0;\n }\n if (action === \"placeholder\") {\n if (typeof reply.placeholder !== \"string\") return fail(1, name + \": the vault gave no placeholder\");\n await say(1, reply.placeholder + newline);\n return 0;\n }\n if (reply.state === \"cancelled\") return fail(1, name + \": cancelled\");\n if (reply.state === \"expired\") return fail(124, name + \": the request expired\");\n if (reply.state !== \"done\") return fail(1, name + \": the vault gave no answer\");\n const out = reveal ? reply.value : reply.placeholder;\n if (typeof out !== \"string\") return fail(1, name + \": the vault gave no \" + (reveal ? \"value\" : \"placeholder\"));\n await say(1, out + newline);\n return 0;\n\n async function exchange(req) {\n const file = await ctx.open(\"/dev/sealed\", { read: true, write: true });\n try {\n await ctx.write(file.fd, JSON.stringify(req));\n const parts = [];\n for (;;) {\n const chunk = await ctx.read(file.fd, 65536);\n if (chunk.length === 0) break;\n parts.push(chunk);\n }\n const bytes = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));\n let at = 0;\n for (const part of parts) {\n bytes.set(part, at);\n at += part.length;\n part.fill(0);\n }\n const text = new TextDecoder().decode(bytes);\n bytes.fill(0);\n const parsed = JSON.parse(text);\n if (typeof parsed !== \"object\" || parsed === null) throw Object.assign(new Error(\"EIO\"), { code: \"EIO\" });\n return parsed;\n } finally {\n await file.close().catch(() => undefined);\n }\n }\n}\n";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-kernel",
3
- "version": "1.174.2",
3
+ "version": "1.175.0",
4
4
  "description": "SLICC's wasm-realm kernel: run Emscripten programs in the browser against OPFS, with fork, spawn, pipes and waitpid",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -70,7 +70,7 @@
70
70
  },
71
71
  "devDependencies": {
72
72
  "@ai-ecoverse/py-numpy": "2.5.4-4",
73
- "@ai-ecoverse/slicc-cdp": "1.46.2",
73
+ "@ai-ecoverse/slicc-cdp": "1.46.4",
74
74
  "@ai-ecoverse/slicc-scrub": "1.1.0",
75
75
  "@ai-ecoverse/slicc-shared-web": "2.13.10",
76
76
  "@ai-ecoverse/wasi-cargo": "0.99.0-6",