@fungi.computer/mycelium 0.0.0-stage → 0.0.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 (78) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +303 -2
  3. package/THIRD_PARTY_NOTICES +2 -0
  4. package/dist/access.d.ts +129 -0
  5. package/dist/access.js +166 -0
  6. package/dist/capability-source.d.ts +44 -0
  7. package/dist/capability-source.js +1 -0
  8. package/dist/compiler.d.ts +28 -0
  9. package/dist/compiler.js +221 -0
  10. package/dist/define.d.ts +8 -0
  11. package/dist/define.js +7 -0
  12. package/dist/effect.d.ts +89 -0
  13. package/dist/effect.js +42 -0
  14. package/dist/errors.d.ts +48 -0
  15. package/dist/errors.js +62 -0
  16. package/dist/execute-tool.d.ts +22 -0
  17. package/dist/execute-tool.js +163 -0
  18. package/dist/image-collector.d.ts +47 -0
  19. package/dist/image-collector.js +39 -0
  20. package/dist/index.d.ts +149 -0
  21. package/dist/index.js +22 -0
  22. package/dist/internal/build-identity.d.ts +1 -0
  23. package/dist/internal/build-identity.js +15 -0
  24. package/dist/internal/build-identity.node.d.ts +1 -0
  25. package/dist/internal/build-identity.node.js +42 -0
  26. package/dist/internal/execution-lifecycle.d.ts +44 -0
  27. package/dist/internal/execution-lifecycle.js +328 -0
  28. package/dist/internal/mcp-principal.d.ts +14 -0
  29. package/dist/internal/mcp-principal.js +17 -0
  30. package/dist/mcp-catalog.d.ts +23 -0
  31. package/dist/mcp-catalog.js +110 -0
  32. package/dist/mcp.d.ts +92 -0
  33. package/dist/mcp.js +250 -0
  34. package/dist/operation-schema.d.ts +47 -0
  35. package/dist/operation-schema.js +50 -0
  36. package/dist/promise-facade.d.ts +3 -0
  37. package/dist/promise-facade.js +82 -0
  38. package/dist/registration.d.ts +74 -0
  39. package/dist/registration.js +157 -0
  40. package/dist/remote.d.ts +33 -0
  41. package/dist/remote.js +126 -0
  42. package/dist/runtime.d.ts +51 -0
  43. package/dist/runtime.js +159 -0
  44. package/dist/sandbox-boundary.d.ts +44 -0
  45. package/dist/sandbox-boundary.js +325 -0
  46. package/dist/sandbox-failure-event.d.ts +15 -0
  47. package/dist/sandbox-failure-event.js +34 -0
  48. package/dist/sandbox-failure.d.ts +128 -0
  49. package/dist/sandbox-failure.js +161 -0
  50. package/dist/sandbox-guest.d.ts +34 -0
  51. package/dist/sandbox-guest.js +131 -0
  52. package/dist/sandbox-wire.d.ts +76 -0
  53. package/dist/sandbox-wire.js +190 -0
  54. package/dist/sandbox.d.ts +41 -0
  55. package/dist/sandbox.js +1 -0
  56. package/dist/semaphore-transition.d.ts +7 -0
  57. package/dist/semaphore-transition.js +9 -0
  58. package/dist/source-runtime.d.ts +28 -0
  59. package/dist/source-runtime.js +162 -0
  60. package/dist/testing.d.ts +11 -0
  61. package/dist/testing.js +19 -0
  62. package/dist/workers/index.d.ts +9 -0
  63. package/dist/workers/index.js +90 -0
  64. package/docs/api/README.md +25 -0
  65. package/docs/api/define.md +20 -0
  66. package/docs/api/effect.md +245 -0
  67. package/docs/api/index.md +1081 -0
  68. package/docs/api/mcp.md +239 -0
  69. package/docs/api/remote.md +108 -0
  70. package/docs/api/sandbox-boundary.md +325 -0
  71. package/docs/api/sandbox-failure.md +1133 -0
  72. package/docs/api/sandbox-guest.md +191 -0
  73. package/docs/api/sandbox-wire.md +117 -0
  74. package/docs/api/sandbox.md +81 -0
  75. package/docs/api/semaphore-transition.md +40 -0
  76. package/docs/api/testing.md +72 -0
  77. package/docs/api/workers.md +55 -0
  78. package/package.json +132 -3
