@secure-exec/core 0.0.0-main.bccb3a2

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.
Files changed (271) hide show
  1. package/README.md +7 -0
  2. package/commands/[ +0 -0
  3. package/commands/_stubs +0 -0
  4. package/commands/arch +0 -0
  5. package/commands/awk +0 -0
  6. package/commands/b2sum +0 -0
  7. package/commands/base32 +0 -0
  8. package/commands/base64 +0 -0
  9. package/commands/basename +0 -0
  10. package/commands/basenc +0 -0
  11. package/commands/bash +0 -0
  12. package/commands/cat +0 -0
  13. package/commands/chcon +0 -0
  14. package/commands/chgrp +0 -0
  15. package/commands/chmod +0 -0
  16. package/commands/chown +0 -0
  17. package/commands/chroot +0 -0
  18. package/commands/cksum +0 -0
  19. package/commands/codex +0 -0
  20. package/commands/codex-exec +0 -0
  21. package/commands/column +0 -0
  22. package/commands/comm +0 -0
  23. package/commands/cp +0 -0
  24. package/commands/curl +0 -0
  25. package/commands/cut +0 -0
  26. package/commands/date +0 -0
  27. package/commands/dd +0 -0
  28. package/commands/df +0 -0
  29. package/commands/diff +0 -0
  30. package/commands/dir +0 -0
  31. package/commands/dircolors +0 -0
  32. package/commands/dirname +0 -0
  33. package/commands/du +0 -0
  34. package/commands/echo +0 -0
  35. package/commands/egrep +0 -0
  36. package/commands/env +0 -0
  37. package/commands/expand +0 -0
  38. package/commands/expr +0 -0
  39. package/commands/factor +0 -0
  40. package/commands/false +0 -0
  41. package/commands/fd +0 -0
  42. package/commands/fgrep +0 -0
  43. package/commands/file +0 -0
  44. package/commands/find +0 -0
  45. package/commands/fmt +0 -0
  46. package/commands/fold +0 -0
  47. package/commands/git +0 -0
  48. package/commands/grep +0 -0
  49. package/commands/groups +0 -0
  50. package/commands/gunzip +0 -0
  51. package/commands/gzip +0 -0
  52. package/commands/head +0 -0
  53. package/commands/hostid +0 -0
  54. package/commands/hostname +0 -0
  55. package/commands/http-test +0 -0
  56. package/commands/id +0 -0
  57. package/commands/install +0 -0
  58. package/commands/join +0 -0
  59. package/commands/jq +0 -0
  60. package/commands/kill +0 -0
  61. package/commands/link +0 -0
  62. package/commands/ln +0 -0
  63. package/commands/logname +0 -0
  64. package/commands/ls +0 -0
  65. package/commands/md5sum +0 -0
  66. package/commands/mkdir +0 -0
  67. package/commands/mkfifo +0 -0
  68. package/commands/mknod +0 -0
  69. package/commands/mktemp +0 -0
  70. package/commands/more +0 -0
  71. package/commands/mv +0 -0
  72. package/commands/nice +0 -0
  73. package/commands/nl +0 -0
  74. package/commands/nohup +0 -0
  75. package/commands/nproc +0 -0
  76. package/commands/numfmt +0 -0
  77. package/commands/od +0 -0
  78. package/commands/paste +0 -0
  79. package/commands/pathchk +0 -0
  80. package/commands/pinky +0 -0
  81. package/commands/printenv +0 -0
  82. package/commands/printf +0 -0
  83. package/commands/ptx +0 -0
  84. package/commands/pwd +0 -0
  85. package/commands/readlink +0 -0
  86. package/commands/realpath +0 -0
  87. package/commands/rev +0 -0
  88. package/commands/rg +0 -0
  89. package/commands/rm +0 -0
  90. package/commands/rmdir +0 -0
  91. package/commands/runcon +0 -0
  92. package/commands/sed +0 -0
  93. package/commands/seq +0 -0
  94. package/commands/sh +0 -0
  95. package/commands/sha1sum +0 -0
  96. package/commands/sha224sum +0 -0
  97. package/commands/sha256sum +0 -0
  98. package/commands/sha384sum +0 -0
  99. package/commands/sha512sum +0 -0
  100. package/commands/shred +0 -0
  101. package/commands/shuf +0 -0
  102. package/commands/sleep +0 -0
  103. package/commands/sort +0 -0
  104. package/commands/spawn-test-host +0 -0
  105. package/commands/split +0 -0
  106. package/commands/stat +0 -0
  107. package/commands/stdbuf +0 -0
  108. package/commands/strings +0 -0
  109. package/commands/stty +0 -0
  110. package/commands/sum +0 -0
  111. package/commands/sync +0 -0
  112. package/commands/tac +0 -0
  113. package/commands/tail +0 -0
  114. package/commands/tar +0 -0
  115. package/commands/tee +0 -0
  116. package/commands/test +0 -0
  117. package/commands/timeout +0 -0
  118. package/commands/touch +0 -0
  119. package/commands/tr +0 -0
  120. package/commands/tree +0 -0
  121. package/commands/true +0 -0
  122. package/commands/truncate +0 -0
  123. package/commands/tsort +0 -0
  124. package/commands/tty +0 -0
  125. package/commands/uname +0 -0
  126. package/commands/unexpand +0 -0
  127. package/commands/uniq +0 -0
  128. package/commands/unlink +0 -0
  129. package/commands/uptime +0 -0
  130. package/commands/users +0 -0
  131. package/commands/vdir +0 -0
  132. package/commands/wc +0 -0
  133. package/commands/which +0 -0
  134. package/commands/who +0 -0
  135. package/commands/whoami +0 -0
  136. package/commands/xargs +0 -0
  137. package/commands/xu +0 -0
  138. package/commands/yes +0 -0
  139. package/commands/yq +0 -0
  140. package/commands/zcat +0 -0
  141. package/dist/binary.d.ts +4 -0
  142. package/dist/binary.js +25 -0
  143. package/dist/bytes.d.ts +2 -0
  144. package/dist/bytes.js +6 -0
  145. package/dist/callbacks.d.ts +41 -0
  146. package/dist/callbacks.js +94 -0
  147. package/dist/cargo.d.ts +2 -0
  148. package/dist/cargo.js +142 -0
  149. package/dist/correlation.d.ts +10 -0
  150. package/dist/correlation.js +49 -0
  151. package/dist/descriptors.d.ts +34 -0
  152. package/dist/descriptors.js +37 -0
  153. package/dist/event-buffer.d.ts +90 -0
  154. package/dist/event-buffer.js +313 -0
  155. package/dist/ext.d.ts +7 -0
  156. package/dist/ext.js +13 -0
  157. package/dist/filesystem.d.ts +41 -0
  158. package/dist/filesystem.js +70 -0
  159. package/dist/frame-payload-codec.d.ts +8 -0
  160. package/dist/frame-payload-codec.js +14 -0
  161. package/dist/frame-rpc.d.ts +38 -0
  162. package/dist/frame-rpc.js +73 -0
  163. package/dist/frame-stream.d.ts +27 -0
  164. package/dist/frame-stream.js +99 -0
  165. package/dist/framing.d.ts +7 -0
  166. package/dist/framing.js +22 -0
  167. package/dist/generated/AcpLimitsConfig.d.ts +4 -0
  168. package/dist/generated/AcpLimitsConfig.js +2 -0
  169. package/dist/generated/CreateVmConfig.d.ts +19 -0
  170. package/dist/generated/CreateVmConfig.js +1 -0
  171. package/dist/generated/FsPermissionRule.d.ts +6 -0
  172. package/dist/generated/FsPermissionRule.js +1 -0
  173. package/dist/generated/FsPermissionRuleSet.d.ts +6 -0
  174. package/dist/generated/FsPermissionRuleSet.js +1 -0
  175. package/dist/generated/FsPermissionScope.d.ts +3 -0
  176. package/dist/generated/FsPermissionScope.js +1 -0
  177. package/dist/generated/HttpLimitsConfig.d.ts +3 -0
  178. package/dist/generated/HttpLimitsConfig.js +2 -0
  179. package/dist/generated/JsModuleResolution.d.ts +1 -0
  180. package/dist/generated/JsModuleResolution.js +2 -0
  181. package/dist/generated/JsRuntimeConfig.d.ts +26 -0
  182. package/dist/generated/JsRuntimeConfig.js +1 -0
  183. package/dist/generated/JsRuntimeLimitsConfig.d.ts +8 -0
  184. package/dist/generated/JsRuntimeLimitsConfig.js +2 -0
  185. package/dist/generated/JsRuntimePlatform.d.ts +1 -0
  186. package/dist/generated/JsRuntimePlatform.js +2 -0
  187. package/dist/generated/MountPluginDescriptor.d.ts +4 -0
  188. package/dist/generated/MountPluginDescriptor.js +2 -0
  189. package/dist/generated/NativeRootFilesystemConfig.d.ts +5 -0
  190. package/dist/generated/NativeRootFilesystemConfig.js +1 -0
  191. package/dist/generated/PatternPermissionRule.d.ts +6 -0
  192. package/dist/generated/PatternPermissionRule.js +1 -0
  193. package/dist/generated/PatternPermissionRuleSet.d.ts +6 -0
  194. package/dist/generated/PatternPermissionRuleSet.js +1 -0
  195. package/dist/generated/PatternPermissionScope.d.ts +3 -0
  196. package/dist/generated/PatternPermissionScope.js +1 -0
  197. package/dist/generated/PermissionMode.d.ts +1 -0
  198. package/dist/generated/PermissionMode.js +2 -0
  199. package/dist/generated/PermissionsPolicy.d.ts +10 -0
  200. package/dist/generated/PermissionsPolicy.js +1 -0
  201. package/dist/generated/PluginLimitsConfig.d.ts +4 -0
  202. package/dist/generated/PluginLimitsConfig.js +2 -0
  203. package/dist/generated/PythonLimitsConfig.d.ts +6 -0
  204. package/dist/generated/PythonLimitsConfig.js +2 -0
  205. package/dist/generated/ResourceLimitsConfig.d.ts +22 -0
  206. package/dist/generated/ResourceLimitsConfig.js +2 -0
  207. package/dist/generated/RootFilesystemConfig.d.ts +9 -0
  208. package/dist/generated/RootFilesystemConfig.js +1 -0
  209. package/dist/generated/RootFilesystemEntry.d.ts +13 -0
  210. package/dist/generated/RootFilesystemEntry.js +1 -0
  211. package/dist/generated/RootFilesystemEntryEncoding.d.ts +1 -0
  212. package/dist/generated/RootFilesystemEntryEncoding.js +2 -0
  213. package/dist/generated/RootFilesystemEntryKind.d.ts +1 -0
  214. package/dist/generated/RootFilesystemEntryKind.js +2 -0
  215. package/dist/generated/RootFilesystemLowerDescriptor.d.ts +7 -0
  216. package/dist/generated/RootFilesystemLowerDescriptor.js +1 -0
  217. package/dist/generated/RootFilesystemMode.d.ts +1 -0
  218. package/dist/generated/RootFilesystemMode.js +2 -0
  219. package/dist/generated/ToolLimitsConfig.d.ts +10 -0
  220. package/dist/generated/ToolLimitsConfig.js +2 -0
  221. package/dist/generated/VmDnsConfig.d.ts +6 -0
  222. package/dist/generated/VmDnsConfig.js +2 -0
  223. package/dist/generated/VmLimitsConfig.d.ts +18 -0
  224. package/dist/generated/VmLimitsConfig.js +1 -0
  225. package/dist/generated/VmListenPolicyConfig.d.ts +5 -0
  226. package/dist/generated/VmListenPolicyConfig.js +2 -0
  227. package/dist/generated/WasmLimitsConfig.d.ts +5 -0
  228. package/dist/generated/WasmLimitsConfig.js +2 -0
  229. package/dist/generated-protocol.d.ts +1037 -0
  230. package/dist/generated-protocol.js +2887 -0
  231. package/dist/index.d.ts +26 -0
  232. package/dist/index.js +25 -0
  233. package/dist/json.d.ts +2 -0
  234. package/dist/json.js +20 -0
  235. package/dist/kernel-proxy.d.ts +151 -0
  236. package/dist/kernel-proxy.js +1737 -0
  237. package/dist/native-client.d.ts +41 -0
  238. package/dist/native-client.js +124 -0
  239. package/dist/node-runtime.d.ts +516 -0
  240. package/dist/node-runtime.js +794 -0
  241. package/dist/numbers.d.ts +1 -0
  242. package/dist/numbers.js +8 -0
  243. package/dist/ownership.d.ts +18 -0
  244. package/dist/ownership.js +77 -0
  245. package/dist/permissions.d.ts +29 -0
  246. package/dist/permissions.js +68 -0
  247. package/dist/process.d.ts +35 -0
  248. package/dist/process.js +125 -0
  249. package/dist/protocol-client.d.ts +46 -0
  250. package/dist/protocol-client.js +180 -0
  251. package/dist/protocol-frames.d.ts +68 -0
  252. package/dist/protocol-frames.js +139 -0
  253. package/dist/protocol-maps.d.ts +28 -0
  254. package/dist/protocol-maps.js +217 -0
  255. package/dist/protocol-schema.d.ts +10 -0
  256. package/dist/protocol-schema.js +11 -0
  257. package/dist/request-payloads.d.ts +137 -0
  258. package/dist/request-payloads.js +210 -0
  259. package/dist/response-payloads.d.ts +107 -0
  260. package/dist/response-payloads.js +161 -0
  261. package/dist/sidecar-client.d.ts +242 -0
  262. package/dist/sidecar-client.js +797 -0
  263. package/dist/state.d.ts +40 -0
  264. package/dist/state.js +44 -0
  265. package/dist/test-runtime.d.ts +534 -0
  266. package/dist/test-runtime.js +2146 -0
  267. package/dist/vm-config.d.ts +31 -0
  268. package/dist/vm-config.js +1 -0
  269. package/fixtures/alpine-defaults.json +520 -0
  270. package/fixtures/base-filesystem.json +528 -0
  271. package/package.json +197 -0
package/dist/cargo.js ADDED
@@ -0,0 +1,142 @@
1
+ import { accessSync, constants as fsConstants, existsSync, readFileSync, readdirSync, statSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import path from "node:path";
4
+ const CARGO_BINARY_NAME = process.platform === "win32" ? "cargo.exe" : "cargo";
5
+ function hasPathSeparator(candidate) {
6
+ return candidate.includes("/") || candidate.includes("\\");
7
+ }
8
+ function isExecutableFile(candidate) {
9
+ try {
10
+ if (!statSync(candidate).isFile()) {
11
+ return false;
12
+ }
13
+ accessSync(candidate, fsConstants.X_OK);
14
+ return true;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ function resolveExecutableOnPath(binaryName) {
21
+ const pathEntries = (process.env.PATH ?? "")
22
+ .split(path.delimiter)
23
+ .map((entry) => entry.trim())
24
+ .filter(Boolean);
25
+ for (const entry of pathEntries) {
26
+ const candidate = path.join(entry, binaryName);
27
+ if (isExecutableFile(candidate)) {
28
+ return candidate;
29
+ }
30
+ }
31
+ return null;
32
+ }
33
+ function resolveExecutableCandidate(candidate) {
34
+ if (hasPathSeparator(candidate)) {
35
+ return isExecutableFile(candidate) ? candidate : null;
36
+ }
37
+ return resolveExecutableOnPath(candidate);
38
+ }
39
+ function getToolchainCargoFromRustupHome(rustupHome) {
40
+ const toolchainsDir = path.join(rustupHome, "toolchains");
41
+ if (!existsSync(toolchainsDir)) {
42
+ return null;
43
+ }
44
+ const settingsPath = path.join(rustupHome, "settings.toml");
45
+ const orderedToolchains = [];
46
+ if (existsSync(settingsPath)) {
47
+ const defaultToolchain = readFileSync(settingsPath, "utf8")
48
+ .match(/^default_toolchain\s*=\s*"([^"]+)"/m)?.[1]
49
+ ?.trim();
50
+ if (defaultToolchain) {
51
+ orderedToolchains.push(defaultToolchain);
52
+ }
53
+ }
54
+ for (const entry of readdirSync(toolchainsDir)) {
55
+ if (!orderedToolchains.includes(entry)) {
56
+ orderedToolchains.push(entry);
57
+ }
58
+ }
59
+ for (const toolchain of orderedToolchains) {
60
+ const cargoPath = path.join(toolchainsDir, toolchain, "bin", CARGO_BINARY_NAME);
61
+ if (existsSync(cargoPath)) {
62
+ return { cargoPath, rustupHome };
63
+ }
64
+ }
65
+ return null;
66
+ }
67
+ function inferRustupHomesFromPath() {
68
+ const rustupHomes = new Set();
69
+ const pathEntries = (process.env.PATH ?? "")
70
+ .split(path.delimiter)
71
+ .map((entry) => entry.trim())
72
+ .filter(Boolean);
73
+ for (const entry of pathEntries) {
74
+ if (path.basename(entry) !== "bin") {
75
+ continue;
76
+ }
77
+ const parentDir = path.dirname(entry);
78
+ if (existsSync(path.join(parentDir, "toolchains"))) {
79
+ rustupHomes.add(parentDir);
80
+ }
81
+ const siblingRoot = path.dirname(parentDir);
82
+ try {
83
+ for (const sibling of readdirSync(siblingRoot, { withFileTypes: true })) {
84
+ if (!sibling.isDirectory()) {
85
+ continue;
86
+ }
87
+ const siblingPath = path.join(siblingRoot, sibling.name);
88
+ if (existsSync(path.join(siblingPath, "toolchains"))) {
89
+ rustupHomes.add(siblingPath);
90
+ }
91
+ }
92
+ }
93
+ catch { }
94
+ }
95
+ return [...rustupHomes];
96
+ }
97
+ function ensureToolchainEnvironment(toolchainCargo) {
98
+ const toolchainBin = path.dirname(toolchainCargo.cargoPath);
99
+ const currentPathEntries = (process.env.PATH ?? "")
100
+ .split(path.delimiter)
101
+ .filter(Boolean);
102
+ if (!currentPathEntries.includes(toolchainBin)) {
103
+ process.env.PATH = [toolchainBin, ...currentPathEntries].join(path.delimiter);
104
+ }
105
+ if (!process.env.RUSTUP_HOME) {
106
+ process.env.RUSTUP_HOME = toolchainCargo.rustupHome;
107
+ }
108
+ const toolchainName = path.basename(path.dirname(toolchainBin));
109
+ if (!process.env.RUSTUP_TOOLCHAIN) {
110
+ process.env.RUSTUP_TOOLCHAIN = toolchainName;
111
+ }
112
+ }
113
+ export function findCargoBinary() {
114
+ const explicitCargo = process.env.CARGO?.trim();
115
+ const rustupHomes = [
116
+ process.env.RUSTUP_HOME?.trim(),
117
+ path.join(homedir(), ".rustup"),
118
+ ...inferRustupHomesFromPath(),
119
+ ].filter((candidate) => Boolean(candidate));
120
+ const toolchainCargoCandidates = rustupHomes
121
+ .map((rustupHome) => getToolchainCargoFromRustupHome(rustupHome))
122
+ .filter((candidate) => Boolean(candidate));
123
+ if (toolchainCargoCandidates.length > 0) {
124
+ ensureToolchainEnvironment(toolchainCargoCandidates[0]);
125
+ }
126
+ const candidates = [
127
+ explicitCargo,
128
+ ...toolchainCargoCandidates.map((candidate) => candidate.cargoPath),
129
+ path.join(homedir(), ".cargo", "bin", CARGO_BINARY_NAME),
130
+ CARGO_BINARY_NAME,
131
+ ].filter((candidate) => Boolean(candidate));
132
+ for (const candidate of candidates) {
133
+ const resolved = resolveExecutableCandidate(candidate);
134
+ if (resolved) {
135
+ return resolved;
136
+ }
137
+ }
138
+ return null;
139
+ }
140
+ export function resolveCargoBinary() {
141
+ return findCargoBinary() ?? CARGO_BINARY_NAME;
142
+ }
@@ -0,0 +1,10 @@
1
+ export declare class PendingResponseRegistry<TResponse> {
2
+ private readonly pending;
3
+ waitForResponse(requestId: number, options: {
4
+ timeoutMs: number;
5
+ timeoutMessage: () => string;
6
+ }): Promise<TResponse>;
7
+ resolve(requestId: number, frame: TResponse): boolean;
8
+ reject(requestId: number, error: Error): boolean;
9
+ rejectAll(error: Error): void;
10
+ }
@@ -0,0 +1,49 @@
1
+ export class PendingResponseRegistry {
2
+ pending = new Map();
3
+ waitForResponse(requestId, options) {
4
+ if (this.pending.has(requestId)) {
5
+ throw new Error(`response waiter already registered for request ${requestId}`);
6
+ }
7
+ return new Promise((resolve, reject) => {
8
+ const entry = {
9
+ resolve: (frame) => {
10
+ clearTimeout(entry.timer);
11
+ this.pending.delete(requestId);
12
+ resolve(frame);
13
+ },
14
+ reject: (error) => {
15
+ clearTimeout(entry.timer);
16
+ this.pending.delete(requestId);
17
+ reject(error);
18
+ },
19
+ timer: setTimeout(() => {
20
+ this.pending.delete(requestId);
21
+ reject(new Error(options.timeoutMessage()));
22
+ }, options.timeoutMs),
23
+ };
24
+ this.pending.set(requestId, entry);
25
+ });
26
+ }
27
+ resolve(requestId, frame) {
28
+ const pending = this.pending.get(requestId);
29
+ if (!pending) {
30
+ return false;
31
+ }
32
+ pending.resolve(frame);
33
+ return true;
34
+ }
35
+ reject(requestId, error) {
36
+ const pending = this.pending.get(requestId);
37
+ if (!pending) {
38
+ return false;
39
+ }
40
+ pending.reject(error);
41
+ return true;
42
+ }
43
+ rejectAll(error) {
44
+ for (const pending of this.pending.values()) {
45
+ pending.reject(error);
46
+ }
47
+ this.pending.clear();
48
+ }
49
+ }
@@ -0,0 +1,34 @@
1
+ import type * as protocol from "./generated-protocol.js";
2
+ export type LiveSidecarPlacement = {
3
+ kind: "shared";
4
+ pool?: string | null;
5
+ } | {
6
+ kind: "explicit";
7
+ sidecar_id: string;
8
+ };
9
+ export type MountConfigJsonPrimitive = string | number | boolean | null;
10
+ export type MountConfigJsonValue = MountConfigJsonPrimitive | MountConfigJsonObject | MountConfigJsonValue[];
11
+ export interface MountConfigJsonObject {
12
+ [key: string]: MountConfigJsonValue;
13
+ }
14
+ export interface NativeMountPluginDescriptor<TConfig extends MountConfigJsonObject = MountConfigJsonObject> {
15
+ id: string;
16
+ config?: TConfig;
17
+ }
18
+ export interface LiveMountDescriptor {
19
+ guest_path: string;
20
+ read_only: boolean;
21
+ plugin: NativeMountPluginDescriptor;
22
+ }
23
+ export interface LiveSoftwareDescriptor {
24
+ package_name: string;
25
+ root: string;
26
+ }
27
+ export interface LiveProjectedModuleDescriptor {
28
+ package_name: string;
29
+ entrypoint: string;
30
+ }
31
+ export declare function toGeneratedSidecarPlacement(placement: LiveSidecarPlacement): protocol.SidecarPlacement;
32
+ export declare function toGeneratedMountDescriptor(descriptor: LiveMountDescriptor): protocol.MountDescriptor;
33
+ export declare function toGeneratedSoftwareDescriptor(descriptor: LiveSoftwareDescriptor): protocol.SoftwareDescriptor;
34
+ export declare function toGeneratedProjectedModuleDescriptor(descriptor: LiveProjectedModuleDescriptor): protocol.ProjectedModuleDescriptor;
@@ -0,0 +1,37 @@
1
+ import { stringifyJsonUtf8 } from "./json.js";
2
+ export function toGeneratedSidecarPlacement(placement) {
3
+ switch (placement.kind) {
4
+ case "shared":
5
+ return {
6
+ tag: "SidecarPlacementShared",
7
+ val: { pool: placement.pool ?? null },
8
+ };
9
+ case "explicit":
10
+ return {
11
+ tag: "SidecarPlacementExplicit",
12
+ val: { sidecarId: placement.sidecar_id },
13
+ };
14
+ }
15
+ }
16
+ export function toGeneratedMountDescriptor(descriptor) {
17
+ return {
18
+ guestPath: descriptor.guest_path,
19
+ readOnly: descriptor.read_only,
20
+ plugin: {
21
+ id: descriptor.plugin.id,
22
+ config: stringifyJsonUtf8(descriptor.plugin.config ?? {}, "mount plugin config"),
23
+ },
24
+ };
25
+ }
26
+ export function toGeneratedSoftwareDescriptor(descriptor) {
27
+ return {
28
+ packageName: descriptor.package_name,
29
+ root: descriptor.root,
30
+ };
31
+ }
32
+ export function toGeneratedProjectedModuleDescriptor(descriptor) {
33
+ return {
34
+ packageName: descriptor.package_name,
35
+ entrypoint: descriptor.entrypoint,
36
+ };
37
+ }
@@ -0,0 +1,90 @@
1
+ import { type LiveExtEnvelope } from "./ext.js";
2
+ import type * as protocol from "./generated-protocol.js";
3
+ import { type LiveOwnershipScope } from "./ownership.js";
4
+ export declare const ANY_BUFFERED_EVENT_KEY = "*";
5
+ export type { LiveOwnershipScope } from "./ownership.js";
6
+ export type LiveSidecarEventPayload = {
7
+ type: "vm_lifecycle";
8
+ state: "creating" | "ready" | "disposing" | "disposed" | "failed";
9
+ } | {
10
+ type: "process_output";
11
+ process_id: string;
12
+ channel: "stdout" | "stderr";
13
+ chunk: Uint8Array;
14
+ } | {
15
+ type: "process_exited";
16
+ process_id: string;
17
+ exit_code: number;
18
+ } | {
19
+ type: "structured";
20
+ name: string;
21
+ detail: Record<string, string>;
22
+ } | {
23
+ type: "ext";
24
+ envelope: LiveExtEnvelope;
25
+ };
26
+ export interface LiveSidecarEventFrame {
27
+ ownership: LiveOwnershipScope;
28
+ payload: LiveSidecarEventPayload;
29
+ }
30
+ export type LiveSidecarEventSelector = {
31
+ any: true;
32
+ } | {
33
+ type: "vm_lifecycle";
34
+ ownership?: LiveOwnershipScope;
35
+ state?: Extract<LiveSidecarEventPayload, {
36
+ type: "vm_lifecycle";
37
+ }>["state"];
38
+ } | {
39
+ type: "process_output";
40
+ ownership?: LiveOwnershipScope;
41
+ processId?: string;
42
+ channel?: Extract<LiveSidecarEventPayload, {
43
+ type: "process_output";
44
+ }>["channel"];
45
+ } | {
46
+ type: "process_exited";
47
+ ownership?: LiveOwnershipScope;
48
+ processId?: string;
49
+ } | {
50
+ type: "structured";
51
+ ownership?: LiveOwnershipScope;
52
+ name?: string;
53
+ detail?: Record<string, string>;
54
+ };
55
+ export type LiveSidecarBufferedEventRecord<TEvent extends LiveSidecarEventFrame> = {
56
+ event: TEvent;
57
+ keys: readonly string[];
58
+ };
59
+ export type LiveSidecarEventWaitMatcher<TEvent extends LiveSidecarEventFrame> = {
60
+ matches: (event: TEvent) => boolean;
61
+ bufferKey: string | null;
62
+ };
63
+ export declare class SidecarEventBufferOverflow extends Error {
64
+ readonly capacity: number;
65
+ readonly bufferedEvents: number;
66
+ readonly eventType: LiveSidecarEventPayload["type"];
67
+ constructor(options: {
68
+ capacity: number;
69
+ bufferedEvents: number;
70
+ eventType: LiveSidecarEventPayload["type"];
71
+ });
72
+ }
73
+ export declare class SidecarEventBuffer<TEvent extends LiveSidecarEventFrame> {
74
+ private readonly capacity;
75
+ private readonly bufferedEvents;
76
+ private readonly bufferedEventQueues;
77
+ private nextBufferedEventId;
78
+ constructor(capacity: number);
79
+ get size(): number;
80
+ buffer(event: TEvent): SidecarEventBufferOverflow | null;
81
+ take(matcher: LiveSidecarEventWaitMatcher<TEvent>): TEvent | null;
82
+ private takeFromKey;
83
+ private remove;
84
+ }
85
+ export declare function sidecarSelectorMatchesEvent<TEvent extends LiveSidecarEventFrame>(selector: LiveSidecarEventSelector, event: TEvent): boolean;
86
+ export declare function sidecarSelectorBufferKey(selector: LiveSidecarEventSelector): string | null;
87
+ export declare function normalizeSidecarEventMatcher<TEvent extends LiveSidecarEventFrame>(selector: LiveSidecarEventSelector | ((event: TEvent) => boolean)): LiveSidecarEventWaitMatcher<TEvent>;
88
+ export declare function fromGeneratedEventPayload(payload: protocol.EventPayload): LiveSidecarEventPayload;
89
+ export declare function sidecarEventWaitAbortError(reason: unknown): Error;
90
+ export declare function sidecarEventBufferKeys<TEvent extends LiveSidecarEventFrame>(event: TEvent): string[];
@@ -0,0 +1,313 @@
1
+ import { fromGeneratedExtEnvelope, } from "./ext.js";
2
+ import { ownershipMatchesSelector, ownershipSelectorKey, } from "./ownership.js";
3
+ import { fromGeneratedStreamChannel, fromGeneratedVmLifecycleState, } from "./protocol-maps.js";
4
+ export const ANY_BUFFERED_EVENT_KEY = "*";
5
+ export class SidecarEventBufferOverflow extends Error {
6
+ capacity;
7
+ bufferedEvents;
8
+ eventType;
9
+ constructor(options) {
10
+ super(`sidecar event buffer overflow after ${options.bufferedEvents} queued events (capacity ${options.capacity}) while buffering ${options.eventType}`);
11
+ this.name = "SidecarEventBufferOverflow";
12
+ this.capacity = options.capacity;
13
+ this.bufferedEvents = options.bufferedEvents;
14
+ this.eventType = options.eventType;
15
+ }
16
+ }
17
+ export class SidecarEventBuffer {
18
+ capacity;
19
+ bufferedEvents = new Map();
20
+ bufferedEventQueues = new Map();
21
+ nextBufferedEventId = 1;
22
+ constructor(capacity) {
23
+ this.capacity = capacity;
24
+ }
25
+ get size() {
26
+ return this.bufferedEvents.size;
27
+ }
28
+ buffer(event) {
29
+ if (this.bufferedEvents.size >= this.capacity) {
30
+ return new SidecarEventBufferOverflow({
31
+ capacity: this.capacity,
32
+ bufferedEvents: this.bufferedEvents.size,
33
+ eventType: event.payload.type,
34
+ });
35
+ }
36
+ const eventId = this.nextBufferedEventId++;
37
+ const keys = sidecarEventBufferKeys(event);
38
+ this.bufferedEvents.set(eventId, {
39
+ event,
40
+ keys,
41
+ });
42
+ for (const key of keys) {
43
+ const queue = this.bufferedEventQueues.get(key);
44
+ if (queue) {
45
+ queue.add(eventId);
46
+ continue;
47
+ }
48
+ this.bufferedEventQueues.set(key, new Set([eventId]));
49
+ }
50
+ return null;
51
+ }
52
+ take(matcher) {
53
+ if (matcher.bufferKey !== null) {
54
+ return this.takeFromKey(matcher.bufferKey);
55
+ }
56
+ const queue = this.bufferedEventQueues.get(ANY_BUFFERED_EVENT_KEY);
57
+ if (!queue) {
58
+ return null;
59
+ }
60
+ for (const eventId of queue) {
61
+ const record = this.bufferedEvents.get(eventId);
62
+ if (!record) {
63
+ continue;
64
+ }
65
+ if (!matcher.matches(record.event)) {
66
+ continue;
67
+ }
68
+ return this.remove(eventId);
69
+ }
70
+ return null;
71
+ }
72
+ takeFromKey(key) {
73
+ const queue = this.bufferedEventQueues.get(key);
74
+ if (!queue) {
75
+ return null;
76
+ }
77
+ for (const eventId of queue) {
78
+ const record = this.bufferedEvents.get(eventId);
79
+ if (!record) {
80
+ queue.delete(eventId);
81
+ continue;
82
+ }
83
+ return this.remove(eventId);
84
+ }
85
+ return null;
86
+ }
87
+ remove(eventId) {
88
+ const record = this.bufferedEvents.get(eventId);
89
+ if (!record) {
90
+ return null;
91
+ }
92
+ this.bufferedEvents.delete(eventId);
93
+ for (const key of record.keys) {
94
+ const queue = this.bufferedEventQueues.get(key);
95
+ if (!queue) {
96
+ continue;
97
+ }
98
+ queue.delete(eventId);
99
+ if (queue.size === 0) {
100
+ this.bufferedEventQueues.delete(key);
101
+ }
102
+ }
103
+ return record.event;
104
+ }
105
+ }
106
+ function buildBufferKey(type, options) {
107
+ const parts = [`type:${type}`];
108
+ if (options?.ownership) {
109
+ parts.push(`ownership:${ownershipSelectorKey(options.ownership)}`);
110
+ }
111
+ if (options?.state) {
112
+ parts.push(`state:${options.state}`);
113
+ }
114
+ if (options?.processId) {
115
+ parts.push(`process:${options.processId}`);
116
+ }
117
+ if (options?.channel) {
118
+ parts.push(`channel:${options.channel}`);
119
+ }
120
+ if (options?.name) {
121
+ parts.push(`name:${options.name}`);
122
+ }
123
+ return parts.join("|");
124
+ }
125
+ export function sidecarSelectorMatchesEvent(selector, event) {
126
+ if ("any" in selector) {
127
+ return true;
128
+ }
129
+ if (event.payload.type !== selector.type) {
130
+ return false;
131
+ }
132
+ if (!ownershipMatchesSelector(selector.ownership, event.ownership)) {
133
+ return false;
134
+ }
135
+ switch (selector.type) {
136
+ case "vm_lifecycle": {
137
+ const payload = event.payload;
138
+ return selector.state === undefined || payload.state === selector.state;
139
+ }
140
+ case "process_output": {
141
+ const payload = event.payload;
142
+ return ((selector.processId === undefined ||
143
+ payload.process_id === selector.processId) &&
144
+ (selector.channel === undefined || payload.channel === selector.channel));
145
+ }
146
+ case "process_exited": {
147
+ const payload = event.payload;
148
+ return (selector.processId === undefined ||
149
+ payload.process_id === selector.processId);
150
+ }
151
+ case "structured": {
152
+ const payload = event.payload;
153
+ if (selector.name !== undefined && payload.name !== selector.name) {
154
+ return false;
155
+ }
156
+ if (!selector.detail) {
157
+ return true;
158
+ }
159
+ for (const [key, value] of Object.entries(selector.detail)) {
160
+ if (payload.detail[key] !== value) {
161
+ return false;
162
+ }
163
+ }
164
+ return true;
165
+ }
166
+ }
167
+ }
168
+ export function sidecarSelectorBufferKey(selector) {
169
+ if ("any" in selector) {
170
+ return ANY_BUFFERED_EVENT_KEY;
171
+ }
172
+ switch (selector.type) {
173
+ case "vm_lifecycle":
174
+ return buildBufferKey(selector.type, {
175
+ ownership: selector.ownership,
176
+ state: selector.state,
177
+ });
178
+ case "process_output":
179
+ return buildBufferKey(selector.type, {
180
+ ownership: selector.ownership,
181
+ processId: selector.processId,
182
+ channel: selector.channel,
183
+ });
184
+ case "process_exited":
185
+ return buildBufferKey(selector.type, {
186
+ ownership: selector.ownership,
187
+ processId: selector.processId,
188
+ });
189
+ case "structured":
190
+ if (selector.detail) {
191
+ return null;
192
+ }
193
+ return buildBufferKey(selector.type, {
194
+ ownership: selector.ownership,
195
+ name: selector.name,
196
+ });
197
+ }
198
+ }
199
+ export function normalizeSidecarEventMatcher(selector) {
200
+ if (typeof selector === "function") {
201
+ return {
202
+ matches: selector,
203
+ bufferKey: null,
204
+ };
205
+ }
206
+ return {
207
+ matches: (event) => sidecarSelectorMatchesEvent(selector, event),
208
+ bufferKey: sidecarSelectorBufferKey(selector),
209
+ };
210
+ }
211
+ export function fromGeneratedEventPayload(payload) {
212
+ switch (payload.tag) {
213
+ case "VmLifecycleEvent":
214
+ return {
215
+ type: "vm_lifecycle",
216
+ state: fromGeneratedVmLifecycleState(payload.val.state),
217
+ };
218
+ case "ProcessOutputEvent":
219
+ return {
220
+ type: "process_output",
221
+ process_id: payload.val.processId,
222
+ channel: fromGeneratedStreamChannel(payload.val.channel),
223
+ chunk: Buffer.from(payload.val.chunk),
224
+ };
225
+ case "ProcessExitedEvent":
226
+ return {
227
+ type: "process_exited",
228
+ process_id: payload.val.processId,
229
+ exit_code: payload.val.exitCode,
230
+ };
231
+ case "StructuredEvent":
232
+ return {
233
+ type: "structured",
234
+ name: payload.val.name,
235
+ detail: Object.fromEntries(payload.val.detail),
236
+ };
237
+ case "ExtEnvelope":
238
+ return {
239
+ type: "ext",
240
+ envelope: fromGeneratedExtEnvelope(payload.val),
241
+ };
242
+ }
243
+ }
244
+ export function sidecarEventWaitAbortError(reason) {
245
+ return reason instanceof Error
246
+ ? reason
247
+ : new Error(reason ? String(reason) : "sidecar event wait aborted");
248
+ }
249
+ export function sidecarEventBufferKeys(event) {
250
+ const owner = event.ownership;
251
+ const keys = new Set([
252
+ ANY_BUFFERED_EVENT_KEY,
253
+ buildBufferKey(event.payload.type),
254
+ buildBufferKey(event.payload.type, { ownership: owner }),
255
+ ]);
256
+ switch (event.payload.type) {
257
+ case "vm_lifecycle":
258
+ keys.add(buildBufferKey(event.payload.type, {
259
+ state: event.payload.state,
260
+ }));
261
+ keys.add(buildBufferKey(event.payload.type, {
262
+ ownership: owner,
263
+ state: event.payload.state,
264
+ }));
265
+ break;
266
+ case "process_output":
267
+ keys.add(buildBufferKey(event.payload.type, {
268
+ processId: event.payload.process_id,
269
+ }));
270
+ keys.add(buildBufferKey(event.payload.type, {
271
+ channel: event.payload.channel,
272
+ }));
273
+ keys.add(buildBufferKey(event.payload.type, {
274
+ processId: event.payload.process_id,
275
+ channel: event.payload.channel,
276
+ }));
277
+ keys.add(buildBufferKey(event.payload.type, {
278
+ ownership: owner,
279
+ processId: event.payload.process_id,
280
+ }));
281
+ keys.add(buildBufferKey(event.payload.type, {
282
+ ownership: owner,
283
+ channel: event.payload.channel,
284
+ }));
285
+ keys.add(buildBufferKey(event.payload.type, {
286
+ ownership: owner,
287
+ processId: event.payload.process_id,
288
+ channel: event.payload.channel,
289
+ }));
290
+ break;
291
+ case "process_exited":
292
+ keys.add(buildBufferKey(event.payload.type, {
293
+ processId: event.payload.process_id,
294
+ }));
295
+ keys.add(buildBufferKey(event.payload.type, {
296
+ ownership: owner,
297
+ processId: event.payload.process_id,
298
+ }));
299
+ break;
300
+ case "structured":
301
+ keys.add(buildBufferKey(event.payload.type, {
302
+ name: event.payload.name,
303
+ }));
304
+ keys.add(buildBufferKey(event.payload.type, {
305
+ ownership: owner,
306
+ name: event.payload.name,
307
+ }));
308
+ break;
309
+ case "ext":
310
+ break;
311
+ }
312
+ return [...keys];
313
+ }
package/dist/ext.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type * as sidecarProtocol from "./generated-protocol.js";
2
+ export interface LiveExtEnvelope {
3
+ namespace: string;
4
+ payload: Uint8Array;
5
+ }
6
+ export declare function toGeneratedExtEnvelope(envelope: LiveExtEnvelope): sidecarProtocol.ExtEnvelope;
7
+ export declare function fromGeneratedExtEnvelope(envelope: sidecarProtocol.ExtEnvelope): LiveExtEnvelope;