holycodex 0.15.0 → 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.
- package/README.md +4 -0
- package/dist/assets/plugin/hooks/hooks.json +17 -0
- package/dist/assets/plugin/hooks/version.ts +54 -0
- package/dist/assets/plugin/plugin.json +27 -32
- package/dist/assets/plugin/skills/writing-for-agents/SKILL.md +20 -4
- package/dist/{binary-DYvVDqZ5.js → binary-BCtnZPMA.js} +438 -285
- package/dist/binary-K1P4tTUI.js +3 -0
- package/dist/index.js +4 -4
- package/dist/{src-DamQOFzF.js → src-BmUZJGuC.js} +338 -254
- package/dist/src-BrjytttX.js +3 -0
- package/package.json +4 -4
- package/dist/assets/plugin/hooks/manifest.json +0 -11
- package/dist/binary-DODC08JV.js +0 -3
- package/dist/src-BOQ_ib7j.js +0 -3
|
@@ -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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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))
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
|
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 (
|
|
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(
|
|
29617
|
+
text: nativeImportReplacement(source.slice(token.start, end))
|
|
29438
29618
|
});
|
|
29439
29619
|
index = tokenIndexAtOrBefore(tokens, end) - 1;
|
|
29440
|
-
|
|
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 (
|
|
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: "
|
|
29628
|
+
text: "__hcWorkflowResult = "
|
|
29451
29629
|
});
|
|
29452
29630
|
index += 1;
|
|
29453
|
-
|
|
29454
|
-
|
|
29455
|
-
if (token.
|
|
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 (
|
|
29458
|
-
|
|
29459
|
-
|
|
29460
|
-
|
|
29461
|
-
|
|
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
|
|
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
|
|
30074
|
-
if (
|
|
30075
|
-
|
|
30076
|
-
id,
|
|
30077
|
-
|
|
30078
|
-
|
|
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))
|
|
31040
|
-
|
|
31041
|
-
|
|
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 {
|
|
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 };
|