atabey 0.1.1-beta → 0.1.2

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 (229) hide show
  1. package/README.md +144 -78
  2. package/dist/atabey/src/cli/commands/coverage.js +17 -12
  3. package/dist/atabey/src/cli/commands/coverage.js.map +1 -1
  4. package/dist/atabey/src/cli/commands/lint.d.ts +2 -1
  5. package/dist/atabey/src/cli/commands/lint.js +20 -1
  6. package/dist/atabey/src/cli/commands/lint.js.map +1 -1
  7. package/dist/atabey/src/cli/commands/mcp.js +56 -23
  8. package/dist/atabey/src/cli/commands/mcp.js.map +1 -1
  9. package/dist/atabey/src/cli/commands/orchestrate.d.ts +6 -6
  10. package/dist/shared/src/agent-identity.d.ts +1 -34
  11. package/dist/shared/src/agent-identity.js +1 -76
  12. package/dist/shared/src/agent-identity.js.map +1 -1
  13. package/dist/shared/src/api-catalog.d.ts +1 -57
  14. package/dist/shared/src/api-catalog.js +1 -253
  15. package/dist/shared/src/api-catalog.js.map +1 -1
  16. package/dist/shared/src/audit-chain.d.ts +1 -80
  17. package/dist/shared/src/audit-chain.js +1 -261
  18. package/dist/shared/src/audit-chain.js.map +1 -1
  19. package/dist/shared/src/audit.d.ts +1 -121
  20. package/dist/shared/src/audit.js +1 -321
  21. package/dist/shared/src/audit.js.map +1 -1
  22. package/dist/shared/src/constants.d.ts +1 -150
  23. package/dist/shared/src/constants.js +1 -211
  24. package/dist/shared/src/constants.js.map +1 -1
  25. package/dist/shared/src/database.d.ts +1 -6
  26. package/dist/shared/src/database.js +1 -15
  27. package/dist/shared/src/database.js.map +1 -1
  28. package/dist/shared/src/errors.d.ts +1 -46
  29. package/dist/shared/src/errors.js +1 -68
  30. package/dist/shared/src/errors.js.map +1 -1
  31. package/dist/shared/src/file-lock.d.ts +1 -93
  32. package/dist/shared/src/file-lock.js +1 -239
  33. package/dist/shared/src/file-lock.js.map +1 -1
  34. package/dist/shared/src/fs.d.ts +1 -9
  35. package/dist/shared/src/fs.js +1 -53
  36. package/dist/shared/src/fs.js.map +1 -1
  37. package/dist/shared/src/index.d.ts +2 -31
  38. package/dist/shared/src/index.js +2 -31
  39. package/dist/shared/src/index.js.map +1 -1
  40. package/dist/shared/src/job-queue.d.ts +1 -76
  41. package/dist/shared/src/job-queue.js +1 -199
  42. package/dist/shared/src/job-queue.js.map +1 -1
  43. package/dist/shared/src/lock.d.ts +1 -82
  44. package/dist/shared/src/lock.js +1 -158
  45. package/dist/shared/src/lock.js.map +1 -1
  46. package/dist/shared/src/logger.d.ts +1 -31
  47. package/dist/shared/src/logger.js +1 -152
  48. package/dist/shared/src/logger.js.map +1 -1
  49. package/dist/shared/src/memory-prune.d.ts +1 -18
  50. package/dist/shared/src/memory-prune.js +1 -47
  51. package/dist/shared/src/memory-prune.js.map +1 -1
  52. package/dist/shared/src/migrations.d.ts +1 -69
  53. package/dist/shared/src/migrations.js +1 -393
  54. package/dist/shared/src/migrations.js.map +1 -1
  55. package/dist/shared/src/modules/agent/agent-identity.d.ts +34 -0
  56. package/dist/shared/src/modules/agent/agent-identity.js +77 -0
  57. package/dist/shared/src/modules/agent/agent-identity.js.map +1 -0
  58. package/dist/shared/src/modules/agent/api-catalog.d.ts +57 -0
  59. package/dist/shared/src/modules/agent/api-catalog.js +254 -0
  60. package/dist/shared/src/modules/agent/api-catalog.js.map +1 -0
  61. package/dist/shared/src/modules/agent/index.d.ts +3 -0
  62. package/dist/shared/src/modules/agent/index.js +4 -0
  63. package/dist/shared/src/modules/agent/index.js.map +1 -0
  64. package/dist/shared/src/modules/agent/tokenizer.d.ts +54 -0
  65. package/dist/shared/src/modules/agent/tokenizer.js +272 -0
  66. package/dist/shared/src/modules/agent/tokenizer.js.map +1 -0
  67. package/dist/shared/src/modules/concurrency/file-lock.d.ts +93 -0
  68. package/dist/shared/src/modules/concurrency/file-lock.js +240 -0
  69. package/dist/shared/src/modules/concurrency/file-lock.js.map +1 -0
  70. package/dist/shared/src/modules/concurrency/index.d.ts +6 -0
  71. package/dist/shared/src/modules/concurrency/index.js +7 -0
  72. package/dist/shared/src/modules/concurrency/index.js.map +1 -0
  73. package/dist/shared/src/modules/concurrency/job-queue.d.ts +76 -0
  74. package/dist/shared/src/modules/concurrency/job-queue.js +200 -0
  75. package/dist/shared/src/modules/concurrency/job-queue.js.map +1 -0
  76. package/dist/shared/src/modules/concurrency/lock.d.ts +82 -0
  77. package/dist/shared/src/modules/concurrency/lock.js +159 -0
  78. package/dist/shared/src/modules/concurrency/lock.js.map +1 -0
  79. package/dist/shared/src/modules/concurrency/resilience.d.ts +84 -0
  80. package/dist/shared/src/modules/concurrency/resilience.js +217 -0
  81. package/dist/shared/src/modules/concurrency/resilience.js.map +1 -0
  82. package/dist/shared/src/modules/concurrency/worker-pool.d.ts +52 -0
  83. package/dist/shared/src/modules/concurrency/worker-pool.js +229 -0
  84. package/dist/shared/src/modules/concurrency/worker-pool.js.map +1 -0
  85. package/dist/shared/src/modules/concurrency/worker-thread.d.ts +21 -0
  86. package/dist/shared/src/modules/concurrency/worker-thread.js +67 -0
  87. package/dist/shared/src/modules/concurrency/worker-thread.js.map +1 -0
  88. package/dist/shared/src/modules/index.d.ts +14 -0
  89. package/dist/shared/src/modules/index.js +15 -0
  90. package/dist/shared/src/modules/index.js.map +1 -0
  91. package/dist/shared/src/modules/observability/audit-chain.d.ts +80 -0
  92. package/dist/shared/src/modules/observability/audit-chain.js +262 -0
  93. package/dist/shared/src/modules/observability/audit-chain.js.map +1 -0
  94. package/dist/shared/src/modules/observability/audit.d.ts +121 -0
  95. package/dist/shared/src/modules/observability/audit.js +322 -0
  96. package/dist/shared/src/modules/observability/audit.js.map +1 -0
  97. package/dist/shared/src/modules/observability/index.d.ts +4 -0
  98. package/dist/shared/src/modules/observability/index.js +5 -0
  99. package/dist/shared/src/modules/observability/index.js.map +1 -0
  100. package/dist/shared/src/modules/observability/logger.d.ts +31 -0
  101. package/dist/shared/src/modules/observability/logger.js +153 -0
  102. package/dist/shared/src/modules/observability/logger.js.map +1 -0
  103. package/dist/shared/src/modules/observability/otel.d.ts +39 -0
  104. package/dist/shared/src/modules/observability/otel.js +93 -0
  105. package/dist/shared/src/modules/observability/otel.js.map +1 -0
  106. package/dist/shared/src/modules/primitives/constants.d.ts +150 -0
  107. package/dist/shared/src/modules/primitives/constants.js +212 -0
  108. package/dist/shared/src/modules/primitives/constants.js.map +1 -0
  109. package/dist/shared/src/modules/primitives/errors.d.ts +46 -0
  110. package/dist/shared/src/modules/primitives/errors.js +69 -0
  111. package/dist/shared/src/modules/primitives/errors.js.map +1 -0
  112. package/dist/shared/src/modules/primitives/fs.d.ts +9 -0
  113. package/dist/shared/src/modules/primitives/fs.js +54 -0
  114. package/dist/shared/src/modules/primitives/fs.js.map +1 -0
  115. package/dist/shared/src/modules/primitives/index.d.ts +7 -0
  116. package/dist/shared/src/modules/primitives/index.js +8 -0
  117. package/dist/shared/src/modules/primitives/index.js.map +1 -0
  118. package/dist/shared/src/modules/primitives/outbound-http.d.ts +32 -0
  119. package/dist/shared/src/modules/primitives/outbound-http.js +88 -0
  120. package/dist/shared/src/modules/primitives/outbound-http.js.map +1 -0
  121. package/dist/shared/src/modules/primitives/string.d.ts +1 -0
  122. package/dist/shared/src/modules/primitives/string.js +30 -0
  123. package/dist/shared/src/modules/primitives/string.js.map +1 -0
  124. package/dist/shared/src/modules/primitives/time.d.ts +5 -0
  125. package/dist/shared/src/modules/primitives/time.js +35 -0
  126. package/dist/shared/src/modules/primitives/time.js.map +1 -0
  127. package/dist/shared/src/modules/primitives/types.d.ts +27 -0
  128. package/dist/shared/src/modules/primitives/types.js +17 -0
  129. package/dist/shared/src/modules/primitives/types.js.map +1 -0
  130. package/dist/shared/src/modules/sandbox/index.d.ts +3 -0
  131. package/dist/shared/src/modules/sandbox/index.js +4 -0
  132. package/dist/shared/src/modules/sandbox/index.js.map +1 -0
  133. package/dist/shared/src/modules/sandbox/sandbox-fs.d.ts +28 -0
  134. package/dist/shared/src/modules/sandbox/sandbox-fs.js +143 -0
  135. package/dist/shared/src/modules/sandbox/sandbox-fs.js.map +1 -0
  136. package/dist/shared/src/modules/sandbox/sandbox-runtime.d.ts +78 -0
  137. package/dist/shared/src/modules/sandbox/sandbox-runtime.js +282 -0
  138. package/dist/shared/src/modules/sandbox/sandbox-runtime.js.map +1 -0
  139. package/dist/shared/src/modules/sandbox/sandbox.d.ts +54 -0
  140. package/dist/shared/src/modules/sandbox/sandbox.js +179 -0
  141. package/dist/shared/src/modules/sandbox/sandbox.js.map +1 -0
  142. package/dist/shared/src/modules/security/index.d.ts +5 -0
  143. package/dist/shared/src/modules/security/index.js +6 -0
  144. package/dist/shared/src/modules/security/index.js.map +1 -0
  145. package/dist/shared/src/modules/security/pii.d.ts +70 -0
  146. package/dist/shared/src/modules/security/pii.js +276 -0
  147. package/dist/shared/src/modules/security/pii.js.map +1 -0
  148. package/dist/shared/src/modules/security/policy-gate.d.ts +42 -0
  149. package/dist/shared/src/modules/security/policy-gate.js +172 -0
  150. package/dist/shared/src/modules/security/policy-gate.js.map +1 -0
  151. package/dist/shared/src/modules/security/retention.d.ts +68 -0
  152. package/dist/shared/src/modules/security/retention.js +218 -0
  153. package/dist/shared/src/modules/security/retention.js.map +1 -0
  154. package/dist/shared/src/modules/security/secrets.d.ts +99 -0
  155. package/dist/shared/src/modules/security/secrets.js +371 -0
  156. package/dist/shared/src/modules/security/secrets.js.map +1 -0
  157. package/dist/shared/src/modules/security/tls.d.ts +87 -0
  158. package/dist/shared/src/modules/security/tls.js +154 -0
  159. package/dist/shared/src/modules/security/tls.js.map +1 -0
  160. package/dist/shared/src/modules/storage/database.d.ts +6 -0
  161. package/dist/shared/src/modules/storage/database.js +16 -0
  162. package/dist/shared/src/modules/storage/database.js.map +1 -0
  163. package/dist/shared/src/modules/storage/index.d.ts +4 -0
  164. package/dist/shared/src/modules/storage/index.js +5 -0
  165. package/dist/shared/src/modules/storage/index.js.map +1 -0
  166. package/dist/shared/src/modules/storage/memory-prune.d.ts +18 -0
  167. package/dist/shared/src/modules/storage/memory-prune.js +48 -0
  168. package/dist/shared/src/modules/storage/memory-prune.js.map +1 -0
  169. package/dist/shared/src/modules/storage/migrations.d.ts +69 -0
  170. package/dist/shared/src/modules/storage/migrations.js +394 -0
  171. package/dist/shared/src/modules/storage/migrations.js.map +1 -0
  172. package/dist/shared/src/modules/storage/storage.d.ts +341 -0
  173. package/dist/shared/src/modules/storage/storage.js +1004 -0
  174. package/dist/shared/src/modules/storage/storage.js.map +1 -0
  175. package/dist/shared/src/otel.d.ts +1 -39
  176. package/dist/shared/src/otel.js +1 -92
  177. package/dist/shared/src/otel.js.map +1 -1
  178. package/dist/shared/src/outbound-http.d.ts +1 -32
  179. package/dist/shared/src/outbound-http.js +1 -87
  180. package/dist/shared/src/outbound-http.js.map +1 -1
  181. package/dist/shared/src/pii.d.ts +1 -70
  182. package/dist/shared/src/pii.js +1 -275
  183. package/dist/shared/src/pii.js.map +1 -1
  184. package/dist/shared/src/policy-gate.d.ts +1 -42
  185. package/dist/shared/src/policy-gate.js +1 -171
  186. package/dist/shared/src/policy-gate.js.map +1 -1
  187. package/dist/shared/src/resilience.d.ts +1 -84
  188. package/dist/shared/src/resilience.js +1 -216
  189. package/dist/shared/src/resilience.js.map +1 -1
  190. package/dist/shared/src/retention.d.ts +1 -68
  191. package/dist/shared/src/retention.js +1 -217
  192. package/dist/shared/src/retention.js.map +1 -1
  193. package/dist/shared/src/sandbox-fs.d.ts +1 -28
  194. package/dist/shared/src/sandbox-fs.js +1 -142
  195. package/dist/shared/src/sandbox-fs.js.map +1 -1
  196. package/dist/shared/src/sandbox-runtime.d.ts +1 -78
  197. package/dist/shared/src/sandbox-runtime.js +1 -281
  198. package/dist/shared/src/sandbox-runtime.js.map +1 -1
  199. package/dist/shared/src/sandbox.d.ts +1 -54
  200. package/dist/shared/src/sandbox.js +1 -178
  201. package/dist/shared/src/sandbox.js.map +1 -1
  202. package/dist/shared/src/secrets.d.ts +1 -99
  203. package/dist/shared/src/secrets.js +1 -370
  204. package/dist/shared/src/secrets.js.map +1 -1
  205. package/dist/shared/src/storage.d.ts +1 -341
  206. package/dist/shared/src/storage.js +1 -1003
  207. package/dist/shared/src/storage.js.map +1 -1
  208. package/dist/shared/src/string.d.ts +1 -1
  209. package/dist/shared/src/string.js +1 -29
  210. package/dist/shared/src/string.js.map +1 -1
  211. package/dist/shared/src/time.d.ts +1 -5
  212. package/dist/shared/src/time.js +1 -34
  213. package/dist/shared/src/time.js.map +1 -1
  214. package/dist/shared/src/tls.d.ts +1 -87
  215. package/dist/shared/src/tls.js +1 -153
  216. package/dist/shared/src/tls.js.map +1 -1
  217. package/dist/shared/src/tokenizer.d.ts +1 -54
  218. package/dist/shared/src/tokenizer.js +1 -271
  219. package/dist/shared/src/tokenizer.js.map +1 -1
  220. package/dist/shared/src/types.d.ts +1 -27
  221. package/dist/shared/src/types.js +1 -16
  222. package/dist/shared/src/types.js.map +1 -1
  223. package/dist/shared/src/worker-pool.d.ts +1 -52
  224. package/dist/shared/src/worker-pool.js +1 -228
  225. package/dist/shared/src/worker-pool.js.map +1 -1
  226. package/dist/shared/src/worker-thread.d.ts +1 -21
  227. package/dist/shared/src/worker-thread.js +1 -66
  228. package/dist/shared/src/worker-thread.js.map +1 -1
  229. package/package.json +4 -4