@@ -0,0 +1,34 @@
1
+ import { z } from "zod";
2
+ /** Closed guest envelope: guest exceptions cannot masquerade as host failures. */
3
+ export declare const sandboxGuestResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
+ ok: z.ZodLiteral<true>;
5
+ value: z.ZodUnknown;
6
+ }, z.core.$strict>, z.ZodObject<{
7
+ ok: z.ZodLiteral<false>;
8
+ error: z.ZodObject<{
9
+ kind: z.ZodLiteral<"guest_threw">;
10
+ name: z.ZodString;
11
+ message: z.ZodString;
12
+ transportMessage: z.ZodOptional<z.ZodString>;
13
+ }, z.core.$strict>;
14
+ }, z.core.$strict>], "ok">;
15
+ /** Locate syntax in the submitted code, accounting for Codemode's normalization. */
16
+ export declare function submittedSourceLocation(normalized: string, submitted: string): Readonly<{
17
+ line: number;
18
+ column: number;
19
+ excerpt: string;
20
+ }> | null;
21
+ /** Parsed guest namespace segments; callbacks never cross this wire. */
22
+ export declare const sandboxNamespaceSegmentSchema: z.ZodString;
23
+ /** A transport alias is interpolated as a strict JavaScript binding identifier. */
24
+ export declare const sandboxTransportAliasSchema: z.ZodString;
25
+ /** Transport aliases mapped to their logical namespace paths. */
26
+ export declare const sandboxNamespacePathsSchema: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
27
+ /** Serializable flat transport table; operation keys may have any namespace depth. */
28
+ export declare const sandboxBindingNamesSchema: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
29
+ /** Serializable operation names; callbacks stay in the host's existing binding table. */
30
+ export declare function sandboxBindingNames<A>(bindings: Readonly<Record<string, Readonly<Record<string, A>>>>): Readonly<Record<string, readonly string[]>>;
31
+ /** Injective provider identifier: Codemode sanitizes dotted function names. */
32
+ export declare function sandboxProviderOperationName(operation: string): string;
33
+ /** Capture name and text inside the guest, before Codemode erases Error.name. */
34
+ export declare function sandboxGuestProgram(normalized: string, bindings?: Readonly<Record<string, readonly string[]>>, namespacePaths?: Readonly<Record<string, readonly string[]>>, transportName?: (operation: string) => string): string;
@@ -0,0 +1,131 @@
1
+ import { parse } from "acorn";
2
+ import { z } from "zod";
3
+ import { sandboxSourceError } from "./sandbox-boundary.js";
4
+ /** Closed guest envelope: guest exceptions cannot masquerade as host failures. */
5
+ export const sandboxGuestResultSchema = z.discriminatedUnion("ok", [
6
+ z.strictObject({ ok: z.literal(true), value: z.unknown() }),
7
+ z.strictObject({
8
+ ok: z.literal(false),
9
+ error: z.strictObject({
10
+ kind: z.literal("guest_threw"),
11
+ name: z.string().max(80),
12
+ message: z.string().max(512),
13
+ transportMessage: z.string().max(512).optional(),
14
+ }),
15
+ }),
16
+ ]);
17
+ /** Locate syntax in the submitted code, accounting for Codemode's normalization. */
18
+ export function submittedSourceLocation(normalized, submitted) {
19
+ try {
20
+ parse(`(${normalized})`, { ecmaVersion: "latest", sourceType: "module" });
21
+ return null;
22
+ }
23
+ catch (cause) {
24
+ const diagnostic = sandboxSourceError(cause);
25
+ if (diagnostic === undefined)
26
+ throw cause;
27
+ const { pos } = diagnostic;
28
+ const prelude = "async () => {\n";
29
+ const source = normalized.startsWith(prelude)
30
+ ? normalized.slice(prelude.length, -"\n}".length)
31
+ : normalized;
32
+ const start = submitted.indexOf(source);
33
+ if (start < 0)
34
+ throw cause;
35
+ const offset = Math.min(submitted.length, Math.max(0, pos - 1 - normalized.indexOf(source) + start));
36
+ const prefix = submitted.slice(0, offset).split(/\r\n|[\n\r\u2028\u2029]/u);
37
+ const line = prefix.length;
38
+ return {
39
+ line,
40
+ column: (prefix.at(-1)?.length ?? 0) + 1,
41
+ excerpt: (submitted.split(/\r\n|[\n\r\u2028\u2029]/u)[line - 1] ?? "")
42
+ .replace(/\p{Cc}|\p{Cf}/gu, " ")
43
+ .slice(0, 160),
44
+ };
45
+ }
46
+ }
47
+ /** Parsed guest namespace segments; callbacks never cross this wire. */
48
+ export const sandboxNamespaceSegmentSchema = z
49
+ .string()
50
+ .regex(/^[A-Za-z][A-Za-z0-9_]*$/u);
51
+ /** A transport alias is interpolated as a strict JavaScript binding identifier. */
52
+ export const sandboxTransportAliasSchema = sandboxNamespaceSegmentSchema.refine((alias) => {
53
+ if (alias === "env")
54
+ return false;
55
+ try {
56
+ parse(`let ${alias};`, { ecmaVersion: "latest", sourceType: "module" });
57
+ return true;
58
+ }
59
+ catch (cause) {
60
+ if (!(cause instanceof SyntaxError))
61
+ throw cause;
62
+ return false;
63
+ }
64
+ }, "Invalid sandbox transport alias");
65
+ /** Transport aliases mapped to their logical namespace paths. */
66
+ export const sandboxNamespacePathsSchema = z.record(sandboxTransportAliasSchema, z.array(sandboxNamespaceSegmentSchema).min(1));
67
+ /** Serializable flat transport table; operation keys may have any namespace depth. */
68
+ export const sandboxBindingNamesSchema = z.record(sandboxTransportAliasSchema, z.array(z.string().regex(/^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)*$/u)));
69
+ /** Serializable operation names; callbacks stay in the host's existing binding table. */
70
+ export function sandboxBindingNames(bindings) {
71
+ return Object.fromEntries(Object.entries(bindings).map(([namespace, operations]) => [
72
+ namespace,
73
+ Object.keys(operations),
74
+ ]));
75
+ }
76
+ /** Project compiler-owned paths without changing any callback or authority identity. */
77
+ function guestEnvironment(bindings, namespacePaths, transportName) {
78
+ const root = { kind: "namespace", children: new Map() };
79
+ const paths = sandboxNamespacePathsSchema.parse(namespacePaths);
80
+ for (const [alias, operations] of Object.entries(sandboxBindingNamesSchema.parse(bindings))) {
81
+ for (const operation of operations) {
82
+ const path = [...(paths[alias] ?? [alias]), ...operation.split(".")];
83
+ let parent = root;
84
+ for (const segment of path.slice(0, -1)) {
85
+ const found = parent.children.get(segment);
86
+ if (found?.kind === "operation")
87
+ throw new Error("Operation conflicts with namespace");
88
+ const child = found ?? {
89
+ kind: "namespace",
90
+ children: new Map(),
91
+ };
92
+ parent.children.set(segment, child);
93
+ parent = child;
94
+ }
95
+ const name = path.at(-1);
96
+ if (name === undefined || parent.children.has(name))
97
+ throw new Error("Duplicate guest operation path");
98
+ parent.children.set(name, {
99
+ kind: "operation",
100
+ call: `(...args) => ${alias}[${JSON.stringify(transportName(operation))}](...args)`,
101
+ });
102
+ }
103
+ }
104
+ const expression = (node) => `Object.freeze({${[...node.children]
105
+ .map(([name, child]) => `[${JSON.stringify(name)}]: ${child.kind === "operation" ? child.call : expression(child)}`)
106
+ .join(",")}})`;
107
+ return expression(root);
108
+ }
109
+ /** Injective provider identifier: Codemode sanitizes dotted function names. */
110
+ export function sandboxProviderOperationName(operation) {
111
+ return `operation_${Array.from(new TextEncoder().encode(operation), (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
112
+ }
113
+ /** Capture name and text inside the guest, before Codemode erases Error.name. */
114
+ export function sandboxGuestProgram(normalized, bindings = {}, namespacePaths = {}, transportName) {
115
+ return `async () => {
116
+ const env = ${guestEnvironment(bindings, namespacePaths, transportName ?? ((operation) => operation))};
117
+ return await (async (${Object.keys(bindings).join(",")}) => {
118
+ try { return { ok: true, value: await (${normalized})() }; }
119
+ catch (cause) {
120
+ const name = cause instanceof Error ? cause.name : "ThrownValue";
121
+ const message = cause instanceof Error ? cause.message : String(cause);
122
+ const transportMessage = cause instanceof Error && cause.cause instanceof Error ? cause.cause.message.slice(0, 512) : undefined;
123
+ return { ok: false, error: { kind: "guest_threw", name: String(name).slice(0, 80), message: String(message).replace(/\\p{Cc}/gu, " ").slice(0, 512), ...(transportMessage === undefined ? {} : { transportMessage }) } };
124
+ }
125
+ })(${Object.keys(bindings)
126
+ .map((alias) => transportName === undefined
127
+ ? alias
128
+ : (namespacePaths[alias] ?? [alias]).reduce((value, segment) => `${value}[${JSON.stringify(segment)}]`, "env"))
129
+ .join(",")});
130
+ }`;
131
+ }
@@ -0,0 +1,76 @@
1
+ import { z } from "zod";
2
+ import { type SandboxFailure } from "./sandbox-failure.js";
3
+ /** The host-to-host result contract; raw diagnostic fields never go to guest code. */
4
+ export declare const sandboxWireSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
5
+ ok: z.ZodLiteral<true>;
6
+ value: z.ZodJSONSchema;
7
+ }, z.core.$strict>, z.ZodObject<{
8
+ ok: z.ZodLiteral<false>;
9
+ error: z.ZodDiscriminatedUnion<[z.ZodObject<{
10
+ kind: z.ZodLiteral<"invalid_source">;
11
+ line: z.ZodNumber;
12
+ column: z.ZodNumber;
13
+ excerpt: z.ZodString;
14
+ }, z.core.$strict>, z.ZodObject<{
15
+ kind: z.ZodLiteral<"guest_threw">;
16
+ name: z.ZodString;
17
+ message: z.ZodString;
18
+ transportMessage: z.ZodOptional<z.ZodString>;
19
+ }, z.core.$strict>, z.ZodObject<{
20
+ kind: z.ZodLiteral<"deadline_exceeded">;
21
+ limitMs: z.ZodNumber;
22
+ elapsedMs: z.ZodNumber;
23
+ }, z.core.$strict>, z.ZodObject<{
24
+ kind: z.ZodLiteral<"result_not_json">;
25
+ valueKind: z.ZodString;
26
+ rawCause: z.ZodJSONSchema;
27
+ }, z.core.$strict>, z.ZodObject<{
28
+ kind: z.ZodLiteral<"sandbox_crashed">;
29
+ rawCause: z.ZodJSONSchema;
30
+ }, z.core.$strict>, z.ZodObject<{
31
+ kind: z.ZodLiteral<"bad_response">;
32
+ reason: z.ZodString;
33
+ rawCause: z.ZodJSONSchema;
34
+ }, z.core.$strict>, z.ZodObject<{
35
+ kind: z.ZodLiteral<"dispatch_lost">;
36
+ elapsedMs: z.ZodNumber;
37
+ transport: z.ZodString;
38
+ errno: z.ZodOptional<z.ZodString>;
39
+ rawCause: z.ZodJSONSchema;
40
+ }, z.core.$strict>, z.ZodObject<{
41
+ kind: z.ZodLiteral<"cancelled">;
42
+ by: z.ZodEnum<{
43
+ caller: "caller";
44
+ operator: "operator";
45
+ }>;
46
+ }, z.core.$strict>, z.ZodObject<{
47
+ kind: z.ZodLiteral<"result_too_large">;
48
+ size: z.ZodNumber;
49
+ }, z.core.$strict>, z.ZodObject<{
50
+ kind: z.ZodLiteral<"capability_failed">;
51
+ namespace: z.ZodString;
52
+ operation: z.ZodString;
53
+ cause: z.ZodObject<{
54
+ kind: z.ZodEnum<{
55
+ Files: "Files";
56
+ Forage: "Forage";
57
+ InvalidInput: "InvalidInput";
58
+ Unavailable: "Unavailable";
59
+ OperationFailed: "OperationFailed";
60
+ }>;
61
+ message: z.ZodString;
62
+ }, z.core.$strict>;
63
+ rawCause: z.ZodJSONSchema;
64
+ }, z.core.$strict>, z.ZodObject<{
65
+ kind: z.ZodLiteral<"unknown">;
66
+ rawCause: z.ZodJSONSchema;
67
+ }, z.core.$strict>], "kind">;
68
+ }, z.core.$strict>], "ok">;
69
+ /** Typed, decoded host wire value. */
70
+ export type SandboxWire = z.output<typeof sandboxWireSchema>;
71
+ /** Convert one validated wire failure into the shared error channel. */
72
+ export declare function sandboxWireFailure(error: Extract<SandboxWire, {
73
+ ok: false;
74
+ }>["error"]): SandboxFailure;
75
+ /** Host-only encoding; the guest receives only the admitted diagnostic text. */
76
+ export declare function sandboxFailureWire(failure: SandboxFailure): z.core.util.JSONType;
@@ -0,0 +1,190 @@
1
+ import { sandboxOperatorValue, sandboxGuestFailure, } from "./sandbox-boundary.js";
2
+ import { z } from "zod";
3
+ import { SourceInvalid, DeadlineExceeded, ResultNotJson, SandboxCrashed, BadResponse, DispatchLost, Cancelled, ResultTooLarge, CapabilityFailed, Unknown, } from "./sandbox-failure.js";
4
+ /** The host-to-host result contract; raw diagnostic fields never go to guest code. */
5
+ export const sandboxWireSchema = z.discriminatedUnion("ok", [
6
+ z.strictObject({ ok: z.literal(true), value: z.json() }),
7
+ z.strictObject({
8
+ ok: z.literal(false),
9
+ error: z.discriminatedUnion("kind", [
10
+ z.strictObject({
11
+ kind: z.literal("invalid_source"),
12
+ line: z.number().int().min(1),
13
+ column: z.number().int().min(1),
14
+ excerpt: z.string().max(160),
15
+ }),
16
+ z.strictObject({
17
+ kind: z.literal("guest_threw"),
18
+ name: z.string().max(80),
19
+ message: z.string().max(512),
20
+ transportMessage: z.string().max(512).optional(),
21
+ }),
22
+ z.strictObject({
23
+ kind: z.literal("deadline_exceeded"),
24
+ limitMs: z.number().int().positive(),
25
+ elapsedMs: z.number().nonnegative(),
26
+ }),
27
+ z.strictObject({
28
+ kind: z.literal("result_not_json"),
29
+ valueKind: z.string().max(80),
30
+ rawCause: z.json(),
31
+ }),
32
+ z.strictObject({
33
+ kind: z.literal("sandbox_crashed"),
34
+ rawCause: z.json(),
35
+ }),
36
+ z.strictObject({
37
+ kind: z.literal("bad_response"),
38
+ reason: z.string(),
39
+ rawCause: z.json(),
40
+ }),
41
+ z.strictObject({
42
+ kind: z.literal("dispatch_lost"),
43
+ elapsedMs: z.number().nonnegative(),
44
+ transport: z.string(),
45
+ errno: z.string().optional(),
46
+ rawCause: z.json(),
47
+ }),
48
+ z.strictObject({
49
+ kind: z.literal("cancelled"),
50
+ by: z.enum(["caller", "operator"]),
51
+ }),
52
+ z.strictObject({
53
+ kind: z.literal("result_too_large"),
54
+ size: z.number().nonnegative(),
55
+ }),
56
+ z.strictObject({
57
+ kind: z.literal("capability_failed"),
58
+ namespace: z.string(),
59
+ operation: z.string(),
60
+ cause: z.strictObject({
61
+ kind: z.enum([
62
+ "Files",
63
+ "Forage",
64
+ "InvalidInput",
65
+ "Unavailable",
66
+ "OperationFailed",
67
+ ]),
68
+ message: z.string().max(1000),
69
+ }),
70
+ rawCause: z.json(),
71
+ }),
72
+ z.strictObject({ kind: z.literal("unknown"), rawCause: z.json() }),
73
+ ]),
74
+ }),
75
+ ]);
76
+ /** Convert one validated wire failure into the shared error channel. */
77
+ export function sandboxWireFailure(error) {
78
+ switch (error.kind) {
79
+ case "invalid_source":
80
+ return new SourceInvalid(error);
81
+ case "guest_threw":
82
+ return sandboxGuestFailure(error);
83
+ case "deadline_exceeded":
84
+ return new DeadlineExceeded(error);
85
+ case "result_not_json":
86
+ return new ResultNotJson({
87
+ kind: error.valueKind,
88
+ rawCause: error.rawCause,
89
+ });
90
+ case "sandbox_crashed":
91
+ return new SandboxCrashed(error);
92
+ case "bad_response":
93
+ return new BadResponse(error);
94
+ case "dispatch_lost":
95
+ return new DispatchLost(error);
96
+ case "cancelled":
97
+ return new Cancelled(error);
98
+ case "result_too_large":
99
+ return new ResultTooLarge(error);
100
+ case "capability_failed":
101
+ return new CapabilityFailed(error);
102
+ case "unknown":
103
+ return new Unknown(error);
104
+ }
105
+ }
106
+ /** Host-only encoding; the guest receives only the admitted diagnostic text. */
107
+ export function sandboxFailureWire(failure) {
108
+ let error;
109
+ switch (failure._tag) {
110
+ case "SourceInvalid":
111
+ error = {
112
+ kind: "invalid_source",
113
+ line: failure.line,
114
+ column: failure.column,
115
+ excerpt: failure.excerpt,
116
+ };
117
+ break;
118
+ case "GuestThrew":
119
+ error = {
120
+ kind: "guest_threw",
121
+ name: failure.name.slice(0, 80),
122
+ message: failure.message.slice(0, 512),
123
+ };
124
+ if (failure.transportMessage !== undefined)
125
+ error.transportMessage = failure.transportMessage;
126
+ break;
127
+ case "DeadlineExceeded":
128
+ error = {
129
+ kind: "deadline_exceeded",
130
+ limitMs: failure.limitMs,
131
+ elapsedMs: failure.elapsedMs,
132
+ };
133
+ break;
134
+ case "Cancelled":
135
+ error = { kind: "cancelled", by: failure.by };
136
+ break;
137
+ case "DispatchLost":
138
+ error = {
139
+ kind: "dispatch_lost",
140
+ elapsedMs: failure.elapsedMs,
141
+ transport: failure.transport,
142
+ rawCause: sandboxOperatorValue(failure.rawCause),
143
+ };
144
+ if (failure.errno !== undefined)
145
+ error.errno = failure.errno;
146
+ break;
147
+ case "SandboxCrashed":
148
+ error = {
149
+ kind: "sandbox_crashed",
150
+ rawCause: sandboxOperatorValue(failure.rawCause),
151
+ };
152
+ break;
153
+ case "BadResponse":
154
+ error = {
155
+ kind: "bad_response",
156
+ reason: failure.reason,
157
+ rawCause: sandboxOperatorValue(failure.rawCause),
158
+ };
159
+ break;
160
+ case "ResultNotJson":
161
+ error = {
162
+ kind: "result_not_json",
163
+ valueKind: failure.kind,
164
+ rawCause: sandboxOperatorValue(failure.rawCause),
165
+ };
166
+ break;
167
+ case "ResultTooLarge":
168
+ error = { kind: "result_too_large", size: failure.size };
169
+ break;
170
+ case "CapabilityFailed":
171
+ error = {
172
+ kind: "capability_failed",
173
+ namespace: failure.namespace,
174
+ operation: failure.operation,
175
+ cause: {
176
+ kind: failure.cause.kind,
177
+ message: failure.cause.message.slice(0, 1000),
178
+ },
179
+ rawCause: sandboxOperatorValue(failure.rawCause),
180
+ };
181
+ break;
182
+ case "Unknown":
183
+ error = {
184
+ kind: "unknown",
185
+ rawCause: sandboxOperatorValue(failure.rawCause),
186
+ };
187
+ break;
188
+ }
189
+ return z.json().parse({ ok: false, error });
190
+ }
@@ -0,0 +1,41 @@
1
+ import type { input, output, ZodJSONSchema, ZodUnknown } from "zod";
2
+ /** JSON value allowed to cross the sandbox and capability boundary. */
3
+ export type MyceliumJsonValue = output<ZodJSONSchema>;
4
+ /** Untrusted value supplied by or returned from a host sandbox boundary. */
5
+ export type SandboxValue = input<ZodUnknown>;
6
+ /** One invocation binding visible to the host-provided sandbox. */
7
+ export type SandboxBinding = (input: SandboxValue) => Promise<MyceliumJsonValue>;
8
+ /** Request crossing the root Promise-shaped sandbox seam. */
9
+ export type SandboxRequest = Readonly<{
10
+ /** Fresh identity shared by the request and every bound operation call. */
11
+ executionId: string;
12
+ /** Model-authored program to evaluate inside the host sandbox. */
13
+ code: string;
14
+ /** Effective Mycelium execution budget; cancellation remains authoritative. */
15
+ timeoutMs: number;
16
+ /** Transport aliases mapped to flat relative operation paths. */
17
+ bindings: Readonly<Record<string, Readonly<Record<string, SandboxBinding>>>>;
18
+ /** Logical namespace path for each transport alias; defaults to `[alias]`. */
19
+ namespacePaths?: Readonly<Record<string, readonly string[]>>;
20
+ /**
21
+ * Every bound execution alias mapped to its stable module id. Always
22
+ * present on a request built by `runExecution`; optional only so a
23
+ * hand-built request from an older call site keeps compiling.
24
+ */
25
+ modules?: Readonly<Record<string, string>>;
26
+ /**
27
+ * Stable Session identity for this run; null for session-free hosts.
28
+ * Always present on a request built by `runExecution`; optional only so a
29
+ * hand-built request from an older call site keeps compiling.
30
+ */
31
+ sessionId?: string | null;
32
+ }>;
33
+ /** Promise-shaped sandbox interface implemented by a host or stranger. */
34
+ export type Sandbox = Readonly<{
35
+ /** Operator identity of this transport. */
36
+ adapter?: string;
37
+ /** Source revision supplied by the host build. */
38
+ buildSha?: string;
39
+ /** Evaluate one bounded program and settle only after cancellation is observed. */
40
+ execute: (request: SandboxRequest, signal: AbortSignal) => Promise<SandboxValue>;
41
+ }>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Semaphore from "effect/Semaphore";
3
+ /**
4
+ * Serialize a synchronous state claim and settle its Effect outside the gate.
5
+ * Interruption cannot release the caller until settlement finishes.
6
+ */
7
+ export declare function claimThenSettle<A, B, E>(gate: Semaphore.Semaphore, claim: () => A, settle: (claimed: A) => Effect.Effect<B, E>): Effect.Effect<B, E>;
@@ -0,0 +1,9 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Semaphore from "effect/Semaphore";
3
+ /**
4
+ * Serialize a synchronous state claim and settle its Effect outside the gate.
5
+ * Interruption cannot release the caller until settlement finishes.
6
+ */
7
+ export function claimThenSettle(gate, claim, settle) {
8
+ return Effect.uninterruptibleMask((restore) => restore(gate.take(1)).pipe(Effect.flatMap(() => Effect.sync(claim).pipe(Effect.ensuring(gate.release(1)))), Effect.flatMap(settle)));
9
+ }
@@ -0,0 +1,28 @@
1
+ import * as Effect from "effect/Effect";
2
+ import type { CapabilitySession, CapabilitySource } from "./capability-source.js";
3
+ import { type CompiledSurface } from "./compiler.js";
4
+ import { type MyceliumError } from "./errors.js";
5
+ import { type ExecuteDoor } from "./execute-tool.js";
6
+ import type { AccessOptions } from "./access.js";
7
+ import type { BackingWorkTracker } from "./internal/execution-lifecycle.js";
8
+ import type { EffectSandbox } from "./runtime.js";
9
+ import type { ModuleRegistration } from "./registration.js";
10
+ /** Coherent candidate revision built from static and acquired modules. */
11
+ export type SourceCandidate = Readonly<{
12
+ readonly compiled: CompiledSurface;
13
+ readonly executeDoor: ExecuteDoor;
14
+ readonly isStale: () => boolean;
15
+ readonly close: () => Effect.Effect<void, MyceliumError>;
16
+ }>;
17
+ /** Inputs needed to build one off-to-the-side candidate revision. */
18
+ export type SourceCandidateOptions = Readonly<{
19
+ readonly modules: readonly ModuleRegistration[];
20
+ readonly sources: readonly CapabilitySource[];
21
+ readonly session?: CapabilitySession | undefined;
22
+ readonly sandbox: EffectSandbox;
23
+ readonly backingWork: BackingWorkTracker;
24
+ readonly precompiled?: CompiledSurface;
25
+ readonly access: AccessOptions;
26
+ }>;
27
+ /** Acquire one non-stale candidate or fail after one bounded retry. */
28
+ export declare function acquireSourceCandidate(options: SourceCandidateOptions): Effect.Effect<SourceCandidate, MyceliumError>;