holycodex 0.15.0-dev.29.1 → 0.15.1-dev.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,11 @@
1
1
  #!/usr/bin/env bun
2
+ import { createRequire } from "node:module";
3
+ import { dirname, join } from "node:path";
2
4
  import { fileURLToPath } from "node:url";
5
+ import { spawnSync } from "node:child_process";
3
6
  import { newQuickJSWASMModule } from "quickjs-emscripten";
7
+ import { mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
8
+ import { tmpdir } from "node:os";
4
9
  //#region packages/core/src/common.ts
5
10
  const CLI_SCHEMA_VERSION = "0.15";
6
11
  const STATE_SCHEMA_EPOCH = "state-0.15";
@@ -3336,7 +3341,7 @@ const dedupe = (self) => dedupeWith(self, equivalence());
3336
3341
  * @since 2.0.0
3337
3342
  * @category folding
3338
3343
  */
3339
- const join$1 = /*#__PURE__*/ dual(2, (self, sep) => fromIterable$6(self).join(sep));
3344
+ const join$2 = /*#__PURE__*/ dual(2, (self, sep) => fromIterable$6(self).join(sep));
3340
3345
  //#endregion
3341
3346
  //#region node_modules/.bun/effect@3.22.1/node_modules/effect/dist/esm/BigDecimal.js
3342
3347
  /**
@@ -9166,7 +9171,7 @@ const InvalidData = (path, message, options = { pathDelim: "." }) => {
9166
9171
  Object.defineProperty(error, "toString", {
9167
9172
  enumerable: false,
9168
9173
  value() {
9169
- return `(Invalid data at ${pipe(this.path, join$1(options.pathDelim))}: "${this.message}")`;
9174
+ return `(Invalid data at ${pipe(this.path, join$2(options.pathDelim))}: "${this.message}")`;
9170
9175
  }
9171
9176
  });
9172
9177
  return error;
@@ -9180,7 +9185,7 @@ const MissingData = (path, message, options = { pathDelim: "." }) => {
9180
9185
  Object.defineProperty(error, "toString", {
9181
9186
  enumerable: false,
9182
9187
  value() {
9183
- return `(Missing data at ${pipe(this.path, join$1(options.pathDelim))}: "${this.message}")`;
9188
+ return `(Missing data at ${pipe(this.path, join$2(options.pathDelim))}: "${this.message}")`;
9184
9189
  }
9185
9190
  });
9186
9191
  return error;
@@ -9195,7 +9200,7 @@ const SourceUnavailable = (path, message, cause, options = { pathDelim: "." }) =
9195
9200
  Object.defineProperty(error, "toString", {
9196
9201
  enumerable: false,
9197
9202
  value() {
9198
- return `(Source unavailable at ${pipe(this.path, join$1(options.pathDelim))}: "${this.message}")`;
9203
+ return `(Source unavailable at ${pipe(this.path, join$2(options.pathDelim))}: "${this.message}")`;
9199
9204
  }
9200
9205
  });
9201
9206
  return error;
@@ -9209,7 +9214,7 @@ const Unsupported = (path, message, options = { pathDelim: "." }) => {
9209
9214
  Object.defineProperty(error, "toString", {
9210
9215
  enumerable: false,
9211
9216
  value() {
9212
- return `(Unsupported operation at ${pipe(this.path, join$1(options.pathDelim))}: "${this.message}")`;
9217
+ return `(Unsupported operation at ${pipe(this.path, join$2(options.pathDelim))}: "${this.message}")`;
9213
9218
  }
9214
9219
  });
9215
9220
  return error;
@@ -9478,7 +9483,7 @@ const fromEnv = (options) => {
9478
9483
  pathDelim: "_",
9479
9484
  seqDelim: ","
9480
9485
  }, options);
9481
- const makePathString = (path) => pipe(path, join$1(pathDelim));
9486
+ const makePathString = (path) => pipe(path, join$2(pathDelim));
9482
9487
  const unmakePathString = (pathString) => pathString.split(pathDelim);
9483
9488
  const getEnv = () => typeof process !== "undefined" && "env" in process && typeof process.env === "object" ? process.env : {};
9484
9489
  const load = (path, primitive, split = true) => {
@@ -9570,7 +9575,7 @@ const fromFlatLoop = (flat, prefix, config, split) => {
9570
9575
  if (isLeft(left) && isRight(right$4)) return fail$4(left.left);
9571
9576
  if (isRight(left) && isLeft(right$4)) return fail$4(right$4.left);
9572
9577
  if (isRight(left) && isRight(right$4)) {
9573
- const path = pipe(prefix, join$1("."));
9578
+ const path = pipe(prefix, join$2("."));
9574
9579
  const fail = fromFlatLoopFail(prefix, path);
9575
9580
  const [lefts, rights] = extend(fail, fail, pipe(left.right, map$5(right)), pipe(right$4.right, map$5(right)));
9576
9581
  return pipe(lefts, zip$1(rights), forEachSequential(([left, right]) => pipe(zip(left, right), map$2(([left, right]) => op.zip(left, right)))));
@@ -11459,7 +11464,7 @@ const fiberProto = {
11459
11464
  /** @internal */
11460
11465
  const RuntimeFiberTypeId = /*#__PURE__*/ Symbol.for("effect/Fiber");
11461
11466
  /** @internal */
11462
- const join = (self) => zipLeft(flatten$1(self.await), self.inheritAll);
11467
+ const join$1 = (self) => zipLeft(flatten$1(self.await), self.inheritAll);
11463
11468
  ({ ...CommitPrototype }), { ...fiberProto };
11464
11469
  /** @internal */
11465
11470
  const currentFiberURI = "effect/FiberCurrent";
@@ -12758,7 +12763,7 @@ var FiberRuntime = class extends Class {
12758
12763
  this.refreshRefCache();
12759
12764
  }
12760
12765
  commit() {
12761
- return join(this);
12766
+ return join$1(this);
12762
12767
  }
12763
12768
  /**
12764
12769
  * The identity of the fiber.
@@ -13766,7 +13771,7 @@ const forEachConcurrentDiscard = (self, f, batching, processAll, n) => uninterru
13766
13771
  };
13767
13772
  for (let i = 0; i < fibersCount; i++) next();
13768
13773
  }));
13769
- return asVoid(onExit$1(flatten$1(restore(join(processingFiber))), exitMatch({
13774
+ return asVoid(onExit$1(flatten$1(restore(join$1(processingFiber))), exitMatch({
13770
13775
  onFailure: (cause) => {
13771
13776
  onInterruptSignal();
13772
13777
  const target = residual.length + 1;
@@ -13962,11 +13967,11 @@ const raceWith = /*#__PURE__*/ dual(3, (self, other, options) => raceFibersWith(
13962
13967
  /** @internal */
13963
13968
  const race = /*#__PURE__*/ dual(2, (self, that) => fiberIdWith((parentFiberId) => raceWith(self, that, {
13964
13969
  onSelfDone: (exit, right) => exitMatchEffect(exit, {
13965
- onFailure: (cause) => pipe(join(right), mapErrorCause((cause2) => parallel$2(cause, cause2))),
13970
+ onFailure: (cause) => pipe(join$1(right), mapErrorCause((cause2) => parallel$2(cause, cause2))),
13966
13971
  onSuccess: (value) => pipe(right, interruptAsFiber(parentFiberId), as(value))
13967
13972
  }),
13968
13973
  onOtherDone: (exit, left) => exitMatchEffect(exit, {
13969
- onFailure: (cause) => pipe(join(left), mapErrorCause((cause2) => parallel$2(cause2, cause))),
13974
+ onFailure: (cause) => pipe(join$1(left), mapErrorCause((cause2) => parallel$2(cause2, cause))),
13970
13975
  onSuccess: (value) => pipe(left, interruptAsFiber(parentFiberId), as(value))
13971
13976
  })
13972
13977
  })));
@@ -22392,7 +22397,7 @@ const effortRank = {
22392
22397
  const ROUTE_EFFORT_OVERRIDES = [
22393
22398
  {
22394
22399
  plan: "plus-low",
22395
- rationale: "Preserve the approved HolyCodex 0.14.1 plus-low route effort policy.",
22400
+ rationale: "Preserve the approved plus-low route effort policy.",
22396
22401
  efforts: {
22397
22402
  "Explorer:lookup": "medium",
22398
22403
  "Explorer:trace": "high",
@@ -22409,7 +22414,7 @@ const ROUTE_EFFORT_OVERRIDES = [
22409
22414
  },
22410
22415
  {
22411
22416
  plan: "plus",
22412
- rationale: "Preserve the approved HolyCodex 0.14.1 plus route effort policy.",
22417
+ rationale: "Preserve the approved plus route effort policy.",
22413
22418
  efforts: {
22414
22419
  "Explorer:lookup": "medium",
22415
22420
  "Explorer:trace": "high",
@@ -22426,7 +22431,7 @@ const ROUTE_EFFORT_OVERRIDES = [
22426
22431
  },
22427
22432
  {
22428
22433
  plan: "plus-high",
22429
- rationale: "Preserve the approved HolyCodex 0.14.1 plus-high route effort policy.",
22434
+ rationale: "Preserve the approved plus-high route effort policy.",
22430
22435
  efforts: {
22431
22436
  "Explorer:lookup": "medium",
22432
22437
  "Explorer:trace": "xhigh",
@@ -22443,7 +22448,7 @@ const ROUTE_EFFORT_OVERRIDES = [
22443
22448
  },
22444
22449
  {
22445
22450
  plan: "pro-5x",
22446
- rationale: "Preserve the approved HolyCodex 0.14.1 pro-5x route effort policy.",
22451
+ rationale: "Preserve the approved pro-5x route effort policy.",
22447
22452
  efforts: {
22448
22453
  "Explorer:lookup": "high",
22449
22454
  "Explorer:trace": "xhigh",
@@ -22460,7 +22465,7 @@ const ROUTE_EFFORT_OVERRIDES = [
22460
22465
  },
22461
22466
  {
22462
22467
  plan: "pro-20x",
22463
- rationale: "Preserve the approved HolyCodex 0.14.1 pro-20x route effort policy.",
22468
+ rationale: "Preserve the approved pro-20x route effort policy.",
22464
22469
  efforts: {
22465
22470
  "Explorer:lookup": "high",
22466
22471
  "Explorer:trace": "xhigh",
@@ -23036,7 +23041,7 @@ function step(definition) {
23036
23041
  const inputCodec = toUnknownCodec(assignment.input);
23037
23042
  const outputCodec = toUnknownCodec(assignment.output);
23038
23043
  const nodeAssignment = {
23039
- payload: assignment.payload,
23044
+ ...assignment.payload === void 0 ? {} : { payload: assignment.payload },
23040
23045
  input: inputCodec,
23041
23046
  output: outputCodec,
23042
23047
  ...assignment.route === void 0 ? {} : { route: assignment.route },
@@ -23148,7 +23153,7 @@ function normalizeAssignment(assignment) {
23148
23153
  if (containsCallable(assignment.payload)) throw new Error("A workflow assignment payload must be inert data.");
23149
23154
  const metadata = assignment.metadata === void 0 ? void 0 : Object.freeze({ ...assignment.metadata });
23150
23155
  return Object.freeze({
23151
- payload: assignment.payload,
23156
+ ...assignment.payload === void 0 ? {} : { payload: assignment.payload },
23152
23157
  input: assignment.input,
23153
23158
  output: assignment.output,
23154
23159
  ...assignment.route === void 0 ? {} : { route: assignment.route },
@@ -23377,6 +23382,26 @@ function isRecord$3(value) {
23377
23382
  return typeof value === "object" && value !== null && !Array.isArray(value);
23378
23383
  }
23379
23384
  //#endregion
23385
+ //#region packages/workflow-runtime/src/schema.ts
23386
+ /** Decode portable schema IR with the real host-side Effect Schema runtime. */
23387
+ function decodePortableSchema(schema, value) {
23388
+ const ir = "__holycodexSchema" in schema ? schema.__holycodexSchema : schema;
23389
+ const parsed = decodeUnknownEither(toEffectSchema(ir))(value);
23390
+ if (isLeft(parsed)) throw new Error("The workflow value does not match its schema.");
23391
+ return parsed.right;
23392
+ }
23393
+ function toEffectSchema(ir) {
23394
+ switch (ir.kind) {
23395
+ case "string": return String$;
23396
+ case "number": return Number$;
23397
+ case "boolean": return Boolean$;
23398
+ case "unknown": return Unknown;
23399
+ case "literal": return Literal(ir.value);
23400
+ case "array": return Array$(toEffectSchema(ir.element));
23401
+ case "struct": return Struct(Object.fromEntries(Object.entries(ir.fields).map(([key, value]) => [key, toEffectSchema(value)])));
23402
+ }
23403
+ }
23404
+ //#endregion
23380
23405
  //#region packages/workflow-runtime/src/errors.ts
23381
23406
  function workflowFailure(code, message, details = {}) {
23382
23407
  return Object.freeze({
@@ -23544,7 +23569,23 @@ function isDigest(value) {
23544
23569
  return typeof value === "string" && /^[0-9a-f]{64}$/u.test(value);
23545
23570
  }
23546
23571
  function isCodec(value) {
23547
- return isRecord$2(value) && typeof value["id"] === "string" && typeof value["name"] === "string";
23572
+ return isRecord$2(value) && typeof value["id"] === "string" && typeof value["name"] === "string" && (value["schema"] === void 0 || isPortableSchema(value["schema"]));
23573
+ }
23574
+ function isPortableSchema(value) {
23575
+ if (!isRecord$2(value) || typeof value["kind"] !== "string") return false;
23576
+ switch (value["kind"]) {
23577
+ case "string":
23578
+ case "number":
23579
+ case "boolean":
23580
+ case "unknown": return true;
23581
+ case "literal": return value["value"] === null || typeof value["value"] === "string" || typeof value["value"] === "boolean" || typeof value["value"] === "number" && Number.isFinite(value["value"]);
23582
+ case "array": return isPortableSchema(value["element"]);
23583
+ case "struct": {
23584
+ const fields = value["fields"];
23585
+ return isRecord$2(fields) && Object.values(fields).every(isPortableSchema);
23586
+ }
23587
+ default: return false;
23588
+ }
23548
23589
  }
23549
23590
  function isInput(value) {
23550
23591
  if (!isRecord$2(value) || typeof value["kind"] !== "string") return false;
@@ -23771,7 +23812,7 @@ function nativeNode(node, codecs) {
23771
23812
  const outputCodec = requireNativeCodec(codecs, node.assignment.outputCodecId);
23772
23813
  const input = nativeInput(node.input, codecs);
23773
23814
  const assignment = {
23774
- payload: node.assignment.hasPayload ? nativePayload(node.assignment.payload, codecs) : void 0,
23815
+ ...node.assignment.hasPayload ? { payload: nativePayload(node.assignment.payload, codecs) } : {},
23775
23816
  input: inputCodec,
23776
23817
  output: outputCodec,
23777
23818
  metadata: node.assignment.metadata,
@@ -23853,7 +23894,11 @@ function nativePayload(value, codecs, seen = /* @__PURE__ */ new Set()) {
23853
23894
  if (seen.has(value)) throw workflowFailure("validation", "The native workflow payload is cyclic.");
23854
23895
  seen.add(value);
23855
23896
  try {
23856
- if (Array.isArray(value)) return value.map((item) => nativePayload(item, codecs, seen));
23897
+ if (Array.isArray(value)) {
23898
+ const result = [];
23899
+ for (const item of value) result.push(nativePayload(item, codecs, seen));
23900
+ return result;
23901
+ }
23857
23902
  const result = {};
23858
23903
  for (const [key, item] of Object.entries(value)) result[key] = nativePayload(item, codecs, seen);
23859
23904
  return result;
@@ -29324,6 +29369,7 @@ function createScanner(skipTrivia, languageVariant = LanguageVariant.Standard, t
29324
29369
  }
29325
29370
  //#endregion
29326
29371
  //#region packages/workflow-runtime/src/transform.ts
29372
+ const require = createRequire(import.meta.url);
29327
29373
  const FORBIDDEN_WORDS = /* @__PURE__ */ new Set([
29328
29374
  "enum",
29329
29375
  "namespace",
@@ -29372,7 +29418,16 @@ const NATIVE_FORBIDDEN_IDENTIFIERS = /* @__PURE__ */ new Set([
29372
29418
  "async",
29373
29419
  "await"
29374
29420
  ]);
29375
- const NATIVE_RUNTIME_IMPORTS = /* @__PURE__ */ new Set(["workflow", "createCodec"]);
29421
+ const NATIVE_WORKFLOW_IMPORTS = /* @__PURE__ */ new Set(["workflow", "createCodec"]);
29422
+ const NATIVE_SCHEMA_IMPORTS = /* @__PURE__ */ new Set([
29423
+ "String",
29424
+ "Number",
29425
+ "Boolean",
29426
+ "Unknown",
29427
+ "Literal",
29428
+ "Array",
29429
+ "Struct"
29430
+ ]);
29376
29431
  function transformWorkflowSource(source, maxSourceBytes) {
29377
29432
  if (new TextEncoder().encode(source).byteLength > maxSourceBytes) throw sourceError("The workflow source is too large.");
29378
29433
  const scanner = createScanner(true, LanguageVariant.Standard, source, 0, source.length);
@@ -29387,11 +29442,10 @@ function transformWorkflowSource(source, maxSourceBytes) {
29387
29442
  if (text === "export") {
29388
29443
  if (braceDepth !== 0) throw sourceError("Nested exports are disabled.");
29389
29444
  const exportStart = start;
29390
- const next = nextToken(scanner);
29391
- if (next.text !== "default") throw sourceError("Only a default workflow result is supported.");
29445
+ if (scanner.scan() === SyntaxKind.EndOfFile || scanner.getTokenText() !== "default") throw sourceError("Only a default workflow result is supported.");
29392
29446
  replacements.push({
29393
29447
  start: exportStart,
29394
- end: next.end,
29448
+ end: scanner.getTokenEnd(),
29395
29449
  text: "return "
29396
29450
  });
29397
29451
  token = scanner.scan();
@@ -29417,48 +29471,192 @@ function transformWorkflowSource(source, maxSourceBytes) {
29417
29471
  */
29418
29472
  function transformNativeWorkflowSource(source, maxSourceBytes, maxTransformedBytes) {
29419
29473
  if (new TextEncoder().encode(source).byteLength > maxSourceBytes) throw sourceError("The native workflow source is too large.");
29474
+ const transformed = compileNativeWorkflowSource(source);
29475
+ if (new TextEncoder().encode(transformed).byteLength > maxTransformedBytes) throw sourceError("The transformed native workflow is too large.");
29476
+ return transformed;
29477
+ }
29478
+ const WORKFLOW_DECLARATIONS = `
29479
+ type WorkflowJsonPrimitive = string | number | boolean | null;
29480
+ type WorkflowJsonValue = WorkflowJsonPrimitive | readonly WorkflowJsonValue[] | { readonly [key: string]: WorkflowJsonValue };
29481
+ interface WorkflowValueCodec<T extends WorkflowJsonValue = WorkflowJsonValue> { readonly name: string; readonly decode: (value: unknown) => T; }
29482
+ interface WorkflowAssignment<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> { readonly payload?: WorkflowJsonValue; readonly input: WorkflowValueCodec<I>; readonly output: WorkflowValueCodec<O>; readonly metadata?: Record<string, WorkflowJsonValue>; readonly route?: string; }
29483
+ interface WorkflowStepDefinition<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> { readonly id: string; readonly assignment: WorkflowAssignment<I, O>; }
29484
+ interface WorkflowValue<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> { readonly input: I; readonly output: O; }
29485
+ interface WorkflowWait<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> { readonly input: I; readonly result: O; }
29486
+ type WorkflowQueueStageOutput<Current extends WorkflowJsonValue, Stage> = Stage extends WorkflowValue<Current, infer Output> ? Output : Stage extends WorkflowWait<Current, infer Output> ? Output : Stage extends (input: Current) => WorkflowValue<Current, infer Output> ? Output : Stage extends (input: Current) => WorkflowWait<Current, infer Output> ? Output : never;
29487
+ type WorkflowQueueStageChain<Current extends WorkflowJsonValue, Stages extends readonly unknown[]> = Stages extends readonly [infer Stage, ...infer Rest] ? [WorkflowQueueStageOutput<Current, Stage>] extends [never] ? never : readonly [Stage, ...WorkflowQueueStageChain<WorkflowQueueStageOutput<Current, Stage>, Rest>] : readonly [];
29488
+ type WorkflowQueueOutput<Current extends WorkflowJsonValue, Stages extends readonly unknown[]> = Stages extends readonly [infer Stage, ...infer Rest] ? WorkflowQueueOutput<WorkflowQueueStageOutput<Current, Stage>, Rest> : Current;
29489
+ interface WorkflowDsl {
29490
+ readonly step: <I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue>(definition: WorkflowStepDefinition<I, O>) => WorkflowValue<I, O>;
29491
+ readonly queue: <I extends WorkflowJsonValue, O extends WorkflowJsonValue, const Stages extends readonly unknown[]>(first: WorkflowValue<I, O>, ...stages: Stages & WorkflowQueueStageChain<O, Stages>) => WorkflowValue<I, WorkflowQueueOutput<O, Stages>>;
29492
+ readonly start: <I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue>(workflow: WorkflowValue<I, O>) => WorkflowValue<I, O>;
29493
+ readonly wait: {
29494
+ <I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue>(workflow: WorkflowValue<I, O> | WorkflowWait<I, O>): WorkflowWait<I, O>;
29495
+ <Named extends Record<string, WorkflowValue<WorkflowJsonValue, WorkflowJsonValue> | WorkflowWait<WorkflowJsonValue, WorkflowJsonValue>>>(values: Named): WorkflowWait<WorkflowJsonValue, WorkflowJsonValue>;
29496
+ };
29497
+ }
29498
+ interface WorkflowPortableSchema<T extends WorkflowJsonValue = WorkflowJsonValue> { readonly __holycodexSchema: WorkflowJsonValue; readonly _type?: T; }
29499
+ declare module "@holycodex/workflow" {
29500
+ export type JsonValue = WorkflowJsonValue;
29501
+ export type ValueCodec<T extends WorkflowJsonValue = WorkflowJsonValue> = WorkflowValueCodec<T>;
29502
+ export type Assignment<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> = WorkflowAssignment<I, O>;
29503
+ export type StepDefinition<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> = WorkflowStepDefinition<I, O>;
29504
+ export type Workflow<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> = WorkflowValue<I, O>;
29505
+ export type Wait<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> = WorkflowWait<I, O>;
29506
+ export const workflow: WorkflowDsl;
29507
+ export function createCodec<T extends WorkflowJsonValue = WorkflowJsonValue>(name: string, decoder: ((value: unknown) => T) | WorkflowPortableSchema<T>): ValueCodec<T>;
29508
+ }
29509
+ declare module "@holycodex/workflow-runtime" {
29510
+ export type ValueCodec<T extends WorkflowJsonValue = WorkflowJsonValue> = WorkflowValueCodec<T>;
29511
+ export type Assignment<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> = WorkflowAssignment<I, O>;
29512
+ export type StepDefinition<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> = WorkflowStepDefinition<I, O>;
29513
+ export type Workflow<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> = WorkflowValue<I, O>;
29514
+ export type Wait<I extends WorkflowJsonValue = WorkflowJsonValue, O extends WorkflowJsonValue = WorkflowJsonValue> = WorkflowWait<I, O>;
29515
+ export const workflow: WorkflowDsl;
29516
+ export function createCodec<T extends WorkflowJsonValue = WorkflowJsonValue>(name: string, decoder: ((value: unknown) => T) | WorkflowPortableSchema<T>): ValueCodec<T>;
29517
+ }
29518
+ declare module "effect/Schema" {
29519
+ export interface Schema<T extends WorkflowJsonValue = WorkflowJsonValue> extends WorkflowPortableSchema<T> {}
29520
+ export const String: Schema<string>;
29521
+ export const Number: Schema<number>;
29522
+ export const Boolean: Schema<boolean>;
29523
+ export const Unknown: Schema<WorkflowJsonValue>;
29524
+ export function Literal<T extends string | number | boolean | null>(value: T): Schema<T>;
29525
+ export function Array<T>(element: Schema<T>): Schema<readonly T[]>;
29526
+ export function Struct<const Fields extends Record<string, Schema>>(fields: Fields): Schema<{ readonly [K in keyof Fields]: Fields[K] extends Schema<infer T> ? T : never }>;
29527
+ }
29528
+ `;
29529
+ function compileNativeWorkflowSource(source) {
29530
+ const root = mkdtempSync(join(tmpdir(), "holycodex-workflow-"));
29531
+ const sourceFile = join(root, "workflow.ts");
29532
+ const declarationFile = join(root, "workflow-modules.d.ts");
29533
+ const configFile = join(root, "tsconfig.json");
29534
+ try {
29535
+ writeFileSync(sourceFile, source);
29536
+ writeFileSync(declarationFile, WORKFLOW_DECLARATIONS);
29537
+ writeFileSync(configFile, JSON.stringify({
29538
+ compilerOptions: {
29539
+ strict: true,
29540
+ noEmit: true,
29541
+ skipLibCheck: true,
29542
+ target: "ES2022",
29543
+ module: "ESNext",
29544
+ moduleResolution: "Bundler",
29545
+ types: []
29546
+ },
29547
+ files: [sourceFile, declarationFile]
29548
+ }));
29549
+ const compiler = resolveTypeScriptCompiler();
29550
+ const check = spawnSync(compiler, [
29551
+ "--project",
29552
+ configFile,
29553
+ "--pretty",
29554
+ "false"
29555
+ ], { encoding: "utf8" });
29556
+ if (check.status !== 0) throw sourceError(`The native workflow TypeScript source is invalid:\n${(check.stdout || check.stderr).trim()}`);
29557
+ const rewritten = rewriteNativeSource(source);
29558
+ const outputFile = join(root, "workflow.emit.js");
29559
+ const emitConfig = join(root, "emit-tsconfig.json");
29560
+ writeFileSync(join(root, "workflow.emit.ts"), `let __hcWorkflowResult;\n${rewritten}\nreturn __hcWorkflowResult;`);
29561
+ writeFileSync(emitConfig, JSON.stringify({
29562
+ compilerOptions: {
29563
+ target: "ES2022",
29564
+ module: "ESNext",
29565
+ noCheck: true,
29566
+ outDir: root
29567
+ },
29568
+ files: [join(root, "workflow.emit.ts")]
29569
+ }));
29570
+ if (spawnSync(compiler, [
29571
+ "--project",
29572
+ emitConfig,
29573
+ "--pretty",
29574
+ "false"
29575
+ ], { encoding: "utf8" }).status !== 0) throw sourceError("The native workflow TypeScript source could not be emitted.");
29576
+ return `(() => {\n${readFileSync(outputFile, "utf8")}\n})()`;
29577
+ } finally {
29578
+ rmSync(root, {
29579
+ recursive: true,
29580
+ force: true
29581
+ });
29582
+ }
29583
+ }
29584
+ function resolveTypeScriptCompiler() {
29585
+ const packageName = `@typescript/typescript-${process.platform === "win32" ? "win32" : process.platform === "darwin" ? "darwin" : "linux"}-${process.arch === "arm64" ? "arm64" : "x64"}`;
29586
+ try {
29587
+ const packageRoot = dirname(require.resolve("typescript/package.json"));
29588
+ const executable = process.platform === "win32" ? "tsc.exe" : "tsc";
29589
+ const direct = join(packageRoot, "lib", executable);
29590
+ try {
29591
+ readFileSync(direct);
29592
+ return direct;
29593
+ } catch {
29594
+ const bunRoot = join(packageRoot, "..", "..", "..");
29595
+ const platformDir = readdirSync(bunRoot).find((entry) => entry.startsWith(`${packageName.replace("/", "+")}@`));
29596
+ if (!platformDir) throw new Error("platform compiler package is missing");
29597
+ return join(bunRoot, platformDir, "node_modules", packageName, "lib", executable);
29598
+ }
29599
+ } catch {
29600
+ throw sourceError("The TypeScript compiler is unavailable for native workflows.");
29601
+ }
29602
+ }
29603
+ function rewriteNativeSource(source) {
29420
29604
  const tokens = scan(source);
29421
29605
  const replacements = [];
29422
29606
  let braceDepth = 0;
29423
- let defaultExports = 0;
29607
+ let exports = 0;
29424
29608
  for (let index = 0; index < tokens.length; index += 1) {
29425
29609
  const token = tokens[index];
29426
29610
  if (!token) continue;
29427
- if (token.text === "{") braceDepth += 1;
29428
- if (token.text === "}") braceDepth = Math.max(0, braceDepth - 1);
29429
29611
  if (token.text === "import") {
29430
- if (tokens[index + 1]?.text === "(") throw sourceError("Dynamic workflow imports are disabled.");
29431
- if (braceDepth !== 0) throw sourceError("Nested workflow imports are disabled.");
29612
+ if (braceDepth !== 0) throw sourceError("Nested native workflow imports are disabled.");
29432
29613
  const end = findStatementEnd(tokens, index);
29433
- const statement = source.slice(token.start, end);
29434
29614
  replacements.push({
29435
29615
  start: token.start,
29436
29616
  end,
29437
- text: nativeImportReplacement(statement)
29617
+ text: nativeImportReplacement(source.slice(token.start, end))
29438
29618
  });
29439
29619
  index = tokenIndexAtOrBefore(tokens, end) - 1;
29440
- continue;
29441
- }
29442
- if (token.text === "export") {
29443
- if (braceDepth !== 0 || tokens[index + 1]?.text !== "default") throw sourceError("Only one default native workflow export is supported.");
29444
- defaultExports += 1;
29620
+ } else if (token.text === "export") {
29621
+ if (braceDepth !== 0) throw sourceError("Nested exports are disabled.");
29445
29622
  const next = tokens[index + 1];
29446
- if (!next) throw sourceError("The native workflow default export is incomplete.");
29623
+ if (next?.text !== "default") throw sourceError("Only a default native workflow export is supported.");
29624
+ exports += 1;
29447
29625
  replacements.push({
29448
29626
  start: token.start,
29449
29627
  end: next.end,
29450
- text: "return "
29628
+ text: "__hcWorkflowResult = "
29451
29629
  });
29452
29630
  index += 1;
29453
- continue;
29454
- }
29455
- if (token.isIdentifier && NATIVE_FORBIDDEN_IDENTIFIERS.has(token.text)) throw sourceError(`The native workflow uses forbidden syntax: ${token.text}.`);
29631
+ } else if (token.text === "await" || token.isIdentifier && NATIVE_FORBIDDEN_IDENTIFIERS.has(token.text)) throw sourceError(`The native workflow uses forbidden syntax: ${token.text}.`);
29632
+ if (token.text === "{") braceDepth += 1;
29633
+ if (token.text === "}") braceDepth = Math.max(0, braceDepth - 1);
29456
29634
  }
29457
- if (defaultExports !== 1) throw sourceError("The native workflow must export exactly one default workflow.wait(...) value.");
29458
- replacements.push(...findTypeScriptRemovals(tokens, source, replacements));
29459
- const transformed = `(() => {\n${applyReplacements(source, deduplicateReplacements(replacements))}\n})()`;
29460
- if (new TextEncoder().encode(transformed).byteLength > maxTransformedBytes) throw sourceError("The transformed native workflow is too large.");
29461
- return transformed;
29635
+ if (exports !== 1) throw sourceError("The native workflow must export exactly one workflow.wait(...) value.");
29636
+ return applyReplacements(source, replacements);
29637
+ }
29638
+ function nativeImportReplacement(statement) {
29639
+ const match = /^import\s+(type\s+)?(\{[\s\S]*\}|\*\s+as\s+[A-Za-z_$][\w$]*)\s+from\s+["']([^"']+)["']\s*;?$/u.exec(statement.trim());
29640
+ if (!match) throw sourceError("Native workflows may use only named imports from the approved modules.");
29641
+ if (match[1]) return "";
29642
+ const moduleName = match[3];
29643
+ if (moduleName !== "@holycodex/workflow" && moduleName !== "@holycodex/workflow-runtime" && moduleName !== "effect/Schema") throw sourceError("Native workflow imports are restricted to @holycodex/workflow and effect/Schema.");
29644
+ const bindings = match[2] ?? "";
29645
+ if (bindings.startsWith("*")) {
29646
+ if (moduleName !== "effect/Schema") throw sourceError("Workflow imports must be named imports.");
29647
+ const local = bindings.slice(bindings.indexOf("as") + 3).trim();
29648
+ return local === "Schema" ? "" : `const ${local} = Schema;`;
29649
+ }
29650
+ return bindings.slice(1, -1).split(",").map((entry) => entry.trim()).filter(Boolean).map((entry) => {
29651
+ const parts = entry.split(/\s+as\s+/u).map((part) => part.trim());
29652
+ const imported = parts[0] ?? "";
29653
+ const local = parts[1] ?? imported;
29654
+ if (imported.startsWith("type ")) return "";
29655
+ const name = imported.replace(/^type\s+/u, "");
29656
+ if (!(moduleName === "effect/Schema" ? NATIVE_SCHEMA_IMPORTS : NATIVE_WORKFLOW_IMPORTS).has(name)) throw sourceError(`The native workflow import ${name} is not approved.`);
29657
+ if (local === name && moduleName !== "effect/Schema") return "";
29658
+ return `const ${local} = ${moduleName === "effect/Schema" ? `Schema.${name}` : name};`;
29659
+ }).filter(Boolean).join("\n");
29462
29660
  }
29463
29661
  function scan(source) {
29464
29662
  const scanner = createScanner(true, LanguageVariant.Standard, source, 0, source.length);
@@ -29475,21 +29673,6 @@ function scan(source) {
29475
29673
  }
29476
29674
  return tokens;
29477
29675
  }
29478
- function nativeImportReplacement(statement) {
29479
- const match = /^import\s+(type\s+)?\{([\s\S]*)\}\s+from\s+["']([^"']+)["']\s*;?$/u.exec(statement.trim());
29480
- if (!match) throw sourceError("Native workflows may use only explicit named imports from the runtime DSL.");
29481
- const typeOnly = match[1] !== void 0;
29482
- if (match[3] !== "@holycodex/workflow-runtime") throw sourceError("Native workflow imports must use @holycodex/workflow-runtime.");
29483
- const names = (match[2] ?? "").split(",").map((value) => value.trim()).filter((value) => value.length > 0);
29484
- for (const name of names) {
29485
- if (name.startsWith("type ")) continue;
29486
- const [imported, local] = name.split(/\s+as\s+/u).map((value) => value.trim());
29487
- if (typeOnly) continue;
29488
- if (!imported || !NATIVE_RUNTIME_IMPORTS.has(imported)) throw sourceError(`The native workflow import ${imported ?? ""} is not approved.`);
29489
- if (local && local !== imported) throw sourceError("Native workflow import aliases are not supported.");
29490
- }
29491
- return "";
29492
- }
29493
29676
  function findStatementEnd(tokens, startIndex) {
29494
29677
  let sawFrom = false;
29495
29678
  for (let index = startIndex + 1; index < tokens.length; index += 1) {
@@ -29511,179 +29694,6 @@ function tokenIndexAtOrBefore(tokens, position) {
29511
29694
  while (index < tokens.length && (tokens[index]?.start ?? 0) < position) index += 1;
29512
29695
  return index;
29513
29696
  }
29514
- function findTypeScriptRemovals(tokens, source, existingReplacements) {
29515
- const removals = [];
29516
- for (let index = 0; index < tokens.length; index += 1) {
29517
- const token = tokens[index];
29518
- if (!token) continue;
29519
- if (existingReplacements.some((replacement) => replacement.start <= token.start && token.end <= replacement.end)) continue;
29520
- if (token.text === "type" || token.text === "interface") {
29521
- if (tokens[index - 1]?.text === "import") continue;
29522
- const end = findTypeDeclarationEnd(tokens, index);
29523
- removals.push({
29524
- start: token.start,
29525
- end,
29526
- text: ""
29527
- });
29528
- index = tokenIndexAtOrBefore(tokens, end) - 1;
29529
- continue;
29530
- }
29531
- if (token.text === "as" || token.text === "satisfies") {
29532
- const end = findTypeExpressionEnd(tokens, index);
29533
- removals.push({
29534
- start: token.start,
29535
- end,
29536
- text: ""
29537
- });
29538
- index = tokenIndexAtOrBefore(tokens, end) - 1;
29539
- continue;
29540
- }
29541
- if (token.text === "<" && isTypeArgumentList(tokens, index)) {
29542
- const end = matchingTokenEnd(tokens, index, "<", ">");
29543
- if (end !== void 0) {
29544
- removals.push({
29545
- start: token.start,
29546
- end,
29547
- text: ""
29548
- });
29549
- index = tokenIndexAtOrBefore(tokens, end) - 1;
29550
- }
29551
- continue;
29552
- }
29553
- if (token.text === ":" && isTypeAnnotation(tokens, index)) {
29554
- const end = findTypeExpressionEnd(tokens, index);
29555
- removals.push({
29556
- start: token.start,
29557
- end,
29558
- text: ""
29559
- });
29560
- index = tokenIndexAtOrBefore(tokens, end) - 1;
29561
- continue;
29562
- }
29563
- if (token.text === "?" && tokens[index + 1]?.text === ":" && isTypeAnnotation(tokens, index + 1)) removals.push({
29564
- start: token.start,
29565
- end: token.end,
29566
- text: ""
29567
- });
29568
- if (token.text === "!" && isNonNullAssertion(tokens, index)) removals.push({
29569
- start: token.start,
29570
- end: token.end,
29571
- text: ""
29572
- });
29573
- }
29574
- return removals;
29575
- }
29576
- function findTypeDeclarationEnd(tokens, start) {
29577
- let brace = 0;
29578
- let paren = 0;
29579
- let bracket = 0;
29580
- for (let index = start; index < tokens.length; index += 1) {
29581
- const text = tokens[index]?.text;
29582
- if (text === "{") brace += 1;
29583
- else if (text === "}") brace = Math.max(0, brace - 1);
29584
- else if (text === "(") paren += 1;
29585
- else if (text === ")") paren = Math.max(0, paren - 1);
29586
- else if (text === "[") bracket += 1;
29587
- else if (text === "]") bracket = Math.max(0, bracket - 1);
29588
- if (text === ";" && brace === 0 && paren === 0 && bracket === 0) return tokens[index]?.end ?? 0;
29589
- if (index > start && brace === 0 && paren === 0 && bracket === 0 && text === "}") return tokens[index]?.end ?? 0;
29590
- }
29591
- return tokens.at(-1)?.end ?? 0;
29592
- }
29593
- function findTypeExpressionEnd(tokens, start) {
29594
- let angle = 0;
29595
- let brace = 0;
29596
- let bracket = 0;
29597
- let paren = 0;
29598
- let lastEnd = tokens[start]?.end ?? 0;
29599
- for (let index = start + 1; index < tokens.length; index += 1) {
29600
- const text = tokens[index]?.text;
29601
- if (text === "<") angle += 1;
29602
- else if (text === ">" && angle > 0) angle -= 1;
29603
- else if (text === "{") brace += 1;
29604
- else if (text === "}" && brace > 0) brace -= 1;
29605
- else if (text === "[") bracket += 1;
29606
- else if (text === "]" && bracket > 0) bracket -= 1;
29607
- else if (text === "(") paren += 1;
29608
- else if (text === ")" && paren > 0) paren -= 1;
29609
- if (angle === 0 && brace === 0 && bracket === 0 && paren === 0 && (text === "," || text === ";" || text === ")" || text === "]" || text === "}" || text === "=" || text === "=>" || text === "?")) break;
29610
- lastEnd = tokens[index]?.end ?? lastEnd;
29611
- }
29612
- return lastEnd;
29613
- }
29614
- function isTypeArgumentList(tokens, index) {
29615
- const end = matchingTokenIndex(tokens, index, "<", ">");
29616
- return end !== void 0 && tokens[end + 1]?.text === "(" && (tokens[index - 1]?.isIdentifier === true || tokens[index - 1]?.text === ")");
29617
- }
29618
- function matchingTokenEnd(tokens, start, open, close) {
29619
- const index = matchingTokenIndex(tokens, start, open, close);
29620
- return index === void 0 ? void 0 : tokens[index]?.end;
29621
- }
29622
- function matchingTokenIndex(tokens, start, open, close) {
29623
- let depth = 0;
29624
- for (let index = start; index < tokens.length; index += 1) {
29625
- const text = tokens[index]?.text;
29626
- if (text === open) depth += 1;
29627
- else if (text === close) {
29628
- depth -= 1;
29629
- if (depth === 0) return index;
29630
- }
29631
- }
29632
- }
29633
- function isTypeAnnotation(tokens, index) {
29634
- const previous = tokens[index - 1]?.text;
29635
- if (previous === ")") return true;
29636
- const parameterOpen = nearestOpenParen(tokens, index);
29637
- if (parameterOpen !== void 0) {
29638
- const close = matchingTokenIndex(tokens, parameterOpen, "(", ")");
29639
- if (close !== void 0) {
29640
- const after = tokens[close + 1]?.text;
29641
- if (after === "=>" || after === "{" || after === ":") return true;
29642
- }
29643
- }
29644
- if (previous && isVariableDeclaration(tokens, index)) return true;
29645
- return tokens[index + 1]?.text !== void 0 && tokens[index + 2]?.text === "=>";
29646
- }
29647
- function nearestOpenParen(tokens, index) {
29648
- let depth = 0;
29649
- for (let cursor = index - 1; cursor >= 0; cursor -= 1) {
29650
- const text = tokens[cursor]?.text;
29651
- if (text === ")") depth += 1;
29652
- else if (text === "(") {
29653
- if (depth === 0) return cursor;
29654
- depth -= 1;
29655
- }
29656
- }
29657
- }
29658
- function isVariableDeclaration(tokens, index) {
29659
- for (let cursor = index - 1; cursor >= 0; cursor -= 1) {
29660
- const text = tokens[cursor]?.text;
29661
- if (text === ";" || text === "{" || text === "}") return false;
29662
- if (text === "const" || text === "let" || text === "var") return true;
29663
- }
29664
- return false;
29665
- }
29666
- function isNonNullAssertion(tokens, index) {
29667
- const previous = tokens[index - 1]?.text;
29668
- const next = tokens[index + 1]?.text;
29669
- return previous !== void 0 && next !== void 0 && next !== "=" && next !== "!";
29670
- }
29671
- function deduplicateReplacements(replacements) {
29672
- const seen = /* @__PURE__ */ new Set();
29673
- return replacements.filter((replacement) => {
29674
- const key = `${replacement.start}:${replacement.end}`;
29675
- if (seen.has(key)) return false;
29676
- seen.add(key);
29677
- return true;
29678
- });
29679
- }
29680
- function nextToken(scanner) {
29681
- if (scanner.scan() === SyntaxKind.EndOfFile) throw sourceError("The workflow default result is incomplete.");
29682
- return {
29683
- text: scanner.getTokenText(),
29684
- end: scanner.getTokenEnd()
29685
- };
29686
- }
29687
29697
  function applyReplacements(source, replacements) {
29688
29698
  let result = source;
29689
29699
  const ordered = [...replacements].sort((left, right) => left.start - right.start || left.end - right.end);
@@ -29849,6 +29859,41 @@ var NativeSourceSession = class {
29849
29859
  const start = this.context.newFunction("__hcStart", (...args) => this.callback(() => this.start(args)));
29850
29860
  const wait = this.context.newFunction("__hcWait", (...args) => this.callback(() => this.wait(args)));
29851
29861
  const createCodec = this.context.newFunction("__hcCreateCodec", (...args) => this.callback(() => this.createCodec(args)));
29862
+ const schema = this.context.evalCode(`
29863
+ (() => {
29864
+ const make = value => Object.freeze({ __holycodexSchema: Object.freeze(value) });
29865
+ const struct = fields => {
29866
+ const result = Object.create(null);
29867
+ for (const key of Object.keys(fields)) {
29868
+ const schema = fields[key]?.__holycodexSchema;
29869
+ if (!schema) throw new Error("The workflow struct field schema is invalid.");
29870
+ result[key] = schema;
29871
+ }
29872
+ return make({ kind: "struct", fields: result });
29873
+ };
29874
+ return Object.freeze({
29875
+ String: make({ kind: "string" }),
29876
+ Number: make({ kind: "number" }),
29877
+ Boolean: make({ kind: "boolean" }),
29878
+ Unknown: make({ kind: "unknown" }),
29879
+ Literal: value => {
29880
+ if (value !== null && typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
29881
+ throw new Error("The workflow literal schema is invalid.");
29882
+ }
29883
+ return make({ kind: "literal", value });
29884
+ },
29885
+ Array: element => {
29886
+ if (!element?.__holycodexSchema) throw new Error("The workflow array schema is invalid.");
29887
+ return make({ kind: "array", element: element.__holycodexSchema });
29888
+ },
29889
+ Struct: struct
29890
+ });
29891
+ })()
29892
+ `);
29893
+ if (schema.error) {
29894
+ schema.error.dispose();
29895
+ throw new WorkflowRuntimeError("evaluation_failed", "The native schema facade could not be prepared.");
29896
+ }
29852
29897
  const bootstrap = this.context.evalCode(`
29853
29898
  (() => {
29854
29899
  const symbolicKey = Symbol("HolyCodex callback output");
@@ -29913,15 +29958,18 @@ var NativeSourceSession = class {
29913
29958
  this.disposeHandle(workflow);
29914
29959
  this.context.setProp(this.context.global, "workflow", frozenWorkflow);
29915
29960
  this.context.setProp(this.context.global, "createCodec", createCodec);
29961
+ this.context.setProp(this.context.global, "Schema", schema.value);
29916
29962
  const result = this.context.evalCode(transformed);
29917
29963
  this.context.setProp(this.context.global, "workflow", this.context.undefined);
29918
29964
  this.context.setProp(this.context.global, "createCodec", this.context.undefined);
29965
+ this.context.setProp(this.context.global, "Schema", this.context.undefined);
29919
29966
  this.disposeHandle(frozenWorkflow);
29920
29967
  this.disposeHandle(step);
29921
29968
  this.disposeHandle(queue);
29922
29969
  this.disposeHandle(start);
29923
29970
  this.disposeHandle(wait);
29924
29971
  this.disposeHandle(createCodec);
29972
+ schema.value.dispose();
29925
29973
  if (result.error) {
29926
29974
  result.error.dispose();
29927
29975
  const callbackFailure = this.callbackFailure;
@@ -29961,16 +30009,17 @@ var NativeSourceSession = class {
29961
30009
  };
29962
30010
  }
29963
30011
  codecDescriptors() {
29964
- return Object.freeze([...this.codecs.values()].map(({ id, name }) => Object.freeze({
30012
+ return Object.freeze([...this.codecs.values()].map(({ id, name, schema }) => Object.freeze({
29965
30013
  id,
29966
- name
30014
+ name,
30015
+ ...schema === void 0 ? {} : { schema }
29967
30016
  })));
29968
30017
  }
29969
30018
  codecProxies() {
29970
30019
  const result = /* @__PURE__ */ new Map();
29971
30020
  for (const record of this.codecs.values()) result.set(record.id, Object.freeze({
29972
30021
  name: record.name,
29973
- decode: (value) => this.decode(record, value)
30022
+ decode: (value) => record.schema === void 0 ? this.decode(record, value) : decodePortableSchema(record.schema, value)
29974
30023
  }));
29975
30024
  return readonlyMap(result);
29976
30025
  }
@@ -29981,7 +30030,7 @@ var NativeSourceSession = class {
29981
30030
  this.symbolicFunction?.dispose();
29982
30031
  this.serializeFunction = void 0;
29983
30032
  this.symbolicFunction = void 0;
29984
- for (const record of this.codecs.values()) record.decoder.dispose();
30033
+ for (const record of this.codecs.values()) record.decoder?.dispose();
29985
30034
  this.codecs.clear();
29986
30035
  this.runtime.removeInterruptHandler();
29987
30036
  try {
@@ -30068,15 +30117,25 @@ var NativeSourceSession = class {
30068
30117
  if (args.length !== 2) throw new Error("createCodec expects a name and decoder.");
30069
30118
  const name = this.context.getString(args[0] ?? this.context.undefined);
30070
30119
  if (name.length === 0 || name.length > 256) throw new Error("A workflow codec name is invalid.");
30071
- if (String(this.context.typeof(args[1] ?? this.context.undefined)) !== "function") throw new Error("A workflow codec decoder must be a function.");
30072
30120
  const id = `codec-${this.nextCodec += 1}`;
30073
- const decoder = args[1]?.dup();
30074
- if (!decoder) throw new Error("The workflow codec decoder is unavailable.");
30075
- this.codecs.set(id, {
30076
- id,
30077
- name,
30078
- decoder
30079
- });
30121
+ const decoderValue = this.context.dump(args[1] ?? this.context.undefined);
30122
+ if (isPortableSchemaValue(decoderValue)) {
30123
+ if (!isPortableSchemaIR(decoderValue.__holycodexSchema)) throw new Error("The workflow schema facade value is invalid.");
30124
+ this.codecs.set(id, {
30125
+ id,
30126
+ name,
30127
+ schema: decoderValue.__holycodexSchema
30128
+ });
30129
+ } else {
30130
+ if (String(this.context.typeof(args[1] ?? this.context.undefined)) !== "function") throw new Error("A workflow codec decoder must be a function.");
30131
+ const decoder = args[1]?.dup();
30132
+ if (!decoder) throw new Error("The workflow codec decoder is unavailable.");
30133
+ this.codecs.set(id, {
30134
+ id,
30135
+ name,
30136
+ decoder
30137
+ });
30138
+ }
30080
30139
  return this.jsonHandle({
30081
30140
  __hcCodecId: id,
30082
30141
  name
@@ -30242,6 +30301,7 @@ var NativeSourceSession = class {
30242
30301
  });
30243
30302
  }
30244
30303
  decode(record, value) {
30304
+ if (record.decoder === void 0) throw new WorkflowRuntimeError("invalid_result", "The native codec decoder is unavailable.");
30245
30305
  if (this.disposed) throw new WorkflowRuntimeError("evaluation_failed", "The native workflow sandbox is disposed.");
30246
30306
  if (!isJsonValue$1(value)) throw new WorkflowRuntimeError("invalid_result", "The codec input is not JSON.");
30247
30307
  if (new TextEncoder().encode(canonicalJson(value)).byteLength > this.limits.maxCodecBytes) throw new WorkflowRuntimeError("resource_limit", "The codec input is too large.");
@@ -30287,6 +30347,21 @@ var NativeSourceSession = class {
30287
30347
  }
30288
30348
  }
30289
30349
  };
30350
+ function isPortableSchemaValue(value) {
30351
+ return typeof value === "object" && value !== null && !Array.isArray(value) && "__holycodexSchema" in value && typeof value.__holycodexSchema === "object" && value.__holycodexSchema !== null;
30352
+ }
30353
+ function isPortableSchemaIR(value) {
30354
+ if (!isRecord(value) || typeof value["kind"] !== "string") return false;
30355
+ const kind = value["kind"];
30356
+ if (kind === "string" || kind === "number" || kind === "boolean" || kind === "unknown") return true;
30357
+ if (kind === "literal") {
30358
+ const literal = value["value"];
30359
+ return literal === null || typeof literal === "string" || typeof literal === "boolean" || typeof literal === "number" && Number.isFinite(literal);
30360
+ }
30361
+ if (kind === "array") return isPortableSchemaIR(value["element"]);
30362
+ if (kind === "struct" && typeof value["fields"] === "object" && value["fields"] !== null && !Array.isArray(value["fields"])) return Object.values(value["fields"]).every(isPortableSchemaIR);
30363
+ return false;
30364
+ }
30290
30365
  function readMetadata(value) {
30291
30366
  if (value === void 0) return {};
30292
30367
  if (!isRecord(value) || !isJsonValue$1(value)) throw new Error("The workflow assignment metadata is invalid.");
@@ -31018,7 +31093,7 @@ function readInputSource(source, results, rootInput) {
31018
31093
  return assembleOutputTargets(source.targets, results);
31019
31094
  }
31020
31095
  function materializeAssignment(assignment, input, results, route, attempt) {
31021
- const payload = assignment.payload === void 0 ? input : resolvePayload(assignment.payload, results);
31096
+ const payload = assignment.payload === void 0 ? requireJsonValue(input) : resolvePayload(assignment.payload, results);
31022
31097
  return Object.freeze({
31023
31098
  ...assignment,
31024
31099
  payload,
@@ -31032,18 +31107,27 @@ function materializeAssignment(assignment, input, results, route, attempt) {
31032
31107
  function resolvePayload(value, results, seen = /* @__PURE__ */ new Set()) {
31033
31108
  if (typeof value === "object" && value !== null) {
31034
31109
  const source = readSymbolicSource(value);
31035
- if (source !== void 0) return assembleWorkflowOutput(source, results);
31110
+ if (source !== void 0) return requireJsonValue(assembleWorkflowOutput(source, results));
31036
31111
  if (seen.has(value)) throw workflowFailure("validation", "The workflow assignment payload is cyclic.");
31037
31112
  seen.add(value);
31038
31113
  try {
31039
- if (Array.isArray(value)) return value.map((entry) => resolvePayload(entry, results, seen));
31040
- const pairs = Object.entries(value).map(([key, entry]) => [key, resolvePayload(entry, results, seen)]);
31041
- return Object.fromEntries(pairs);
31114
+ if (Array.isArray(value)) {
31115
+ const result = [];
31116
+ for (const entry of value) result.push(resolvePayload(entry, results, seen));
31117
+ return result;
31118
+ }
31119
+ const result = {};
31120
+ for (const [key, entry] of Object.entries(value)) result[key] = resolvePayload(entry, results, seen);
31121
+ return result;
31042
31122
  } finally {
31043
31123
  seen.delete(value);
31044
31124
  }
31045
31125
  }
31046
31126
  if (typeof value === "function") throw workflowFailure("validation", "The workflow assignment payload is executable.");
31127
+ return requireJsonValue(value);
31128
+ }
31129
+ function requireJsonValue(value) {
31130
+ if (!isJsonValue$1(value)) throw workflowFailure("validation", "The workflow value is not inert JSON.");
31047
31131
  return value;
31048
31132
  }
31049
31133
  function assembleTerminalResult(plan, results) {
@@ -31870,4 +31954,4 @@ function isAbsolutePath(value) {
31870
31954
  return value.startsWith("/") || /^[A-Za-z]:[\\/]/u.test(value);
31871
31955
  }
31872
31956
  //#endregion
31873
- export { EffortSchema as $, scoped as $t, MAX_WORKFLOW_LIMITS as A, filter as At, SPECIALIST_OUTCOME_VERSION as B, positive as Bt, workflowFailure as C, Record as Ct, Wait as D, Unknown as Dt, Step as E, Union as Et, serializeProtocolMessage as F, maxLength as Ft, parseCliEnvelope as G, fail$1 as Gt, SpecialistOutcomeV2Schema as H, _void as Ht, toWireLimits as I, minItems as It, canonicalJson as J, orElseSucceed as Jt, specialistOutcomeFromCapabilityResult as K, gen as Kt, lookupPlan as L, minLength as Lt, WorkflowProtocolMessageSchema as M, greaterThanOrEqualTo as Mt, WorkflowRuntimeError as N, int as Nt, Workflow as O, declare as Ot, parseProtocolLine as P, maxItems as Pt, DelegationModeSchema as Q, runSync as Qt, lookupRoute as R, optional as Rt, isWorkflowFailure as S, Number$ as St, Run as T, Struct as Tt, normalizeSpecialistOutcome as U, acquireRelease as Ut, SpecialistOutcomeSchema as V, is as Vt, parseCapabilityResultV2 as W, async as Wt, domainSeparatedSha256 as X, raceFirst as Xt, canonicalJsonUtf8 as Y, provide as Yt, sha256DomainDigest as Z, runPromise as Zt, NATIVE_WORKFLOW_ABI_VERSION as _, decodeUnknown$1 as _t, runExecutionPlan as a, mapError$2 as an, ServiceTierSchema as at, nativeWorkflowIdentityDigest as b, Literal as bt, loadNativeWorkflowSource as c, succeed$2 as cn, createSha256Digest as ct, CompileOptionsSchema as d, isRight as dn, CapabilityNameSchema as dt, succeed$1 as en, PlanNameSchema as et, ExecutionPlan as f, CLI_SCHEMA_VERSION as fn, OPTIONAL_CAPABILITY_NAMES as ft, NATIVE_OUTPUT_REFERENCE_KEY as g, resolveOptionalCapabilitySelections as gt, hydrateWorkflowPlanIR as h, pluginIdsForOptionalCapabilities as ht, makeCapacityService as i, fromEffect as in, RouteKeySchema as it, WorkflowLimitsSchema as j, greaterThan as jt, DEFAULT_WORKFLOW_LIMITS as k, decodeUnknownEither as kt, mergeNativeWorkflowLimits as l, Tag as ln, createTrustId as lt, compileWorkflowUnsafe as m, migrateOptionalCapabilitySelections as mt, evaluateWorkflowCompatibility as n, tryPromise as nn, RoleSkillProfileSchema as nt, DEFAULT_NATIVE_WORKFLOW_LIMITS as o, provide$1 as on, lookupRoleDefinition as ot, compileWorkflow as p, STATE_SCHEMA_EPOCH as pn, capabilityHealth as pt, canonicalIdentityUtf8 as q, mapError$1 as qt, runWorkflowChild as r, try_ as rn, RoleTaskSchema as rt, evaluateNativeWorkflowSource as s, scoped$1 as sn, createProjectId as st, evaluateWorkflow as t, sync as tn, RoleSchema as tt, transformNativeWorkflowSource as u, isLeft as un, CAPABILITY_REGISTRY as ut, freezeWorkflowPlanIR as v, Array$ as vt, Queue as w, String$ as wt, validateWorkflowPlanIR as x, Null as xt, nativePlanJson as y, Boolean$ as yt, resolvePlanSelection as z, pattern as zt };
31957
+ export { DelegationModeSchema as $, runSync as $t, DEFAULT_WORKFLOW_LIMITS as A, decodeUnknownEither as At, resolvePlanSelection as B, pattern as Bt, workflowFailure as C, Number$ as Ct, Step as D, Union as Dt, Run as E, Struct as Et, parseProtocolLine as F, maxItems as Ft, parseCapabilityResultV2 as G, async as Gt, SpecialistOutcomeSchema as H, is as Ht, serializeProtocolMessage as I, maxLength as It, canonicalIdentityUtf8 as J, mapError$1 as Jt, parseCliEnvelope as K, fail$1 as Kt, toWireLimits as L, minItems as Lt, WorkflowLimitsSchema as M, greaterThan as Mt, WorkflowProtocolMessageSchema as N, greaterThanOrEqualTo as Nt, Wait as O, Unknown as Ot, WorkflowRuntimeError as P, int as Pt, sha256DomainDigest as Q, runPromise as Qt, lookupPlan as R, minLength as Rt, isWorkflowFailure as S, Null as St, Queue as T, String$ as Tt, SpecialistOutcomeV2Schema as U, _void as Ut, SPECIALIST_OUTCOME_VERSION as V, positive as Vt, normalizeSpecialistOutcome as W, acquireRelease as Wt, canonicalJsonUtf8 as X, provide as Xt, canonicalJson as Y, orElseSucceed as Yt, domainSeparatedSha256 as Z, raceFirst as Zt, NATIVE_WORKFLOW_ABI_VERSION as _, resolveOptionalCapabilitySelections as _t, runExecutionPlan as a, fromEffect as an, RouteKeySchema as at, nativeWorkflowIdentityDigest as b, Boolean$ as bt, loadNativeWorkflowSource as c, scoped$1 as cn, createProjectId as ct, CompileOptionsSchema as d, isLeft as dn, CAPABILITY_REGISTRY as dt, scoped as en, EffortSchema as et, ExecutionPlan as f, isRight as fn, CapabilityNameSchema as ft, NATIVE_OUTPUT_REFERENCE_KEY as g, pluginIdsForOptionalCapabilities as gt, hydrateWorkflowPlanIR as h, migrateOptionalCapabilitySelections as ht, makeCapacityService as i, try_ as in, RoleTaskSchema as it, MAX_WORKFLOW_LIMITS as j, filter as jt, Workflow as k, declare as kt, mergeNativeWorkflowLimits as l, succeed$2 as ln, createSha256Digest as lt, compileWorkflowUnsafe as m, STATE_SCHEMA_EPOCH as mn, capabilityHealth as mt, evaluateWorkflowCompatibility as n, sync as nn, RoleSchema as nt, DEFAULT_NATIVE_WORKFLOW_LIMITS as o, mapError$2 as on, ServiceTierSchema as ot, compileWorkflow as p, CLI_SCHEMA_VERSION as pn, OPTIONAL_CAPABILITY_NAMES as pt, specialistOutcomeFromCapabilityResult as q, gen as qt, runWorkflowChild as r, tryPromise as rn, RoleSkillProfileSchema as rt, evaluateNativeWorkflowSource as s, provide$1 as sn, lookupRoleDefinition as st, evaluateWorkflow as t, succeed$1 as tn, PlanNameSchema as tt, transformNativeWorkflowSource as u, Tag as un, createTrustId as ut, freezeWorkflowPlanIR as v, decodeUnknown$1 as vt, decodePortableSchema as w, Record as wt, validateWorkflowPlanIR as x, Literal as xt, nativePlanJson as y, Array$ as yt, lookupRoute as z, optional as zt };