@@ -0,0 +1,7 @@
1
+ export * from "./constants.js";
2
+ export * from "./types.js";
3
+ export * from "./errors.js";
4
+ export * from "./fs.js";
5
+ export * from "./string.js";
6
+ export * from "./time.js";
7
+ export * from "./outbound-http.js";
@@ -0,0 +1,8 @@
1
+ export * from "./constants.js";
2
+ export * from "./types.js";
3
+ export * from "./errors.js";
4
+ export * from "./fs.js";
5
+ export * from "./string.js";
6
+ export * from "./time.js";
7
+ export * from "./outbound-http.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../shared/src/modules/primitives/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Outbound HTTP(S) helper with TLS 1.3 / mTLS client-certificate support.
3
+ *
4
+ * Node's global `fetch` does not expose per-request client certificates, so
5
+ * Atabey tooling that performs outbound requests uses this `http`/`https`
6
+ * based transport instead. It performs a SINGLE request (no redirect
7
+ * following) and returns the raw response so callers can re-validate each hop
8
+ * (e.g. SSRF checks) before continuing.
9
+ */
10
+ import http from "http";
11
+ export interface OutboundRequestInput {
12
+ url: string;
13
+ method?: string;
14
+ headers?: Record<string, string>;
15
+ body?: string;
16
+ timeoutMs?: number;
17
+ /** Max response body bytes to buffer (default 5 MiB). */
18
+ maxBytes?: number;
19
+ }
20
+ export interface OutboundResponse {
21
+ status: number;
22
+ headers: http.IncomingHttpHeaders;
23
+ text: string;
24
+ /** Redirect target (from the Location header), if any. */
25
+ location?: string;
26
+ finalUrl: string;
27
+ }
28
+ /**
29
+ * Perform a single outbound request. TLS client options come from
30
+ * `resolveOutboundTlsOptions()` (ATABEY_TLS_CLIENT_* env vars).
31
+ */
32
+ export declare function outboundRequest(input: OutboundRequestInput): Promise<OutboundResponse>;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Outbound HTTP(S) helper with TLS 1.3 / mTLS client-certificate support.
3
+ *
4
+ * Node's global `fetch` does not expose per-request client certificates, so
5
+ * Atabey tooling that performs outbound requests uses this `http`/`https`
6
+ * based transport instead. It performs a SINGLE request (no redirect
7
+ * following) and returns the raw response so callers can re-validate each hop
8
+ * (e.g. SSRF checks) before continuing.
9
+ */
10
+ import http from "http";
11
+ import https from "https";
12
+ import { URL } from "url";
13
+ import { resolveOutboundTlsOptions } from "../security/tls.js";
14
+ /**
15
+ * Perform a single outbound request. TLS client options come from
16
+ * `resolveOutboundTlsOptions()` (ATABEY_TLS_CLIENT_* env vars).
17
+ */
18
+ export function outboundRequest(input) {
19
+ return new Promise((resolve, reject) => {
20
+ let parsed;
21
+ try {
22
+ parsed = new URL(input.url);
23
+ }
24
+ catch {
25
+ reject(new Error(`Invalid URL: ${input.url}`));
26
+ return;
27
+ }
28
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
29
+ reject(new Error(`Protocol '${parsed.protocol}' not supported (only http:/https:).`));
30
+ return;
31
+ }
32
+ const isHttps = parsed.protocol === "https:";
33
+ const mod = isHttps ? https : http;
34
+ const tls = isHttps ? resolveOutboundTlsOptions() : null;
35
+ const maxBytes = input.maxBytes ?? 5 * 1024 * 1024;
36
+ const requestOptions = {
37
+ protocol: parsed.protocol,
38
+ hostname: parsed.hostname,
39
+ port: parsed.port || (isHttps ? 443 : 80),
40
+ path: `${parsed.pathname}${parsed.search}`,
41
+ method: (input.method || "GET").toUpperCase(),
42
+ headers: {
43
+ // Avoid transparent compression so we buffer exactly what was sent.
44
+ "Accept-Encoding": "identity",
45
+ ...(input.headers || {}),
46
+ },
47
+ };
48
+ if (isHttps && tls) {
49
+ requestOptions.minVersion = tls.options.minVersion;
50
+ if (tls.options.cert)
51
+ requestOptions.cert = tls.options.cert;
52
+ if (tls.options.key)
53
+ requestOptions.key = tls.options.key;
54
+ if (tls.options.ca)
55
+ requestOptions.ca = tls.options.ca;
56
+ if (tls.options.servername)
57
+ requestOptions.servername = tls.options.servername;
58
+ }
59
+ const req = mod.request(requestOptions, (res) => {
60
+ const chunks = [];
61
+ let size = 0;
62
+ res.on("data", (chunk) => {
63
+ size += chunk.length;
64
+ if (size <= maxBytes)
65
+ chunks.push(chunk);
66
+ });
67
+ res.on("end", () => {
68
+ resolve({
69
+ status: res.statusCode || 0,
70
+ headers: res.headers,
71
+ text: Buffer.concat(chunks).toString("utf8"),
72
+ location: typeof res.headers.location === "string" ? res.headers.location : undefined,
73
+ finalUrl: input.url,
74
+ });
75
+ });
76
+ res.on("error", reject);
77
+ });
78
+ const timeoutMs = input.timeoutMs ?? 30000;
79
+ req.setTimeout(timeoutMs, () => {
80
+ req.destroy(new Error(`Outbound request timed out after ${timeoutMs}ms`));
81
+ });
82
+ req.on("error", reject);
83
+ if (input.body !== undefined)
84
+ req.write(input.body);
85
+ req.end();
86
+ });
87
+ }
88
+ //# sourceMappingURL=outbound-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbound-http.js","sourceRoot":"","sources":["../../../../../../shared/src/modules/primitives/outbound-http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function stripMarkdownCodeBlocks(text: string): string;
@@ -0,0 +1,30 @@
1
+ export function stripMarkdownCodeBlocks(text) {
2
+ // Regex to find markdown code blocks (```lang ... ```) and extract their content.
3
+ // Handles cases where LLMs might wrap JSON in such blocks.
4
+ const markdownCodeBlockRegex = /```(?:\w+)?\s*([\s\S]*?)\s*```/g;
5
+ // Attempt to extract content from a single markdown code block.
6
+ const cleanedText = text.replace(markdownCodeBlockRegex, "$1").trim();
7
+ // If after stripping, it looks like JSON, return it.
8
+ if ((cleanedText.startsWith("{") && cleanedText.endsWith("}")) || (cleanedText.startsWith("[") && cleanedText.endsWith("]"))) {
9
+ return cleanedText;
10
+ }
11
+ // Fallback: If the original text itself was valid JSON (without being in a code block)
12
+ // or if the stripping made it valid, this check helps.
13
+ try {
14
+ JSON.parse(text.trim());
15
+ return text.trim(); // Original text was valid JSON
16
+ }
17
+ catch {
18
+ // Continue if original text wasn't valid JSON
19
+ }
20
+ // Try a more specific JSON code block extraction if the generic one didn't yield valid JSON
21
+ const specificJsonCodeBlockRegex = /```json\s*(\{[\s\S]*?\}|\[[\s\S]*?\])\s*```/g;
22
+ const specificMatch = text.match(specificJsonCodeBlockRegex);
23
+ if (specificMatch && specificMatch[1]) {
24
+ return specificMatch[1].trim();
25
+ }
26
+ // If all else fails, return the most aggressively stripped version.
27
+ // JSON.parse will fail if it's not valid, which is the expected behavior.
28
+ return cleanedText;
29
+ }
30
+ //# sourceMappingURL=string.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string.js","sourceRoot":"","sources":["../../../../../../shared/src/modules/primitives/string.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAChD,kFAAkF;IAClF,2DAA2D;IAC3D,MAAM,sBAAsB,GAAG,iCAAiC,CAAC;IAEjE,gEAAgE;IAChE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAEtE,qDAAqD;IACrD,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC3H,OAAO,WAAW,CAAC;IACvB,CAAC;IAED,uFAAuF;IACvF,uDAAuD;IACvD,IAAI,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,+BAA+B;IACvD,CAAC;IAAC,MAAM,CAAC;QACL,8CAA8C;IAClD,CAAC;IAED,4FAA4F;IAC5F,MAAM,0BAA0B,GAAG,8CAA8C,CAAC;IAClF,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC7D,IAAI,aAAa,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QACpC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,oEAAoE;IACpE,0EAA0E;IAC1E,OAAO,WAAW,CAAC;AACvB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Time and unique ID utilities shared across Atabey CLI and MCP servers.
3
+ */
4
+ export declare function generateULID(seedTime?: number, seed?: number): string;
5
+ export declare function sleep(ms: number): void;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Time and unique ID utilities shared across Atabey CLI and MCP servers.
3
+ */
4
+ import crypto from "crypto";
5
+ export function generateULID(seedTime = Date.now(), seed) {
6
+ const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
7
+ const ENCODING_LEN = ENCODING.length;
8
+ let time = seedTime;
9
+ const timeChars = new Array(10);
10
+ for (let i = 9; i >= 0; i--) {
11
+ timeChars[i] = ENCODING.charAt(time % ENCODING_LEN);
12
+ time = Math.floor(time / ENCODING_LEN);
13
+ }
14
+ const randomChars = new Array(16);
15
+ if (seed !== undefined) {
16
+ // Deterministic (test/seed) path — legacy LCG for reproducibility.
17
+ let pseudoRandom = seed;
18
+ for (let i = 0; i < 16; i++) {
19
+ pseudoRandom = (pseudoRandom * 16807) % 2147483647;
20
+ randomChars[i] = ENCODING.charAt(pseudoRandom % ENCODING_LEN);
21
+ }
22
+ }
23
+ else {
24
+ // Cryptographically strong randomness (no Math.random collisions).
25
+ const bytes = crypto.randomBytes(16);
26
+ for (let i = 0; i < 16; i++) {
27
+ randomChars[i] = ENCODING.charAt(bytes[i] % ENCODING_LEN);
28
+ }
29
+ }
30
+ return timeChars.join("") + randomChars.join("");
31
+ }
32
+ export function sleep(ms) {
33
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
34
+ }
35
+ //# sourceMappingURL=time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../../../../../../shared/src/modules/primitives/time.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,UAAU,YAAY,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,IAAa;IAC7D,MAAM,QAAQ,GAAG,kCAAkC,CAAC;IACpD,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC;IACrC,IAAI,IAAI,GAAG,QAAQ,CAAC;IACpB,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC;QACpD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACrB,mEAAmE;QACnE,IAAI,YAAY,GAAG,IAAI,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1B,YAAY,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC,GAAG,UAAU,CAAC;YACnD,WAAW,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC,CAAC;QAClE,CAAC;IACL,CAAC;SAAM,CAAC;QACJ,mEAAmE;QACnE,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1B,WAAW,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC;QAC9D,CAAC;IACL,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EAAU;IAC5B,OAAO,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Atabey Framework — Internal Branded Types
3
+ * Used to enforce absolute type safety within the core orchestration logic.
4
+ */
5
+ export type Brand<K, T> = K & {
6
+ __brand: T;
7
+ };
8
+ export type TraceID = Brand<string, "TraceID">;
9
+ export type AgentID = Brand<string, "AgentID">;
10
+ export type PhaseID = Brand<string, "PhaseID">;
11
+ export type ProjectPath = Brand<string, "ProjectPath">;
12
+ export type MessageID = Brand<number, "MessageID">;
13
+ export type TaskID = Brand<string, "TaskID">;
14
+ export type LogID = Brand<number, "LogID">;
15
+ export type PlanID = Brand<string, "PlanID">;
16
+ /**
17
+ * Casts a raw string to a Branded Type.
18
+ * Use this only at the boundaries of the system.
19
+ */
20
+ export declare function asTraceID(val: string): TraceID;
21
+ export declare function asAgentID(val: string): AgentID;
22
+ export declare function asPhaseID(val: string): PhaseID;
23
+ export declare function asProjectPath(val: string): ProjectPath;
24
+ export declare function asMessageID(val: number): MessageID;
25
+ export declare function asTaskID(val: string): TaskID;
26
+ export declare function asLogID(val: number): LogID;
27
+ export declare function asPlanID(val: string): PlanID;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Atabey Framework — Internal Branded Types
3
+ * Used to enforce absolute type safety within the core orchestration logic.
4
+ */
5
+ /**
6
+ * Casts a raw string to a Branded Type.
7
+ * Use this only at the boundaries of the system.
8
+ */
9
+ export function asTraceID(val) { return val; }
10
+ export function asAgentID(val) { return val; }
11
+ export function asPhaseID(val) { return val; }
12
+ export function asProjectPath(val) { return val; }
13
+ export function asMessageID(val) { return val; }
14
+ export function asTaskID(val) { return val; }
15
+ export function asLogID(val) { return val; }
16
+ export function asPlanID(val) { return val; }
17
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../shared/src/modules/primitives/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW,IAAa,OAAO,GAAc,CAAC,CAAC,CAAC;AAC1E,MAAM,UAAU,SAAS,CAAC,GAAW,IAAa,OAAO,GAAc,CAAC,CAAC,CAAC;AAC1E,MAAM,UAAU,SAAS,CAAC,GAAW,IAAa,OAAO,GAAc,CAAC,CAAC,CAAC;AAC1E,MAAM,UAAU,aAAa,CAAC,GAAW,IAAiB,OAAO,GAAkB,CAAC,CAAC,CAAC;AACtF,MAAM,UAAU,WAAW,CAAC,GAAW,IAAe,OAAO,GAAgB,CAAC,CAAC,CAAC;AAChF,MAAM,UAAU,QAAQ,CAAC,GAAW,IAAY,OAAO,GAAa,CAAC,CAAC,CAAC;AACvE,MAAM,UAAU,OAAO,CAAC,GAAW,IAAW,OAAO,GAAY,CAAC,CAAC,CAAC;AACpE,MAAM,UAAU,QAAQ,CAAC,GAAW,IAAY,OAAO,GAAa,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./sandbox.js";
2
+ export * from "./sandbox-fs.js";
3
+ export * from "./sandbox-runtime.js";
@@ -0,0 +1,4 @@
1
+ export * from "./sandbox.js";
2
+ export * from "./sandbox-fs.js";
3
+ export * from "./sandbox-runtime.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../shared/src/modules/sandbox/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Sandboxed filesystem mutations — Phase 1.2.
3
+ *
4
+ * - Always holds AtomicFileLock (try/finally).
5
+ * - When runtime=container: write via container stdin → /workspace/<path>
6
+ * - When runtime=uid|none: write on host under projectRoot (safePath caller responsibility)
7
+ * - ATABEY_SANDBOX_REQUIRED=true rejects writes if isolation is none
8
+ */
9
+ import { type SandboxRuntimeConfig } from "./sandbox-runtime.js";
10
+ export interface SandboxFsWriteResult {
11
+ absolutePath: string;
12
+ relativePath: string;
13
+ runtime: SandboxRuntimeConfig["effectiveMode"];
14
+ isolationLabel: string;
15
+ bytes: number;
16
+ }
17
+ /**
18
+ * Normalize user path to a project-relative POSIX path.
19
+ * Absolute paths are accepted only if they resolve inside projectRoot.
20
+ */
21
+ export declare function assertSafeRelativePath(userPath: string, projectRoot?: string): string;
22
+ /**
23
+ * Write file content under project root using the active local sandbox runtime.
24
+ */
25
+ export declare function writeFileInSandbox(projectRoot: string, userPath: string, content: string, options?: {
26
+ ownerId?: string;
27
+ timeoutMs?: number;
28
+ }): Promise<SandboxFsWriteResult>;
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Sandboxed filesystem mutations — Phase 1.2.
3
+ *
4
+ * - Always holds AtomicFileLock (try/finally).
5
+ * - When runtime=container: write via container stdin → /workspace/<path>
6
+ * - When runtime=uid|none: write on host under projectRoot (safePath caller responsibility)
7
+ * - ATABEY_SANDBOX_REQUIRED=true rejects writes if isolation is none
8
+ */
9
+ import fs from "fs";
10
+ import path from "path";
11
+ import crypto from "crypto";
12
+ import { AtomicFileLock } from "../concurrency/file-lock.js";
13
+ import { resolveSandboxRuntimeConfig, SandboxRequiredError, } from "./sandbox-runtime.js";
14
+ /**
15
+ * Normalize user path to a project-relative POSIX path.
16
+ * Absolute paths are accepted only if they resolve inside projectRoot.
17
+ */
18
+ export function assertSafeRelativePath(userPath, projectRoot) {
19
+ if (!userPath || !userPath.trim()) {
20
+ throw new Error("[SANDBOX_FS] Empty path is not allowed");
21
+ }
22
+ const trimmed = userPath.trim();
23
+ if (trimmed.includes("\0")) {
24
+ throw new Error("[SANDBOX_FS] Illegal null byte in path");
25
+ }
26
+ let rel = trimmed.replace(/\\/g, "/");
27
+ // Absolute path → must live under projectRoot
28
+ if (path.isAbsolute(trimmed) || rel.startsWith("/")) {
29
+ if (!projectRoot) {
30
+ throw new Error(`[SANDBOX_FS] Absolute paths require projectRoot: "${userPath}"`);
31
+ }
32
+ const root = path.resolve(projectRoot);
33
+ const abs = path.resolve(trimmed);
34
+ const rootCheck = process.platform === "win32" ? root.toLowerCase() : root;
35
+ const absCheck = process.platform === "win32" ? abs.toLowerCase() : abs;
36
+ if (!absCheck.startsWith(rootCheck + path.sep) && absCheck !== rootCheck) {
37
+ throw new Error(`[SANDBOX_FS] Absolute path escapes project root: "${userPath}"`);
38
+ }
39
+ rel = path.relative(root, abs).replace(/\\/g, "/");
40
+ if (!rel || rel === ".") {
41
+ throw new Error("[SANDBOX_FS] Path resolves to project root; refuse write");
42
+ }
43
+ if (rel.startsWith("..")) {
44
+ throw new Error(`[SANDBOX_FS] Path traversal denied: "${userPath}"`);
45
+ }
46
+ return rel;
47
+ }
48
+ // Relative: reject .. segments
49
+ const parts = [];
50
+ for (const seg of rel.split("/")) {
51
+ if (!seg || seg === ".")
52
+ continue;
53
+ if (seg === "..") {
54
+ throw new Error(`[SANDBOX_FS] Path traversal denied: "${userPath}"`);
55
+ }
56
+ parts.push(seg);
57
+ }
58
+ if (parts.length === 0) {
59
+ throw new Error("[SANDBOX_FS] Path resolves to project root; refuse write");
60
+ }
61
+ return parts.join("/");
62
+ }
63
+ function createLock(projectRoot) {
64
+ return new AtomicFileLock({
65
+ projectRoot,
66
+ locksDir: path.join(projectRoot, ".atabey", "locks"),
67
+ ttlMs: 5 * 60 * 1000,
68
+ timeoutMs: 15_000,
69
+ });
70
+ }
71
+ function hostWriteAtomic(absolutePath, content) {
72
+ const dir = path.dirname(absolutePath);
73
+ if (!fs.existsSync(dir)) {
74
+ fs.mkdirSync(dir, { recursive: true });
75
+ }
76
+ // Write exact bytes (callers decide trailing newline — patch/replace need fidelity)
77
+ const tempPath = `${absolutePath}.${crypto.randomBytes(6).toString("hex")}.tmp`;
78
+ try {
79
+ fs.writeFileSync(tempPath, content, "utf8");
80
+ fs.renameSync(tempPath, absolutePath);
81
+ }
82
+ catch (err) {
83
+ try {
84
+ if (fs.existsSync(tempPath))
85
+ fs.unlinkSync(tempPath);
86
+ }
87
+ catch { /* ignore */ }
88
+ throw err;
89
+ }
90
+ }
91
+ /**
92
+ * Reject writes whose real (symlink-resolved) path escapes the project root.
93
+ * Lexical checks alone are defeated by a symlink inside the project that
94
+ * points at e.g. ~/.ssh/authorized_keys.
95
+ */
96
+ function assertRealPathInsideRoot(absolutePath, root) {
97
+ const realRoot = fs.existsSync(root) ? fs.realpathSync(root) : root;
98
+ let probe = absolutePath;
99
+ while (probe !== path.dirname(probe)) {
100
+ if (fs.existsSync(probe)) {
101
+ const real = fs.realpathSync(probe) + absolutePath.slice(probe.length);
102
+ if (real !== realRoot && !real.startsWith(realRoot + path.sep)) {
103
+ throw new Error(`[SANDBOX_FS] Symlink escape denied: "${absolutePath}"`);
104
+ }
105
+ return;
106
+ }
107
+ probe = path.dirname(probe);
108
+ }
109
+ }
110
+ /**
111
+ * Write file content under project root using the active local sandbox runtime.
112
+ */
113
+ export async function writeFileInSandbox(projectRoot, userPath, content, options) {
114
+ const root = path.resolve(projectRoot);
115
+ const relativePath = assertSafeRelativePath(userPath, root);
116
+ const absolutePath = path.resolve(root, relativePath);
117
+ if (!absolutePath.startsWith(root + path.sep) && absolutePath !== root) {
118
+ throw new Error(`[SANDBOX_FS] Resolved path escapes project root: "${userPath}"`);
119
+ }
120
+ assertRealPathInsideRoot(absolutePath, root);
121
+ const cfg = resolveSandboxRuntimeConfig(root, options?.timeoutMs);
122
+ if (cfg.required && cfg.effectiveMode === "none") {
123
+ throw new SandboxRequiredError("[SANDBOX_REQUIRED] File write blocked: no OS sandbox isolation available. " +
124
+ "Set ATABEY_SANDBOX_RUNTIME=seatbelt or uid, or disable ATABEY_SANDBOX_REQUIRED.");
125
+ }
126
+ const owner = options?.ownerId || process.env.ATABEY_ACTIVE_AGENT || "mcp-writer";
127
+ const lock = createLock(root);
128
+ return lock.withLock(relativePath, owner, async () => {
129
+ hostWriteAtomic(absolutePath, content);
130
+ return {
131
+ absolutePath,
132
+ relativePath,
133
+ runtime: cfg.effectiveMode,
134
+ isolationLabel: cfg.effectiveMode === "seatbelt"
135
+ ? "seatbelt host write (project-bound)"
136
+ : cfg.effectiveMode === "uid"
137
+ ? "uid host write (project-bound)"
138
+ : "host write (project-bound)",
139
+ bytes: Buffer.byteLength(content, "utf8"),
140
+ };
141
+ });
142
+ }
143
+ //# sourceMappingURL=sandbox-fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-fs.js","sourceRoot":"","sources":["../../../../../../shared/src/modules/sandbox/sandbox-fs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Sandbox Runtime — Pure local OS process isolation for agent commands (Zero Docker/Container).
3
+ *
4
+ * Modes (ATABEY_SANDBOX_RUNTIME):
5
+ * none — host spawn (allow-list + env scrubbing)
6
+ * uid — host spawn with POSIX uid/gid drop (see sandbox.ts)
7
+ * seatbelt — macOS kernel sandbox (/usr/bin/sandbox-exec) confining writes to projectRoot
8
+ * and denying network access by default
9
+ * auto — seatbelt if available on macOS, else uid if configured, else none
10
+ *
11
+ * Hardening:
12
+ * ATABEY_SANDBOX_REQUIRED=true → deny execution when isolation is effectively "none"
13
+ * ATABEY_SANDBOX_NETWORK=none → deny outbound/inbound network inside seatbelt (default: none)
14
+ */
15
+ import { resolveSandboxIdentity } from "./sandbox.js";
16
+ export type SandboxRuntimeMode = "none" | "uid" | "seatbelt" | "auto";
17
+ export type SandboxEngine = "seatbelt" | "none";
18
+ export interface SandboxRuntimeConfig {
19
+ mode: SandboxRuntimeMode;
20
+ /** Resolved effective mode after auto detection. */
21
+ effectiveMode: "none" | "uid" | "seatbelt";
22
+ engine: SandboxEngine;
23
+ network: string;
24
+ required: boolean;
25
+ projectRoot: string;
26
+ timeoutMs: number;
27
+ }
28
+ export interface RunInSandboxRequest {
29
+ command: string;
30
+ args: string[];
31
+ projectRoot: string;
32
+ timeoutMs?: number;
33
+ env?: NodeJS.ProcessEnv;
34
+ /** Optional stdin payload. */
35
+ stdin?: string | Buffer;
36
+ }
37
+ export interface RunInSandboxResult {
38
+ code: number | null;
39
+ stdout: string;
40
+ stderr: string;
41
+ runtime: SandboxRuntimeConfig["effectiveMode"];
42
+ engine: SandboxEngine;
43
+ /** Human-readable isolation description for logs/errors. */
44
+ isolationLabel: string;
45
+ }
46
+ export declare class SandboxRequiredError extends Error {
47
+ constructor(message: string);
48
+ }
49
+ export declare const SEATBELT_BINARY = "/usr/bin/sandbox-exec";
50
+ export declare function resolveDefaultSandboxRequired(_mode?: SandboxRuntimeMode): boolean;
51
+ /**
52
+ * Detect available native OS sandbox engine (cached).
53
+ */
54
+ export declare function detectOsSandboxEngine(): SandboxEngine;
55
+ /** Test helper */
56
+ export declare function clearSandboxRuntimeCache(): void;
57
+ /**
58
+ * Resolve full runtime configuration for a project.
59
+ */
60
+ export declare function resolveSandboxRuntimeConfig(projectRoot: string, timeoutMs?: number): SandboxRuntimeConfig;
61
+ /**
62
+ * Build macOS Seatbelt (`/usr/bin/sandbox-exec`) SBPL profile and argv.
63
+ * Confines file writes strictly to `projectRoot` and OS temp directories,
64
+ * and denies network access when `cfg.network === "none"`.
65
+ */
66
+ export declare function buildSeatbeltArgs(cfg: SandboxRuntimeConfig, command: string, args: string[]): string[];
67
+ /**
68
+ * Run a command under the configured local OS sandbox runtime.
69
+ */
70
+ export declare function runInSandbox(req: RunInSandboxRequest): Promise<RunInSandboxResult>;
71
+ /**
72
+ * Diagnostic snapshot for CLI.
73
+ */
74
+ export declare function getSandboxRuntimeStatus(projectRoot?: string): {
75
+ config: SandboxRuntimeConfig;
76
+ isolationLabel: string;
77
+ identity: ReturnType<typeof resolveSandboxIdentity>;
78
+ };