@kontextmind/kxm
Version:
KXM local-first multi-agent orchestration and operator dashboard
23,835 lines • 931 kB
JavaScript
#!/usr/bin/env node
import { createRequire as __kxmCreateRequire } from 'node:module'; const require = __kxmCreateRequire(import.meta.url);
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined") return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
var __commonJS = (cb, mod) => function __require2() {
try {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
} catch (e) {
throw mod = 0, e;
}
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// node_modules/ajv/dist/compile/codegen/code.js
var require_code = __commonJS({
"node_modules/ajv/dist/compile/codegen/code.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.regexpCode = exports.getEsmExportName = exports.getProperty = exports.safeStringify = exports.stringify = exports.strConcat = exports.addCodeArg = exports.str = exports._ = exports.nil = exports._Code = exports.Name = exports.IDENTIFIER = exports._CodeOrName = void 0;
var _CodeOrName = class {
};
exports._CodeOrName = _CodeOrName;
exports.IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i;
var Name = class extends _CodeOrName {
constructor(s) {
super();
if (!exports.IDENTIFIER.test(s))
throw new Error("CodeGen: name must be a valid identifier");
this.str = s;
}
toString() {
return this.str;
}
emptyStr() {
return false;
}
get names() {
return { [this.str]: 1 };
}
};
exports.Name = Name;
var _Code = class extends _CodeOrName {
constructor(code) {
super();
this._items = typeof code === "string" ? [code] : code;
}
toString() {
return this.str;
}
emptyStr() {
if (this._items.length > 1)
return false;
const item = this._items[0];
return item === "" || item === '""';
}
get str() {
var _a;
return (_a = this._str) !== null && _a !== void 0 ? _a : this._str = this._items.reduce((s, c) => `${s}${c}`, "");
}
get names() {
var _a;
return (_a = this._names) !== null && _a !== void 0 ? _a : this._names = this._items.reduce((names, c) => {
if (c instanceof Name)
names[c.str] = (names[c.str] || 0) + 1;
return names;
}, {});
}
};
exports._Code = _Code;
exports.nil = new _Code("");
function _(strs, ...args) {
const code = [strs[0]];
let i = 0;
while (i < args.length) {
addCodeArg(code, args[i]);
code.push(strs[++i]);
}
return new _Code(code);
}
exports._ = _;
var plus = new _Code("+");
function str(strs, ...args) {
const expr = [safeStringify(strs[0])];
let i = 0;
while (i < args.length) {
expr.push(plus);
addCodeArg(expr, args[i]);
expr.push(plus, safeStringify(strs[++i]));
}
optimize(expr);
return new _Code(expr);
}
exports.str = str;
function addCodeArg(code, arg) {
if (arg instanceof _Code)
code.push(...arg._items);
else if (arg instanceof Name)
code.push(arg);
else
code.push(interpolate(arg));
}
exports.addCodeArg = addCodeArg;
function optimize(expr) {
let i = 1;
while (i < expr.length - 1) {
if (expr[i] === plus) {
const res = mergeExprItems(expr[i - 1], expr[i + 1]);
if (res !== void 0) {
expr.splice(i - 1, 3, res);
continue;
}
expr[i++] = "+";
}
i++;
}
}
function mergeExprItems(a, b) {
if (b === '""')
return a;
if (a === '""')
return b;
if (typeof a == "string") {
if (b instanceof Name || a[a.length - 1] !== '"')
return;
if (typeof b != "string")
return `${a.slice(0, -1)}${b}"`;
if (b[0] === '"')
return a.slice(0, -1) + b.slice(1);
return;
}
if (typeof b == "string" && b[0] === '"' && !(a instanceof Name))
return `"${a}${b.slice(1)}`;
return;
}
function strConcat(c1, c2) {
return c2.emptyStr() ? c1 : c1.emptyStr() ? c2 : str`${c1}${c2}`;
}
exports.strConcat = strConcat;
function interpolate(x) {
return typeof x == "number" || typeof x == "boolean" || x === null ? x : safeStringify(Array.isArray(x) ? x.join(",") : x);
}
function stringify4(x) {
return new _Code(safeStringify(x));
}
exports.stringify = stringify4;
function safeStringify(x) {
return JSON.stringify(x).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
}
exports.safeStringify = safeStringify;
function getProperty(key) {
return typeof key == "string" && exports.IDENTIFIER.test(key) ? new _Code(`.${key}`) : _`[${key}]`;
}
exports.getProperty = getProperty;
function getEsmExportName(key) {
if (typeof key == "string" && exports.IDENTIFIER.test(key)) {
return new _Code(`${key}`);
}
throw new Error(`CodeGen: invalid export name: ${key}, use explicit $id name mapping`);
}
exports.getEsmExportName = getEsmExportName;
function regexpCode(rx) {
return new _Code(rx.toString());
}
exports.regexpCode = regexpCode;
}
});
// node_modules/ajv/dist/compile/codegen/scope.js
var require_scope = __commonJS({
"node_modules/ajv/dist/compile/codegen/scope.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValueScope = exports.ValueScopeName = exports.Scope = exports.varKinds = exports.UsedValueState = void 0;
var code_1 = require_code();
var ValueError = class extends Error {
constructor(name) {
super(`CodeGen: "code" for ${name} not defined`);
this.value = name.value;
}
};
var UsedValueState;
(function(UsedValueState2) {
UsedValueState2[UsedValueState2["Started"] = 0] = "Started";
UsedValueState2[UsedValueState2["Completed"] = 1] = "Completed";
})(UsedValueState || (exports.UsedValueState = UsedValueState = {}));
exports.varKinds = {
const: new code_1.Name("const"),
let: new code_1.Name("let"),
var: new code_1.Name("var")
};
var Scope = class {
constructor({ prefixes, parent } = {}) {
this._names = {};
this._prefixes = prefixes;
this._parent = parent;
}
toName(nameOrPrefix) {
return nameOrPrefix instanceof code_1.Name ? nameOrPrefix : this.name(nameOrPrefix);
}
name(prefix) {
return new code_1.Name(this._newName(prefix));
}
_newName(prefix) {
const ng = this._names[prefix] || this._nameGroup(prefix);
return `${prefix}${ng.index++}`;
}
_nameGroup(prefix) {
var _a, _b;
if (((_b = (_a = this._parent) === null || _a === void 0 ? void 0 : _a._prefixes) === null || _b === void 0 ? void 0 : _b.has(prefix)) || this._prefixes && !this._prefixes.has(prefix)) {
throw new Error(`CodeGen: prefix "${prefix}" is not allowed in this scope`);
}
return this._names[prefix] = { prefix, index: 0 };
}
};
exports.Scope = Scope;
var ValueScopeName = class extends code_1.Name {
constructor(prefix, nameStr) {
super(nameStr);
this.prefix = prefix;
}
setValue(value, { property, itemIndex }) {
this.value = value;
this.scopePath = (0, code_1._)`.${new code_1.Name(property)}[${itemIndex}]`;
}
};
exports.ValueScopeName = ValueScopeName;
var line = (0, code_1._)`\n`;
var ValueScope = class extends Scope {
constructor(opts) {
super(opts);
this._values = {};
this._scope = opts.scope;
this.opts = { ...opts, _n: opts.lines ? line : code_1.nil };
}
get() {
return this._scope;
}
name(prefix) {
return new ValueScopeName(prefix, this._newName(prefix));
}
value(nameOrPrefix, value) {
var _a;
if (value.ref === void 0)
throw new Error("CodeGen: ref must be passed in value");
const name = this.toName(nameOrPrefix);
const { prefix } = name;
const valueKey = (_a = value.key) !== null && _a !== void 0 ? _a : value.ref;
let vs = this._values[prefix];
if (vs) {
const _name = vs.get(valueKey);
if (_name)
return _name;
} else {
vs = this._values[prefix] = /* @__PURE__ */ new Map();
}
vs.set(valueKey, name);
const s = this._scope[prefix] || (this._scope[prefix] = []);
const itemIndex = s.length;
s[itemIndex] = value.ref;
name.setValue(value, { property: prefix, itemIndex });
return name;
}
getValue(prefix, keyOrRef) {
const vs = this._values[prefix];
if (!vs)
return;
return vs.get(keyOrRef);
}
scopeRefs(scopeName, values = this._values) {
return this._reduceValues(values, (name) => {
if (name.scopePath === void 0)
throw new Error(`CodeGen: name "${name}" has no value`);
return (0, code_1._)`${scopeName}${name.scopePath}`;
});
}
scopeCode(values = this._values, usedValues, getCode) {
return this._reduceValues(values, (name) => {
if (name.value === void 0)
throw new Error(`CodeGen: name "${name}" has no value`);
return name.value.code;
}, usedValues, getCode);
}
_reduceValues(values, valueCode, usedValues = {}, getCode) {
let code = code_1.nil;
for (const prefix in values) {
const vs = values[prefix];
if (!vs)
continue;
const nameSet = usedValues[prefix] = usedValues[prefix] || /* @__PURE__ */ new Map();
vs.forEach((name) => {
if (nameSet.has(name))
return;
nameSet.set(name, UsedValueState.Started);
let c = valueCode(name);
if (c) {
const def = this.opts.es5 ? exports.varKinds.var : exports.varKinds.const;
code = (0, code_1._)`${code}${def} ${name} = ${c};${this.opts._n}`;
} else if (c = getCode === null || getCode === void 0 ? void 0 : getCode(name)) {
code = (0, code_1._)`${code}${c}${this.opts._n}`;
} else {
throw new ValueError(name);
}
nameSet.set(name, UsedValueState.Completed);
});
}
return code;
}
};
exports.ValueScope = ValueScope;
}
});
// node_modules/ajv/dist/compile/codegen/index.js
var require_codegen = __commonJS({
"node_modules/ajv/dist/compile/codegen/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.or = exports.and = exports.not = exports.CodeGen = exports.operators = exports.varKinds = exports.ValueScopeName = exports.ValueScope = exports.Scope = exports.Name = exports.regexpCode = exports.stringify = exports.getProperty = exports.nil = exports.strConcat = exports.str = exports._ = void 0;
var code_1 = require_code();
var scope_1 = require_scope();
var code_2 = require_code();
Object.defineProperty(exports, "_", { enumerable: true, get: function() {
return code_2._;
} });
Object.defineProperty(exports, "str", { enumerable: true, get: function() {
return code_2.str;
} });
Object.defineProperty(exports, "strConcat", { enumerable: true, get: function() {
return code_2.strConcat;
} });
Object.defineProperty(exports, "nil", { enumerable: true, get: function() {
return code_2.nil;
} });
Object.defineProperty(exports, "getProperty", { enumerable: true, get: function() {
return code_2.getProperty;
} });
Object.defineProperty(exports, "stringify", { enumerable: true, get: function() {
return code_2.stringify;
} });
Object.defineProperty(exports, "regexpCode", { enumerable: true, get: function() {
return code_2.regexpCode;
} });
Object.defineProperty(exports, "Name", { enumerable: true, get: function() {
return code_2.Name;
} });
var scope_2 = require_scope();
Object.defineProperty(exports, "Scope", { enumerable: true, get: function() {
return scope_2.Scope;
} });
Object.defineProperty(exports, "ValueScope", { enumerable: true, get: function() {
return scope_2.ValueScope;
} });
Object.defineProperty(exports, "ValueScopeName", { enumerable: true, get: function() {
return scope_2.ValueScopeName;
} });
Object.defineProperty(exports, "varKinds", { enumerable: true, get: function() {
return scope_2.varKinds;
} });
exports.operators = {
GT: new code_1._Code(">"),
GTE: new code_1._Code(">="),
LT: new code_1._Code("<"),
LTE: new code_1._Code("<="),
EQ: new code_1._Code("==="),
NEQ: new code_1._Code("!=="),
NOT: new code_1._Code("!"),
OR: new code_1._Code("||"),
AND: new code_1._Code("&&"),
ADD: new code_1._Code("+")
};
var Node = class {
optimizeNodes() {
return this;
}
optimizeNames(_names, _constants) {
return this;
}
};
var Def = class extends Node {
constructor(varKind, name, rhs) {
super();
this.varKind = varKind;
this.name = name;
this.rhs = rhs;
}
render({ es5, _n }) {
const varKind = es5 ? scope_1.varKinds.var : this.varKind;
const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
return `${varKind} ${this.name}${rhs};` + _n;
}
optimizeNames(names, constants) {
if (!names[this.name.str])
return;
if (this.rhs)
this.rhs = optimizeExpr(this.rhs, names, constants);
return this;
}
get names() {
return this.rhs instanceof code_1._CodeOrName ? this.rhs.names : {};
}
};
var Assign = class extends Node {
constructor(lhs, rhs, sideEffects) {
super();
this.lhs = lhs;
this.rhs = rhs;
this.sideEffects = sideEffects;
}
render({ _n }) {
return `${this.lhs} = ${this.rhs};` + _n;
}
optimizeNames(names, constants) {
if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
return;
this.rhs = optimizeExpr(this.rhs, names, constants);
return this;
}
get names() {
const names = this.lhs instanceof code_1.Name ? {} : { ...this.lhs.names };
return addExprNames(names, this.rhs);
}
};
var AssignOp = class extends Assign {
constructor(lhs, op, rhs, sideEffects) {
super(lhs, rhs, sideEffects);
this.op = op;
}
render({ _n }) {
return `${this.lhs} ${this.op}= ${this.rhs};` + _n;
}
};
var Label = class extends Node {
constructor(label) {
super();
this.label = label;
this.names = {};
}
render({ _n }) {
return `${this.label}:` + _n;
}
};
var Break = class extends Node {
constructor(label) {
super();
this.label = label;
this.names = {};
}
render({ _n }) {
const label = this.label ? ` ${this.label}` : "";
return `break${label};` + _n;
}
};
var Throw = class extends Node {
constructor(error) {
super();
this.error = error;
}
render({ _n }) {
return `throw ${this.error};` + _n;
}
get names() {
return this.error.names;
}
};
var AnyCode = class extends Node {
constructor(code) {
super();
this.code = code;
}
render({ _n }) {
return `${this.code};` + _n;
}
optimizeNodes() {
return `${this.code}` ? this : void 0;
}
optimizeNames(names, constants) {
this.code = optimizeExpr(this.code, names, constants);
return this;
}
get names() {
return this.code instanceof code_1._CodeOrName ? this.code.names : {};
}
};
var ParentNode = class extends Node {
constructor(nodes = []) {
super();
this.nodes = nodes;
}
render(opts) {
return this.nodes.reduce((code, n) => code + n.render(opts), "");
}
optimizeNodes() {
const { nodes } = this;
let i = nodes.length;
while (i--) {
const n = nodes[i].optimizeNodes();
if (Array.isArray(n))
nodes.splice(i, 1, ...n);
else if (n)
nodes[i] = n;
else
nodes.splice(i, 1);
}
return nodes.length > 0 ? this : void 0;
}
optimizeNames(names, constants) {
const { nodes } = this;
let i = nodes.length;
while (i--) {
const n = nodes[i];
if (n.optimizeNames(names, constants))
continue;
subtractNames(names, n.names);
nodes.splice(i, 1);
}
return nodes.length > 0 ? this : void 0;
}
get names() {
return this.nodes.reduce((names, n) => addNames(names, n.names), {});
}
};
var BlockNode = class extends ParentNode {
render(opts) {
return "{" + opts._n + super.render(opts) + "}" + opts._n;
}
};
var Root = class extends ParentNode {
};
var Else = class extends BlockNode {
};
Else.kind = "else";
var If = class _If extends BlockNode {
constructor(condition, nodes) {
super(nodes);
this.condition = condition;
}
render(opts) {
let code = `if(${this.condition})` + super.render(opts);
if (this.else)
code += "else " + this.else.render(opts);
return code;
}
optimizeNodes() {
super.optimizeNodes();
const cond = this.condition;
if (cond === true)
return this.nodes;
let e = this.else;
if (e) {
const ns = e.optimizeNodes();
e = this.else = Array.isArray(ns) ? new Else(ns) : ns;
}
if (e) {
if (cond === false)
return e instanceof _If ? e : e.nodes;
if (this.nodes.length)
return this;
return new _If(not(cond), e instanceof _If ? [e] : e.nodes);
}
if (cond === false || !this.nodes.length)
return void 0;
return this;
}
optimizeNames(names, constants) {
var _a;
this.else = (_a = this.else) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants);
if (!(super.optimizeNames(names, constants) || this.else))
return;
this.condition = optimizeExpr(this.condition, names, constants);
return this;
}
get names() {
const names = super.names;
addExprNames(names, this.condition);
if (this.else)
addNames(names, this.else.names);
return names;
}
};
If.kind = "if";
var For = class extends BlockNode {
};
For.kind = "for";
var ForLoop = class extends For {
constructor(iteration) {
super();
this.iteration = iteration;
}
render(opts) {
return `for(${this.iteration})` + super.render(opts);
}
optimizeNames(names, constants) {
if (!super.optimizeNames(names, constants))
return;
this.iteration = optimizeExpr(this.iteration, names, constants);
return this;
}
get names() {
return addNames(super.names, this.iteration.names);
}
};
var ForRange = class extends For {
constructor(varKind, name, from, to) {
super();
this.varKind = varKind;
this.name = name;
this.from = from;
this.to = to;
}
render(opts) {
const varKind = opts.es5 ? scope_1.varKinds.var : this.varKind;
const { name, from, to } = this;
return `for(${varKind} ${name}=${from}; ${name}<${to}; ${name}++)` + super.render(opts);
}
get names() {
const names = addExprNames(super.names, this.from);
return addExprNames(names, this.to);
}
};
var ForIter = class extends For {
constructor(loop, varKind, name, iterable) {
super();
this.loop = loop;
this.varKind = varKind;
this.name = name;
this.iterable = iterable;
}
render(opts) {
return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
}
optimizeNames(names, constants) {
if (!super.optimizeNames(names, constants))
return;
this.iterable = optimizeExpr(this.iterable, names, constants);
return this;
}
get names() {
return addNames(super.names, this.iterable.names);
}
};
var Func = class extends BlockNode {
constructor(name, args, async) {
super();
this.name = name;
this.args = args;
this.async = async;
}
render(opts) {
const _async = this.async ? "async " : "";
return `${_async}function ${this.name}(${this.args})` + super.render(opts);
}
};
Func.kind = "func";
var Return = class extends ParentNode {
render(opts) {
return "return " + super.render(opts);
}
};
Return.kind = "return";
var Try = class extends BlockNode {
render(opts) {
let code = "try" + super.render(opts);
if (this.catch)
code += this.catch.render(opts);
if (this.finally)
code += this.finally.render(opts);
return code;
}
optimizeNodes() {
var _a, _b;
super.optimizeNodes();
(_a = this.catch) === null || _a === void 0 ? void 0 : _a.optimizeNodes();
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNodes();
return this;
}
optimizeNames(names, constants) {
var _a, _b;
super.optimizeNames(names, constants);
(_a = this.catch) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants);
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants);
return this;
}
get names() {
const names = super.names;
if (this.catch)
addNames(names, this.catch.names);
if (this.finally)
addNames(names, this.finally.names);
return names;
}
};
var Catch = class extends BlockNode {
constructor(error) {
super();
this.error = error;
}
render(opts) {
return `catch(${this.error})` + super.render(opts);
}
};
Catch.kind = "catch";
var Finally = class extends BlockNode {
render(opts) {
return "finally" + super.render(opts);
}
};
Finally.kind = "finally";
var CodeGen = class {
constructor(extScope, opts = {}) {
this._values = {};
this._blockStarts = [];
this._constants = {};
this.opts = { ...opts, _n: opts.lines ? "\n" : "" };
this._extScope = extScope;
this._scope = new scope_1.Scope({ parent: extScope });
this._nodes = [new Root()];
}
toString() {
return this._root.render(this.opts);
}
// returns unique name in the internal scope
name(prefix) {
return this._scope.name(prefix);
}
// reserves unique name in the external scope
scopeName(prefix) {
return this._extScope.name(prefix);
}
// reserves unique name in the external scope and assigns value to it
scopeValue(prefixOrName, value) {
const name = this._extScope.value(prefixOrName, value);
const vs = this._values[name.prefix] || (this._values[name.prefix] = /* @__PURE__ */ new Set());
vs.add(name);
return name;
}
getScopeValue(prefix, keyOrRef) {
return this._extScope.getValue(prefix, keyOrRef);
}
// return code that assigns values in the external scope to the names that are used internally
// (same names that were returned by gen.scopeName or gen.scopeValue)
scopeRefs(scopeName) {
return this._extScope.scopeRefs(scopeName, this._values);
}
scopeCode() {
return this._extScope.scopeCode(this._values);
}
_def(varKind, nameOrPrefix, rhs, constant) {
const name = this._scope.toName(nameOrPrefix);
if (rhs !== void 0 && constant)
this._constants[name.str] = rhs;
this._leafNode(new Def(varKind, name, rhs));
return name;
}
// `const` declaration (`var` in es5 mode)
const(nameOrPrefix, rhs, _constant) {
return this._def(scope_1.varKinds.const, nameOrPrefix, rhs, _constant);
}
// `let` declaration with optional assignment (`var` in es5 mode)
let(nameOrPrefix, rhs, _constant) {
return this._def(scope_1.varKinds.let, nameOrPrefix, rhs, _constant);
}
// `var` declaration with optional assignment
var(nameOrPrefix, rhs, _constant) {
return this._def(scope_1.varKinds.var, nameOrPrefix, rhs, _constant);
}
// assignment code
assign(lhs, rhs, sideEffects) {
return this._leafNode(new Assign(lhs, rhs, sideEffects));
}
// `+=` code
add(lhs, rhs) {
return this._leafNode(new AssignOp(lhs, exports.operators.ADD, rhs));
}
// appends passed SafeExpr to code or executes Block
code(c) {
if (typeof c == "function")
c();
else if (c !== code_1.nil)
this._leafNode(new AnyCode(c));
return this;
}
// returns code for object literal for the passed argument list of key-value pairs
object(...keyValues) {
const code = ["{"];
for (const [key, value] of keyValues) {
if (code.length > 1)
code.push(",");
code.push(key);
if (key !== value || this.opts.es5) {
code.push(":");
(0, code_1.addCodeArg)(code, value);
}
}
code.push("}");
return new code_1._Code(code);
}
// `if` clause (or statement if `thenBody` and, optionally, `elseBody` are passed)
if(condition, thenBody, elseBody) {
this._blockNode(new If(condition));
if (thenBody && elseBody) {
this.code(thenBody).else().code(elseBody).endIf();
} else if (thenBody) {
this.code(thenBody).endIf();
} else if (elseBody) {
throw new Error('CodeGen: "else" body without "then" body');
}
return this;
}
// `else if` clause - invalid without `if` or after `else` clauses
elseIf(condition) {
return this._elseNode(new If(condition));
}
// `else` clause - only valid after `if` or `else if` clauses
else() {
return this._elseNode(new Else());
}
// end `if` statement (needed if gen.if was used only with condition)
endIf() {
return this._endBlockNode(If, Else);
}
_for(node, forBody) {
this._blockNode(node);
if (forBody)
this.code(forBody).endFor();
return this;
}
// a generic `for` clause (or statement if `forBody` is passed)
for(iteration, forBody) {
return this._for(new ForLoop(iteration), forBody);
}
// `for` statement for a range of values
forRange(nameOrPrefix, from, to, forBody, varKind = this.opts.es5 ? scope_1.varKinds.var : scope_1.varKinds.let) {
const name = this._scope.toName(nameOrPrefix);
return this._for(new ForRange(varKind, name, from, to), () => forBody(name));
}
// `for-of` statement (in es5 mode replace with a normal for loop)
forOf(nameOrPrefix, iterable, forBody, varKind = scope_1.varKinds.const) {
const name = this._scope.toName(nameOrPrefix);
if (this.opts.es5) {
const arr = iterable instanceof code_1.Name ? iterable : this.var("_arr", iterable);
return this.forRange("_i", 0, (0, code_1._)`${arr}.length`, (i) => {
this.var(name, (0, code_1._)`${arr}[${i}]`);
forBody(name);
});
}
return this._for(new ForIter("of", varKind, name, iterable), () => forBody(name));
}
// `for-in` statement.
// With option `ownProperties` replaced with a `for-of` loop for object keys
forIn(nameOrPrefix, obj, forBody, varKind = this.opts.es5 ? scope_1.varKinds.var : scope_1.varKinds.const) {
if (this.opts.ownProperties) {
return this.forOf(nameOrPrefix, (0, code_1._)`Object.keys(${obj})`, forBody);
}
const name = this._scope.toName(nameOrPrefix);
return this._for(new ForIter("in", varKind, name, obj), () => forBody(name));
}
// end `for` loop
endFor() {
return this._endBlockNode(For);
}
// `label` statement
label(label) {
return this._leafNode(new Label(label));
}
// `break` statement
break(label) {
return this._leafNode(new Break(label));
}
// `return` statement
return(value) {
const node = new Return();
this._blockNode(node);
this.code(value);
if (node.nodes.length !== 1)
throw new Error('CodeGen: "return" should have one node');
return this._endBlockNode(Return);
}
// `try` statement
try(tryBody, catchCode, finallyCode) {
if (!catchCode && !finallyCode)
throw new Error('CodeGen: "try" without "catch" and "finally"');
const node = new Try();
this._blockNode(node);
this.code(tryBody);
if (catchCode) {
const error = this.name("e");
this._currNode = node.catch = new Catch(error);
catchCode(error);
}
if (finallyCode) {
this._currNode = node.finally = new Finally();
this.code(finallyCode);
}
return this._endBlockNode(Catch, Finally);
}
// `throw` statement
throw(error) {
return this._leafNode(new Throw(error));
}
// start self-balancing block
block(body, nodeCount) {
this._blockStarts.push(this._nodes.length);
if (body)
this.code(body).endBlock(nodeCount);
return this;
}
// end the current self-balancing block
endBlock(nodeCount) {
const len = this._blockStarts.pop();
if (len === void 0)
throw new Error("CodeGen: not in self-balancing block");
const toClose = this._nodes.length - len;
if (toClose < 0 || nodeCount !== void 0 && toClose !== nodeCount) {
throw new Error(`CodeGen: wrong number of nodes: ${toClose} vs ${nodeCount} expected`);
}
this._nodes.length = len;
return this;
}
// `function` heading (or definition if funcBody is passed)
func(name, args = code_1.nil, async, funcBody) {
this._blockNode(new Func(name, args, async));
if (funcBody)
this.code(funcBody).endFunc();
return this;
}
// end function definition
endFunc() {
return this._endBlockNode(Func);
}
optimize(n = 1) {
while (n-- > 0) {
this._root.optimizeNodes();
this._root.optimizeNames(this._root.names, this._constants);
}
}
_leafNode(node) {
this._currNode.nodes.push(node);
return this;
}
_blockNode(node) {
this._currNode.nodes.push(node);
this._nodes.push(node);
}
_endBlockNode(N1, N2) {
const n = this._currNode;
if (n instanceof N1 || N2 && n instanceof N2) {
this._nodes.pop();
return this;
}
throw new Error(`CodeGen: not in block "${N2 ? `${N1.kind}/${N2.kind}` : N1.kind}"`);
}
_elseNode(node) {
const n = this._currNode;
if (!(n instanceof If)) {
throw new Error('CodeGen: "else" without "if"');
}
this._currNode = n.else = node;
return this;
}
get _root() {
return this._nodes[0];
}
get _currNode() {
const ns = this._nodes;
return ns[ns.length - 1];
}
set _currNode(node) {
const ns = this._nodes;
ns[ns.length - 1] = node;
}
};
exports.CodeGen = CodeGen;
function addNames(names, from) {
for (const n in from)
names[n] = (names[n] || 0) + (from[n] || 0);
return names;
}
function addExprNames(names, from) {
return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
}
function optimizeExpr(expr, names, constants) {
if (expr instanceof code_1.Name)
return replaceName(expr);
if (!canOptimize(expr))
return expr;
return new code_1._Code(expr._items.reduce((items, c) => {
if (c instanceof code_1.Name)
c = replaceName(c);
if (c instanceof code_1._Code)
items.push(...c._items);
else
items.push(c);
return items;
}, []));
function replaceName(n) {
const c = constants[n.str];
if (c === void 0 || names[n.str] !== 1)
return n;
delete names[n.str];
return c;
}
function canOptimize(e) {
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants[c.str] !== void 0);
}
}
function subtractNames(names, from) {
for (const n in from)
names[n] = (names[n] || 0) - (from[n] || 0);
}
function not(x) {
return typeof x == "boolean" || typeof x == "number" || x === null ? !x : (0, code_1._)`!${par(x)}`;
}
exports.not = not;
var andCode = mappend(exports.operators.AND);
function and(...args) {
return args.reduce(andCode);
}
exports.and = and;
var orCode = mappend(exports.operators.OR);
function or(...args) {
return args.reduce(orCode);
}
exports.or = or;
function mappend(op) {
return (x, y) => x === code_1.nil ? y : y === code_1.nil ? x : (0, code_1._)`${par(x)} ${op} ${par(y)}`;
}
function par(x) {
return x instanceof code_1.Name ? x : (0, code_1._)`(${x})`;
}
}
});
// node_modules/ajv/dist/compile/util.js
var require_util = __commonJS({
"node_modules/ajv/dist/compile/util.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkStrictMode = exports.getErrorPath = exports.Type = exports.useFunc = exports.setEvaluated = exports.evaluatedPropsToName = exports.mergeEvaluated = exports.eachItem = exports.unescapeJsonPointer = exports.escapeJsonPointer = exports.escapeFragment = exports.unescapeFragment = exports.schemaRefOrVal = exports.schemaHasRulesButRef = exports.schemaHasRules = exports.checkUnknownRules = exports.alwaysValidSchema = exports.toHash = void 0;
var codegen_1 = require_codegen();
var code_1 = require_code();
function toHash(arr) {
const hash = {};
for (const item of arr)
hash[item] = true;
return hash;
}
exports.toHash = toHash;
function alwaysValidSchema(it, schema) {
if (typeof schema == "boolean")
return schema;
if (Object.keys(schema).length === 0)
return true;
checkUnknownRules(it, schema);
return !schemaHasRules(schema, it.self.RULES.all);
}
exports.alwaysValidSchema = alwaysValidSchema;
function checkUnknownRules(it, schema = it.schema) {
const { opts, self } = it;
if (!opts.strictSchema)
return;
if (typeof schema === "boolean")
return;
const rules = self.RULES.keywords;
for (const key in schema) {
if (!rules[key])
checkStrictMode(it, `unknown keyword: "${key}"`);
}
}
exports.checkUnknownRules = checkUnknownRules;
function schemaHasRules(schema, rules) {
if (typeof schema == "boolean")
return !schema;
for (const key in schema)
if (rules[key])
return true;
return false;
}
exports.schemaHasRules = schemaHasRules;
function schemaHasRulesButRef(schema, RULES) {
if (typeof schema == "boolean")
return !schema;
for (const key in schema)
if (key !== "$ref" && RULES.all[key])
return true;
return false;
}
exports.schemaHasRulesButRef = schemaHasRulesButRef;
function schemaRefOrVal({ topSchemaRef, schemaPath }, schema, keyword, $data) {
if (!$data) {
if (typeof schema == "number" || typeof schema == "boolean")
return schema;
if (typeof schema == "string")
return (0, codegen_1._)`${schema}`;
}
return (0, codegen_1._)`${topSchemaRef}${schemaPath}${(0, codegen_1.getProperty)(keyword)}`;
}
exports.schemaRefOrVal = schemaRefOrVal;
function unescapeFragment(str) {
return unescapeJsonPointer(decodeURIComponent(str));
}
exports.unescapeFragment = unescapeFragment;
function escapeFragment(str) {
return encodeURIComponent(escapeJsonPointer(str));
}
exports.escapeFragment = escapeFragment;
function escapeJsonPointer(str) {
if (typeof str == "number")
return `${str}`;
return str.replace(/~/g, "~0").replace(/\//g, "~1");
}
exports.escapeJsonPointer = escapeJsonPointer;
function unescapeJsonPointer(str) {
return str.replace(/~1/g, "/").replace(/~0/g, "~");
}
exports.unescapeJsonPointer = unescapeJsonPointer;
function eachItem(xs, f) {
if (Array.isArray(xs)) {
for (const x of xs)
f(x);
} else {
f(xs);
}
}
exports.eachItem = eachItem;
function makeMergeEvaluated({ mergeNames, mergeToName, mergeValues, resultToName }) {
return (gen, from, to, toName) => {
const res = to === void 0 ? from : to instanceof codegen_1.Name ? (from instanceof codegen_1.Name ? mergeNames(gen, from, to) : mergeToName(gen, from, to), to) : from instanceof codegen_1.Name ? (mergeToName(gen, to, from), from) : mergeValues(from, to);
return toName === codegen_1.Name && !(res instanceof codegen_1.Name) ? resultToName(gen, res) : res;
};
}
exports.mergeEvaluated = {
props: makeMergeEvaluated({
mergeNames: (gen, from, to) => gen.if((0, codegen_1._)`${to} !== true && ${from} !== undefined`, () => {
gen.if((0, codegen_1._)`${from} === true`, () => gen.assign(to, true), () => gen.assign(to, (0, codegen_1._)`${to} || {}`).code((0, codegen_1._)`Object.assign(${to}, ${from})`));
}),
mergeToName: (gen, from, to) => gen.if((0, codegen_1._)`${to} !== true`, () => {
if (from === true) {
gen.assign(to, true);
} else {
gen.assign(to, (0, codegen_1._)`${to} || {}`);
setEvaluated(gen, to, from);
}
}),
mergeValues: (from, to) => from === true ? true : { ...from, ...to },
resultToName: evaluatedPropsToName
}),
items: makeMergeEvaluated({
mergeNames: (gen, from, to) => gen.if((0, codegen_1._)`${to} !== true && ${from} !== undefined`, () => gen.assign(to, (0, codegen_1._)`${from} === true ? true : ${to} > ${from} ? ${to} : ${from}`)),
mergeToName: (gen, from, to) => gen.if((0, codegen_1._)`${to} !== true`, () => gen.assign(to, from === true ? true : (0, codegen_1._)`${to} > ${from} ? ${to} : ${from}`)),
mergeValues: (from, to) => from === true ? true : Math.max(from, to),
resultToName: (gen, items) => gen.var("items", items)
})
};
function evaluatedPropsToName(gen, ps) {
if (ps === true)
return gen.var("props", true);
const props = gen.var("props", (0, codegen_1._)`{}`);
if (ps !== void 0)
setEvaluated(gen, props, ps);
return props;
}
exports.evaluatedPropsToName = evaluatedPropsToName;
function setEvaluated(gen, props, ps) {
Object.keys(ps).forEach((p) => gen.assign((0, codegen_1._)`${props}${(0, codegen_1.getProperty)(p)}`, true));
}
exports.setEvaluated = setEvaluated;
var snippets = {};
function useFunc(gen, f) {
return gen.scopeValue("func", {
ref: f,
code: snippets[f.code] || (snippets[f.code] = new code_1._Code(f.code))
});
}
exports.useFunc = useFunc;
var Type;
(function(Type2) {
Type2[Type2["Num"] = 0] = "Num";
Type2[Type2["Str"] = 1] = "Str";
})(Type || (exports.Type = Type = {}));
function getErrorPath(dataProp, dataPropType, jsPropertySyntax) {
if (dataProp instanceof codegen_1.Name) {
const isNumber = dataPropType === Type.Num;
return jsPropertySyntax ? isNumber ? (0, codegen_1._)`"[" + ${dataProp} + "]"` : (0, codegen_1._)`"['" + ${dataProp} + "']"` : isNumber ? (0, codegen_1._)`"/" + ${dataProp}` : (0, codegen_1._)`"/" + ${dataProp}.replace(/~/g, "~0").replace(/\\//g, "~1")`;
}
return jsPropertySyntax ? (0, codegen_1.getProperty)(dataProp).toString() : "/" + escapeJsonPointer(dataProp);
}
exports.getErrorPath = getErrorPath;
function checkStrictMode(it, msg, mode = it.opts.strictSchema) {
if (!mode)
return;
msg = `strict mode: ${msg}`;
if (mode === true)
throw new Error(msg);
it.self.logger.warn(msg);
}
exports.checkStrictMode = checkStrictMode;
}
});
// node_modules/ajv/dist/compile/names.js
var require_names = __commonJS({
"node_modules/ajv/dist/compile/names.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var names = {
// validation function arguments
data: new codegen_1.Name("data"),
// data passed to validation function
// args passed from referencing schema
valCxt: new codegen_1.Name("valCxt"),
// validation/data context - should not be used directly, it is destructured to the names below
instancePath: new codegen_1.Name("instancePath"),
parentData: new codegen_1.Name("parentData"),
parentDataProperty: new codegen_1.Name("parentDataProperty"),
rootData: new codegen_1.Name("rootData"),
// root data - same as the data passed to the first/top validation function
dynamicAnchors: new codegen_1.Name("dynamicAnchors"),
// used to support recursiveRef and dynamicRef
// function scoped variables
vErrors: new codegen_1.Name("vErrors"),
// null or array of validation errors
errors: new codegen_1.Name("errors"),
// counter of validation errors
this: new codegen_1.Name("this"),
// "globals"
self: new codegen_1.Name("self"),
scope: new codegen_1.Name("scope"),
// JTD serialize/parse name for JSON string and position
json: new codegen_1.Name("json"),
jsonPos: new codegen_1.Name("jsonPos"),
jsonLen: new codegen_1.Name("jsonLen"),
jsonPart: new codegen_1.Name("jsonPart")
};
exports.default = names;
}
});
// node_modules/ajv/dist/compile/errors.js
var require_errors = __commonJS({
"node_modules/ajv/dist/compile/errors.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extendErrors = exports.resetErrorsCount = exports.reportExtraError = exports.reportError = exports.keyword$DataError = exports.keywordError = void 0;
var codegen_1 = require_codegen();
var util_1 = require_util();
var names_1 = require_names();
exports.keywordError = {
message: ({ keyword }) => (0, codegen_1.str)`must pass "${keyword}" keyword validation`
};
exports.keyword$DataError = {
message: ({ keyword, schemaType }) => schemaType ? (0, codegen_1.str)`"${keyword}" keyword must be ${schemaType} ($data)` : (0, codegen_1.str)`"${keyword}" keyword is invalid ($data)`
};
function reportError(cxt, error = exports.keywordError, errorPaths, overrideAllErrors) {
const { it } = cxt;
const { gen, compositeRule, allErrors } = it;
const errObj = errorObjectCode(cxt, error, errorPaths);
if (overrideAllErrors !== null && overrideAllErrors !== void 0 ? overrideAllErrors : compositeRule || allErrors) {
addError(gen, errObj);
} else {
returnErrors(it, (0, codegen_1._)`[${errObj}]`);
}
}
exports.reportError = reportError;
function reportExtraError(cxt, error = exports.keywordError, errorPaths) {
const { it } = cxt;
const { gen, compositeRule, allErrors } = it;
const errObj = errorObjectCode(cxt, error, errorPaths);
addError(gen, errObj);
if (!(compositeRule || allErrors)) {
returnErrors(it, names_1.default.vErrors);
}
}
exports.reportExtraError = reportExtraError;
function resetErrorsCount(gen, errsCount) {
gen.assign(names_1.default.errors, errsCount);
gen.if((0, codegen_1._)`${names_1.default.vErrors} !== null`, () => gen.if(errsCount, () => gen.assign((0, codegen_1._)`${names_1.default.vErrors}.length`, errsCount), () => gen.assign(names_1.default.vErrors, null)));
}
exports.resetErrorsCount = resetErrorsCount;
function extendErrors({ gen, keyword, schemaValue, data, errsCount, it }) {
if (errsCount === void 0)
throw new Error("ajv implementation error");
const err = gen.name("err");
gen.forRange("i", errsCount, names_1.default.errors, (i) => {
gen.const(err, (0, codegen_1._)`${names_1.default.vErrors}[${i}]`);
gen.if((0, codegen_1._)`${err}.instancePath === undefined`, () => gen.assign((0, codegen_1._)`${err}.instancePath`, (0, codegen_1.strConcat)(names_1.default.instancePath, it.errorPath)));
gen.assign((0, codegen_1._)`${err}.schemaPath`, (0, codegen_1.str)`${it.errSchemaPath}/${keyword}`);
if (it.opts.verbose) {
gen.assign((0, codegen_1._)`${err}.schema`, schemaValue);
gen.assign((0, codegen_1._)`${err}.data`, data);
}
});
}
exports.extendErrors = extendErrors;
function addError(gen, errObj) {
const err = gen.const("err", errObj);
gen.if((0, codegen_1._)`${names_1.default.vErrors} === null`, () => gen.assign(names_1.default.vErrors, (0, codegen_1._)`[${err}]`), (0, codegen_1._)`${names_1.default.vErrors}.push(${err})`);
gen.code((0, codegen_1._)`${names_1.default.errors}++`);
}
function returnErrors(it, errs) {
const { gen, validateName, schemaEnv } = it;
if (schemaEnv.$async) {
gen.throw((0, codegen_1._)`new ${it.ValidationError}(${errs})`);
} else {
gen.assign((0, codegen_1._)`${validateName}.errors`, errs);
gen.return(false);
}
}
var E = {
keyword: new codegen_1.Name("keyword"),
schemaPath: new codegen_1.Name("schemaPath"),
// also used in JTD errors
params: new codegen_1.Name("params"),
propertyName: new codegen_1.Name("propertyName"),
message: new codegen_1.Name("message"),
schema: new codegen_1.Name("schema"),
parentSchema: new codegen_1.Name("parentSchema")
};
function errorObjectCode(cxt, error, errorPaths) {
const { createErrors } = cxt.it;
if (createErrors === false)
return (0, codegen_1._)`{}`;
return errorObject(cxt, error, errorPaths);
}
function errorObject(cxt, error, errorPaths = {}) {
const { gen, it } = cxt;
const keyValues = [
errorInstancePath(it, errorPaths),
errorSchemaPath(cxt, errorPaths)
];
extraErrorProps(cxt, error, keyValues);
return gen.object(...keyValues);
}
function errorInstancePath({ errorPath }, { instancePath }) {
const instPath = instancePath ? (0, codegen_1.str)`${errorPath}${(0, util_1.getErrorPath)(instancePath, util_1.Type.Str)}` : errorPath;
return [names_1.default.instancePath, (0, codegen_1.strConcat)(names_1.default.instancePath, instPath)];
}
function errorSchemaPath({ keyword, it: { errSchemaPath } }, { schemaPath, parentSchema }) {
let schPath = parentSchema ? errSchemaPath : (0, codegen_1.str)`${errSchemaPath}/${keyword}`;
if (schemaPath) {
schPath = (0, codegen_1.str)`${schPath}${(0, util_1.getErrorPath)(schemaPath, util_1.Type.Str)}`;
}
return [E.schemaPath, schPath];
}
function extraErrorProps(cxt, { params, message }, keyValues) {
const { keyword, data, schemaValue, it } = cxt;
const { opts, propertyName, topSchemaRef, schemaPath } = it;
keyValues.push([E.keyword, keyword], [E.params, typeof params == "function" ? params(cxt) : params || (0, codegen_1._)`{}`]);
if (opts.messages) {
keyValues.push([E.message, typeof message == "function" ? message(cxt) : message]);
}
if (opts.verbose) {
keyValues.push([E.schema, schemaValue], [E.parentSchema, (0, codegen_1._)`${topSchemaRef}${schemaPath}`], [names_1.default.data, data]);
}
if (propertyName)
keyValues.push([E.propertyName, propertyName]);
}
}
});
// node_modules/ajv/dist/compile/validate/boolSchema.js
var require_boolSchema = __commonJS({
"node_modules/ajv/dist/compile/validate/boolSchema.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.boolOrEmptySchema = exports.topBoolOrEmptySchema = void 0;
var errors_1 = require_errors();
var codegen_1 = require_codegen();
var names_1 = require_names();
var boolError = {
message: "boolean schema is false"
};
function topBoolOrEmptySchema(it) {
const { gen, schema, validateName } = it;
if (schema === false) {
falseSchemaError(it, false);
} else if (typeof schema == "object" && schema.$async === true) {
gen.return(names_1.default.data);
} else {
gen.assign((0, codegen_1._)`${validateName}.errors`, null);
gen.return(true);
}
}
exports.topBoolOrEmptySchema = topBoolOrEmptySchema;
function boolOrEmptySchema(it, valid) {
const { gen, schema } = it;
if (schema === false) {
gen.var(valid, false);
falseSchemaError(it);
} else {
gen.var(valid, true);
}
}
exports.boolOrEmptySchema = boolOrEmptySchema;
function falseSchemaError(it, overrideAllErrors) {
const { gen, data } = it;
const cxt = {
gen,
keyword: "false schema",
data,
schema: false,
schemaCode: false,
schemaValue: false,
params: {},
it
};
(0, errors_1.reportError)(cxt, boolError, void 0, overrideAllErrors);
}
}
});
// node_modules/ajv/dist/compile/rules.js
var require_rules = __commonJS({
"node_modules/ajv/dist/compile/rules.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRules = exports.isJSONType = void 0;
var _jsonTypes = ["string", "number", "integer", "boolean", "null", "object", "array"];
var jsonTypes = new Set(_jsonTypes);
function isJSONType(x) {
return typeof x == "string" && jsonTypes.has(x);
}
exports.isJSONType = isJSONType;
function getRules() {
const groups = {
number: { type: "number", rules: [] },
string: { type: "string", rules: [] },
array: { type: "array", rules: [] },
object: { type: "object", rules: [] }
};
return {
types: { ...groups, integer: true, boolean: true, null: true },
rules: [{ rules: [] }, groups.number, groups.string, groups.array, groups.object],
post: { rules: [] },
all: {},
keywords: {}
};
}
exports.getRules = getRules;
}
});
// node_modules/ajv/dist/compile/validate/applicability.js
var require_applicability = __commonJS({
"node_modules/ajv/dist/compile/validate/applicability.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.shouldUseRule = exports.shouldUseGroup = exports.schemaHasRulesForType = void 0;
function schemaHasRulesForType({ schema, self }, type) {
const group = self.RULES.types[type];
return group && group !== true && shouldUseGroup(schema, group);
}
exports.schemaHasRulesForType = schemaHasRulesForType;
function shouldUseGroup(schema, group) {
return group.rules.some((rule) => shouldUseRule(schema, rule));
}
exports.shouldUseGroup = shouldUseGroup;
function shouldUseRule(schema, rule) {
var _a;
return schema[rule.keyword] !== void 0 || ((_a = rule.definition.implements) === null || _a === void 0 ? void 0 : _a.some((kwd) => schema[kwd] !== void 0));
}
exports.shouldUseRule = shouldUseRule;
}
});
// node_modules/ajv/dist/compile/validate/dataType.js
var require_dataType = __commonJS({
"node_modules/ajv/dist/compile/validate/dataType.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.reportTypeError = exports.checkDataTypes = exports.checkDataType = exports.coerceAndCheckDataType = exports.getJSONTypes = exports.getSchemaTypes = exports.DataType = void 0;
var rules_1 = require_rules();
var applicability_1 = require_applicability();
var errors_1 = require_errors();
var codegen_1 = require_codegen();
var util_1 = require_util();
var DataType;
(function(DataType2) {
DataType2[DataType2["Correct"] = 0] = "Correct";
DataType2[DataType2["Wrong"] = 1] = "Wrong";
})(DataType || (exports.DataType = DataType = {}));
function getSchemaTypes(schema) {
const types = getJSONTypes(schema.type);
const hasNull = types.includes("null");
if (hasNull) {
if (schema.nullable === false)
throw new Error("type: null contradicts nullable: false");
} else {
if (!types.length && schema.nullable !== void 0) {
throw new Error('"nullable" cannot be used without "type"');
}
if (schema.nullable === true)
types.push("null");
}
return types;
}
exports.getSchemaTypes = getSchemaTypes;
function getJSONTypes(ts) {
const types = Array.isArray(ts) ? ts : ts ? [ts] : [];
if (types.every(rules_1.isJSONType))
return types;
throw new Error("type must be JSONType or JSONType[]: " + types.join(","));
}
exports.getJSONTypes = getJSONTypes;
function coerceAndCheckDataType(it, types) {
const { gen, data, opts } = it;
const coerceTo = coerceToTypes(types, opts.coerceTypes);
const checkTypes = types.length > 0 && !(coerceTo.length === 0 && types.length === 1 && (0, applicability_1.schemaHasRulesForType)(it, types[0]));
if (checkTypes) {
const wrongType = checkDataTypes(types, data, opts.strictNumbers, DataType.Wrong);
gen.if(wrongType, () => {
if (coerceTo.length)
coerceData(it, types, coerceTo);
else
reportTypeError(it);
});
}
return checkTypes;
}
exports.coerceAndCheckDataType = coerceAndCheckDataType;
var COERCIBLE = /* @__PURE__ */ new Set(["string", "number", "integer", "boolean", "null"]);
function coerceToTypes(types, coerceTypes) {
return coerceTypes ? types.filter((t) => COERCIBLE.has(t) || coerceTypes === "array" && t === "array") : [];
}
function coerceData(it, types, coerceTo) {
const { gen, data, opts } = it;
const dataType = gen.let("dataType", (0, codegen_1._)`typeof ${data}`);
const coerced = gen.let("coerced", (0, codegen_1._)`undefined`);
if (opts.coerceTypes === "array") {
gen.if((0, codegen_1._)`${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () => gen.assign(data, (0, codegen_1._)`${data}[0]`).assign(dataType, (0, codegen_1._)`typeof ${data}`).if(checkDataTypes(types, data, opts.strictNumbers), () => gen.assign(coerced, data)));
}
gen.if((0, codegen_1._)`${coerced} !== undefined`);
for (const t of coerceTo) {
if (COERCIBLE.has(t) || t === "array" && opts.coerceTypes === "array") {
coerceSpecificType(t);
}
}
gen.else();
reportTypeError(it);
gen.endIf();
gen.if((0, codegen_1._)`${coerced} !== undefined`, () => {
gen.assign(data, coerced);
assignParentData(it, coerced);
});
function coerceSpecificType(t) {
switch (t) {
case "string":
gen.elseIf((0, codegen_1._)`${dataType} == "number" || ${dataType} == "boolean"`).assign(coerced, (0, codegen_1._)`"" + ${data}`).elseIf((0, codegen_1._)`${data} === null`).assign(coerced, (0, codegen_1._)`""`);
return;
case "number":
gen.elseIf((0, codegen_1._)`${dataType} == "boolean" || ${data} === null
|| (${dataType} == "string" && ${data} && ${data} == +${data})`).assign(coerced, (0, codegen_1._)`+${data}`);
return;
case "integer":
gen.elseIf((0, codegen_1._)`${dataType} === "boolean" || ${data} === null
|| (${dataType} === "string" && ${data} && ${data} == +${data} && !(${data} % 1))`).assign(coerced, (0, codegen_1._)`+${data}`);
return;
case "boolean":
gen.elseIf((0, codegen_1._)`${data} === "false" || ${data} === 0 || ${data} === null`).assign(coerced, false).elseIf((0, codegen_1._)`${data} === "true" || ${data} === 1`).assign(coerced, true);
return;
case "null":
gen.elseIf((0, codegen_1._)`${data} === "" || ${data} === 0 || ${data} === false`);
gen.assign(coerced, null);
return;
case "array":
gen.elseIf((0, codegen_1._)`${dataType} === "string" || ${dataType} === "number"
|| ${dataType} === "boolean" || ${data} === null`).assign(coerced, (0, codegen_1._)`[${data}]`);
}
}
}
function assignParentData({ gen, parentData, parentDataProperty }, expr) {
gen.if((0, codegen_1._)`${parentData} !== undefined`, () => gen.assign((0, codegen_1._)`${parentData}[${parentDataProperty}]`, expr));
}
function checkDataType(dataType, data, strictNums, correct = DataType.Correct) {
const EQ = correct === DataType.Correct ? codegen_1.operators.EQ : codegen_1.operators.NEQ;
let cond;
switch (dataType) {
case "null":
return (0, codegen_1._)`${data} ${EQ} null`;
case "array":
cond = (0, codegen_1._)`Array.isArray(${data})`;
break;
case "object":
cond = (0, codegen_1._)`${data} && typeof ${data} == "object" && !Array.isArray(${data})`;
break;
case "integer":
cond = numCond((0, codegen_1._)`!(${data} % 1) && !isNaN(${data})`);
break;
case "number":
cond = numCond();
break;
default:
return (0, codegen_1._)`typeof ${data} ${EQ} ${dataType}`;
}
return correct === DataType.Correct ? cond : (0, codegen_1.not)(cond);
function numCond(_cond = codegen_1.nil) {
return (0, codegen_1.and)((0, codegen_1._)`typeof ${data} == "number"`, _cond, strictNums ? (0, codegen_1._)`isFinite(${data})` : codegen_1.nil);
}
}
exports.checkDataType = checkDataType;
function checkDataTypes(dataTypes, data, strictNums, correct) {
if (dataTypes.length === 1) {
return checkDataType(dataTypes[0], data, strictNums, correct);
}
let cond;
const types = (0, util_1.toHash)(dataTypes);
if (types.array && types.object) {
const notObj = (0, codegen_1._)`typeof ${data} != "object"`;
cond = types.null ? notObj : (0, codegen_1._)`!${data} || ${notObj}`;
delete types.null;
delete types.array;
delete types.object;
} else {
cond = codegen_1.nil;
}
if (types.number)
delete types.integer;
for (const t in types)
cond = (0, codegen_1.and)(cond, checkDataType(t, data, strictNums, correct));
return cond;
}
exports.checkDataTypes = checkDataTypes;
var typeError = {
message: ({ schema }) => `must be ${schema}`,
params: ({ schema, schemaValue }) => typeof schema == "string" ? (0, codegen_1._)`{type: ${schema}}` : (0, codegen_1._)`{type: ${schemaValue}}`
};
function reportTypeError(it) {
const cxt = getTypeErrorContext(it);
(0, errors_1.reportError)(cxt, typeError);
}
exports.reportTypeError = reportTypeError;
function getTypeErrorContext(it) {
const { gen, data, schema } = it;
const schemaCode = (0, util_1.schemaRefOrVal)(it, schema, "type");
return {
gen,
keyword: "type",
data,
schema: schema.type,
schemaCode,
schemaValue: schemaCode,
parentSchema: schema,
params: {},
it
};
}
}
});
// node_modules/ajv/dist/compile/validate/defaults.js
var require_defaults = __commonJS({
"node_modules/ajv/dist/compile/validate/defaults.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.assignDefaults = void 0;
var codegen_1 = require_codegen();
var util_1 = require_util();
function assignDefaults(it, ty) {
const { properties, items } = it.schema;
if (ty === "object" && properties) {
for (const key in properties) {
assignDefault(it, key, properties[key].default);
}
} else if (ty === "array" && Array.isArray(items)) {
items.forEach((sch, i) => assignDefault(it, i, sch.default));
}
}
exports.assignDefaults = assignDefaults;
function assignDefault(it, prop, defaultValue) {
const { gen, compositeRule, data, opts } = it;
if (defaultValue === void 0)
return;
const childData = (0, codegen_1._)`${data}${(0, codegen_1.getProperty)(prop)}`;
if (compositeRule) {
(0, util_1.checkStrictMode)(it, `default is ignored for: ${childData}`);
return;
}
let condition = (0, codegen_1._)`${childData} === undefined`;
if (opts.useDefaults === "empty") {
condition = (0, codegen_1._)`${condition} || ${childData} === null || ${childData} === ""`;
}
gen.if(condition, (0, codegen_1._)`${childData} = ${(0, codegen_1.stringify)(defaultValue)}`);
}
}
});
// node_modules/ajv/dist/vocabularies/code.js
var require_code2 = __commonJS({
"node_modules/ajv/dist/vocabularies/code.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateUnion = exports.validateArray = exports.usePattern = exports.callValidateCode = exports.schemaProperties = exports.allSchemaProperties = exports.noPropertyInData = exports.propertyInData = exports.isOwnProperty = exports.hasPropFunc = exports.reportMissingProp = exports.checkMissingProp = exports.checkReportMissingProp = void 0;
var codegen_1 = require_codegen();
var util_1 = require_util();
var names_1 = require_names();
var util_2 = require_util();
function checkReportMissingProp(cxt, prop) {
const { gen, data, it } = cxt;
gen.if(noPropertyInData(gen, data, prop, it.opts.ownProperties), () => {
cxt.setParams({ missingProperty: (0, codegen_1._)`${prop}` }, true);
cxt.error();
});
}
exports.checkReportMissingProp = checkReportMissingProp;
function checkMissingProp({ gen, data, it: { opts } }, properties, missing) {
return (0, codegen_1.or)(...properties.map((prop) => (0, codegen_1.and)(noPropertyInData(gen, data, prop, opts.ownProperties), (0, codegen_1._)`${missing} = ${prop}`)));
}
exports.checkMissingProp = checkMissingProp;
function reportMissingProp(cxt, missing) {
cxt.setParams({ missingProperty: missing }, true);
cxt.error();
}
exports.reportMissingProp = reportMissingProp;
function hasPropFunc(gen) {
return gen.scopeValue("func", {
// eslint-disable-next-line @typescript-eslint/unbound-method
ref: Object.prototype.hasOwnProperty,
code: (0, codegen_1._)`Object.prototype.hasOwnProperty`
});
}
exports.hasPropFunc = hasPropFunc;
function isOwnProperty(gen, data, property) {
return (0, codegen_1._)`${hasPropFunc(gen)}.call(${data}, ${property})`;
}
exports.isOwnProperty = isOwnProperty;
function propertyInData(gen, data, property, ownProperties) {
const cond = (0, codegen_1._)`${data}${(0, codegen_1.getProperty)(property)} !== undefined`;
return ownProperties ? (0, codegen_1._)`${cond} && ${isOwnProperty(gen, data, property)}` : cond;
}
exports.propertyInData = propertyInData;
function noPropertyInData(gen, data, property, ownProperties) {
const cond = (0, codegen_1._)`${data}${(0, codegen_1.getProperty)(property)} === undefined`;
return ownProperties ? (0, codegen_1.or)(cond, (0, codegen_1.not)(isOwnProperty(gen, data, property))) : cond;
}
exports.noPropertyInData = noPropertyInData;
function allSchemaProperties(schemaMap) {
return schemaMap ? Object.keys(schemaMap).filter((p) => p !== "__proto__") : [];
}
exports.allSchemaProperties = allSchemaProperties;
function schemaProperties(it, schemaMap) {
return allSchemaProperties(schemaMap).filter((p) => !(0, util_1.alwaysValidSchema)(it, schemaMap[p]));
}
exports.schemaProperties = schemaProperties;
function callValidateCode({ schemaCode, data, it: { gen, topSchemaRef, schemaPath, errorPath }, it }, func, context, passSchema) {
const dataAndSchema = passSchema ? (0, codegen_1._)`${schemaCode}, ${data}, ${topSchemaRef}${schemaPath}` : data;
const valCxt = [
[names_1.default.instancePath, (0, codegen_1.strConcat)(names_1.default.instancePath, errorPath)],
[names_1.default.parentData, it.parentData],
[names_1.default.parentDataProperty, it.parentDataProperty],
[names_1.default.rootData, names_1.default.rootData]
];
if (it.opts.dynamicRef)
valCxt.push([names_1.default.dynamicAnchors, names_1.default.dynamicAnchors]);
const args = (0, codegen_1._)`${dataAndSchema}, ${gen.object(...valCxt)}`;
return context !== codegen_1.nil ? (0, codegen_1._)`${func}.call(${context}, ${args})` : (0, codegen_1._)`${func}(${args})`;
}
exports.callValidateCode = callValidateCode;
var newRegExp = (0, codegen_1._)`new RegExp`;
function usePattern({ gen, it: { opts } }, pattern) {
const u = opts.unicodeRegExp ? "u" : "";
const { regExp } = opts.code;
const rx = regExp(pattern, u);
return gen.scopeValue("pattern", {
key: rx.toString(),
ref: rx,
code: (0, codegen_1._)`${regExp.code === "new RegExp" ? newRegExp : (0, util_2.useFunc)(gen, regExp)}(${pattern}, ${u})`
});
}
exports.usePattern = usePattern;
function validateArray(cxt) {
const { gen, data, keyword, it } = cxt;
const valid = gen.name("valid");
if (it.allErrors) {
const validArr = gen.let("valid", true);
validateItems(() => gen.assign(validArr, false));
return validArr;
}
gen.var(valid, true);
validateItems(() => gen.break());
return valid;
function validateItems(notValid) {
const len = gen.const("len", (0, codegen_1._)`${data}.length`);
gen.forRange("i", 0, len, (i) => {
cxt.subschema({
keyword,
dataProp: i,
dataPropType: util_1.Type.Num
}, valid);
gen.if((0, codegen_1.not)(valid), notValid);
});
}
}
exports.validateArray = validateArray;
function validateUnion(cxt) {
const { gen, schema, keyword, it } = cxt;
if (!Array.isArray(schema))
throw new Error("ajv implementation error");
const alwaysValid = schema.some((sch) => (0, util_1.alwaysValidSchema)(it, sch));
if (alwaysValid && !it.opts.unevaluated)
return;
const valid = gen.let("valid", false);
const schValid = gen.name("_valid");
gen.block(() => schema.forEach((_sch, i) => {
const schCxt = cxt.subschema({
keyword,
schemaProp: i,
compositeRule: true
}, schValid);
gen.assign(valid, (0, codegen_1._)`${valid} || ${schValid}`);
const merged = cxt.mergeValidEvaluated(schCxt, schValid);
if (!merged)
gen.if((0, codegen_1.not)(valid));
}));
cxt.result(valid, () => cxt.reset(), () => cxt.error(true));
}
exports.validateUnion = validateUnion;
}
});
// node_modules/ajv/dist/compile/validate/keyword.js
var require_keyword = __commonJS({
"node_modules/ajv/dist/compile/validate/keyword.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateKeywordUsage = exports.validSchemaType = exports.funcKeywordCode = exports.macroKeywordCode = void 0;
var codegen_1 = require_codegen();
var names_1 = require_names();
var code_1 = require_code2();
var errors_1 = require_errors();
function macroKeywordCode(cxt, def) {
const { gen, keyword, schema, parentSchema, it } = cxt;
const macroSchema = def.macro.call(it.self, schema, parentSchema, it);
const schemaRef = useKeyword(gen, keyword, macroSchema);
if (it.opts.validateSchema !== false)
it.self.validateSchema(macroSchema, true);
const valid = gen.name("valid");
cxt.subschema({
schema: macroSchema,
schemaPath: codegen_1.nil,
errSchemaPath: `${it.errSchemaPath}/${keyword}`,
topSchemaRef: schemaRef,
compositeRule: true
}, valid);
cxt.pass(valid, () => cxt.error(true));
}
exports.macroKeywordCode = macroKeywordCode;
function funcKeywordCode(cxt, def) {
var _a;
const { gen, keyword, schema, parentSchema, $data, it } = cxt;
checkAsyncKeyword(it, def);
const validate = !$data && def.compile ? def.compile.call(it.self, schema, parentSchema, it) : def.validate;
const validateRef = useKeyword(gen, keyword, validate);
const valid = gen.let("valid");
cxt.block$data(valid, validateKeyword);
cxt.ok((_a = def.valid) !== null && _a !== void 0 ? _a : valid);
function validateKeyword() {
if (def.errors === false) {
assignValid();
if (def.modifying)
modifyData(cxt);
reportErrs(() => cxt.error());
} else {
const ruleErrs = def.async ? validateAsync() : validateSync();
if (def.modifying)
modifyData(cxt);
reportErrs(() => addErrs(cxt, ruleErrs));
}
}
function validateAsync() {
const ruleErrs = gen.let("ruleErrs", null);
gen.try(() => assignValid((0, codegen_1._)`await `), (e) => gen.assign(valid, false).if((0, codegen_1._)`${e} instanceof ${it.ValidationError}`, () => gen.assign(ruleErrs, (0, codegen_1._)`${e}.errors`), () => gen.throw(e)));
return ruleErrs;
}
function validateSync() {
const validateErrs = (0, codegen_1._)`${validateRef}.errors`;
gen.assign(validateErrs, null);
assignValid(codegen_1.nil);
return validateErrs;
}
function assignValid(_await = def.async ? (0, codegen_1._)`await ` : codegen_1.nil) {
const passCxt = it.opts.passContext ? names_1.default.this : names_1.default.self;
const passSchema = !("compile" in def && !$data || def.schema === false);
gen.assign(valid, (0, codegen_1._)`${_await}${(0, code_1.callValidateCode)(cxt, validateRef, passCxt, passSchema)}`, def.modifying);
}
function reportErrs(errors) {
var _a2;
gen.if((0, codegen_1.not)((_a2 = def.valid) !== null && _a2 !== void 0 ? _a2 : valid), errors);
}
}
exports.funcKeywordCode = funcKeywordCode;
function modifyData(cxt) {
const { gen, data, it } = cxt;
gen.if(it.parentData, () => gen.assign(data, (0, codegen_1._)`${it.parentData}[${it.parentDataProperty}]`));
}
function addErrs(cxt, errs) {
const { gen } = cxt;
gen.if((0, codegen_1._)`Array.isArray(${errs})`, () => {
gen.assign(names_1.default.vErrors, (0, codegen_1._)`${names_1.default.vErrors} === null ? ${errs} : ${names_1.default.vErrors}.concat(${errs})`).assign(names_1.default.errors, (0, codegen_1._)`${names_1.default.vErrors}.length`);
(0, errors_1.extendErrors)(cxt);
}, () => cxt.error());
}
function checkAsyncKeyword({ schemaEnv }, def) {
if (def.async && !schemaEnv.$async)
throw new Error("async keyword in sync schema");
}
function useKeyword(gen, keyword, result) {
if (result === void 0)
throw new Error(`keyword "${keyword}" failed to compile`);
return gen.scopeValue("keyword", typeof result == "function" ? { ref: result } : { ref: result, code: (0, codegen_1.stringify)(result) });
}
function validSchemaType(schema, schemaType, allowUndefined = false) {
return !schemaType.length || schemaType.some((st) => st === "array" ? Array.isArray(schema) : st === "object" ? schema && typeof schema == "object" && !Array.isArray(schema) : typeof schema == st || allowUndefined && typeof schema == "undefined");
}
exports.validSchemaType = validSchemaType;
function validateKeywordUsage({ schema, opts, self, errSchemaPath }, def, keyword) {
if (Array.isArray(def.keyword) ? !def.keyword.includes(keyword) : def.keyword !== keyword) {
throw new Error("ajv implementation error");
}
const deps = def.dependencies;
if (deps === null || deps === void 0 ? void 0 : deps.some((kwd) => !Object.prototype.hasOwnProperty.call(schema, kwd))) {
throw new Error(`parent schema must have dependencies of ${keyword}: ${deps.join(",")}`);
}
if (def.validateSchema) {
const valid = def.validateSchema(schema[keyword]);
if (!valid) {
const msg = `keyword "${keyword}" value is invalid at path "${errSchemaPath}": ` + self.errorsText(def.validateSchema.errors);
if (opts.validateSchema === "log")
self.logger.error(msg);
else
throw new Error(msg);
}
}
}
exports.validateKeywordUsage = validateKeywordUsage;
}
});
// node_modules/ajv/dist/compile/validate/subschema.js
var require_subschema = __commonJS({
"node_modules/ajv/dist/compile/validate/subschema.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extendSubschemaMode = exports.extendSubschemaData = exports.getSubschema = void 0;
var codegen_1 = require_codegen();
var util_1 = require_util();
function getSubschema(it, { keyword, schemaProp, schema, schemaPath, errSchemaPath, topSchemaRef }) {
if (keyword !== void 0 && schema !== void 0) {
throw new Error('both "keyword" and "schema" passed, only one allowed');
}
if (keyword !== void 0) {
const sch = it.schema[keyword];
return schemaProp === void 0 ? {
schema: sch,
schemaPath: (0, codegen_1._)`${it.schemaPath}${(0, codegen_1.getProperty)(keyword)}`,
errSchemaPath: `${it.errSchemaPath}/${keyword}`
} : {
schema: sch[schemaProp],
schemaPath: (0, codegen_1._)`${it.schemaPath}${(0, codegen_1.getProperty)(keyword)}${(0, codegen_1.getProperty)(schemaProp)}`,
errSchemaPath: `${it.errSchemaPath}/${keyword}/${(0, util_1.escapeFragment)(schemaProp)}`
};
}
if (schema !== void 0) {
if (schemaPath === void 0 || errSchemaPath === void 0 || topSchemaRef === void 0) {
throw new Error('"schemaPath", "errSchemaPath" and "topSchemaRef" are required with "schema"');
}
return {
schema,
schemaPath,
topSchemaRef,
errSchemaPath
};
}
throw new Error('either "keyword" or "schema" must be passed');
}
exports.getSubschema = getSubschema;
function extendSubschemaData(subschema, it, { dataProp, dataPropType: dpType, data, dataTypes, propertyName }) {
if (data !== void 0 && dataProp !== void 0) {
throw new Error('both "data" and "dataProp" passed, only one allowed');
}
const { gen } = it;
if (dataProp !== void 0) {
const { errorPath, dataPathArr, opts } = it;
const nextData = gen.let("data", (0, codegen_1._)`${it.data}${(0, codegen_1.getProperty)(dataProp)}`, true);
dataContextProps(nextData);
subschema.errorPath = (0, codegen_1.str)`${errorPath}${(0, util_1.getErrorPath)(dataProp, dpType, opts.jsPropertySyntax)}`;
subschema.parentDataProperty = (0, codegen_1._)`${dataProp}`;
subschema.dataPathArr = [...dataPathArr, subschema.parentDataProperty];
}
if (data !== void 0) {
const nextData = data instanceof codegen_1.Name ? data : gen.let("data", data, true);
dataContextProps(nextData);
if (propertyName !== void 0)
subschema.propertyName = propertyName;
}
if (dataTypes)
subschema.dataTypes = dataTypes;
function dataContextProps(_nextData) {
subschema.data = _nextData;
subschema.dataLevel = it.dataLevel + 1;
subschema.dataTypes = [];
it.definedProperties = /* @__PURE__ */ new Set();
subschema.parentData = it.data;
subschema.dataNames = [...it.dataNames, _nextData];
}
}
exports.extendSubschemaData = extendSubschemaData;
function extendSubschemaMode(subschema, { jtdDiscriminator, jtdMetadata, compositeRule, createErrors, allErrors }) {
if (compositeRule !== void 0)
subschema.compositeRule = compositeRule;
if (createErrors !== void 0)
subschema.createErrors = createErrors;
if (allErrors !== void 0)
subschema.allErrors = allErrors;
subschema.jtdDiscriminator = jtdDiscriminator;
subschema.jtdMetadata = jtdMetadata;
}
exports.extendSubschemaMode = extendSubschemaMode;
}
});
// node_modules/fast-deep-equal/index.js
var require_fast_deep_equal = __commonJS({
"node_modules/fast-deep-equal/index.js"(exports, module) {
"use strict";
module.exports = function equal(a, b) {
if (a === b) return true;
if (a && b && typeof a == "object" && typeof b == "object") {
if (a.constructor !== b.constructor) return false;
var length, i, keys;
if (Array.isArray(a)) {
length = a.length;
if (length != b.length) return false;
for (i = length; i-- !== 0; )
if (!equal(a[i], b[i])) return false;
return true;
}
if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
keys = Object.keys(a);
length = keys.length;
if (length !== Object.keys(b).length) return false;
for (i = length; i-- !== 0; )
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
for (i = length; i-- !== 0; ) {
var key = keys[i];
if (!equal(a[key], b[key])) return false;
}
return true;
}
return a !== a && b !== b;
};
}
});
// node_modules/json-schema-traverse/index.js
var require_json_schema_traverse = __commonJS({
"node_modules/json-schema-traverse/index.js"(exports, module) {
"use strict";
var traverse = module.exports = function(schema, opts, cb) {
if (typeof opts == "function") {
cb = opts;
opts = {};
}
cb = opts.cb || cb;
var pre = typeof cb == "function" ? cb : cb.pre || function() {
};
var post = cb.post || function() {
};
_traverse(opts, pre, post, schema, "", schema);
};
traverse.keywords = {
additionalItems: true,
items: true,
contains: true,
additionalProperties: true,
propertyNames: true,
not: true,
if: true,
then: true,
else: true
};
traverse.arrayKeywords = {
items: true,
allOf: true,
anyOf: true,
oneOf: true
};
traverse.propsKeywords = {
$defs: true,
definitions: true,
properties: true,
patternProperties: true,
dependencies: true
};
traverse.skipKeywords = {
default: true,
enum: true,
const: true,
required: true,
maximum: true,
minimum: true,
exclusiveMaximum: true,
exclusiveMinimum: true,
multipleOf: true,
maxLength: true,
minLength: true,
pattern: true,
format: true,
maxItems: true,
minItems: true,
uniqueItems: true,
maxProperties: true,
minProperties: true
};
function _traverse(opts, pre, post, schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex) {
if (schema && typeof schema == "object" && !Array.isArray(schema)) {
pre(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
for (var key in schema) {
var sch = schema[key];
if (Array.isArray(sch)) {
if (key in traverse.arrayKeywords) {
for (var i = 0; i < sch.length; i++)
_traverse(opts, pre, post, sch[i], jsonPtr + "/" + key + "/" + i, rootSchema, jsonPtr, key, schema, i);
}
} else if (key in traverse.propsKeywords) {
if (sch && typeof sch == "object") {
for (var prop in sch)
_traverse(opts, pre, post, sch[prop], jsonPtr + "/" + key + "/" + escapeJsonPtr(prop), rootSchema, jsonPtr, key, schema, prop);
}
} else if (key in traverse.keywords || opts.allKeys && !(key in traverse.skipKeywords)) {
_traverse(opts, pre, post, sch, jsonPtr + "/" + key, rootSchema, jsonPtr, key, schema);
}
}
post(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex);
}
}
function escapeJsonPtr(str) {
return str.replace(/~/g, "~0").replace(/\//g, "~1");
}
}
});
// node_modules/ajv/dist/compile/resolve.js
var require_resolve = __commonJS({
"node_modules/ajv/dist/compile/resolve.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSchemaRefs = exports.resolveUrl = exports.normalizeId = exports._getFullPath = exports.getFullPath = exports.inlineRef = void 0;
var util_1 = require_util();
var equal = require_fast_deep_equal();
var traverse = require_json_schema_traverse();
var SIMPLE_INLINED = /* @__PURE__ */ new Set([
"type",
"format",
"pattern",
"maxLength",
"minLength",
"maxProperties",
"minProperties",
"maxItems",
"minItems",
"maximum",
"minimum",
"uniqueItems",
"multipleOf",
"required",
"enum",
"const"
]);
function inlineRef(schema, limit = true) {
if (typeof schema == "boolean")
return true;
if (limit === true)
return !hasRef(schema);
if (!limit)
return false;
return countKeys(schema) <= limit;
}
exports.inlineRef = inlineRef;
var REF_KEYWORDS = /* @__PURE__ */ new Set([
"$ref",
"$recursiveRef",
"$recursiveAnchor",
"$dynamicRef",
"$dynamicAnchor"
]);
function hasRef(schema) {
for (const key in schema) {
if (REF_KEYWORDS.has(key))
return true;
const sch = schema[key];
if (Array.isArray(sch) && sch.some(hasRef))
return true;
if (typeof sch == "object" && hasRef(sch))
return true;
}
return false;
}
function countKeys(schema) {
let count = 0;
for (const key in schema) {
if (key === "$ref")
return Infinity;
count++;
if (SIMPLE_INLINED.has(key))
continue;
if (typeof schema[key] == "object") {
(0, util_1.eachItem)(schema[key], (sch) => count += countKeys(sch));
}
if (count === Infinity)
return Infinity;
}
return count;
}
function getFullPath(resolver, id = "", normalize) {
if (normalize !== false)
id = normalizeId(id);
const p = resolver.parse(id);
return _getFullPath(resolver, p);
}
exports.getFullPath = getFullPath;
function _getFullPath(resolver, p) {
const serialized = resolver.serialize(p);
return serialized.split("#")[0] + "#";
}
exports._getFullPath = _getFullPath;
var TRAILING_SLASH_HASH = /#\/?$/;
function normalizeId(id) {
return id ? id.replace(TRAILING_SLASH_HASH, "") : "";
}
exports.normalizeId = normalizeId;
function resolveUrl(resolver, baseId, id) {
id = normalizeId(id);
return resolver.resolve(baseId, id);
}
exports.resolveUrl = resolveUrl;
var ANCHOR = /^[a-z_][-a-z0-9._]*$/i;
function getSchemaRefs(schema, baseId) {
if (typeof schema == "boolean")
return {};
const { schemaId, uriResolver } = this.opts;
const schId = normalizeId(schema[schemaId] || baseId);
const baseIds = { "": schId };
const pathPrefix = getFullPath(uriResolver, schId, false);
const localRefs = {};
const schemaRefs = /* @__PURE__ */ new Set();
traverse(schema, { allKeys: true }, (sch, jsonPtr, _, parentJsonPtr) => {
if (parentJsonPtr === void 0)
return;
const fullPath = pathPrefix + jsonPtr;
let innerBaseId = baseIds[parentJsonPtr];
if (typeof sch[schemaId] == "string")
innerBaseId = addRef.call(this, sch[schemaId]);
addAnchor.call(this, sch.$anchor);
addAnchor.call(this, sch.$dynamicAnchor);
baseIds[jsonPtr] = innerBaseId;
function addRef(ref) {
const _resolve = this.opts.uriResolver.resolve;
ref = normalizeId(innerBaseId ? _resolve(innerBaseId, ref) : ref);
if (schemaRefs.has(ref))
throw ambiguos(ref);
schemaRefs.add(ref);
let schOrRef = this.refs[ref];
if (typeof schOrRef == "string")
schOrRef = this.refs[schOrRef];
if (typeof schOrRef == "object") {
checkAmbiguosRef(sch, schOrRef.schema, ref);
} else if (ref !== normalizeId(fullPath)) {
if (ref[0] === "#") {
checkAmbiguosRef(sch, localRefs[ref], ref);
localRefs[ref] = sch;
} else {
this.refs[ref] = fullPath;
}
}
return ref;
}
function addAnchor(anchor) {
if (typeof anchor == "string") {
if (!ANCHOR.test(anchor))
throw new Error(`invalid anchor "${anchor}"`);
addRef.call(this, `#${anchor}`);
}
}
});
return localRefs;
function checkAmbiguosRef(sch1, sch2, ref) {
if (sch2 !== void 0 && !equal(sch1, sch2))
throw ambiguos(ref);
}
function ambiguos(ref) {
return new Error(`reference "${ref}" resolves to more than one schema`);
}
}
exports.getSchemaRefs = getSchemaRefs;
}
});
// node_modules/ajv/dist/compile/validate/index.js
var require_validate = __commonJS({
"node_modules/ajv/dist/compile/validate/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getData = exports.KeywordCxt = exports.validateFunctionCode = void 0;
var boolSchema_1 = require_boolSchema();
var dataType_1 = require_dataType();
var applicability_1 = require_applicability();
var dataType_2 = require_dataType();
var defaults_1 = require_defaults();
var keyword_1 = require_keyword();
var subschema_1 = require_subschema();
var codegen_1 = require_codegen();
var names_1 = require_names();
var resolve_1 = require_resolve();
var util_1 = require_util();
var errors_1 = require_errors();
function validateFunctionCode(it) {
if (isSchemaObj(it)) {
checkKeywords(it);
if (schemaCxtHasRules(it)) {
topSchemaObjCode(it);
return;
}
}
validateFunction(it, () => (0, boolSchema_1.topBoolOrEmptySchema)(it));
}
exports.validateFunctionCode = validateFunctionCode;
function validateFunction({ gen, validateName, schema, schemaEnv, opts }, body) {
if (opts.code.es5) {
gen.func(validateName, (0, codegen_1._)`${names_1.default.data}, ${names_1.default.valCxt}`, schemaEnv.$async, () => {
gen.code((0, codegen_1._)`"use strict"; ${funcSourceUrl(schema, opts)}`);
destructureValCxtES5(gen, opts);
gen.code(body);
});
} else {
gen.func(validateName, (0, codegen_1._)`${names_1.default.data}, ${destructureValCxt(opts)}`, schemaEnv.$async, () => gen.code(funcSourceUrl(schema, opts)).code(body));
}
}
function destructureValCxt(opts) {
return (0, codegen_1._)`{${names_1.default.instancePath}="", ${names_1.default.parentData}, ${names_1.default.parentDataProperty}, ${names_1.default.rootData}=${names_1.default.data}${opts.dynamicRef ? (0, codegen_1._)`, ${names_1.default.dynamicAnchors}={}` : codegen_1.nil}}={}`;
}
function destructureValCxtES5(gen, opts) {
gen.if(names_1.default.valCxt, () => {
gen.var(names_1.default.instancePath, (0, codegen_1._)`${names_1.default.valCxt}.${names_1.default.instancePath}`);
gen.var(names_1.default.parentData, (0, codegen_1._)`${names_1.default.valCxt}.${names_1.default.parentData}`);
gen.var(names_1.default.parentDataProperty, (0, codegen_1._)`${names_1.default.valCxt}.${names_1.default.parentDataProperty}`);
gen.var(names_1.default.rootData, (0, codegen_1._)`${names_1.default.valCxt}.${names_1.default.rootData}`);
if (opts.dynamicRef)
gen.var(names_1.default.dynamicAnchors, (0, codegen_1._)`${names_1.default.valCxt}.${names_1.default.dynamicAnchors}`);
}, () => {
gen.var(names_1.default.instancePath, (0, codegen_1._)`""`);
gen.var(names_1.default.parentData, (0, codegen_1._)`undefined`);
gen.var(names_1.default.parentDataProperty, (0, codegen_1._)`undefined`);
gen.var(names_1.default.rootData, names_1.default.data);
if (opts.dynamicRef)
gen.var(names_1.default.dynamicAnchors, (0, codegen_1._)`{}`);
});
}
function topSchemaObjCode(it) {
const { schema, opts, gen } = it;
validateFunction(it, () => {
if (opts.$comment && schema.$comment)
commentKeyword(it);
checkNoDefault(it);
gen.let(names_1.default.vErrors, null);
gen.let(names_1.default.errors, 0);
if (opts.unevaluated)
resetEvaluated(it);
typeAndKeywords(it);
returnResults(it);
});
return;
}
function resetEvaluated(it) {
const { gen, validateName } = it;
it.evaluated = gen.const("evaluated", (0, codegen_1._)`${validateName}.evaluated`);
gen.if((0, codegen_1._)`${it.evaluated}.dynamicProps`, () => gen.assign((0, codegen_1._)`${it.evaluated}.props`, (0, codegen_1._)`undefined`));
gen.if((0, codegen_1._)`${it.evaluated}.dynamicItems`, () => gen.assign((0, codegen_1._)`${it.evaluated}.items`, (0, codegen_1._)`undefined`));
}
function funcSourceUrl(schema, opts) {
const schId = typeof schema == "object" && schema[opts.schemaId];
return schId && (opts.code.source || opts.code.process) ? (0, codegen_1._)`/*# sourceURL=${schId} */` : codegen_1.nil;
}
function subschemaCode(it, valid) {
if (isSchemaObj(it)) {
checkKeywords(it);
if (schemaCxtHasRules(it)) {
subSchemaObjCode(it, valid);
return;
}
}
(0, boolSchema_1.boolOrEmptySchema)(it, valid);
}
function schemaCxtHasRules({ schema, self }) {
if (typeof schema == "boolean")
return !schema;
for (const key in schema)
if (self.RULES.all[key])
return true;
return false;
}
function isSchemaObj(it) {
return typeof it.schema != "boolean";
}
function subSchemaObjCode(it, valid) {
const { schema, gen, opts } = it;
if (opts.$comment && schema.$comment)
commentKeyword(it);
updateContext(it);
checkAsyncSchema(it);
const errsCount = gen.const("_errs", names_1.default.errors);
typeAndKeywords(it, errsCount);
gen.var(valid, (0, codegen_1._)`${errsCount} === ${names_1.default.errors}`);
}
function checkKeywords(it) {
(0, util_1.checkUnknownRules)(it);
checkRefsAndKeywords(it);
}
function typeAndKeywords(it, errsCount) {
if (it.opts.jtd)
return schemaKeywords(it, [], false, errsCount);
const types = (0, dataType_1.getSchemaTypes)(it.schema);
const checkedTypes = (0, dataType_1.coerceAndCheckDataType)(it, types);
schemaKeywords(it, types, !checkedTypes, errsCount);
}
function checkRefsAndKeywords(it) {
const { schema, errSchemaPath, opts, self } = it;
if (schema.$ref && opts.ignoreKeywordsWithRef && (0, util_1.schemaHasRulesButRef)(schema, self.RULES)) {
self.logger.warn(`$ref: keywords ignored in schema at path "${errSchemaPath}"`);
}
}
function checkNoDefault(it) {
const { schema, opts } = it;
if (schema.default !== void 0 && opts.useDefaults && opts.strictSchema) {
(0, util_1.checkStrictMode)(it, "default is ignored in the schema root");
}
}
function updateContext(it) {
const schId = it.schema[it.opts.schemaId];
if (schId)
it.baseId = (0, resolve_1.resolveUrl)(it.opts.uriResolver, it.baseId, schId);
}
function checkAsyncSchema(it) {
if (it.schema.$async && !it.schemaEnv.$async)
throw new Error("async schema in sync schema");
}
function commentKeyword({ gen, schemaEnv, schema, errSchemaPath, opts }) {
const msg = schema.$comment;
if (opts.$comment === true) {
gen.code((0, codegen_1._)`${names_1.default.self}.logger.log(${msg})`);
} else if (typeof opts.$comment == "function") {
const schemaPath = (0, codegen_1.str)`${errSchemaPath}/$comment`;
const rootName = gen.scopeValue("root", { ref: schemaEnv.root });
gen.code((0, codegen_1._)`${names_1.default.self}.opts.$comment(${msg}, ${schemaPath}, ${rootName}.schema)`);
}
}
function returnResults(it) {
const { gen, schemaEnv, validateName, ValidationError, opts } = it;
if (schemaEnv.$async) {
gen.if((0, codegen_1._)`${names_1.default.errors} === 0`, () => gen.return(names_1.default.data), () => gen.throw((0, codegen_1._)`new ${ValidationError}(${names_1.default.vErrors})`));
} else {
gen.assign((0, codegen_1._)`${validateName}.errors`, names_1.default.vErrors);
if (opts.unevaluated)
assignEvaluated(it);
gen.return((0, codegen_1._)`${names_1.default.errors} === 0`);
}
}
function assignEvaluated({ gen, evaluated, props, items }) {
if (props instanceof codegen_1.Name)
gen.assign((0, codegen_1._)`${evaluated}.props`, props);
if (items instanceof codegen_1.Name)
gen.assign((0, codegen_1._)`${evaluated}.items`, items);
}
function schemaKeywords(it, types, typeErrors, errsCount) {
const { gen, schema, data, allErrors, opts, self } = it;
const { RULES } = self;
if (schema.$ref && (opts.ignoreKeywordsWithRef || !(0, util_1.schemaHasRulesButRef)(schema, RULES))) {
gen.block(() => keywordCode(it, "$ref", RULES.all.$ref.definition));
return;
}
if (!opts.jtd)
checkStrictTypes(it, types);
gen.block(() => {
for (const group of RULES.rules)
groupKeywords(group);
groupKeywords(RULES.post);
});
function groupKeywords(group) {
if (!(0, applicability_1.shouldUseGroup)(schema, group))
return;
if (group.type) {
gen.if((0, dataType_2.checkDataType)(group.type, data, opts.strictNumbers));
iterateKeywords(it, group);
if (types.length === 1 && types[0] === group.type && typeErrors) {
gen.else();
(0, dataType_2.reportTypeError)(it);
}
gen.endIf();
} else {
iterateKeywords(it, group);
}
if (!allErrors)
gen.if((0, codegen_1._)`${names_1.default.errors} === ${errsCount || 0}`);
}
}
function iterateKeywords(it, group) {
const { gen, schema, opts: { useDefaults } } = it;
if (useDefaults)
(0, defaults_1.assignDefaults)(it, group.type);
gen.block(() => {
for (const rule of group.rules) {
if ((0, applicability_1.shouldUseRule)(schema, rule)) {
keywordCode(it, rule.keyword, rule.definition, group.type);
}
}
});
}
function checkStrictTypes(it, types) {
if (it.schemaEnv.meta || !it.opts.strictTypes)
return;
checkContextTypes(it, types);
if (!it.opts.allowUnionTypes)
checkMultipleTypes(it, types);
checkKeywordTypes(it, it.dataTypes);
}
function checkContextTypes(it, types) {
if (!types.length)
return;
if (!it.dataTypes.length) {
it.dataTypes = types;
return;
}
types.forEach((t) => {
if (!includesType(it.dataTypes, t)) {
strictTypesError(it, `type "${t}" not allowed by context "${it.dataTypes.join(",")}"`);
}
});
narrowSchemaTypes(it, types);
}
function checkMultipleTypes(it, ts) {
if (ts.length > 1 && !(ts.length === 2 && ts.includes("null"))) {
strictTypesError(it, "use allowUnionTypes to allow union type keyword");
}
}
function checkKeywordTypes(it, ts) {
const rules = it.self.RULES.all;
for (const keyword in rules) {
const rule = rules[keyword];
if (typeof rule == "object" && (0, applicability_1.shouldUseRule)(it.schema, rule)) {
const { type } = rule.definition;
if (type.length && !type.some((t) => hasApplicableType(ts, t))) {
strictTypesError(it, `missing type "${type.join(",")}" for keyword "${keyword}"`);
}
}
}
}
function hasApplicableType(schTs, kwdT) {
return schTs.includes(kwdT) || kwdT === "number" && schTs.includes("integer");
}
function includesType(ts, t) {
return ts.includes(t) || t === "integer" && ts.includes("number");
}
function narrowSchemaTypes(it, withTypes) {
const ts = [];
for (const t of it.dataTypes) {
if (includesType(withTypes, t))
ts.push(t);
else if (withTypes.includes("integer") && t === "number")
ts.push("integer");
}
it.dataTypes = ts;
}
function strictTypesError(it, msg) {
const schemaPath = it.schemaEnv.baseId + it.errSchemaPath;
msg += ` at "${schemaPath}" (strictTypes)`;
(0, util_1.checkStrictMode)(it, msg, it.opts.strictTypes);
}
var KeywordCxt = class {
constructor(it, def, keyword) {
(0, keyword_1.validateKeywordUsage)(it, def, keyword);
this.gen = it.gen;
this.allErrors = it.allErrors;
this.keyword = keyword;
this.data = it.data;
this.schema = it.schema[keyword];
this.$data = def.$data && it.opts.$data && this.schema && this.schema.$data;
this.schemaValue = (0, util_1.schemaRefOrVal)(it, this.schema, keyword, this.$data);
this.schemaType = def.schemaType;
this.parentSchema = it.schema;
this.params = {};
this.it = it;
this.def = def;
if (this.$data) {
this.schemaCode = it.gen.const("vSchema", getData(this.$data, it));
} else {
this.schemaCode = this.schemaValue;
if (!(0, keyword_1.validSchemaType)(this.schema, def.schemaType, def.allowUndefined)) {
throw new Error(`${keyword} value must be ${JSON.stringify(def.schemaType)}`);
}
}
if ("code" in def ? def.trackErrors : def.errors !== false) {
this.errsCount = it.gen.const("_errs", names_1.default.errors);
}
}
result(condition, successAction, failAction) {
this.failResult((0, codegen_1.not)(condition), successAction, failAction);
}
failResult(condition, successAction, failAction) {
this.gen.if(condition);
if (failAction)
failAction();
else
this.error();
if (successAction) {
this.gen.else();
successAction();
if (this.allErrors)
this.gen.endIf();
} else {
if (this.allErrors)
this.gen.endIf();
else
this.gen.else();
}
}
pass(condition, failAction) {
this.failResult((0, codegen_1.not)(condition), void 0, failAction);
}
fail(condition) {
if (condition === void 0) {
this.error();
if (!this.allErrors)
this.gen.if(false);
return;
}
this.gen.if(condition);
this.error();
if (this.allErrors)
this.gen.endIf();
else
this.gen.else();
}
fail$data(condition) {
if (!this.$data)
return this.fail(condition);
const { schemaCode } = this;
this.fail((0, codegen_1._)`${schemaCode} !== undefined && (${(0, codegen_1.or)(this.invalid$data(), condition)})`);
}
error(append, errorParams, errorPaths) {
if (errorParams) {
this.setParams(errorParams);
this._error(append, errorPaths);
this.setParams({});
return;
}
this._error(append, errorPaths);
}
_error(append, errorPaths) {
;
(append ? errors_1.reportExtraError : errors_1.reportError)(this, this.def.error, errorPaths);
}
$dataError() {
(0, errors_1.reportError)(this, this.def.$dataError || errors_1.keyword$DataError);
}
reset() {
if (this.errsCount === void 0)
throw new Error('add "trackErrors" to keyword definition');
(0, errors_1.resetErrorsCount)(this.gen, this.errsCount);
}
ok(cond) {
if (!this.allErrors)
this.gen.if(cond);
}
setParams(obj, assign) {
if (assign)
Object.assign(this.params, obj);
else
this.params = obj;
}
block$data(valid, codeBlock, $dataValid = codegen_1.nil) {
this.gen.block(() => {
this.check$data(valid, $dataValid);
codeBlock();
});
}
check$data(valid = codegen_1.nil, $dataValid = codegen_1.nil) {
if (!this.$data)
return;
const { gen, schemaCode, schemaType, def } = this;
gen.if((0, codegen_1.or)((0, codegen_1._)`${schemaCode} === undefined`, $dataValid));
if (valid !== codegen_1.nil)
gen.assign(valid, true);
if (schemaType.length || def.validateSchema) {
gen.elseIf(this.invalid$data());
this.$dataError();
if (valid !== codegen_1.nil)
gen.assign(valid, false);
}
gen.else();
}
invalid$data() {
const { gen, schemaCode, schemaType, def, it } = this;
return (0, codegen_1.or)(wrong$DataType(), invalid$DataSchema());
function wrong$DataType() {
if (schemaType.length) {
if (!(schemaCode instanceof codegen_1.Name))
throw new Error("ajv implementation error");
const st = Array.isArray(schemaType) ? schemaType : [schemaType];
return (0, codegen_1._)`${(0, dataType_2.checkDataTypes)(st, schemaCode, it.opts.strictNumbers, dataType_2.DataType.Wrong)}`;
}
return codegen_1.nil;
}
function invalid$DataSchema() {
if (def.validateSchema) {
const validateSchemaRef = gen.scopeValue("validate$data", { ref: def.validateSchema });
return (0, codegen_1._)`!${validateSchemaRef}(${schemaCode})`;
}
return codegen_1.nil;
}
}
subschema(appl, valid) {
const subschema = (0, subschema_1.getSubschema)(this.it, appl);
(0, subschema_1.extendSubschemaData)(subschema, this.it, appl);
(0, subschema_1.extendSubschemaMode)(subschema, appl);
const nextContext = { ...this.it, ...subschema, items: void 0, props: void 0 };
subschemaCode(nextContext, valid);
return nextContext;
}
mergeEvaluated(schemaCxt, toName) {
const { it, gen } = this;
if (!it.opts.unevaluated)
return;
if (it.props !== true && schemaCxt.props !== void 0) {
it.props = util_1.mergeEvaluated.props(gen, schemaCxt.props, it.props, toName);
}
if (it.items !== true && schemaCxt.items !== void 0) {
it.items = util_1.mergeEvaluated.items(gen, schemaCxt.items, it.items, toName);
}
}
mergeValidEvaluated(schemaCxt, valid) {
const { it, gen } = this;
if (it.opts.unevaluated && (it.props !== true || it.items !== true)) {
gen.if(valid, () => this.mergeEvaluated(schemaCxt, codegen_1.Name));
return true;
}
}
};
exports.KeywordCxt = KeywordCxt;
function keywordCode(it, keyword, def, ruleType) {
const cxt = new KeywordCxt(it, def, keyword);
if ("code" in def) {
def.code(cxt, ruleType);
} else if (cxt.$data && def.validate) {
(0, keyword_1.funcKeywordCode)(cxt, def);
} else if ("macro" in def) {
(0, keyword_1.macroKeywordCode)(cxt, def);
} else if (def.compile || def.validate) {
(0, keyword_1.funcKeywordCode)(cxt, def);
}
}
var JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/;
var RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;
function getData($data, { dataLevel, dataNames, dataPathArr }) {
let jsonPointer;
let data;
if ($data === "")
return names_1.default.rootData;
if ($data[0] === "/") {
if (!JSON_POINTER.test($data))
throw new Error(`Invalid JSON-pointer: ${$data}`);
jsonPointer = $data;
data = names_1.default.rootData;
} else {
const matches = RELATIVE_JSON_POINTER.exec($data);
if (!matches)
throw new Error(`Invalid JSON-pointer: ${$data}`);
const up = +matches[1];
jsonPointer = matches[2];
if (jsonPointer === "#") {
if (up >= dataLevel)
throw new Error(errorMsg("property/index", up));
return dataPathArr[dataLevel - up];
}
if (up > dataLevel)
throw new Error(errorMsg("data", up));
data = dataNames[dataLevel - up];
if (!jsonPointer)
return data;
}
let expr = data;
const segments = jsonPointer.split("/");
for (const segment of segments) {
if (segment) {
data = (0, codegen_1._)`${data}${(0, codegen_1.getProperty)((0, util_1.unescapeJsonPointer)(segment))}`;
expr = (0, codegen_1._)`${expr} && ${data}`;
}
}
return expr;
function errorMsg(pointerType, up) {
return `Cannot access ${pointerType} ${up} levels up, current level is ${dataLevel}`;
}
}
exports.getData = getData;
}
});
// node_modules/ajv/dist/runtime/validation_error.js
var require_validation_error = __commonJS({
"node_modules/ajv/dist/runtime/validation_error.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ValidationError = class extends Error {
constructor(errors) {
super("validation failed");
this.errors = errors;
this.ajv = this.validation = true;
}
};
exports.default = ValidationError;
}
});
// node_modules/ajv/dist/compile/ref_error.js
var require_ref_error = __commonJS({
"node_modules/ajv/dist/compile/ref_error.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var resolve_1 = require_resolve();
var MissingRefError = class extends Error {
constructor(resolver, baseId, ref, msg) {
super(msg || `can't resolve reference ${ref} from id ${baseId}`);
this.missingRef = (0, resolve_1.resolveUrl)(resolver, baseId, ref);
this.missingSchema = (0, resolve_1.normalizeId)((0, resolve_1.getFullPath)(resolver, this.missingRef));
}
};
exports.default = MissingRefError;
}
});
// node_modules/ajv/dist/compile/index.js
var require_compile = __commonJS({
"node_modules/ajv/dist/compile/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveSchema = exports.getCompilingSchema = exports.resolveRef = exports.compileSchema = exports.SchemaEnv = void 0;
var codegen_1 = require_codegen();
var validation_error_1 = require_validation_error();
var names_1 = require_names();
var resolve_1 = require_resolve();
var util_1 = require_util();
var validate_1 = require_validate();
var SchemaEnv = class {
constructor(env) {
var _a;
this.refs = {};
this.dynamicAnchors = {};
let schema;
if (typeof env.schema == "object")
schema = env.schema;
this.schema = env.schema;
this.schemaId = env.schemaId;
this.root = env.root || this;
this.baseId = (_a = env.baseId) !== null && _a !== void 0 ? _a : (0, resolve_1.normalizeId)(schema === null || schema === void 0 ? void 0 : schema[env.schemaId || "$id"]);
this.schemaPath = env.schemaPath;
this.localRefs = env.localRefs;
this.meta = env.meta;
this.$async = schema === null || schema === void 0 ? void 0 : schema.$async;
this.refs = {};
}
};
exports.SchemaEnv = SchemaEnv;
function compileSchema(sch) {
const _sch = getCompilingSchema.call(this, sch);
if (_sch)
return _sch;
const rootId = (0, resolve_1.getFullPath)(this.opts.uriResolver, sch.root.baseId);
const { es5, lines } = this.opts.code;
const { ownProperties } = this.opts;
const gen = new codegen_1.CodeGen(this.scope, { es5, lines, ownProperties });
let _ValidationError;
if (sch.$async) {
_ValidationError = gen.scopeValue("Error", {
ref: validation_error_1.default,
code: (0, codegen_1._)`require("ajv/dist/runtime/validation_error").default`
});
}
const validateName = gen.scopeName("validate");
sch.validateName = validateName;
const schemaCxt = {
gen,
allErrors: this.opts.allErrors,
data: names_1.default.data,
parentData: names_1.default.parentData,
parentDataProperty: names_1.default.parentDataProperty,
dataNames: [names_1.default.data],
dataPathArr: [codegen_1.nil],
// TODO can its length be used as dataLevel if nil is removed?
dataLevel: 0,
dataTypes: [],
definedProperties: /* @__PURE__ */ new Set(),
topSchemaRef: gen.scopeValue("schema", this.opts.code.source === true ? { ref: sch.schema, code: (0, codegen_1.stringify)(sch.schema) } : { ref: sch.schema }),
validateName,
ValidationError: _ValidationError,
schema: sch.schema,
schemaEnv: sch,
rootId,
baseId: sch.baseId || rootId,
schemaPath: codegen_1.nil,
errSchemaPath: sch.schemaPath || (this.opts.jtd ? "" : "#"),
errorPath: (0, codegen_1._)`""`,
opts: this.opts,
self: this
};
let sourceCode;
try {
this._compilations.add(sch);
(0, validate_1.validateFunctionCode)(schemaCxt);
gen.optimize(this.opts.code.optimize);
const validateCode = gen.toString();
sourceCode = `${gen.scopeRefs(names_1.default.scope)}return ${validateCode}`;
if (this.opts.code.process)
sourceCode = this.opts.code.process(sourceCode, sch);
const makeValidate = new Function(`${names_1.default.self}`, `${names_1.default.scope}`, sourceCode);
const validate = makeValidate(this, this.scope.get());
this.scope.value(validateName, { ref: validate });
validate.errors = null;
validate.schema = sch.schema;
validate.schemaEnv = sch;
if (sch.$async)
validate.$async = true;
if (this.opts.code.source === true) {
validate.source = { validateName, validateCode, scopeValues: gen._values };
}
if (this.opts.unevaluated) {
const { props, items } = schemaCxt;
validate.evaluated = {
props: props instanceof codegen_1.Name ? void 0 : props,
items: items instanceof codegen_1.Name ? void 0 : items,
dynamicProps: props instanceof codegen_1.Name,
dynamicItems: items instanceof codegen_1.Name
};
if (validate.source)
validate.source.evaluated = (0, codegen_1.stringify)(validate.evaluated);
}
sch.validate = validate;
return sch;
} catch (e) {
delete sch.validate;
delete sch.validateName;
if (sourceCode)
this.logger.error("Error compiling schema, function code:", sourceCode);
throw e;
} finally {
this._compilations.delete(sch);
}
}
exports.compileSchema = compileSchema;
function resolveRef(root, baseId, ref) {
var _a;
ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
const schOrFunc = root.refs[ref];
if (schOrFunc)
return schOrFunc;
let _sch = resolve9.call(this, root, ref);
if (_sch === void 0) {
const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
const { schemaId } = this.opts;
if (schema)
_sch = new SchemaEnv({ schema, schemaId, root, baseId });
}
if (_sch === void 0)
return;
return root.refs[ref] = inlineOrCompile.call(this, _sch);
}
exports.resolveRef = resolveRef;
function inlineOrCompile(sch) {
if ((0, resolve_1.inlineRef)(sch.schema, this.opts.inlineRefs))
return sch.schema;
return sch.validate ? sch : compileSchema.call(this, sch);
}
function getCompilingSchema(schEnv) {
for (const sch of this._compilations) {
if (sameSchemaEnv(sch, schEnv))
return sch;
}
}
exports.getCompilingSchema = getCompilingSchema;
function sameSchemaEnv(s1, s2) {
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
}
function resolve9(root, ref) {
let sch;
while (typeof (sch = this.refs[ref]) == "string")
ref = sch;
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
}
function resolveSchema(root, ref) {
const p = this.opts.uriResolver.parse(ref);
const refPath = (0, resolve_1._getFullPath)(this.opts.uriResolver, p);
let baseId = (0, resolve_1.getFullPath)(this.opts.uriResolver, root.baseId, void 0);
if (Object.keys(root.schema).length > 0 && refPath === baseId) {
return getJsonPointer.call(this, p, root);
}
const id = (0, resolve_1.normalizeId)(refPath);
const schOrRef = this.refs[id] || this.schemas[id];
if (typeof schOrRef == "string") {
const sch = resolveSchema.call(this, root, schOrRef);
if (typeof (sch === null || sch === void 0 ? void 0 : sch.schema) !== "object")
return;
return getJsonPointer.call(this, p, sch);
}
if (typeof (schOrRef === null || schOrRef === void 0 ? void 0 : schOrRef.schema) !== "object")
return;
if (!schOrRef.validate)
compileSchema.call(this, schOrRef);
if (id === (0, resolve_1.normalizeId)(ref)) {
const { schema } = schOrRef;
const { schemaId } = this.opts;
const schId = schema[schemaId];
if (schId)
baseId = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, schId);
return new SchemaEnv({ schema, schemaId, root, baseId });
}
return getJsonPointer.call(this, p, schOrRef);
}
exports.resolveSchema = resolveSchema;
var PREVENT_SCOPE_CHANGE = /* @__PURE__ */ new Set([
"properties",
"patternProperties",
"enum",
"dependencies",
"definitions"
]);
function getJsonPointer(parsedRef, { baseId, schema, root }) {
var _a;
if (((_a = parsedRef.fragment) === null || _a === void 0 ? void 0 : _a[0]) !== "/")
return;
for (const part of parsedRef.fragment.slice(1).split("/")) {
if (typeof schema === "boolean")
return;
const partSchema = schema[(0, util_1.unescapeFragment)(part)];
if (partSchema === void 0)
return;
schema = partSchema;
const schId = typeof schema === "object" && schema[this.opts.schemaId];
if (!PREVENT_SCOPE_CHANGE.has(part) && schId) {
baseId = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, schId);
}
}
let env;
if (typeof schema != "boolean" && schema.$ref && !(0, util_1.schemaHasRulesButRef)(schema, this.RULES)) {
const $ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, schema.$ref);
env = resolveSchema.call(this, root, $ref);
}
const { schemaId } = this.opts;
env = env || new SchemaEnv({ schema, schemaId, root, baseId });
if (env.schema !== env.root.schema)
return env;
return void 0;
}
}
});
// node_modules/ajv/dist/refs/data.json
var require_data = __commonJS({
"node_modules/ajv/dist/refs/data.json"(exports, module) {
module.exports = {
$id: "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#",
description: "Meta-schema for $data reference (JSON AnySchema extension proposal)",
type: "object",
required: ["$data"],
properties: {
$data: {
type: "string",
anyOf: [{ format: "relative-json-pointer" }, { format: "json-pointer" }]
}
},
additionalProperties: false
};
}
});
// node_modules/fast-uri/lib/utils.js
var require_utils = __commonJS({
"node_modules/fast-uri/lib/utils.js"(exports, module) {
"use strict";
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u);
var isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u);
var BYTE_HEX = new Array(256);
{
const HEX_DIGITS = "0123456789ABCDEF";
for (let i = 0; i < 256; i++) {
BYTE_HEX[i] = "%" + HEX_DIGITS[i >> 4] + HEX_DIGITS[i & 15];
}
}
function percentEncodeNonAscii(cp) {
if (cp < 2048) {
return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
}
if (cp < 65536) {
return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
}
return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
}
function stringArrayToHexStripped(input) {
let acc = "";
let code = 0;
let i = 0;
for (i = 0; i < input.length; i++) {
code = input[i].charCodeAt(0);
if (code === 48) {
continue;
}
if (!(code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102)) {
return "";
}
acc += input[i];
break;
}
for (i += 1; i < input.length; i++) {
code = input[i].charCodeAt(0);
if (!(code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102)) {
return "";
}
acc += input[i];
}
return acc;
}
var isHextet = RegExp.prototype.test.bind(/^[\dA-Fa-f]{1,4}$/);
var isIPvFuture = RegExp.prototype.test.bind(/^[vV][\dA-Fa-f]+\.[A-Za-z\d\-._~!$&'()*+,;=:]+$/);
var isZoneCharacter = RegExp.prototype.test.bind(/^[A-Za-z\d\-._~]$/);
var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
function isZoneIdentifier(zone) {
if (zone.length === 0) return false;
for (let i = 0; i < zone.length; i++) {
if (isZoneCharacter(zone[i])) continue;
if (zone[i] === "%" && i + 2 < zone.length && isHexPair(zone.slice(i + 1, i + 3))) {
i += 2;
continue;
}
return false;
}
return true;
}
function compressIPv6ZeroRun(hextets) {
let bestStart = -1;
let bestLength = 0;
let runStart = -1;
let runLength = 0;
for (let i = 0; i < hextets.length; i++) {
if (hextets[i] === "0") {
if (runStart === -1) runStart = i;
runLength++;
if (runLength > bestLength) {
bestLength = runLength;
bestStart = runStart;
}
} else {
runStart = -1;
runLength = 0;
}
}
if (bestLength < 2) return hextets.join(":");
const head = hextets.slice(0, bestStart).join(":");
const tail = hextets.slice(bestStart + bestLength).join(":");
return head + "::" + tail;
}
function normalizeIPv6Address(input) {
const compression = input.indexOf("::");
if (compression !== -1 && input.indexOf("::", compression + 1) !== -1) return void 0;
const left = compression === -1 ? input.split(":") : input.slice(0, compression).split(":");
const right = compression === -1 ? [] : input.slice(compression + 2).split(":");
if (compression !== -1) {
if (left.length === 1 && left[0] === "") left.length = 0;
if (right.length === 1 && right[0] === "") right.length = 0;
}
const parts = left.concat(right);
let hextetCount = 0;
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (part === "") return void 0;
if (part.indexOf(".") !== -1) {
if (i !== parts.length - 1 || compression !== -1 && right.length === 0 || !isIPv4(part)) return void 0;
hextetCount += 2;
continue;
}
if (!isHextet(part)) return void 0;
parts[i] = parseInt(part, 16).toString(16);
hextetCount++;
}
if (compression === -1) {
if (hextetCount !== 8) return void 0;
return compressIPv6ZeroRun(parts);
}
if (hextetCount >= 8) return void 0;
const expanded = parts.slice(0, left.length);
for (let i = hextetCount; i < 8; i++) expanded.push("0");
for (let i = left.length; i < parts.length; i++) expanded.push(parts[i]);
return compressIPv6ZeroRun(expanded);
}
function normalizeIPv6(host2) {
const bracketed = host2[0] === "[" && host2[host2.length - 1] === "]";
const hasBracket = host2[0] === "[" || host2[host2.length - 1] === "]";
if (hasBracket && !bracketed) return { host: host2, isIPV6: false, error: true };
let input = bracketed ? host2.slice(1, -1) : host2;
if (bracketed && isIPvFuture(input)) {
input = input.toLowerCase();
return { host: `[${input}]`, escapedHost: input, isIPV6: false, isIPVFuture: true };
}
if (findToken(input, ":") < 2) {
return { host: host2, isIPV6: false, error: bracketed };
}
let zoneIdentifier = "";
const zoneSeparator = input.indexOf("%");
if (zoneSeparator !== -1) {
const separatorLength = input.slice(zoneSeparator, zoneSeparator + 3).toLowerCase() === "%25" ? 3 : 1;
zoneIdentifier = input.slice(zoneSeparator + separatorLength);
if (!isZoneIdentifier(zoneIdentifier)) return { host: host2, isIPV6: false, error: true };
input = input.slice(0, zoneSeparator);
}
const address2 = normalizeIPv6Address(input);
if (address2 === void 0) return { host: host2, isIPV6: false, error: true };
return {
host: address2 + (zoneIdentifier ? "%" + zoneIdentifier : ""),
escapedHost: address2 + (zoneIdentifier ? "%25" + zoneIdentifier : ""),
isIPV6: true
};
}
function findToken(str, token) {
let ind = 0;
for (let i = 0; i < str.length; i++) {
if (str[i] === token) ind++;
}
return ind;
}
function removeDotSegments(path) {
let input = path;
const output = [];
let nextSlash = -1;
let len = 0;
while (len = input.length) {
if (len === 1) {
if (input === ".") {
break;
} else if (input === "/") {
output.push("/");
break;
} else {
output.push(input);
break;
}
} else if (len === 2) {
if (input[0] === ".") {
if (input[1] === ".") {
break;
} else if (input[1] === "/") {
input = input.slice(2);
continue;
}
} else if (input[0] === "/") {
if (input[1] === "." || input[1] === "/") {
output.push("/");
break;
}
}
} else if (len === 3) {
if (input === "/..") {
if (output.length !== 0) {
output.pop();
}
output.push("/");
break;
}
}
if (input[0] === ".") {
if (input[1] === ".") {
if (input[2] === "/") {
input = input.slice(3);
continue;
}
} else if (input[1] === "/") {
input = input.slice(2);
continue;
}
} else if (input[0] === "/") {
if (input[1] === ".") {
if (input[2] === "/") {
input = input.slice(2);
continue;
} else if (input[2] === ".") {
if (input[3] === "/") {
input = input.slice(3);
if (output.length !== 0) {
output.pop();
}
continue;
}
}
}
}
if ((nextSlash = input.indexOf("/", 1)) === -1) {
output.push(input);
break;
} else {
output.push(input.slice(0, nextSlash));
input = input.slice(nextSlash);
}
}
return output.join("");
}
var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
var HOST_DELIM_RE = /[@/?#:]/g;
var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
function reescapeHostDelimiters(host2, isIP2) {
const re = isIP2 ? HOST_DELIM_NO_COLON_RE : HOST_DELIM_RE;
re.lastIndex = 0;
return host2.replace(re, (ch) => HOST_DELIMS[ch]);
}
function normalizePercentEncoding(input, decodeUnreserved = false) {
if (input.indexOf("%") === -1) {
return input;
}
let output = "";
for (let i = 0; i < input.length; i++) {
if (input[i] === "%" && i + 2 < input.length) {
const hex = input.slice(i + 1, i + 3);
if (isHexPair(hex)) {
const normalizedHex = hex.toUpperCase();
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
if (decodeUnreserved && isUnreserved(decoded)) {
output += decoded;
} else {
output += "%" + normalizedHex;
}
i += 2;
continue;
}
}
output += input[i];
}
return output;
}
function normalizePathEncoding(input) {
let output = "";
for (let i = 0; i < input.length; i++) {
const ch = input[i];
if (ch === "%" && i + 2 < input.length) {
const hex = input.slice(i + 1, i + 3);
if (isHexPair(hex)) {
const normalizedHex = hex.toUpperCase();
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
if (decoded !== "." && isUnreserved(decoded)) {
output += decoded;
} else {
output += "%" + normalizedHex;
}
i += 2;
continue;
}
}
if (isPathCharacter(ch)) {
output += ch;
} else {
const code = input.charCodeAt(i);
if (code < 128) {
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
} else if (code < 55296 || code > 57343) {
output += percentEncodeNonAscii(code);
} else if (code <= 56319 && i + 1 < input.length) {
const low = input.charCodeAt(i + 1);
if (low >= 56320 && low <= 57343) {
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
i++;
} else {
output += percentEncodeNonAscii(65533);
}
} else {
output += percentEncodeNonAscii(65533);
}
}
}
return output;
}
function serializePathEncoding(input, pathNoScheme = false) {
let output = "";
let firstSegment = pathNoScheme && input[0] !== "/";
for (let i = 0; i < input.length; i++) {
const ch = input[i];
if (ch === "%" && i + 2 < input.length) {
const hex = input.slice(i + 1, i + 3);
if (isHexPair(hex)) {
output += "%" + hex.toUpperCase();
i += 2;
continue;
}
}
if (ch === "/") {
firstSegment = false;
}
if (isPathCharacter(ch) && (ch !== ":" || !firstSegment)) {
output += ch;
} else {
const code = input.charCodeAt(i);
if (code < 128) {
output += BYTE_HEX[code];
} else if (code < 55296 || code > 57343) {
output += percentEncodeNonAscii(code);
} else if (code <= 56319 && i + 1 < input.length) {
const low = input.charCodeAt(i + 1);
if (low >= 56320 && low <= 57343) {
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
i++;
} else {
output += percentEncodeNonAscii(65533);
}
} else {
output += percentEncodeNonAscii(65533);
}
}
}
return output;
}
function encodeComponent(input, isAllowed) {
let output = "";
for (let i = 0; i < input.length; i++) {
const ch = input[i];
if (ch === "%" && i + 2 < input.length) {
const hex = input.slice(i + 1, i + 3);
if (isHexPair(hex)) {
output += "%" + hex.toUpperCase();
i += 2;
continue;
}
}
if (isAllowed(ch)) {
output += ch;
} else {
const code = input.charCodeAt(i);
if (code < 128) {
output += BYTE_HEX[code];
} else if (code < 55296 || code > 57343) {
output += percentEncodeNonAscii(code);
} else if (code <= 56319 && i + 1 < input.length) {
const low = input.charCodeAt(i + 1);
if (low >= 56320 && low <= 57343) {
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
i++;
} else {
output += percentEncodeNonAscii(65533);
}
} else {
output += percentEncodeNonAscii(65533);
}
}
}
return output;
}
function encodeUserinfo(input) {
return encodeComponent(input, isUserinfoCharacter);
}
function encodeQuery(input) {
return encodeComponent(input, isQueryFragmentCharacter);
}
function encodeFragment(input) {
return encodeComponent(input, isQueryFragmentCharacter);
}
function isEscapeSafe(cp) {
return cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 42 || cp === 43 || cp === 45 || cp === 46 || cp === 47 || cp === 64 || cp === 95;
}
function normalizeQueryFragmentEncoding(input) {
let output = "";
for (let i = 0; i < input.length; i++) {
const ch = input[i];
if (ch === "%" && i + 2 < input.length) {
const hex = input.slice(i + 1, i + 3);
if (isHexPair(hex)) {
const normalizedHex = hex.toUpperCase();
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
if (isUnreserved(decoded)) {
output += decoded;
} else {
output += "%" + normalizedHex;
}
i += 2;
continue;
}
}
if (isQueryFragmentCharacter(ch)) {
output += ch;
} else {
const code = input.charCodeAt(i);
if (code < 128) {
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
} else if (code < 55296 || code > 57343) {
output += percentEncodeNonAscii(code);
} else if (code <= 56319 && i + 1 < input.length) {
const low = input.charCodeAt(i + 1);
if (low >= 56320 && low <= 57343) {
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
i++;
} else {
output += percentEncodeNonAscii(65533);
}
} else {
output += percentEncodeNonAscii(65533);
}
}
}
return output;
}
function escapePreservingEscapes(input) {
let output = "";
for (let i = 0; i < input.length; i++) {
if (input[i] === "%" && i + 2 < input.length) {
const hex = input.slice(i + 1, i + 3);
if (isHexPair(hex)) {
output += "%" + hex.toUpperCase();
i += 2;
continue;
}
}
output += escape(input[i]);
}
return output;
}
function recomposeAuthority(component) {
const uriTokens = [];
if (component.userinfo !== void 0) {
uriTokens.push(encodeUserinfo(component.userinfo));
uriTokens.push("@");
}
if (component.host !== void 0) {
let host2 = component.host;
if (!isIPv4(host2)) {
let ipV6res = normalizeIPv6(host2);
if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
host2 = normalizePercentEncoding(host2, true);
ipV6res = normalizeIPv6(host2);
}
if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
host2 = `[${ipV6res.escapedHost}]`;
} else {
host2 = reescapeHostDelimiters(host2, false);
}
}
uriTokens.push(host2);
}
if (typeof component.port === "number" || typeof component.port === "string") {
uriTokens.push(":");
uriTokens.push(String(component.port));
}
return uriTokens.length ? uriTokens.join("") : void 0;
}
module.exports = {
nonSimpleDomain,
recomposeAuthority,
reescapeHostDelimiters,
normalizePercentEncoding,
normalizePathEncoding,
serializePathEncoding,
normalizeQueryFragmentEncoding,
encodeUserinfo,
encodeQuery,
encodeFragment,
escapePreservingEscapes,
removeDotSegments,
isIPv4,
isUUID,
normalizeIPv6,
stringArrayToHexStripped
};
}
});
// node_modules/fast-uri/lib/schemes.js
var require_schemes = __commonJS({
"node_modules/fast-uri/lib/schemes.js"(exports, module) {
"use strict";
var { isUUID } = require_utils();
var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
var supportedSchemeNames = (
/** @type {const} */
[
"http",
"https",
"ws",
"wss",
"urn",
"urn:uuid"
]
);
function isValidSchemeName(name) {
return supportedSchemeNames.indexOf(
/** @type {*} */
name
) !== -1;
}
function wsIsSecure(wsComponent) {
if (wsComponent.secure === true) {
return true;
} else if (wsComponent.secure === false) {
return false;
} else if (wsComponent.scheme) {
return wsComponent.scheme.length === 3 && (wsComponent.scheme[0] === "w" || wsComponent.scheme[0] === "W") && (wsComponent.scheme[1] === "s" || wsComponent.scheme[1] === "S") && (wsComponent.scheme[2] === "s" || wsComponent.scheme[2] === "S");
} else {
return false;
}
}
function httpParse(component) {
if (!component.host) {
component.error = component.error || "HTTP URIs must have a host.";
}
return component;
}
function httpSerialize(component) {
const secure = String(component.scheme).toLowerCase() === "https";
if (component.port === (secure ? 443 : 80) || component.port === "") {
component.port = void 0;
}
if (!component.path) {
component.path = "/";
}
return component;
}
function wsParse(wsComponent) {
wsComponent.secure = wsIsSecure(wsComponent);
wsComponent.resourceName = (wsComponent.path || "/") + (wsComponent.query ? "?" + wsComponent.query : "");
wsComponent.path = void 0;
wsComponent.query = void 0;
return wsComponent;
}
function wsSerialize(wsComponent) {
if (wsComponent.port === (wsIsSecure(wsComponent) ? 443 : 80) || wsComponent.port === "") {
wsComponent.port = void 0;
}
if (typeof wsComponent.secure === "boolean") {
wsComponent.scheme = wsComponent.secure ? "wss" : "ws";
wsComponent.secure = void 0;
}
if (wsComponent.resourceName) {
const queryIndex = wsComponent.resourceName.indexOf("?");
const path = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
wsComponent.path = path && path !== "/" ? path : void 0;
wsComponent.query = queryIndex === -1 ? void 0 : wsComponent.resourceName.slice(queryIndex + 1);
wsComponent.resourceName = void 0;
}
wsComponent.fragment = void 0;
return wsComponent;
}
function urnParse(urnComponent, options) {
if (!urnComponent.path) {
urnComponent.error = "URN can not be parsed";
return urnComponent;
}
const matches = urnComponent.path.match(URN_REG);
if (matches && matches[0] === urnComponent.path) {
const scheme = options.scheme || urnComponent.scheme || "urn";
urnComponent.nid = matches[1].toLowerCase();
urnComponent.nss = matches[2];
const urnScheme = `${scheme}:${options.nid || urnComponent.nid}`;
const schemeHandler = getSchemeHandler(urnScheme);
urnComponent.path = void 0;
if (schemeHandler) {
urnComponent = schemeHandler.parse(urnComponent, options);
}
} else {
urnComponent.error = urnComponent.error || "URN can not be parsed.";
}
return urnComponent;
}
function urnSerialize(urnComponent, options) {
if (urnComponent.nid === void 0) {
throw new Error("URN without nid cannot be serialized");
}
const scheme = options.scheme || urnComponent.scheme || "urn";
const nid = urnComponent.nid.toLowerCase();
const urnScheme = `${scheme}:${options.nid || nid}`;
const schemeHandler = getSchemeHandler(urnScheme);
if (schemeHandler) {
urnComponent = schemeHandler.serialize(urnComponent, options);
}
const uriComponent = urnComponent;
const nss = urnComponent.nss;
uriComponent.path = `${nid || options.nid}:${nss}`;
options.skipEscape = true;
return uriComponent;
}
function urnuuidParse(urnComponent, options) {
const uuidComponent = urnComponent;
uuidComponent.uuid = uuidComponent.nss;
uuidComponent.nss = void 0;
if (!options.tolerant && (!uuidComponent.uuid || !isUUID(uuidComponent.uuid))) {
uuidComponent.error = uuidComponent.error || "UUID is not valid.";
}
return uuidComponent;
}
function urnuuidSerialize(uuidComponent) {
const urnComponent = uuidComponent;
urnComponent.nss = (uuidComponent.uuid || "").toLowerCase();
return urnComponent;
}
var http = (
/** @type {SchemeHandler} */
{
scheme: "http",
domainHost: true,
parse: httpParse,
serialize: httpSerialize
}
);
var https = (
/** @type {SchemeHandler} */
{
scheme: "https",
domainHost: http.domainHost,
parse: httpParse,
serialize: httpSerialize
}
);
var ws = (
/** @type {SchemeHandler} */
{
scheme: "ws",
domainHost: true,
parse: wsParse,
serialize: wsSerialize
}
);
var wss = (
/** @type {SchemeHandler} */
{
scheme: "wss",
domainHost: ws.domainHost,
parse: ws.parse,
serialize: ws.serialize
}
);
var urn = (
/** @type {SchemeHandler} */
{
scheme: "urn",
parse: urnParse,
serialize: urnSerialize,
skipNormalize: true
}
);
var urnuuid = (
/** @type {SchemeHandler} */
{
scheme: "urn:uuid",
parse: urnuuidParse,
serialize: urnuuidSerialize,
skipNormalize: true
}
);
var SCHEMES = (
/** @type {Record<SchemeName, SchemeHandler>} */
{
http,
https,
ws,
wss,
urn,
"urn:uuid": urnuuid
}
);
Object.setPrototypeOf(SCHEMES, null);
function getSchemeHandler(scheme) {
return scheme && (SCHEMES[
/** @type {SchemeName} */
scheme
] || SCHEMES[
/** @type {SchemeName} */
scheme.toLowerCase()
]) || void 0;
}
module.exports = {
wsIsSecure,
SCHEMES,
isValidSchemeName,
getSchemeHandler
};
}
});
// node_modules/fast-uri/index.js
var require_fast_uri = __commonJS({
"node_modules/fast-uri/index.js"(exports, module) {
"use strict";
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
var { SCHEMES, getSchemeHandler } = require_schemes();
var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
function decodeValidScheme(scheme) {
const decodedScheme = unescape(String(scheme));
if (!VALID_SCHEME.test(decodedScheme)) {
throw new TypeError(MALFORMED_SCHEME_ERROR);
}
return decodedScheme;
}
function normalize(uri, options) {
if (typeof uri === "string") {
uri = /** @type {T} */
normalizeString(uri, options);
} else if (typeof uri === "object") {
uri = /** @type {T} */
parse4(serialize(uri, options), options);
}
return uri;
}
function resolve9(baseURI, relativeURI, options) {
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
const {
parsed: baseParsed,
malformedAuthorityOrPort: baseMalformed,
malformedPercentEncoding: baseMalformedPercentEncoding,
malformedSchemeSpecific: baseMalformedSchemeSpecific,
malformedHost: baseMalformedHost,
malformedScheme: baseMalformedScheme
} = parseWithStatus(baseURI, schemelessOptions);
const {
parsed: relativeParsed,
malformedAuthorityOrPort: relativeMalformed,
malformedPercentEncoding: relativeMalformedPercentEncoding,
malformedSchemeSpecific: relativeMalformedSchemeSpecific,
malformedHost: relativeMalformedHost,
malformedScheme: relativeMalformedScheme
} = parseWithStatus(relativeURI, schemelessOptions);
if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) {
throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
}
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
const resolvedHost = resolved.host;
const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !new RegExp("\\P{ASCII}", "u").test(resolvedHost);
if (resolved.error && !encodedASCIIHost) {
throw new Error(resolved.error);
}
schemelessOptions.skipEscape = true;
return serialize(resolved, schemelessOptions);
}
function resolveComponent(base, relative3, options, skipNormalization) {
const target = {};
if (!skipNormalization) {
base = parse4(serialize(base, options), options);
relative3 = parse4(serialize(relative3, options), options);
}
options = options || {};
if (!options.tolerant && relative3.scheme) {
target.scheme = relative3.scheme;
target.userinfo = relative3.userinfo;
target.host = relative3.host;
target.port = relative3.port;
target.path = removeDotSegments(relative3.path || "");
target.query = relative3.query;
} else {
if (relative3.userinfo !== void 0 || relative3.host !== void 0 || relative3.port !== void 0) {
target.userinfo = relative3.userinfo;
target.host = relative3.host;
target.port = relative3.port;
target.path = removeDotSegments(relative3.path || "");
target.query = relative3.query;
} else {
if (!relative3.path) {
target.path = base.path;
if (relative3.query !== void 0) {
target.query = relative3.query;
} else {
target.query = base.query;
}
} else {
if (relative3.path[0] === "/") {
target.path = removeDotSegments(relative3.path);
} else {
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
target.path = "/" + relative3.path;
} else if (!base.path) {
target.path = relative3.path;
} else {
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative3.path;
}
target.path = removeDotSegments(target.path);
}
target.query = relative3.query;
}
target.userinfo = base.userinfo;
target.host = base.host;
target.port = base.port;
}
target.scheme = base.scheme;
}
target.fragment = relative3.fragment;
return target;
}
function equal(uriA, uriB, options) {
const normalizedA = normalizeComparableURI(uriA, options);
const normalizedB = normalizeComparableURI(uriB, options);
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA === normalizedB;
}
function serialize(cmpts, opts) {
const component = {
host: cmpts.host,
scheme: cmpts.scheme,
userinfo: cmpts.userinfo,
port: cmpts.port,
path: cmpts.path,
query: cmpts.query,
nid: cmpts.nid,
nss: cmpts.nss,
uuid: cmpts.uuid,
fragment: cmpts.fragment,
reference: cmpts.reference,
resourceName: cmpts.resourceName,
secure: cmpts.secure,
error: ""
};
const options = Object.assign({}, opts);
const uriTokens = [];
if (component.scheme) {
component.scheme = decodeValidScheme(component.scheme);
}
const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
if (component.path !== void 0) {
if (!options.skipEscape) {
component.path = serializePathEncoding(component.path, pathNoScheme);
} else {
component.path = normalizePercentEncoding(component.path);
}
}
if (options.reference !== "suffix" && component.scheme) {
component.scheme = decodeValidScheme(component.scheme);
uriTokens.push(component.scheme, ":");
}
const authority = recomposeAuthority(component);
if (authority !== void 0) {
if (options.reference !== "suffix") {
uriTokens.push("//");
}
uriTokens.push(authority);
if (component.path && component.path[0] !== "/") {
uriTokens.push("/");
}
}
if (component.path !== void 0) {
let s = component.path;
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
s = removeDotSegments(s);
}
if (pathNoScheme) {
s = serializePathEncoding(s, true);
}
if (authority === void 0 && s[0] === "/" && s[1] === "/") {
s = "/%2F" + s.slice(2);
}
uriTokens.push(s);
}
if (component.query !== void 0) {
uriTokens.push("?", encodeQuery(component.query));
}
if (component.fragment !== void 0) {
uriTokens.push("#", encodeFragment(component.fragment));
}
return uriTokens.join("");
}
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
function getParseError(parsed, matches) {
if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
return 'URI path must start with "/" when authority is present.';
}
if (typeof parsed.port === "number" && (parsed.port < 0 || parsed.port > 65535)) {
return "URI port is malformed.";
}
return void 0;
}
function hasMalformedPercentEncoding(component) {
if (component === void 0) return false;
let percent = component.indexOf("%");
while (percent !== -1) {
if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) {
return true;
}
percent = component.indexOf("%", percent + 3);
}
return false;
}
function hasMalformedComponentPercentEncoding(matches) {
const host2 = matches[4];
return hasMalformedPercentEncoding(matches[3]) || host2 !== void 0 && !(host2[0] === "[" && host2[host2.length - 1] === "]") && hasMalformedPercentEncoding(host2) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
}
function canonicalizeHost(parsed, options, schemeHandler, isIP2) {
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && parsed.host[0] !== "[" && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP2 === false && nonSimpleDomain(parsed.host)) {
try {
parsed.host = new URL("http://" + parsed.host).hostname;
} catch (e) {
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
return true;
}
}
return false;
}
function parseWithStatus(uri, opts) {
const options = Object.assign({}, opts);
const parsed = {
scheme: void 0,
userinfo: void 0,
host: "",
port: void 0,
path: "",
query: void 0,
fragment: void 0
};
let malformedAuthorityOrPort = false;
let malformedPercentEncoding = false;
let malformedSchemeSpecific = false;
let malformedHost = false;
let malformedIPLiteral = false;
let malformedScheme = false;
let isIP2 = false;
if (options.reference === "suffix") {
if (options.scheme) {
uri = options.scheme + ":" + uri;
} else {
uri = "//" + uri;
}
}
const authorityMatch = uri.match(AUTHORITY_PREFIX);
if (authorityMatch !== null && authorityMatch[1].indexOf("\\") !== -1) {
parsed.error = "URI authority must not contain a literal backslash.";
malformedAuthorityOrPort = true;
}
const introducerMatch = uri.match(AUTHORITY_INTRODUCER_REGION);
if (introducerMatch !== null) {
const region = introducerMatch[1];
const normalizedRegion = region.replace(/[\t\n\r]/g, "");
if (normalizedRegion.length >= 2) {
if (normalizedRegion.slice(0, 2) !== "//") {
parsed.error = parsed.error || "URI authority must not contain a literal backslash.";
malformedAuthorityOrPort = true;
} else if (region.length !== normalizedRegion.length) {
parsed.error = parsed.error || "URI authority introducer must not contain whitespace.";
malformedAuthorityOrPort = true;
}
}
}
const matches = uri.match(URI_PARSE);
if (matches) {
parsed.scheme = matches[1];
parsed.userinfo = matches[3];
parsed.host = matches[4];
parsed.port = parseInt(matches[5], 10);
parsed.path = matches[6] || "";
parsed.query = matches[7];
parsed.fragment = matches[8];
if (parsed.scheme !== void 0) {
const decodedScheme = unescape(parsed.scheme);
if (VALID_SCHEME.test(decodedScheme)) {
parsed.scheme = decodedScheme.toLowerCase();
} else {
parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
malformedScheme = true;
}
}
malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
if (malformedPercentEncoding) {
parsed.error = parsed.error || "URI contains malformed percent-encoding.";
}
if (isNaN(parsed.port)) {
parsed.port = matches[5];
}
const parseError = getParseError(parsed, matches);
if (parseError !== void 0) {
parsed.error = parsed.error || parseError;
malformedAuthorityOrPort = true;
}
if (parsed.host) {
const ipv4result = isIPv4(parsed.host);
if (ipv4result === false) {
const bracketedIPLiteral = parsed.host[0] === "[" && parsed.host[parsed.host.length - 1] === "]";
const ipv6result = normalizeIPv6(parsed.host);
isIP2 = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
malformedIPLiteral = bracketedIPLiteral && ipv6result.error === true;
parsed.host = isIP2 ? ipv6result.host : ipv6result.host.toLowerCase();
if (malformedIPLiteral) {
parsed.error = parsed.error || "URI host is malformed.";
malformedAuthorityOrPort = true;
}
} else {
isIP2 = true;
}
}
if (parsed.scheme === void 0 && parsed.userinfo === void 0 && parsed.host === void 0 && parsed.port === void 0 && parsed.query === void 0 && !parsed.path) {
parsed.reference = "same-document";
} else if (parsed.scheme === void 0) {
parsed.reference = "relative";
} else if (parsed.fragment === void 0) {
parsed.reference = "absolute";
} else {
parsed.reference = "uri";
}
if (options.reference && options.reference !== "suffix" && options.reference !== parsed.reference) {
parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
}
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP2);
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
if (uri.indexOf("%") !== -1) {
if (parsed.host !== void 0 && !malformedIPLiteral) {
const host2 = isIP2 ? parsed.host : normalizePercentEncoding(parsed.host, true);
parsed.host = reescapeHostDelimiters(host2, isIP2);
}
}
if (parsed.path) {
parsed.path = normalizePathEncoding(parsed.path);
}
if (parsed.query) {
parsed.query = normalizeQueryFragmentEncoding(parsed.query);
}
if (parsed.fragment) {
parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
}
}
if (schemeHandler && schemeHandler.parse) {
schemeHandler.parse(parsed, options);
if (schemeHandler === SCHEMES.urn && parsed.nid === void 0) {
malformedSchemeSpecific = true;
}
}
} else {
parsed.error = parsed.error || "URI can not be parsed.";
}
return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
}
function parse4(uri, opts) {
return parseWithStatus(uri, opts).parsed;
}
function normalizeString(uri, opts) {
return normalizeStringWithStatus(uri, opts).normalized;
}
function normalizeStringWithStatus(uri, opts) {
const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
return {
normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
malformedAuthorityOrPort,
malformedPercentEncoding,
malformedSchemeSpecific,
malformedHost,
malformedScheme
};
}
function normalizeComparableURI(uri, opts) {
if (typeof uri !== "string" && typeof uri !== "object") {
return void 0;
}
let value;
try {
value = typeof uri === "string" ? uri : serialize(uri, opts);
} catch {
return void 0;
}
const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
}
var fastUri = {
SCHEMES,
normalize,
resolve: resolve9,
resolveComponent,
equal,
serialize,
parse: parse4
};
module.exports = fastUri;
module.exports.default = fastUri;
module.exports.fastUri = fastUri;
}
});
// node_modules/ajv/dist/runtime/uri.js
var require_uri = __commonJS({
"node_modules/ajv/dist/runtime/uri.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var uri = require_fast_uri();
uri.code = 'require("ajv/dist/runtime/uri").default';
exports.default = uri;
}
});
// node_modules/ajv/dist/core.js
var require_core = __commonJS({
"node_modules/ajv/dist/core.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CodeGen = exports.Name = exports.nil = exports.stringify = exports.str = exports._ = exports.KeywordCxt = void 0;
var validate_1 = require_validate();
Object.defineProperty(exports, "KeywordCxt", { enumerable: true, get: function() {
return validate_1.KeywordCxt;
} });
var codegen_1 = require_codegen();
Object.defineProperty(exports, "_", { enumerable: true, get: function() {
return codegen_1._;
} });
Object.defineProperty(exports, "str", { enumerable: true, get: function() {
return codegen_1.str;
} });
Object.defineProperty(exports, "stringify", { enumerable: true, get: function() {
return codegen_1.stringify;
} });
Object.defineProperty(exports, "nil", { enumerable: true, get: function() {
return codegen_1.nil;
} });
Object.defineProperty(exports, "Name", { enumerable: true, get: function() {
return codegen_1.Name;
} });
Object.defineProperty(exports, "CodeGen", { enumerable: true, get: function() {
return codegen_1.CodeGen;
} });
var validation_error_1 = require_validation_error();
var ref_error_1 = require_ref_error();
var rules_1 = require_rules();
var compile_1 = require_compile();
var codegen_2 = require_codegen();
var resolve_1 = require_resolve();
var dataType_1 = require_dataType();
var util_1 = require_util();
var $dataRefSchema = require_data();
var uri_1 = require_uri();
var defaultRegExp = (str, flags) => new RegExp(str, flags);
defaultRegExp.code = "new RegExp";
var META_IGNORE_OPTIONS = ["removeAdditional", "useDefaults", "coerceTypes"];
var EXT_SCOPE_NAMES = /* @__PURE__ */ new Set([
"validate",
"serialize",
"parse",
"wrapper",
"root",
"schema",
"keyword",
"pattern",
"formats",
"validate$data",
"func",
"obj",
"Error"
]);
var removedOptions = {
errorDataPath: "",
format: "`validateFormats: false` can be used instead.",
nullable: '"nullable" keyword is supported by default.',
jsonPointers: "Deprecated jsPropertySyntax can be used instead.",
extendRefs: "Deprecated ignoreKeywordsWithRef can be used instead.",
missingRefs: "Pass empty schema with $id that should be ignored to ajv.addSchema.",
processCode: "Use option `code: {process: (code, schemaEnv: object) => string}`",
sourceCode: "Use option `code: {source: true}`",
strictDefaults: "It is default now, see option `strict`.",
strictKeywords: "It is default now, see option `strict`.",
uniqueItems: '"uniqueItems" keyword is always validated.',
unknownFormats: "Disable strict mode or pass `true` to `ajv.addFormat` (or `formats` option).",
cache: "Map is used as cache, schema object as key.",
serialize: "Map is used as cache, schema object as key.",
ajvErrors: "It is default now."
};
var deprecatedOptions = {
ignoreKeywordsWithRef: "",
jsPropertySyntax: "",
unicode: '"minLength"/"maxLength" account for unicode characters by default.'
};
var MAX_EXPRESSION = 200;
function requiredOptions(o) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
const s = o.strict;
const _optz = (_a = o.code) === null || _a === void 0 ? void 0 : _a.optimize;
const optimize = _optz === true || _optz === void 0 ? 1 : _optz || 0;
const regExp = (_c = (_b = o.code) === null || _b === void 0 ? void 0 : _b.regExp) !== null && _c !== void 0 ? _c : defaultRegExp;
const uriResolver = (_d = o.uriResolver) !== null && _d !== void 0 ? _d : uri_1.default;
return {
strictSchema: (_f = (_e = o.strictSchema) !== null && _e !== void 0 ? _e : s) !== null && _f !== void 0 ? _f : true,
strictNumbers: (_h = (_g = o.strictNumbers) !== null && _g !== void 0 ? _g : s) !== null && _h !== void 0 ? _h : true,
strictTypes: (_k = (_j = o.strictTypes) !== null && _j !== void 0 ? _j : s) !== null && _k !== void 0 ? _k : "log",
strictTuples: (_m = (_l = o.strictTuples) !== null && _l !== void 0 ? _l : s) !== null && _m !== void 0 ? _m : "log",
strictRequired: (_p = (_o = o.strictRequired) !== null && _o !== void 0 ? _o : s) !== null && _p !== void 0 ? _p : false,
code: o.code ? { ...o.code, optimize, regExp } : { optimize, regExp },
loopRequired: (_q = o.loopRequired) !== null && _q !== void 0 ? _q : MAX_EXPRESSION,
loopEnum: (_r = o.loopEnum) !== null && _r !== void 0 ? _r : MAX_EXPRESSION,
meta: (_s = o.meta) !== null && _s !== void 0 ? _s : true,
messages: (_t = o.messages) !== null && _t !== void 0 ? _t : true,
inlineRefs: (_u = o.inlineRefs) !== null && _u !== void 0 ? _u : true,
schemaId: (_v = o.schemaId) !== null && _v !== void 0 ? _v : "$id",
addUsedSchema: (_w = o.addUsedSchema) !== null && _w !== void 0 ? _w : true,
validateSchema: (_x = o.validateSchema) !== null && _x !== void 0 ? _x : true,
validateFormats: (_y = o.validateFormats) !== null && _y !== void 0 ? _y : true,
unicodeRegExp: (_z = o.unicodeRegExp) !== null && _z !== void 0 ? _z : true,
int32range: (_0 = o.int32range) !== null && _0 !== void 0 ? _0 : true,
uriResolver
};
}
var Ajv = class {
constructor(opts = {}) {
this.schemas = {};
this.refs = {};
this.formats = /* @__PURE__ */ Object.create(null);
this._compilations = /* @__PURE__ */ new Set();
this._loading = {};
this._cache = /* @__PURE__ */ new Map();
opts = this.opts = { ...opts, ...requiredOptions(opts) };
const { es5, lines } = this.opts.code;
this.scope = new codegen_2.ValueScope({ scope: {}, prefixes: EXT_SCOPE_NAMES, es5, lines });
this.logger = getLogger(opts.logger);
const formatOpt = opts.validateFormats;
opts.validateFormats = false;
this.RULES = (0, rules_1.getRules)();
checkOptions.call(this, removedOptions, opts, "NOT SUPPORTED");
checkOptions.call(this, deprecatedOptions, opts, "DEPRECATED", "warn");
this._metaOpts = getMetaSchemaOptions.call(this);
if (opts.formats)
addInitialFormats.call(this);
this._addVocabularies();
this._addDefaultMetaSchema();
if (opts.keywords)
addInitialKeywords.call(this, opts.keywords);
if (typeof opts.meta == "object")
this.addMetaSchema(opts.meta);
addInitialSchemas.call(this);
opts.validateFormats = formatOpt;
}
_addVocabularies() {
this.addKeyword("$async");
}
_addDefaultMetaSchema() {
const { $data, meta, schemaId } = this.opts;
let _dataRefSchema = $dataRefSchema;
if (schemaId === "id") {
_dataRefSchema = { ...$dataRefSchema };
_dataRefSchema.id = _dataRefSchema.$id;
delete _dataRefSchema.$id;
}
if (meta && $data)
this.addMetaSchema(_dataRefSchema, _dataRefSchema[schemaId], false);
}
defaultMeta() {
const { meta, schemaId } = this.opts;
return this.opts.defaultMeta = typeof meta == "object" ? meta[schemaId] || meta : void 0;
}
validate(schemaKeyRef, data) {
let v;
if (typeof schemaKeyRef == "string") {
v = this.getSchema(schemaKeyRef);
if (!v)
throw new Error(`no schema with key or ref "${schemaKeyRef}"`);
} else {
v = this.compile(schemaKeyRef);
}
const valid = v(data);
if (!("$async" in v))
this.errors = v.errors;
return valid;
}
compile(schema, _meta) {
const sch = this._addSchema(schema, _meta);
return sch.validate || this._compileSchemaEnv(sch);
}
compileAsync(schema, meta) {
if (typeof this.opts.loadSchema != "function") {
throw new Error("options.loadSchema should be a function");
}
const { loadSchema } = this.opts;
return runCompileAsync.call(this, schema, meta);
async function runCompileAsync(_schema, _meta) {
await loadMetaSchema.call(this, _schema.$schema);
const sch = this._addSchema(_schema, _meta);
return sch.validate || _compileAsync.call(this, sch);
}
async function loadMetaSchema($ref) {
if ($ref && !this.getSchema($ref)) {
await runCompileAsync.call(this, { $ref }, true);
}
}
async function _compileAsync(sch) {
try {
return this._compileSchemaEnv(sch);
} catch (e) {
if (!(e instanceof ref_error_1.default))
throw e;
checkLoaded.call(this, e);
await loadMissingSchema.call(this, e.missingSchema);
return _compileAsync.call(this, sch);
}
}
function checkLoaded({ missingSchema: ref, missingRef }) {
if (this.refs[ref]) {
throw new Error(`AnySchema ${ref} is loaded but ${missingRef} cannot be resolved`);
}
}
async function loadMissingSchema(ref) {
const _schema = await _loadSchema.call(this, ref);
if (!this.refs[ref])
await loadMetaSchema.call(this, _schema.$schema);
if (!this.refs[ref])
this.addSchema(_schema, ref, meta);
}
async function _loadSchema(ref) {
const p = this._loading[ref];
if (p)
return p;
try {
return await (this._loading[ref] = loadSchema(ref));
} finally {
delete this._loading[ref];
}
}
}
// Adds schema to the instance
addSchema(schema, key, _meta, _validateSchema = this.opts.validateSchema) {
if (Array.isArray(schema)) {
for (const sch of schema)
this.addSchema(sch, void 0, _meta, _validateSchema);
return this;
}
let id;
if (typeof schema === "object") {
const { schemaId } = this.opts;
id = schema[schemaId];
if (id !== void 0 && typeof id != "string") {
throw new Error(`schema ${schemaId} must be string`);
}
}
key = (0, resolve_1.normalizeId)(key || id);
this._checkUnique(key);
this.schemas[key] = this._addSchema(schema, _meta, key, _validateSchema, true);
return this;
}
// Add schema that will be used to validate other schemas
// options in META_IGNORE_OPTIONS are alway set to false
addMetaSchema(schema, key, _validateSchema = this.opts.validateSchema) {
this.addSchema(schema, key, true, _validateSchema);
return this;
}
// Validate schema against its meta-schema
validateSchema(schema, throwOrLogError) {
if (typeof schema == "boolean")
return true;
let $schema;
$schema = schema.$schema;
if ($schema !== void 0 && typeof $schema != "string") {
throw new Error("$schema must be a string");
}
$schema = $schema || this.opts.defaultMeta || this.defaultMeta();
if (!$schema) {
this.logger.warn("meta-schema not available");
this.errors = null;
return true;
}
const valid = this.validate($schema, schema);
if (!valid && throwOrLogError) {
const message = "schema is invalid: " + this.errorsText();
if (this.opts.validateSchema === "log")
this.logger.error(message);
else
throw new Error(message);
}
return valid;
}
// Get compiled schema by `key` or `ref`.
// (`key` that was passed to `addSchema` or full schema reference - `schema.$id` or resolved id)
getSchema(keyRef) {
let sch;
while (typeof (sch = getSchEnv.call(this, keyRef)) == "string")
keyRef = sch;
if (sch === void 0) {
const { schemaId } = this.opts;
const root = new compile_1.SchemaEnv({ schema: {}, schemaId });
sch = compile_1.resolveSchema.call(this, root, keyRef);
if (!sch)
return;
this.refs[keyRef] = sch;
}
return sch.validate || this._compileSchemaEnv(sch);
}
// Remove cached schema(s).
// If no parameter is passed all schemas but meta-schemas are removed.
// If RegExp is passed all schemas with key/id matching pattern but meta-schemas are removed.
// Even if schema is referenced by other schemas it still can be removed as other schemas have local references.
removeSchema(schemaKeyRef) {
if (schemaKeyRef instanceof RegExp) {
this._removeAllSchemas(this.schemas, schemaKeyRef);
this._removeAllSchemas(this.refs, schemaKeyRef);
return this;
}
switch (typeof schemaKeyRef) {
case "undefined":
this._removeAllSchemas(this.schemas);
this._removeAllSchemas(this.refs);
this._cache.clear();
return this;
case "string": {
const sch = getSchEnv.call(this, schemaKeyRef);
if (typeof sch == "object")
this._cache.delete(sch.schema);
delete this.schemas[schemaKeyRef];
delete this.refs[schemaKeyRef];
return this;
}
case "object": {
const cacheKey = schemaKeyRef;
this._cache.delete(cacheKey);
let id = schemaKeyRef[this.opts.schemaId];
if (id) {
id = (0, resolve_1.normalizeId)(id);
delete this.schemas[id];
delete this.refs[id];
}
return this;
}
default:
throw new Error("ajv.removeSchema: invalid parameter");
}
}
// add "vocabulary" - a collection of keywords
addVocabulary(definitions) {
for (const def of definitions)
this.addKeyword(def);
return this;
}
addKeyword(kwdOrDef, def) {
let keyword;
if (typeof kwdOrDef == "string") {
keyword = kwdOrDef;
if (typeof def == "object") {
this.logger.warn("these parameters are deprecated, see docs for addKeyword");
def.keyword = keyword;
}
} else if (typeof kwdOrDef == "object" && def === void 0) {
def = kwdOrDef;
keyword = def.keyword;
if (Array.isArray(keyword) && !keyword.length) {
throw new Error("addKeywords: keyword must be string or non-empty array");
}
} else {
throw new Error("invalid addKeywords parameters");
}
checkKeyword.call(this, keyword, def);
if (!def) {
(0, util_1.eachItem)(keyword, (kwd) => addRule.call(this, kwd));
return this;
}
keywordMetaschema.call(this, def);
const definition = {
...def,
type: (0, dataType_1.getJSONTypes)(def.type),
schemaType: (0, dataType_1.getJSONTypes)(def.schemaType)
};
(0, util_1.eachItem)(keyword, definition.type.length === 0 ? (k) => addRule.call(this, k, definition) : (k) => definition.type.forEach((t) => addRule.call(this, k, definition, t)));
return this;
}
getKeyword(keyword) {
const rule = this.RULES.all[keyword];
return typeof rule == "object" ? rule.definition : !!rule;
}
// Remove keyword
removeKeyword(keyword) {
const { RULES } = this;
delete RULES.keywords[keyword];
delete RULES.all[keyword];
for (const group of RULES.rules) {
const i = group.rules.findIndex((rule) => rule.keyword === keyword);
if (i >= 0)
group.rules.splice(i, 1);
}
return this;
}
// Add format
addFormat(name, format) {
if (typeof format == "string")
format = new RegExp(format);
this.formats[name] = format;
return this;
}
errorsText(errors = this.errors, { separator = ", ", dataVar = "data" } = {}) {
if (!errors || errors.length === 0)
return "No errors";
return errors.map((e) => `${dataVar}${e.instancePath} ${e.message}`).reduce((text2, msg) => text2 + separator + msg);
}
$dataMetaSchema(metaSchema, keywordsJsonPointers) {
const rules = this.RULES.all;
metaSchema = JSON.parse(JSON.stringify(metaSchema));
for (const jsonPointer of keywordsJsonPointers) {
const segments = jsonPointer.split("/").slice(1);
let keywords = metaSchema;
for (const seg of segments)
keywords = keywords[seg];
for (const key in rules) {
const rule = rules[key];
if (typeof rule != "object")
continue;
const { $data } = rule.definition;
const schema = keywords[key];
if ($data && schema)
keywords[key] = schemaOrData(schema);
}
}
return metaSchema;
}
_removeAllSchemas(schemas, regex) {
for (const keyRef in schemas) {
const sch = schemas[keyRef];
if (!regex || regex.test(keyRef)) {
if (typeof sch == "string") {
delete schemas[keyRef];
} else if (sch && !sch.meta) {
this._cache.delete(sch.schema);
delete schemas[keyRef];
}
}
}
}
_addSchema(schema, meta, baseId, validateSchema = this.opts.validateSchema, addSchema = this.opts.addUsedSchema) {
let id;
const { schemaId } = this.opts;
if (typeof schema == "object") {
id = schema[schemaId];
} else {
if (this.opts.jtd)
throw new Error("schema must be object");
else if (typeof schema != "boolean")
throw new Error("schema must be object or boolean");
}
let sch = this._cache.get(schema);
if (sch !== void 0)
return sch;
baseId = (0, resolve_1.normalizeId)(id || baseId);
const localRefs = resolve_1.getSchemaRefs.call(this, schema, baseId);
sch = new compile_1.SchemaEnv({ schema, schemaId, meta, baseId, localRefs });
this._cache.set(sch.schema, sch);
if (addSchema && !baseId.startsWith("#")) {
if (baseId)
this._checkUnique(baseId);
this.refs[baseId] = sch;
}
if (validateSchema)
this.validateSchema(schema, true);
return sch;
}
_checkUnique(id) {
if (this.schemas[id] || this.refs[id]) {
throw new Error(`schema with key or id "${id}" already exists`);
}
}
_compileSchemaEnv(sch) {
if (sch.meta)
this._compileMetaSchema(sch);
else
compile_1.compileSchema.call(this, sch);
if (!sch.validate)
throw new Error("ajv implementation error");
return sch.validate;
}
_compileMetaSchema(sch) {
const currentOpts = this.opts;
this.opts = this._metaOpts;
try {
compile_1.compileSchema.call(this, sch);
} finally {
this.opts = currentOpts;
}
}
};
Ajv.ValidationError = validation_error_1.default;
Ajv.MissingRefError = ref_error_1.default;
exports.default = Ajv;
function checkOptions(checkOpts, options, msg, log = "error") {
for (const key in checkOpts) {
const opt = key;
if (opt in options)
this.logger[log](`${msg}: option ${key}. ${checkOpts[opt]}`);
}
}
function getSchEnv(keyRef) {
keyRef = (0, resolve_1.normalizeId)(keyRef);
return this.schemas[keyRef] || this.refs[keyRef];
}
function addInitialSchemas() {
const optsSchemas = this.opts.schemas;
if (!optsSchemas)
return;
if (Array.isArray(optsSchemas))
this.addSchema(optsSchemas);
else
for (const key in optsSchemas)
this.addSchema(optsSchemas[key], key);
}
function addInitialFormats() {
for (const name in this.opts.formats) {
const format = this.opts.formats[name];
if (format)
this.addFormat(name, format);
}
}
function addInitialKeywords(defs) {
if (Array.isArray(defs)) {
this.addVocabulary(defs);
return;
}
this.logger.warn("keywords option as map is deprecated, pass array");
for (const keyword in defs) {
const def = defs[keyword];
if (!def.keyword)
def.keyword = keyword;
this.addKeyword(def);
}
}
function getMetaSchemaOptions() {
const metaOpts = { ...this.opts };
for (const opt of META_IGNORE_OPTIONS)
delete metaOpts[opt];
return metaOpts;
}
var noLogs = { log() {
}, warn() {
}, error() {
} };
function getLogger(logger) {
if (logger === false)
return noLogs;
if (logger === void 0)
return console;
if (logger.log && logger.warn && logger.error)
return logger;
throw new Error("logger must implement log, warn and error methods");
}
var KEYWORD_NAME = /^[a-z_$][a-z0-9_$:-]*$/i;
function checkKeyword(keyword, def) {
const { RULES } = this;
(0, util_1.eachItem)(keyword, (kwd) => {
if (RULES.keywords[kwd])
throw new Error(`Keyword ${kwd} is already defined`);
if (!KEYWORD_NAME.test(kwd))
throw new Error(`Keyword ${kwd} has invalid name`);
});
if (!def)
return;
if (def.$data && !("code" in def || "validate" in def)) {
throw new Error('$data keyword must have "code" or "validate" function');
}
}
function addRule(keyword, definition, dataType) {
var _a;
const post = definition === null || definition === void 0 ? void 0 : definition.post;
if (dataType && post)
throw new Error('keyword with "post" flag cannot have "type"');
const { RULES } = this;
let ruleGroup = post ? RULES.post : RULES.rules.find(({ type: t }) => t === dataType);
if (!ruleGroup) {
ruleGroup = { type: dataType, rules: [] };
RULES.rules.push(ruleGroup);
}
RULES.keywords[keyword] = true;
if (!definition)
return;
const rule = {
keyword,
definition: {
...definition,
type: (0, dataType_1.getJSONTypes)(definition.type),
schemaType: (0, dataType_1.getJSONTypes)(definition.schemaType)
}
};
if (definition.before)
addBeforeRule.call(this, ruleGroup, rule, definition.before);
else
ruleGroup.rules.push(rule);
RULES.all[keyword] = rule;
(_a = definition.implements) === null || _a === void 0 ? void 0 : _a.forEach((kwd) => this.addKeyword(kwd));
}
function addBeforeRule(ruleGroup, rule, before) {
const i = ruleGroup.rules.findIndex((_rule) => _rule.keyword === before);
if (i >= 0) {
ruleGroup.rules.splice(i, 0, rule);
} else {
ruleGroup.rules.push(rule);
this.logger.warn(`rule ${before} is not defined`);
}
}
function keywordMetaschema(def) {
let { metaSchema } = def;
if (metaSchema === void 0)
return;
if (def.$data && this.opts.$data)
metaSchema = schemaOrData(metaSchema);
def.validateSchema = this.compile(metaSchema, true);
}
var $dataRef = {
$ref: "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#"
};
function schemaOrData(schema) {
return { anyOf: [schema, $dataRef] };
}
}
});
// node_modules/ajv/dist/vocabularies/core/id.js
var require_id = __commonJS({
"node_modules/ajv/dist/vocabularies/core/id.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var def = {
keyword: "id",
code() {
throw new Error('NOT SUPPORTED: keyword "id", use "$id" for schema ID');
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/core/ref.js
var require_ref = __commonJS({
"node_modules/ajv/dist/vocabularies/core/ref.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.callRef = exports.getValidate = void 0;
var ref_error_1 = require_ref_error();
var code_1 = require_code2();
var codegen_1 = require_codegen();
var names_1 = require_names();
var compile_1 = require_compile();
var util_1 = require_util();
var def = {
keyword: "$ref",
schemaType: "string",
code(cxt) {
const { gen, schema: $ref, it } = cxt;
const { baseId, schemaEnv: env, validateName, opts, self } = it;
const { root } = env;
if (($ref === "#" || $ref === "#/") && baseId === root.baseId)
return callRootRef();
const schOrEnv = compile_1.resolveRef.call(self, root, baseId, $ref);
if (schOrEnv === void 0)
throw new ref_error_1.default(it.opts.uriResolver, baseId, $ref);
if (schOrEnv instanceof compile_1.SchemaEnv)
return callValidate(schOrEnv);
return inlineRefSchema(schOrEnv);
function callRootRef() {
if (env === root)
return callRef(cxt, validateName, env, env.$async);
const rootName = gen.scopeValue("root", { ref: root });
return callRef(cxt, (0, codegen_1._)`${rootName}.validate`, root, root.$async);
}
function callValidate(sch) {
const v = getValidate(cxt, sch);
callRef(cxt, v, sch, sch.$async);
}
function inlineRefSchema(sch) {
const schName = gen.scopeValue("schema", opts.code.source === true ? { ref: sch, code: (0, codegen_1.stringify)(sch) } : { ref: sch });
const valid = gen.name("valid");
const schCxt = cxt.subschema({
schema: sch,
dataTypes: [],
schemaPath: codegen_1.nil,
topSchemaRef: schName,
errSchemaPath: $ref
}, valid);
cxt.mergeEvaluated(schCxt);
cxt.ok(valid);
}
}
};
function getValidate(cxt, sch) {
const { gen } = cxt;
return sch.validate ? gen.scopeValue("validate", { ref: sch.validate }) : (0, codegen_1._)`${gen.scopeValue("wrapper", { ref: sch })}.validate`;
}
exports.getValidate = getValidate;
function callRef(cxt, v, sch, $async) {
const { gen, it } = cxt;
const { allErrors, schemaEnv: env, opts } = it;
const passCxt = opts.passContext ? names_1.default.this : codegen_1.nil;
if ($async)
callAsyncRef();
else
callSyncRef();
function callAsyncRef() {
if (!env.$async)
throw new Error("async schema referenced by sync schema");
const valid = gen.let("valid");
gen.try(() => {
gen.code((0, codegen_1._)`await ${(0, code_1.callValidateCode)(cxt, v, passCxt)}`);
addEvaluatedFrom(v);
if (!allErrors)
gen.assign(valid, true);
}, (e) => {
gen.if((0, codegen_1._)`!(${e} instanceof ${it.ValidationError})`, () => gen.throw(e));
addErrorsFrom(e);
if (!allErrors)
gen.assign(valid, false);
});
cxt.ok(valid);
}
function callSyncRef() {
cxt.result((0, code_1.callValidateCode)(cxt, v, passCxt), () => addEvaluatedFrom(v), () => addErrorsFrom(v));
}
function addErrorsFrom(source) {
const errs = (0, codegen_1._)`${source}.errors`;
gen.assign(names_1.default.vErrors, (0, codegen_1._)`${names_1.default.vErrors} === null ? ${errs} : ${names_1.default.vErrors}.concat(${errs})`);
gen.assign(names_1.default.errors, (0, codegen_1._)`${names_1.default.vErrors}.length`);
}
function addEvaluatedFrom(source) {
var _a;
if (!it.opts.unevaluated)
return;
const schEvaluated = (_a = sch === null || sch === void 0 ? void 0 : sch.validate) === null || _a === void 0 ? void 0 : _a.evaluated;
if (it.props !== true) {
if (schEvaluated && !schEvaluated.dynamicProps) {
if (schEvaluated.props !== void 0) {
it.props = util_1.mergeEvaluated.props(gen, schEvaluated.props, it.props);
}
} else {
const props = gen.var("props", (0, codegen_1._)`${source}.evaluated.props`);
it.props = util_1.mergeEvaluated.props(gen, props, it.props, codegen_1.Name);
}
}
if (it.items !== true) {
if (schEvaluated && !schEvaluated.dynamicItems) {
if (schEvaluated.items !== void 0) {
it.items = util_1.mergeEvaluated.items(gen, schEvaluated.items, it.items);
}
} else {
const items = gen.var("items", (0, codegen_1._)`${source}.evaluated.items`);
it.items = util_1.mergeEvaluated.items(gen, items, it.items, codegen_1.Name);
}
}
}
}
exports.callRef = callRef;
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/core/index.js
var require_core2 = __commonJS({
"node_modules/ajv/dist/vocabularies/core/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var id_1 = require_id();
var ref_1 = require_ref();
var core = [
"$schema",
"$id",
"$defs",
"$vocabulary",
{ keyword: "$comment" },
"definitions",
id_1.default,
ref_1.default
];
exports.default = core;
}
});
// node_modules/ajv/dist/vocabularies/validation/limitNumber.js
var require_limitNumber = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/limitNumber.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var ops = codegen_1.operators;
var KWDs = {
maximum: { okStr: "<=", ok: ops.LTE, fail: ops.GT },
minimum: { okStr: ">=", ok: ops.GTE, fail: ops.LT },
exclusiveMaximum: { okStr: "<", ok: ops.LT, fail: ops.GTE },
exclusiveMinimum: { okStr: ">", ok: ops.GT, fail: ops.LTE }
};
var error = {
message: ({ keyword, schemaCode }) => (0, codegen_1.str)`must be ${KWDs[keyword].okStr} ${schemaCode}`,
params: ({ keyword, schemaCode }) => (0, codegen_1._)`{comparison: ${KWDs[keyword].okStr}, limit: ${schemaCode}}`
};
var def = {
keyword: Object.keys(KWDs),
type: "number",
schemaType: "number",
$data: true,
error,
code(cxt) {
const { keyword, data, schemaCode } = cxt;
cxt.fail$data((0, codegen_1._)`${data} ${KWDs[keyword].fail} ${schemaCode} || isNaN(${data})`);
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/validation/multipleOf.js
var require_multipleOf = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/multipleOf.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var error = {
message: ({ schemaCode }) => (0, codegen_1.str)`must be multiple of ${schemaCode}`,
params: ({ schemaCode }) => (0, codegen_1._)`{multipleOf: ${schemaCode}}`
};
var def = {
keyword: "multipleOf",
type: "number",
schemaType: "number",
$data: true,
error,
code(cxt) {
const { gen, data, schemaCode, it } = cxt;
const prec = it.opts.multipleOfPrecision;
const res = gen.let("res");
const invalid = prec ? (0, codegen_1._)`Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}` : (0, codegen_1._)`${res} !== parseInt(${res})`;
cxt.fail$data((0, codegen_1._)`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid}))`);
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/runtime/ucs2length.js
var require_ucs2length = __commonJS({
"node_modules/ajv/dist/runtime/ucs2length.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function ucs2length(str) {
const len = str.length;
let length = 0;
let pos = 0;
let value;
while (pos < len) {
length++;
value = str.charCodeAt(pos++);
if (value >= 55296 && value <= 56319 && pos < len) {
value = str.charCodeAt(pos);
if ((value & 64512) === 56320)
pos++;
}
}
return length;
}
exports.default = ucs2length;
ucs2length.code = 'require("ajv/dist/runtime/ucs2length").default';
}
});
// node_modules/ajv/dist/vocabularies/validation/limitLength.js
var require_limitLength = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/limitLength.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var util_1 = require_util();
var ucs2length_1 = require_ucs2length();
var error = {
message({ keyword, schemaCode }) {
const comp = keyword === "maxLength" ? "more" : "fewer";
return (0, codegen_1.str)`must NOT have ${comp} than ${schemaCode} characters`;
},
params: ({ schemaCode }) => (0, codegen_1._)`{limit: ${schemaCode}}`
};
var def = {
keyword: ["maxLength", "minLength"],
type: "string",
schemaType: "number",
$data: true,
error,
code(cxt) {
const { keyword, data, schemaCode, it } = cxt;
const op = keyword === "maxLength" ? codegen_1.operators.GT : codegen_1.operators.LT;
const len = it.opts.unicode === false ? (0, codegen_1._)`${data}.length` : (0, codegen_1._)`${(0, util_1.useFunc)(cxt.gen, ucs2length_1.default)}(${data})`;
cxt.fail$data((0, codegen_1._)`${len} ${op} ${schemaCode}`);
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/validation/pattern.js
var require_pattern = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/pattern.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var code_1 = require_code2();
var util_1 = require_util();
var codegen_1 = require_codegen();
var error = {
message: ({ schemaCode }) => (0, codegen_1.str)`must match pattern "${schemaCode}"`,
params: ({ schemaCode }) => (0, codegen_1._)`{pattern: ${schemaCode}}`
};
var def = {
keyword: "pattern",
type: "string",
schemaType: "string",
$data: true,
error,
code(cxt) {
const { gen, data, $data, schema, schemaCode, it } = cxt;
const u = it.opts.unicodeRegExp ? "u" : "";
if ($data) {
const { regExp } = it.opts.code;
const regExpCode = regExp.code === "new RegExp" ? (0, codegen_1._)`new RegExp` : (0, util_1.useFunc)(gen, regExp);
const valid = gen.let("valid");
gen.try(() => gen.assign(valid, (0, codegen_1._)`${regExpCode}(${schemaCode}, ${u}).test(${data})`), () => gen.assign(valid, false));
cxt.fail$data((0, codegen_1._)`!${valid}`);
} else {
const regExp = (0, code_1.usePattern)(cxt, schema);
cxt.fail$data((0, codegen_1._)`!${regExp}.test(${data})`);
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/validation/limitProperties.js
var require_limitProperties = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/limitProperties.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var error = {
message({ keyword, schemaCode }) {
const comp = keyword === "maxProperties" ? "more" : "fewer";
return (0, codegen_1.str)`must NOT have ${comp} than ${schemaCode} properties`;
},
params: ({ schemaCode }) => (0, codegen_1._)`{limit: ${schemaCode}}`
};
var def = {
keyword: ["maxProperties", "minProperties"],
type: "object",
schemaType: "number",
$data: true,
error,
code(cxt) {
const { keyword, data, schemaCode } = cxt;
const op = keyword === "maxProperties" ? codegen_1.operators.GT : codegen_1.operators.LT;
cxt.fail$data((0, codegen_1._)`Object.keys(${data}).length ${op} ${schemaCode}`);
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/validation/required.js
var require_required = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/required.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var code_1 = require_code2();
var codegen_1 = require_codegen();
var util_1 = require_util();
var error = {
message: ({ params: { missingProperty } }) => (0, codegen_1.str)`must have required property '${missingProperty}'`,
params: ({ params: { missingProperty } }) => (0, codegen_1._)`{missingProperty: ${missingProperty}}`
};
var def = {
keyword: "required",
type: "object",
schemaType: "array",
$data: true,
error,
code(cxt) {
const { gen, schema, schemaCode, data, $data, it } = cxt;
const { opts } = it;
if (!$data && schema.length === 0)
return;
const useLoop = schema.length >= opts.loopRequired;
if (it.allErrors)
allErrorsMode();
else
exitOnErrorMode();
if (opts.strictRequired) {
const props = cxt.parentSchema.properties;
const { definedProperties } = cxt.it;
for (const requiredKey of schema) {
if ((props === null || props === void 0 ? void 0 : props[requiredKey]) === void 0 && !definedProperties.has(requiredKey)) {
const schemaPath = it.schemaEnv.baseId + it.errSchemaPath;
const msg = `required property "${requiredKey}" is not defined at "${schemaPath}" (strictRequired)`;
(0, util_1.checkStrictMode)(it, msg, it.opts.strictRequired);
}
}
}
function allErrorsMode() {
if (useLoop || $data) {
cxt.block$data(codegen_1.nil, loopAllRequired);
} else {
for (const prop of schema) {
(0, code_1.checkReportMissingProp)(cxt, prop);
}
}
}
function exitOnErrorMode() {
const missing = gen.let("missing");
if (useLoop || $data) {
const valid = gen.let("valid", true);
cxt.block$data(valid, () => loopUntilMissing(missing, valid));
cxt.ok(valid);
} else {
gen.if((0, code_1.checkMissingProp)(cxt, schema, missing));
(0, code_1.reportMissingProp)(cxt, missing);
gen.else();
}
}
function loopAllRequired() {
gen.forOf("prop", schemaCode, (prop) => {
cxt.setParams({ missingProperty: prop });
gen.if((0, code_1.noPropertyInData)(gen, data, prop, opts.ownProperties), () => cxt.error());
});
}
function loopUntilMissing(missing, valid) {
cxt.setParams({ missingProperty: missing });
gen.forOf(missing, schemaCode, () => {
gen.assign(valid, (0, code_1.propertyInData)(gen, data, missing, opts.ownProperties));
gen.if((0, codegen_1.not)(valid), () => {
cxt.error();
gen.break();
});
}, codegen_1.nil);
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/validation/limitItems.js
var require_limitItems = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/limitItems.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var error = {
message({ keyword, schemaCode }) {
const comp = keyword === "maxItems" ? "more" : "fewer";
return (0, codegen_1.str)`must NOT have ${comp} than ${schemaCode} items`;
},
params: ({ schemaCode }) => (0, codegen_1._)`{limit: ${schemaCode}}`
};
var def = {
keyword: ["maxItems", "minItems"],
type: "array",
schemaType: "number",
$data: true,
error,
code(cxt) {
const { keyword, data, schemaCode } = cxt;
const op = keyword === "maxItems" ? codegen_1.operators.GT : codegen_1.operators.LT;
cxt.fail$data((0, codegen_1._)`${data}.length ${op} ${schemaCode}`);
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/runtime/equal.js
var require_equal = __commonJS({
"node_modules/ajv/dist/runtime/equal.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var equal = require_fast_deep_equal();
equal.code = 'require("ajv/dist/runtime/equal").default';
exports.default = equal;
}
});
// node_modules/ajv/dist/vocabularies/validation/uniqueItems.js
var require_uniqueItems = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/uniqueItems.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var dataType_1 = require_dataType();
var codegen_1 = require_codegen();
var util_1 = require_util();
var equal_1 = require_equal();
var error = {
message: ({ params: { i, j } }) => (0, codegen_1.str)`must NOT have duplicate items (items ## ${j} and ${i} are identical)`,
params: ({ params: { i, j } }) => (0, codegen_1._)`{i: ${i}, j: ${j}}`
};
var def = {
keyword: "uniqueItems",
type: "array",
schemaType: "boolean",
$data: true,
error,
code(cxt) {
const { gen, data, $data, schema, parentSchema, schemaCode, it } = cxt;
if (!$data && !schema)
return;
const valid = gen.let("valid");
const itemTypes = parentSchema.items ? (0, dataType_1.getSchemaTypes)(parentSchema.items) : [];
cxt.block$data(valid, validateUniqueItems, (0, codegen_1._)`${schemaCode} === false`);
cxt.ok(valid);
function validateUniqueItems() {
const i = gen.let("i", (0, codegen_1._)`${data}.length`);
const j = gen.let("j");
cxt.setParams({ i, j });
gen.assign(valid, true);
gen.if((0, codegen_1._)`${i} > 1`, () => (canOptimize() ? loopN : loopN2)(i, j));
}
function canOptimize() {
return itemTypes.length > 0 && !itemTypes.some((t) => t === "object" || t === "array");
}
function loopN(i, j) {
const item = gen.name("item");
const wrongType = (0, dataType_1.checkDataTypes)(itemTypes, item, it.opts.strictNumbers, dataType_1.DataType.Wrong);
const indices = gen.const("indices", (0, codegen_1._)`{}`);
gen.for((0, codegen_1._)`;${i}--;`, () => {
gen.let(item, (0, codegen_1._)`${data}[${i}]`);
gen.if(wrongType, (0, codegen_1._)`continue`);
if (itemTypes.length > 1)
gen.if((0, codegen_1._)`typeof ${item} == "string"`, (0, codegen_1._)`${item} += "_"`);
gen.if((0, codegen_1._)`typeof ${indices}[${item}] == "number"`, () => {
gen.assign(j, (0, codegen_1._)`${indices}[${item}]`);
cxt.error();
gen.assign(valid, false).break();
}).code((0, codegen_1._)`${indices}[${item}] = ${i}`);
});
}
function loopN2(i, j) {
const eql = (0, util_1.useFunc)(gen, equal_1.default);
const outer = gen.name("outer");
gen.label(outer).for((0, codegen_1._)`;${i}--;`, () => gen.for((0, codegen_1._)`${j} = ${i}; ${j}--;`, () => gen.if((0, codegen_1._)`${eql}(${data}[${i}], ${data}[${j}])`, () => {
cxt.error();
gen.assign(valid, false).break(outer);
})));
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/validation/const.js
var require_const = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/const.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var util_1 = require_util();
var equal_1 = require_equal();
var error = {
message: "must be equal to constant",
params: ({ schemaCode }) => (0, codegen_1._)`{allowedValue: ${schemaCode}}`
};
var def = {
keyword: "const",
$data: true,
error,
code(cxt) {
const { gen, data, $data, schemaCode, schema } = cxt;
if ($data || schema && typeof schema == "object") {
cxt.fail$data((0, codegen_1._)`!${(0, util_1.useFunc)(gen, equal_1.default)}(${data}, ${schemaCode})`);
} else {
cxt.fail((0, codegen_1._)`${schema} !== ${data}`);
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/validation/enum.js
var require_enum = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/enum.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var util_1 = require_util();
var equal_1 = require_equal();
var error = {
message: "must be equal to one of the allowed values",
params: ({ schemaCode }) => (0, codegen_1._)`{allowedValues: ${schemaCode}}`
};
var def = {
keyword: "enum",
schemaType: "array",
$data: true,
error,
code(cxt) {
const { gen, data, $data, schema, schemaCode, it } = cxt;
if (!$data && schema.length === 0)
throw new Error("enum must have non-empty array");
const useLoop = schema.length >= it.opts.loopEnum;
let eql;
const getEql = () => eql !== null && eql !== void 0 ? eql : eql = (0, util_1.useFunc)(gen, equal_1.default);
let valid;
if (useLoop || $data) {
valid = gen.let("valid");
cxt.block$data(valid, loopEnum);
} else {
if (!Array.isArray(schema))
throw new Error("ajv implementation error");
const vSchema = gen.const("vSchema", schemaCode);
valid = (0, codegen_1.or)(...schema.map((_x, i) => equalCode(vSchema, i)));
}
cxt.pass(valid);
function loopEnum() {
gen.assign(valid, false);
gen.forOf("v", schemaCode, (v) => gen.if((0, codegen_1._)`${getEql()}(${data}, ${v})`, () => gen.assign(valid, true).break()));
}
function equalCode(vSchema, i) {
const sch = schema[i];
return typeof sch === "object" && sch !== null ? (0, codegen_1._)`${getEql()}(${data}, ${vSchema}[${i}])` : (0, codegen_1._)`${data} === ${sch}`;
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/validation/index.js
var require_validation = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var limitNumber_1 = require_limitNumber();
var multipleOf_1 = require_multipleOf();
var limitLength_1 = require_limitLength();
var pattern_1 = require_pattern();
var limitProperties_1 = require_limitProperties();
var required_1 = require_required();
var limitItems_1 = require_limitItems();
var uniqueItems_1 = require_uniqueItems();
var const_1 = require_const();
var enum_1 = require_enum();
var validation = [
// number
limitNumber_1.default,
multipleOf_1.default,
// string
limitLength_1.default,
pattern_1.default,
// object
limitProperties_1.default,
required_1.default,
// array
limitItems_1.default,
uniqueItems_1.default,
// any
{ keyword: "type", schemaType: ["string", "array"] },
{ keyword: "nullable", schemaType: "boolean" },
const_1.default,
enum_1.default
];
exports.default = validation;
}
});
// node_modules/ajv/dist/vocabularies/applicator/additionalItems.js
var require_additionalItems = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/additionalItems.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateAdditionalItems = void 0;
var codegen_1 = require_codegen();
var util_1 = require_util();
var error = {
message: ({ params: { len } }) => (0, codegen_1.str)`must NOT have more than ${len} items`,
params: ({ params: { len } }) => (0, codegen_1._)`{limit: ${len}}`
};
var def = {
keyword: "additionalItems",
type: "array",
schemaType: ["boolean", "object"],
before: "uniqueItems",
error,
code(cxt) {
const { parentSchema, it } = cxt;
const { items } = parentSchema;
if (!Array.isArray(items)) {
(0, util_1.checkStrictMode)(it, '"additionalItems" is ignored when "items" is not an array of schemas');
return;
}
validateAdditionalItems(cxt, items);
}
};
function validateAdditionalItems(cxt, items) {
const { gen, schema, data, keyword, it } = cxt;
it.items = true;
const len = gen.const("len", (0, codegen_1._)`${data}.length`);
if (schema === false) {
cxt.setParams({ len: items.length });
cxt.pass((0, codegen_1._)`${len} <= ${items.length}`);
} else if (typeof schema == "object" && !(0, util_1.alwaysValidSchema)(it, schema)) {
const valid = gen.var("valid", (0, codegen_1._)`${len} <= ${items.length}`);
gen.if((0, codegen_1.not)(valid), () => validateItems(valid));
cxt.ok(valid);
}
function validateItems(valid) {
gen.forRange("i", items.length, len, (i) => {
cxt.subschema({ keyword, dataProp: i, dataPropType: util_1.Type.Num }, valid);
if (!it.allErrors)
gen.if((0, codegen_1.not)(valid), () => gen.break());
});
}
}
exports.validateAdditionalItems = validateAdditionalItems;
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/items.js
var require_items = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/items.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateTuple = void 0;
var codegen_1 = require_codegen();
var util_1 = require_util();
var code_1 = require_code2();
var def = {
keyword: "items",
type: "array",
schemaType: ["object", "array", "boolean"],
before: "uniqueItems",
code(cxt) {
const { schema, it } = cxt;
if (Array.isArray(schema))
return validateTuple(cxt, "additionalItems", schema);
it.items = true;
if ((0, util_1.alwaysValidSchema)(it, schema))
return;
cxt.ok((0, code_1.validateArray)(cxt));
}
};
function validateTuple(cxt, extraItems, schArr = cxt.schema) {
const { gen, parentSchema, data, keyword, it } = cxt;
checkStrictTuple(parentSchema);
if (it.opts.unevaluated && schArr.length && it.items !== true) {
it.items = util_1.mergeEvaluated.items(gen, schArr.length, it.items);
}
const valid = gen.name("valid");
const len = gen.const("len", (0, codegen_1._)`${data}.length`);
schArr.forEach((sch, i) => {
if ((0, util_1.alwaysValidSchema)(it, sch))
return;
gen.if((0, codegen_1._)`${len} > ${i}`, () => cxt.subschema({
keyword,
schemaProp: i,
dataProp: i
}, valid));
cxt.ok(valid);
});
function checkStrictTuple(sch) {
const { opts, errSchemaPath } = it;
const l = schArr.length;
const fullTuple = l === sch.minItems && (l === sch.maxItems || sch[extraItems] === false);
if (opts.strictTuples && !fullTuple) {
const msg = `"${keyword}" is ${l}-tuple, but minItems or maxItems/${extraItems} are not specified or different at path "${errSchemaPath}"`;
(0, util_1.checkStrictMode)(it, msg, opts.strictTuples);
}
}
}
exports.validateTuple = validateTuple;
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/prefixItems.js
var require_prefixItems = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/prefixItems.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var items_1 = require_items();
var def = {
keyword: "prefixItems",
type: "array",
schemaType: ["array"],
before: "uniqueItems",
code: (cxt) => (0, items_1.validateTuple)(cxt, "items")
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/items2020.js
var require_items2020 = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/items2020.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var util_1 = require_util();
var code_1 = require_code2();
var additionalItems_1 = require_additionalItems();
var error = {
message: ({ params: { len } }) => (0, codegen_1.str)`must NOT have more than ${len} items`,
params: ({ params: { len } }) => (0, codegen_1._)`{limit: ${len}}`
};
var def = {
keyword: "items",
type: "array",
schemaType: ["object", "boolean"],
before: "uniqueItems",
error,
code(cxt) {
const { schema, parentSchema, it } = cxt;
const { prefixItems } = parentSchema;
it.items = true;
if ((0, util_1.alwaysValidSchema)(it, schema))
return;
if (prefixItems)
(0, additionalItems_1.validateAdditionalItems)(cxt, prefixItems);
else
cxt.ok((0, code_1.validateArray)(cxt));
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/contains.js
var require_contains = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/contains.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var util_1 = require_util();
var error = {
message: ({ params: { min, max } }) => max === void 0 ? (0, codegen_1.str)`must contain at least ${min} valid item(s)` : (0, codegen_1.str)`must contain at least ${min} and no more than ${max} valid item(s)`,
params: ({ params: { min, max } }) => max === void 0 ? (0, codegen_1._)`{minContains: ${min}}` : (0, codegen_1._)`{minContains: ${min}, maxContains: ${max}}`
};
var def = {
keyword: "contains",
type: "array",
schemaType: ["object", "boolean"],
before: "uniqueItems",
trackErrors: true,
error,
code(cxt) {
const { gen, schema, parentSchema, data, it } = cxt;
let min;
let max;
const { minContains, maxContains } = parentSchema;
if (it.opts.next) {
min = minContains === void 0 ? 1 : minContains;
max = maxContains;
} else {
min = 1;
}
const len = gen.const("len", (0, codegen_1._)`${data}.length`);
cxt.setParams({ min, max });
if (max === void 0 && min === 0) {
(0, util_1.checkStrictMode)(it, `"minContains" == 0 without "maxContains": "contains" keyword ignored`);
return;
}
if (max !== void 0 && min > max) {
(0, util_1.checkStrictMode)(it, `"minContains" > "maxContains" is always invalid`);
cxt.fail();
return;
}
if ((0, util_1.alwaysValidSchema)(it, schema)) {
let cond = (0, codegen_1._)`${len} >= ${min}`;
if (max !== void 0)
cond = (0, codegen_1._)`${cond} && ${len} <= ${max}`;
cxt.pass(cond);
return;
}
it.items = true;
const valid = gen.name("valid");
if (max === void 0 && min === 1) {
validateItems(valid, () => gen.if(valid, () => gen.break()));
} else if (min === 0) {
gen.let(valid, true);
if (max !== void 0)
gen.if((0, codegen_1._)`${data}.length > 0`, validateItemsWithCount);
} else {
gen.let(valid, false);
validateItemsWithCount();
}
cxt.result(valid, () => cxt.reset());
function validateItemsWithCount() {
const schValid = gen.name("_valid");
const count = gen.let("count", 0);
validateItems(schValid, () => gen.if(schValid, () => checkLimits(count)));
}
function validateItems(_valid, block) {
gen.forRange("i", 0, len, (i) => {
cxt.subschema({
keyword: "contains",
dataProp: i,
dataPropType: util_1.Type.Num,
compositeRule: true
}, _valid);
block();
});
}
function checkLimits(count) {
gen.code((0, codegen_1._)`${count}++`);
if (max === void 0) {
gen.if((0, codegen_1._)`${count} >= ${min}`, () => gen.assign(valid, true).break());
} else {
gen.if((0, codegen_1._)`${count} > ${max}`, () => gen.assign(valid, false).break());
if (min === 1)
gen.assign(valid, true);
else
gen.if((0, codegen_1._)`${count} >= ${min}`, () => gen.assign(valid, true));
}
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/dependencies.js
var require_dependencies = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/dependencies.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateSchemaDeps = exports.validatePropertyDeps = exports.error = void 0;
var codegen_1 = require_codegen();
var util_1 = require_util();
var code_1 = require_code2();
exports.error = {
message: ({ params: { property, depsCount, deps } }) => {
const property_ies = depsCount === 1 ? "property" : "properties";
return (0, codegen_1.str)`must have ${property_ies} ${deps} when property ${property} is present`;
},
params: ({ params: { property, depsCount, deps, missingProperty } }) => (0, codegen_1._)`{property: ${property},
missingProperty: ${missingProperty},
depsCount: ${depsCount},
deps: ${deps}}`
// TODO change to reference
};
var def = {
keyword: "dependencies",
type: "object",
schemaType: "object",
error: exports.error,
code(cxt) {
const [propDeps, schDeps] = splitDependencies(cxt);
validatePropertyDeps(cxt, propDeps);
validateSchemaDeps(cxt, schDeps);
}
};
function splitDependencies({ schema }) {
const propertyDeps = {};
const schemaDeps = {};
for (const key in schema) {
if (key === "__proto__")
continue;
const deps = Array.isArray(schema[key]) ? propertyDeps : schemaDeps;
deps[key] = schema[key];
}
return [propertyDeps, schemaDeps];
}
function validatePropertyDeps(cxt, propertyDeps = cxt.schema) {
const { gen, data, it } = cxt;
if (Object.keys(propertyDeps).length === 0)
return;
const missing = gen.let("missing");
for (const prop in propertyDeps) {
const deps = propertyDeps[prop];
if (deps.length === 0)
continue;
const hasProperty = (0, code_1.propertyInData)(gen, data, prop, it.opts.ownProperties);
cxt.setParams({
property: prop,
depsCount: deps.length,
deps: deps.join(", ")
});
if (it.allErrors) {
gen.if(hasProperty, () => {
for (const depProp of deps) {
(0, code_1.checkReportMissingProp)(cxt, depProp);
}
});
} else {
gen.if((0, codegen_1._)`${hasProperty} && (${(0, code_1.checkMissingProp)(cxt, deps, missing)})`);
(0, code_1.reportMissingProp)(cxt, missing);
gen.else();
}
}
}
exports.validatePropertyDeps = validatePropertyDeps;
function validateSchemaDeps(cxt, schemaDeps = cxt.schema) {
const { gen, data, keyword, it } = cxt;
const valid = gen.name("valid");
for (const prop in schemaDeps) {
if ((0, util_1.alwaysValidSchema)(it, schemaDeps[prop]))
continue;
gen.if(
(0, code_1.propertyInData)(gen, data, prop, it.opts.ownProperties),
() => {
const schCxt = cxt.subschema({ keyword, schemaProp: prop }, valid);
cxt.mergeValidEvaluated(schCxt, valid);
},
() => gen.var(valid, true)
// TODO var
);
cxt.ok(valid);
}
}
exports.validateSchemaDeps = validateSchemaDeps;
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/propertyNames.js
var require_propertyNames = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/propertyNames.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var util_1 = require_util();
var error = {
message: "property name must be valid",
params: ({ params }) => (0, codegen_1._)`{propertyName: ${params.propertyName}}`
};
var def = {
keyword: "propertyNames",
type: "object",
schemaType: ["object", "boolean"],
error,
code(cxt) {
const { gen, schema, data, it } = cxt;
if ((0, util_1.alwaysValidSchema)(it, schema))
return;
const valid = gen.name("valid");
gen.forIn("key", data, (key) => {
cxt.setParams({ propertyName: key });
cxt.subschema({
keyword: "propertyNames",
data: key,
dataTypes: ["string"],
propertyName: key,
compositeRule: true
}, valid);
gen.if((0, codegen_1.not)(valid), () => {
cxt.error(true);
if (!it.allErrors)
gen.break();
});
});
cxt.ok(valid);
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js
var require_additionalProperties = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var code_1 = require_code2();
var codegen_1 = require_codegen();
var names_1 = require_names();
var util_1 = require_util();
var error = {
message: "must NOT have additional properties",
params: ({ params }) => (0, codegen_1._)`{additionalProperty: ${params.additionalProperty}}`
};
var def = {
keyword: "additionalProperties",
type: ["object"],
schemaType: ["boolean", "object"],
allowUndefined: true,
trackErrors: true,
error,
code(cxt) {
const { gen, schema, parentSchema, data, errsCount, it } = cxt;
if (!errsCount)
throw new Error("ajv implementation error");
const { allErrors, opts } = it;
it.props = true;
if (opts.removeAdditional !== "all" && (0, util_1.alwaysValidSchema)(it, schema))
return;
const props = (0, code_1.allSchemaProperties)(parentSchema.properties);
const patProps = (0, code_1.allSchemaProperties)(parentSchema.patternProperties);
checkAdditionalProperties();
cxt.ok((0, codegen_1._)`${errsCount} === ${names_1.default.errors}`);
function checkAdditionalProperties() {
gen.forIn("key", data, (key) => {
if (!props.length && !patProps.length)
additionalPropertyCode(key);
else
gen.if(isAdditional(key), () => additionalPropertyCode(key));
});
}
function isAdditional(key) {
let definedProp;
if (props.length > 8) {
const propsSchema = (0, util_1.schemaRefOrVal)(it, parentSchema.properties, "properties");
definedProp = (0, code_1.isOwnProperty)(gen, propsSchema, key);
} else if (props.length) {
definedProp = (0, codegen_1.or)(...props.map((p) => (0, codegen_1._)`${key} === ${p}`));
} else {
definedProp = codegen_1.nil;
}
if (patProps.length) {
definedProp = (0, codegen_1.or)(definedProp, ...patProps.map((p) => (0, codegen_1._)`${(0, code_1.usePattern)(cxt, p)}.test(${key})`));
}
return (0, codegen_1.not)(definedProp);
}
function deleteAdditional(key) {
gen.code((0, codegen_1._)`delete ${data}[${key}]`);
}
function additionalPropertyCode(key) {
if (opts.removeAdditional === "all" || opts.removeAdditional && schema === false) {
deleteAdditional(key);
return;
}
if (schema === false) {
cxt.setParams({ additionalProperty: key });
cxt.error();
if (!allErrors)
gen.break();
return;
}
if (typeof schema == "object" && !(0, util_1.alwaysValidSchema)(it, schema)) {
const valid = gen.name("valid");
if (opts.removeAdditional === "failing") {
applyAdditionalSchema(key, valid, false);
gen.if((0, codegen_1.not)(valid), () => {
cxt.reset();
deleteAdditional(key);
});
} else {
applyAdditionalSchema(key, valid);
if (!allErrors)
gen.if((0, codegen_1.not)(valid), () => gen.break());
}
}
}
function applyAdditionalSchema(key, valid, errors) {
const subschema = {
keyword: "additionalProperties",
dataProp: key,
dataPropType: util_1.Type.Str
};
if (errors === false) {
Object.assign(subschema, {
compositeRule: true,
createErrors: false,
allErrors: false
});
}
cxt.subschema(subschema, valid);
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/properties.js
var require_properties = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/properties.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var validate_1 = require_validate();
var code_1 = require_code2();
var util_1 = require_util();
var additionalProperties_1 = require_additionalProperties();
var def = {
keyword: "properties",
type: "object",
schemaType: "object",
code(cxt) {
const { gen, schema, parentSchema, data, it } = cxt;
if (it.opts.removeAdditional === "all" && parentSchema.additionalProperties === void 0) {
additionalProperties_1.default.code(new validate_1.KeywordCxt(it, additionalProperties_1.default, "additionalProperties"));
}
const allProps = (0, code_1.allSchemaProperties)(schema);
for (const prop of allProps) {
it.definedProperties.add(prop);
}
if (it.opts.unevaluated && allProps.length && it.props !== true) {
it.props = util_1.mergeEvaluated.props(gen, (0, util_1.toHash)(allProps), it.props);
}
const properties = allProps.filter((p) => !(0, util_1.alwaysValidSchema)(it, schema[p]));
if (properties.length === 0)
return;
const valid = gen.name("valid");
for (const prop of properties) {
if (hasDefault(prop)) {
applyPropertySchema(prop);
} else {
gen.if((0, code_1.propertyInData)(gen, data, prop, it.opts.ownProperties));
applyPropertySchema(prop);
if (!it.allErrors)
gen.else().var(valid, true);
gen.endIf();
}
cxt.it.definedProperties.add(prop);
cxt.ok(valid);
}
function hasDefault(prop) {
return it.opts.useDefaults && !it.compositeRule && schema[prop].default !== void 0;
}
function applyPropertySchema(prop) {
cxt.subschema({
keyword: "properties",
schemaProp: prop,
dataProp: prop
}, valid);
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/patternProperties.js
var require_patternProperties = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/patternProperties.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var code_1 = require_code2();
var codegen_1 = require_codegen();
var util_1 = require_util();
var util_2 = require_util();
var def = {
keyword: "patternProperties",
type: "object",
schemaType: "object",
code(cxt) {
const { gen, schema, data, parentSchema, it } = cxt;
const { opts } = it;
const patterns = (0, code_1.allSchemaProperties)(schema);
const alwaysValidPatterns = patterns.filter((p) => (0, util_1.alwaysValidSchema)(it, schema[p]));
if (patterns.length === 0 || alwaysValidPatterns.length === patterns.length && (!it.opts.unevaluated || it.props === true)) {
return;
}
const checkProperties = opts.strictSchema && !opts.allowMatchingProperties && parentSchema.properties;
const valid = gen.name("valid");
if (it.props !== true && !(it.props instanceof codegen_1.Name)) {
it.props = (0, util_2.evaluatedPropsToName)(gen, it.props);
}
const { props } = it;
validatePatternProperties();
function validatePatternProperties() {
for (const pat of patterns) {
if (checkProperties)
checkMatchingProperties(pat);
if (it.allErrors) {
validateProperties(pat);
} else {
gen.var(valid, true);
validateProperties(pat);
gen.if(valid);
}
}
}
function checkMatchingProperties(pat) {
for (const prop in checkProperties) {
if (new RegExp(pat).test(prop)) {
(0, util_1.checkStrictMode)(it, `property ${prop} matches pattern ${pat} (use allowMatchingProperties)`);
}
}
}
function validateProperties(pat) {
gen.forIn("key", data, (key) => {
gen.if((0, codegen_1._)`${(0, code_1.usePattern)(cxt, pat)}.test(${key})`, () => {
const alwaysValid = alwaysValidPatterns.includes(pat);
if (!alwaysValid) {
cxt.subschema({
keyword: "patternProperties",
schemaProp: pat,
dataProp: key,
dataPropType: util_2.Type.Str
}, valid);
}
if (it.opts.unevaluated && props !== true) {
gen.assign((0, codegen_1._)`${props}[${key}]`, true);
} else if (!alwaysValid && !it.allErrors) {
gen.if((0, codegen_1.not)(valid), () => gen.break());
}
});
});
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/not.js
var require_not = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/not.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var util_1 = require_util();
var def = {
keyword: "not",
schemaType: ["object", "boolean"],
trackErrors: true,
code(cxt) {
const { gen, schema, it } = cxt;
if ((0, util_1.alwaysValidSchema)(it, schema)) {
cxt.fail();
return;
}
const valid = gen.name("valid");
cxt.subschema({
keyword: "not",
compositeRule: true,
createErrors: false,
allErrors: false
}, valid);
cxt.failResult(valid, () => cxt.reset(), () => cxt.error());
},
error: { message: "must NOT be valid" }
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/anyOf.js
var require_anyOf = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/anyOf.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var code_1 = require_code2();
var def = {
keyword: "anyOf",
schemaType: "array",
trackErrors: true,
code: code_1.validateUnion,
error: { message: "must match a schema in anyOf" }
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/oneOf.js
var require_oneOf = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/oneOf.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var util_1 = require_util();
var error = {
message: "must match exactly one schema in oneOf",
params: ({ params }) => (0, codegen_1._)`{passingSchemas: ${params.passing}}`
};
var def = {
keyword: "oneOf",
schemaType: "array",
trackErrors: true,
error,
code(cxt) {
const { gen, schema, parentSchema, it } = cxt;
if (!Array.isArray(schema))
throw new Error("ajv implementation error");
if (it.opts.discriminator && parentSchema.discriminator)
return;
const schArr = schema;
const valid = gen.let("valid", false);
const passing = gen.let("passing", null);
const schValid = gen.name("_valid");
cxt.setParams({ passing });
gen.block(validateOneOf);
cxt.result(valid, () => cxt.reset(), () => cxt.error(true));
function validateOneOf() {
schArr.forEach((sch, i) => {
let schCxt;
if ((0, util_1.alwaysValidSchema)(it, sch)) {
gen.var(schValid, true);
} else {
schCxt = cxt.subschema({
keyword: "oneOf",
schemaProp: i,
compositeRule: true
}, schValid);
}
if (i > 0) {
gen.if((0, codegen_1._)`${schValid} && ${valid}`).assign(valid, false).assign(passing, (0, codegen_1._)`[${passing}, ${i}]`).else();
}
gen.if(schValid, () => {
gen.assign(valid, true);
gen.assign(passing, i);
if (schCxt)
cxt.mergeEvaluated(schCxt, codegen_1.Name);
});
});
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/allOf.js
var require_allOf = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/allOf.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var util_1 = require_util();
var def = {
keyword: "allOf",
schemaType: "array",
code(cxt) {
const { gen, schema, it } = cxt;
if (!Array.isArray(schema))
throw new Error("ajv implementation error");
const valid = gen.name("valid");
schema.forEach((sch, i) => {
if ((0, util_1.alwaysValidSchema)(it, sch))
return;
const schCxt = cxt.subschema({ keyword: "allOf", schemaProp: i }, valid);
cxt.ok(valid);
cxt.mergeEvaluated(schCxt);
});
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/if.js
var require_if = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/if.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var util_1 = require_util();
var error = {
message: ({ params }) => (0, codegen_1.str)`must match "${params.ifClause}" schema`,
params: ({ params }) => (0, codegen_1._)`{failingKeyword: ${params.ifClause}}`
};
var def = {
keyword: "if",
schemaType: ["object", "boolean"],
trackErrors: true,
error,
code(cxt) {
const { gen, parentSchema, it } = cxt;
if (parentSchema.then === void 0 && parentSchema.else === void 0) {
(0, util_1.checkStrictMode)(it, '"if" without "then" and "else" is ignored');
}
const hasThen = hasSchema(it, "then");
const hasElse = hasSchema(it, "else");
if (!hasThen && !hasElse)
return;
const valid = gen.let("valid", true);
const schValid = gen.name("_valid");
validateIf();
cxt.reset();
if (hasThen && hasElse) {
const ifClause = gen.let("ifClause");
cxt.setParams({ ifClause });
gen.if(schValid, validateClause("then", ifClause), validateClause("else", ifClause));
} else if (hasThen) {
gen.if(schValid, validateClause("then"));
} else {
gen.if((0, codegen_1.not)(schValid), validateClause("else"));
}
cxt.pass(valid, () => cxt.error(true));
function validateIf() {
const schCxt = cxt.subschema({
keyword: "if",
compositeRule: true,
createErrors: false,
allErrors: false
}, schValid);
cxt.mergeEvaluated(schCxt);
}
function validateClause(keyword, ifClause) {
return () => {
const schCxt = cxt.subschema({ keyword }, schValid);
gen.assign(valid, schValid);
cxt.mergeValidEvaluated(schCxt, valid);
if (ifClause)
gen.assign(ifClause, (0, codegen_1._)`${keyword}`);
else
cxt.setParams({ ifClause: keyword });
};
}
}
};
function hasSchema(it, keyword) {
const schema = it.schema[keyword];
return schema !== void 0 && !(0, util_1.alwaysValidSchema)(it, schema);
}
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/thenElse.js
var require_thenElse = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/thenElse.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var util_1 = require_util();
var def = {
keyword: ["then", "else"],
schemaType: ["object", "boolean"],
code({ keyword, parentSchema, it }) {
if (parentSchema.if === void 0)
(0, util_1.checkStrictMode)(it, `"${keyword}" without "if" is ignored`);
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/index.js
var require_applicator = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var additionalItems_1 = require_additionalItems();
var prefixItems_1 = require_prefixItems();
var items_1 = require_items();
var items2020_1 = require_items2020();
var contains_1 = require_contains();
var dependencies_1 = require_dependencies();
var propertyNames_1 = require_propertyNames();
var additionalProperties_1 = require_additionalProperties();
var properties_1 = require_properties();
var patternProperties_1 = require_patternProperties();
var not_1 = require_not();
var anyOf_1 = require_anyOf();
var oneOf_1 = require_oneOf();
var allOf_1 = require_allOf();
var if_1 = require_if();
var thenElse_1 = require_thenElse();
function getApplicator(draft2020 = false) {
const applicator = [
// any
not_1.default,
anyOf_1.default,
oneOf_1.default,
allOf_1.default,
if_1.default,
thenElse_1.default,
// object
propertyNames_1.default,
additionalProperties_1.default,
dependencies_1.default,
properties_1.default,
patternProperties_1.default
];
if (draft2020)
applicator.push(prefixItems_1.default, items2020_1.default);
else
applicator.push(additionalItems_1.default, items_1.default);
applicator.push(contains_1.default);
return applicator;
}
exports.default = getApplicator;
}
});
// node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.js
var require_dynamicAnchor = __commonJS({
"node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.dynamicAnchor = void 0;
var codegen_1 = require_codegen();
var names_1 = require_names();
var compile_1 = require_compile();
var ref_1 = require_ref();
var def = {
keyword: "$dynamicAnchor",
schemaType: "string",
code: (cxt) => dynamicAnchor(cxt, cxt.schema)
};
function dynamicAnchor(cxt, anchor) {
const { gen, it } = cxt;
it.schemaEnv.root.dynamicAnchors[anchor] = true;
const v = (0, codegen_1._)`${names_1.default.dynamicAnchors}${(0, codegen_1.getProperty)(anchor)}`;
const validate = it.errSchemaPath === "#" ? it.validateName : _getValidate(cxt);
gen.if((0, codegen_1._)`!${v}`, () => gen.assign(v, validate));
}
exports.dynamicAnchor = dynamicAnchor;
function _getValidate(cxt) {
const { schemaEnv, schema, self } = cxt.it;
const { root, baseId, localRefs, meta } = schemaEnv.root;
const { schemaId } = self.opts;
const sch = new compile_1.SchemaEnv({ schema, schemaId, root, baseId, localRefs, meta });
compile_1.compileSchema.call(self, sch);
return (0, ref_1.getValidate)(cxt, sch);
}
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.js
var require_dynamicRef = __commonJS({
"node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.dynamicRef = void 0;
var codegen_1 = require_codegen();
var names_1 = require_names();
var ref_1 = require_ref();
var def = {
keyword: "$dynamicRef",
schemaType: "string",
code: (cxt) => dynamicRef(cxt, cxt.schema)
};
function dynamicRef(cxt, ref) {
const { gen, keyword, it } = cxt;
if (ref[0] !== "#")
throw new Error(`"${keyword}" only supports hash fragment reference`);
const anchor = ref.slice(1);
if (it.allErrors) {
_dynamicRef();
} else {
const valid = gen.let("valid", false);
_dynamicRef(valid);
cxt.ok(valid);
}
function _dynamicRef(valid) {
if (it.schemaEnv.root.dynamicAnchors[anchor]) {
const v = gen.let("_v", (0, codegen_1._)`${names_1.default.dynamicAnchors}${(0, codegen_1.getProperty)(anchor)}`);
gen.if(v, _callRef(v, valid), _callRef(it.validateName, valid));
} else {
_callRef(it.validateName, valid)();
}
}
function _callRef(validate, valid) {
return valid ? () => gen.block(() => {
(0, ref_1.callRef)(cxt, validate);
gen.let(valid, true);
}) : () => (0, ref_1.callRef)(cxt, validate);
}
}
exports.dynamicRef = dynamicRef;
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.js
var require_recursiveAnchor = __commonJS({
"node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var dynamicAnchor_1 = require_dynamicAnchor();
var util_1 = require_util();
var def = {
keyword: "$recursiveAnchor",
schemaType: "boolean",
code(cxt) {
if (cxt.schema)
(0, dynamicAnchor_1.dynamicAnchor)(cxt, "");
else
(0, util_1.checkStrictMode)(cxt.it, "$recursiveAnchor: false is ignored");
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.js
var require_recursiveRef = __commonJS({
"node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var dynamicRef_1 = require_dynamicRef();
var def = {
keyword: "$recursiveRef",
schemaType: "string",
code: (cxt) => (0, dynamicRef_1.dynamicRef)(cxt, cxt.schema)
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/dynamic/index.js
var require_dynamic = __commonJS({
"node_modules/ajv/dist/vocabularies/dynamic/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var dynamicAnchor_1 = require_dynamicAnchor();
var dynamicRef_1 = require_dynamicRef();
var recursiveAnchor_1 = require_recursiveAnchor();
var recursiveRef_1 = require_recursiveRef();
var dynamic = [dynamicAnchor_1.default, dynamicRef_1.default, recursiveAnchor_1.default, recursiveRef_1.default];
exports.default = dynamic;
}
});
// node_modules/ajv/dist/vocabularies/validation/dependentRequired.js
var require_dependentRequired = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/dependentRequired.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var dependencies_1 = require_dependencies();
var def = {
keyword: "dependentRequired",
type: "object",
schemaType: "object",
error: dependencies_1.error,
code: (cxt) => (0, dependencies_1.validatePropertyDeps)(cxt)
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.js
var require_dependentSchemas = __commonJS({
"node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var dependencies_1 = require_dependencies();
var def = {
keyword: "dependentSchemas",
type: "object",
schemaType: "object",
code: (cxt) => (0, dependencies_1.validateSchemaDeps)(cxt)
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/validation/limitContains.js
var require_limitContains = __commonJS({
"node_modules/ajv/dist/vocabularies/validation/limitContains.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var util_1 = require_util();
var def = {
keyword: ["maxContains", "minContains"],
type: "array",
schemaType: "number",
code({ keyword, parentSchema, it }) {
if (parentSchema.contains === void 0) {
(0, util_1.checkStrictMode)(it, `"${keyword}" without "contains" is ignored`);
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/next.js
var require_next = __commonJS({
"node_modules/ajv/dist/vocabularies/next.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var dependentRequired_1 = require_dependentRequired();
var dependentSchemas_1 = require_dependentSchemas();
var limitContains_1 = require_limitContains();
var next = [dependentRequired_1.default, dependentSchemas_1.default, limitContains_1.default];
exports.default = next;
}
});
// node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.js
var require_unevaluatedProperties = __commonJS({
"node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var util_1 = require_util();
var names_1 = require_names();
var error = {
message: "must NOT have unevaluated properties",
params: ({ params }) => (0, codegen_1._)`{unevaluatedProperty: ${params.unevaluatedProperty}}`
};
var def = {
keyword: "unevaluatedProperties",
type: "object",
schemaType: ["boolean", "object"],
trackErrors: true,
error,
code(cxt) {
const { gen, schema, data, errsCount, it } = cxt;
if (!errsCount)
throw new Error("ajv implementation error");
const { allErrors, props } = it;
if (props instanceof codegen_1.Name) {
gen.if((0, codegen_1._)`${props} !== true`, () => gen.forIn("key", data, (key) => gen.if(unevaluatedDynamic(props, key), () => unevaluatedPropCode(key))));
} else if (props !== true) {
gen.forIn("key", data, (key) => props === void 0 ? unevaluatedPropCode(key) : gen.if(unevaluatedStatic(props, key), () => unevaluatedPropCode(key)));
}
it.props = true;
cxt.ok((0, codegen_1._)`${errsCount} === ${names_1.default.errors}`);
function unevaluatedPropCode(key) {
if (schema === false) {
cxt.setParams({ unevaluatedProperty: key });
cxt.error();
if (!allErrors)
gen.break();
return;
}
if (!(0, util_1.alwaysValidSchema)(it, schema)) {
const valid = gen.name("valid");
cxt.subschema({
keyword: "unevaluatedProperties",
dataProp: key,
dataPropType: util_1.Type.Str
}, valid);
if (!allErrors)
gen.if((0, codegen_1.not)(valid), () => gen.break());
}
}
function unevaluatedDynamic(evaluatedProps, key) {
return (0, codegen_1._)`!${evaluatedProps} || !${evaluatedProps}[${key}]`;
}
function unevaluatedStatic(evaluatedProps, key) {
const ps = [];
for (const p in evaluatedProps) {
if (evaluatedProps[p] === true)
ps.push((0, codegen_1._)`${key} !== ${p}`);
}
return (0, codegen_1.and)(...ps);
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.js
var require_unevaluatedItems = __commonJS({
"node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var util_1 = require_util();
var error = {
message: ({ params: { len } }) => (0, codegen_1.str)`must NOT have more than ${len} items`,
params: ({ params: { len } }) => (0, codegen_1._)`{limit: ${len}}`
};
var def = {
keyword: "unevaluatedItems",
type: "array",
schemaType: ["boolean", "object"],
error,
code(cxt) {
const { gen, schema, data, it } = cxt;
const items = it.items || 0;
if (items === true)
return;
const len = gen.const("len", (0, codegen_1._)`${data}.length`);
if (schema === false) {
cxt.setParams({ len: items });
cxt.fail((0, codegen_1._)`${len} > ${items}`);
} else if (typeof schema == "object" && !(0, util_1.alwaysValidSchema)(it, schema)) {
const valid = gen.var("valid", (0, codegen_1._)`${len} <= ${items}`);
gen.if((0, codegen_1.not)(valid), () => validateItems(valid, items));
cxt.ok(valid);
}
it.items = true;
function validateItems(valid, from) {
gen.forRange("i", from, len, (i) => {
cxt.subschema({ keyword: "unevaluatedItems", dataProp: i, dataPropType: util_1.Type.Num }, valid);
if (!it.allErrors)
gen.if((0, codegen_1.not)(valid), () => gen.break());
});
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/unevaluated/index.js
var require_unevaluated = __commonJS({
"node_modules/ajv/dist/vocabularies/unevaluated/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var unevaluatedProperties_1 = require_unevaluatedProperties();
var unevaluatedItems_1 = require_unevaluatedItems();
var unevaluated = [unevaluatedProperties_1.default, unevaluatedItems_1.default];
exports.default = unevaluated;
}
});
// node_modules/ajv/dist/vocabularies/format/format.js
var require_format = __commonJS({
"node_modules/ajv/dist/vocabularies/format/format.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var error = {
message: ({ schemaCode }) => (0, codegen_1.str)`must match format "${schemaCode}"`,
params: ({ schemaCode }) => (0, codegen_1._)`{format: ${schemaCode}}`
};
var def = {
keyword: "format",
type: ["number", "string"],
schemaType: "string",
$data: true,
error,
code(cxt, ruleType) {
const { gen, data, $data, schema, schemaCode, it } = cxt;
const { opts, errSchemaPath, schemaEnv, self } = it;
if (!opts.validateFormats)
return;
if ($data)
validate$DataFormat();
else
validateFormat();
function validate$DataFormat() {
const fmts = gen.scopeValue("formats", {
ref: self.formats,
code: opts.code.formats
});
const fDef = gen.const("fDef", (0, codegen_1._)`${fmts}[${schemaCode}]`);
const fType = gen.let("fType");
const format = gen.let("format");
gen.if((0, codegen_1._)`typeof ${fDef} == "object" && !(${fDef} instanceof RegExp)`, () => gen.assign(fType, (0, codegen_1._)`${fDef}.type || "string"`).assign(format, (0, codegen_1._)`${fDef}.validate`), () => gen.assign(fType, (0, codegen_1._)`"string"`).assign(format, fDef));
cxt.fail$data((0, codegen_1.or)(unknownFmt(), invalidFmt()));
function unknownFmt() {
if (opts.strictSchema === false)
return codegen_1.nil;
return (0, codegen_1._)`${schemaCode} && !${format}`;
}
function invalidFmt() {
const callFormat = schemaEnv.$async ? (0, codegen_1._)`(${fDef}.async ? await ${format}(${data}) : ${format}(${data}))` : (0, codegen_1._)`${format}(${data})`;
const validData = (0, codegen_1._)`(typeof ${format} == "function" ? ${callFormat} : ${format}.test(${data}))`;
return (0, codegen_1._)`${format} && ${format} !== true && ${fType} === ${ruleType} && !${validData}`;
}
}
function validateFormat() {
const formatDef = self.formats[schema];
if (!formatDef) {
unknownFormat();
return;
}
if (formatDef === true)
return;
const [fmtType, format, fmtRef] = getFormat(formatDef);
if (fmtType === ruleType)
cxt.pass(validCondition());
function unknownFormat() {
if (opts.strictSchema === false) {
self.logger.warn(unknownMsg());
return;
}
throw new Error(unknownMsg());
function unknownMsg() {
return `unknown format "${schema}" ignored in schema at path "${errSchemaPath}"`;
}
}
function getFormat(fmtDef) {
const code = fmtDef instanceof RegExp ? (0, codegen_1.regexpCode)(fmtDef) : opts.code.formats ? (0, codegen_1._)`${opts.code.formats}${(0, codegen_1.getProperty)(schema)}` : void 0;
const fmt = gen.scopeValue("formats", { key: schema, ref: fmtDef, code });
if (typeof fmtDef == "object" && !(fmtDef instanceof RegExp)) {
return [fmtDef.type || "string", fmtDef.validate, (0, codegen_1._)`${fmt}.validate`];
}
return ["string", fmtDef, fmt];
}
function validCondition() {
if (typeof formatDef == "object" && !(formatDef instanceof RegExp) && formatDef.async) {
if (!schemaEnv.$async)
throw new Error("async format in sync schema");
return (0, codegen_1._)`await ${fmtRef}(${data})`;
}
return typeof format == "function" ? (0, codegen_1._)`${fmtRef}(${data})` : (0, codegen_1._)`${fmtRef}.test(${data})`;
}
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/vocabularies/format/index.js
var require_format2 = __commonJS({
"node_modules/ajv/dist/vocabularies/format/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var format_1 = require_format();
var format = [format_1.default];
exports.default = format;
}
});
// node_modules/ajv/dist/vocabularies/metadata.js
var require_metadata = __commonJS({
"node_modules/ajv/dist/vocabularies/metadata.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.contentVocabulary = exports.metadataVocabulary = void 0;
exports.metadataVocabulary = [
"title",
"description",
"default",
"deprecated",
"readOnly",
"writeOnly",
"examples"
];
exports.contentVocabulary = [
"contentMediaType",
"contentEncoding",
"contentSchema"
];
}
});
// node_modules/ajv/dist/vocabularies/draft2020.js
var require_draft2020 = __commonJS({
"node_modules/ajv/dist/vocabularies/draft2020.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var core_1 = require_core2();
var validation_1 = require_validation();
var applicator_1 = require_applicator();
var dynamic_1 = require_dynamic();
var next_1 = require_next();
var unevaluated_1 = require_unevaluated();
var format_1 = require_format2();
var metadata_1 = require_metadata();
var draft2020Vocabularies = [
dynamic_1.default,
core_1.default,
validation_1.default,
(0, applicator_1.default)(true),
format_1.default,
metadata_1.metadataVocabulary,
metadata_1.contentVocabulary,
next_1.default,
unevaluated_1.default
];
exports.default = draft2020Vocabularies;
}
});
// node_modules/ajv/dist/vocabularies/discriminator/types.js
var require_types = __commonJS({
"node_modules/ajv/dist/vocabularies/discriminator/types.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DiscrError = void 0;
var DiscrError;
(function(DiscrError2) {
DiscrError2["Tag"] = "tag";
DiscrError2["Mapping"] = "mapping";
})(DiscrError || (exports.DiscrError = DiscrError = {}));
}
});
// node_modules/ajv/dist/vocabularies/discriminator/index.js
var require_discriminator = __commonJS({
"node_modules/ajv/dist/vocabularies/discriminator/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var codegen_1 = require_codegen();
var types_1 = require_types();
var compile_1 = require_compile();
var ref_error_1 = require_ref_error();
var util_1 = require_util();
var error = {
message: ({ params: { discrError, tagName } }) => discrError === types_1.DiscrError.Tag ? `tag "${tagName}" must be string` : `value of tag "${tagName}" must be in oneOf`,
params: ({ params: { discrError, tag, tagName } }) => (0, codegen_1._)`{error: ${discrError}, tag: ${tagName}, tagValue: ${tag}}`
};
var def = {
keyword: "discriminator",
type: "object",
schemaType: "object",
error,
code(cxt) {
const { gen, data, schema, parentSchema, it } = cxt;
const { oneOf: oneOf2 } = parentSchema;
if (!it.opts.discriminator) {
throw new Error("discriminator: requires discriminator option");
}
const tagName = schema.propertyName;
if (typeof tagName != "string")
throw new Error("discriminator: requires propertyName");
if (schema.mapping)
throw new Error("discriminator: mapping is not supported");
if (!oneOf2)
throw new Error("discriminator: requires oneOf keyword");
const valid = gen.let("valid", false);
const tag = gen.const("tag", (0, codegen_1._)`${data}${(0, codegen_1.getProperty)(tagName)}`);
gen.if((0, codegen_1._)`typeof ${tag} == "string"`, () => validateMapping(), () => cxt.error(false, { discrError: types_1.DiscrError.Tag, tag, tagName }));
cxt.ok(valid);
function validateMapping() {
const mapping = getMapping();
gen.if(false);
for (const tagValue in mapping) {
gen.elseIf((0, codegen_1._)`${tag} === ${tagValue}`);
gen.assign(valid, applyTagSchema(mapping[tagValue]));
}
gen.else();
cxt.error(false, { discrError: types_1.DiscrError.Mapping, tag, tagName });
gen.endIf();
}
function applyTagSchema(schemaProp) {
const _valid = gen.name("valid");
const schCxt = cxt.subschema({ keyword: "oneOf", schemaProp }, _valid);
cxt.mergeEvaluated(schCxt, codegen_1.Name);
return _valid;
}
function getMapping() {
var _a;
const oneOfMapping = {};
const topRequired = hasRequired(parentSchema);
let tagRequired = true;
for (let i = 0; i < oneOf2.length; i++) {
let sch = oneOf2[i];
if ((sch === null || sch === void 0 ? void 0 : sch.$ref) && !(0, util_1.schemaHasRulesButRef)(sch, it.self.RULES)) {
const ref = sch.$ref;
sch = compile_1.resolveRef.call(it.self, it.schemaEnv.root, it.baseId, ref);
if (sch instanceof compile_1.SchemaEnv)
sch = sch.schema;
if (sch === void 0)
throw new ref_error_1.default(it.opts.uriResolver, it.baseId, ref);
}
const propSch = (_a = sch === null || sch === void 0 ? void 0 : sch.properties) === null || _a === void 0 ? void 0 : _a[tagName];
if (typeof propSch != "object") {
throw new Error(`discriminator: oneOf subschemas (or referenced schemas) must have "properties/${tagName}"`);
}
tagRequired = tagRequired && (topRequired || hasRequired(sch));
addMappings(propSch, i);
}
if (!tagRequired)
throw new Error(`discriminator: "${tagName}" must be required`);
return oneOfMapping;
function hasRequired({ required }) {
return Array.isArray(required) && required.includes(tagName);
}
function addMappings(sch, i) {
if (sch.const) {
addMapping(sch.const, i);
} else if (sch.enum) {
for (const tagValue of sch.enum) {
addMapping(tagValue, i);
}
} else {
throw new Error(`discriminator: "properties/${tagName}" must have "const" or "enum"`);
}
}
function addMapping(tagValue, i) {
if (typeof tagValue != "string" || tagValue in oneOfMapping) {
throw new Error(`discriminator: "${tagName}" values must be unique strings`);
}
oneOfMapping[tagValue] = i;
}
}
}
};
exports.default = def;
}
});
// node_modules/ajv/dist/refs/json-schema-2020-12/schema.json
var require_schema = __commonJS({
"node_modules/ajv/dist/refs/json-schema-2020-12/schema.json"(exports, module) {
module.exports = {
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://json-schema.org/draft/2020-12/schema",
$vocabulary: {
"https://json-schema.org/draft/2020-12/vocab/core": true,
"https://json-schema.org/draft/2020-12/vocab/applicator": true,
"https://json-schema.org/draft/2020-12/vocab/unevaluated": true,
"https://json-schema.org/draft/2020-12/vocab/validation": true,
"https://json-schema.org/draft/2020-12/vocab/meta-data": true,
"https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
"https://json-schema.org/draft/2020-12/vocab/content": true
},
$dynamicAnchor: "meta",
title: "Core and Validation specifications meta-schema",
allOf: [
{ $ref: "meta/core" },
{ $ref: "meta/applicator" },
{ $ref: "meta/unevaluated" },
{ $ref: "meta/validation" },
{ $ref: "meta/meta-data" },
{ $ref: "meta/format-annotation" },
{ $ref: "meta/content" }
],
type: ["object", "boolean"],
$comment: "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.",
properties: {
definitions: {
$comment: '"definitions" has been replaced by "$defs".',
type: "object",
additionalProperties: { $dynamicRef: "#meta" },
deprecated: true,
default: {}
},
dependencies: {
$comment: '"dependencies" has been split and replaced by "dependentSchemas" and "dependentRequired" in order to serve their differing semantics.',
type: "object",
additionalProperties: {
anyOf: [{ $dynamicRef: "#meta" }, { $ref: "meta/validation#/$defs/stringArray" }]
},
deprecated: true,
default: {}
},
$recursiveAnchor: {
$comment: '"$recursiveAnchor" has been replaced by "$dynamicAnchor".',
$ref: "meta/core#/$defs/anchorString",
deprecated: true
},
$recursiveRef: {
$comment: '"$recursiveRef" has been replaced by "$dynamicRef".',
$ref: "meta/core#/$defs/uriReferenceString",
deprecated: true
}
}
};
}
});
// node_modules/ajv/dist/refs/json-schema-2020-12/meta/applicator.json
var require_applicator2 = __commonJS({
"node_modules/ajv/dist/refs/json-schema-2020-12/meta/applicator.json"(exports, module) {
module.exports = {
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://json-schema.org/draft/2020-12/meta/applicator",
$vocabulary: {
"https://json-schema.org/draft/2020-12/vocab/applicator": true
},
$dynamicAnchor: "meta",
title: "Applicator vocabulary meta-schema",
type: ["object", "boolean"],
properties: {
prefixItems: { $ref: "#/$defs/schemaArray" },
items: { $dynamicRef: "#meta" },
contains: { $dynamicRef: "#meta" },
additionalProperties: { $dynamicRef: "#meta" },
properties: {
type: "object",
additionalProperties: { $dynamicRef: "#meta" },
default: {}
},
patternProperties: {
type: "object",
additionalProperties: { $dynamicRef: "#meta" },
propertyNames: { format: "regex" },
default: {}
},
dependentSchemas: {
type: "object",
additionalProperties: { $dynamicRef: "#meta" },
default: {}
},
propertyNames: { $dynamicRef: "#meta" },
if: { $dynamicRef: "#meta" },
then: { $dynamicRef: "#meta" },
else: { $dynamicRef: "#meta" },
allOf: { $ref: "#/$defs/schemaArray" },
anyOf: { $ref: "#/$defs/schemaArray" },
oneOf: { $ref: "#/$defs/schemaArray" },
not: { $dynamicRef: "#meta" }
},
$defs: {
schemaArray: {
type: "array",
minItems: 1,
items: { $dynamicRef: "#meta" }
}
}
};
}
});
// node_modules/ajv/dist/refs/json-schema-2020-12/meta/unevaluated.json
var require_unevaluated2 = __commonJS({
"node_modules/ajv/dist/refs/json-schema-2020-12/meta/unevaluated.json"(exports, module) {
module.exports = {
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://json-schema.org/draft/2020-12/meta/unevaluated",
$vocabulary: {
"https://json-schema.org/draft/2020-12/vocab/unevaluated": true
},
$dynamicAnchor: "meta",
title: "Unevaluated applicator vocabulary meta-schema",
type: ["object", "boolean"],
properties: {
unevaluatedItems: { $dynamicRef: "#meta" },
unevaluatedProperties: { $dynamicRef: "#meta" }
}
};
}
});
// node_modules/ajv/dist/refs/json-schema-2020-12/meta/content.json
var require_content = __commonJS({
"node_modules/ajv/dist/refs/json-schema-2020-12/meta/content.json"(exports, module) {
module.exports = {
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://json-schema.org/draft/2020-12/meta/content",
$vocabulary: {
"https://json-schema.org/draft/2020-12/vocab/content": true
},
$dynamicAnchor: "meta",
title: "Content vocabulary meta-schema",
type: ["object", "boolean"],
properties: {
contentEncoding: { type: "string" },
contentMediaType: { type: "string" },
contentSchema: { $dynamicRef: "#meta" }
}
};
}
});
// node_modules/ajv/dist/refs/json-schema-2020-12/meta/core.json
var require_core3 = __commonJS({
"node_modules/ajv/dist/refs/json-schema-2020-12/meta/core.json"(exports, module) {
module.exports = {
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://json-schema.org/draft/2020-12/meta/core",
$vocabulary: {
"https://json-schema.org/draft/2020-12/vocab/core": true
},
$dynamicAnchor: "meta",
title: "Core vocabulary meta-schema",
type: ["object", "boolean"],
properties: {
$id: {
$ref: "#/$defs/uriReferenceString",
$comment: "Non-empty fragments not allowed.",
pattern: "^[^#]*#?$"
},
$schema: { $ref: "#/$defs/uriString" },
$ref: { $ref: "#/$defs/uriReferenceString" },
$anchor: { $ref: "#/$defs/anchorString" },
$dynamicRef: { $ref: "#/$defs/uriReferenceString" },
$dynamicAnchor: { $ref: "#/$defs/anchorString" },
$vocabulary: {
type: "object",
propertyNames: { $ref: "#/$defs/uriString" },
additionalProperties: {
type: "boolean"
}
},
$comment: {
type: "string"
},
$defs: {
type: "object",
additionalProperties: { $dynamicRef: "#meta" }
}
},
$defs: {
anchorString: {
type: "string",
pattern: "^[A-Za-z_][-A-Za-z0-9._]*$"
},
uriString: {
type: "string",
format: "uri"
},
uriReferenceString: {
type: "string",
format: "uri-reference"
}
}
};
}
});
// node_modules/ajv/dist/refs/json-schema-2020-12/meta/format-annotation.json
var require_format_annotation = __commonJS({
"node_modules/ajv/dist/refs/json-schema-2020-12/meta/format-annotation.json"(exports, module) {
module.exports = {
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://json-schema.org/draft/2020-12/meta/format-annotation",
$vocabulary: {
"https://json-schema.org/draft/2020-12/vocab/format-annotation": true
},
$dynamicAnchor: "meta",
title: "Format vocabulary meta-schema for annotation results",
type: ["object", "boolean"],
properties: {
format: { type: "string" }
}
};
}
});
// node_modules/ajv/dist/refs/json-schema-2020-12/meta/meta-data.json
var require_meta_data = __commonJS({
"node_modules/ajv/dist/refs/json-schema-2020-12/meta/meta-data.json"(exports, module) {
module.exports = {
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://json-schema.org/draft/2020-12/meta/meta-data",
$vocabulary: {
"https://json-schema.org/draft/2020-12/vocab/meta-data": true
},
$dynamicAnchor: "meta",
title: "Meta-data vocabulary meta-schema",
type: ["object", "boolean"],
properties: {
title: {
type: "string"
},
description: {
type: "string"
},
default: true,
deprecated: {
type: "boolean",
default: false
},
readOnly: {
type: "boolean",
default: false
},
writeOnly: {
type: "boolean",
default: false
},
examples: {
type: "array",
items: true
}
}
};
}
});
// node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.json
var require_validation2 = __commonJS({
"node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.json"(exports, module) {
module.exports = {
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://json-schema.org/draft/2020-12/meta/validation",
$vocabulary: {
"https://json-schema.org/draft/2020-12/vocab/validation": true
},
$dynamicAnchor: "meta",
title: "Validation vocabulary meta-schema",
type: ["object", "boolean"],
properties: {
type: {
anyOf: [
{ $ref: "#/$defs/simpleTypes" },
{
type: "array",
items: { $ref: "#/$defs/simpleTypes" },
minItems: 1,
uniqueItems: true
}
]
},
const: true,
enum: {
type: "array",
items: true
},
multipleOf: {
type: "number",
exclusiveMinimum: 0
},
maximum: {
type: "number"
},
exclusiveMaximum: {
type: "number"
},
minimum: {
type: "number"
},
exclusiveMinimum: {
type: "number"
},
maxLength: { $ref: "#/$defs/nonNegativeInteger" },
minLength: { $ref: "#/$defs/nonNegativeIntegerDefault0" },
pattern: {
type: "string",
format: "regex"
},
maxItems: { $ref: "#/$defs/nonNegativeInteger" },
minItems: { $ref: "#/$defs/nonNegativeIntegerDefault0" },
uniqueItems: {
type: "boolean",
default: false
},
maxContains: { $ref: "#/$defs/nonNegativeInteger" },
minContains: {
$ref: "#/$defs/nonNegativeInteger",
default: 1
},
maxProperties: { $ref: "#/$defs/nonNegativeInteger" },
minProperties: { $ref: "#/$defs/nonNegativeIntegerDefault0" },
required: { $ref: "#/$defs/stringArray" },
dependentRequired: {
type: "object",
additionalProperties: {
$ref: "#/$defs/stringArray"
}
}
},
$defs: {
nonNegativeInteger: {
type: "integer",
minimum: 0
},
nonNegativeIntegerDefault0: {
$ref: "#/$defs/nonNegativeInteger",
default: 0
},
simpleTypes: {
enum: ["array", "boolean", "integer", "null", "number", "object", "string"]
},
stringArray: {
type: "array",
items: { type: "string" },
uniqueItems: true,
default: []
}
}
};
}
});
// node_modules/ajv/dist/refs/json-schema-2020-12/index.js
var require_json_schema_2020_12 = __commonJS({
"node_modules/ajv/dist/refs/json-schema-2020-12/index.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var metaSchema = require_schema();
var applicator = require_applicator2();
var unevaluated = require_unevaluated2();
var content = require_content();
var core = require_core3();
var format = require_format_annotation();
var metadata = require_meta_data();
var validation = require_validation2();
var META_SUPPORT_DATA = ["/properties"];
function addMetaSchema2020($data) {
;
[
metaSchema,
applicator,
unevaluated,
content,
core,
with$data(this, format),
metadata,
with$data(this, validation)
].forEach((sch) => this.addMetaSchema(sch, void 0, false));
return this;
function with$data(ajv, sch) {
return $data ? ajv.$dataMetaSchema(sch, META_SUPPORT_DATA) : sch;
}
}
exports.default = addMetaSchema2020;
}
});
// node_modules/ajv/dist/2020.js
var require__ = __commonJS({
"node_modules/ajv/dist/2020.js"(exports, module) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MissingRefError = exports.ValidationError = exports.CodeGen = exports.Name = exports.nil = exports.stringify = exports.str = exports._ = exports.KeywordCxt = exports.Ajv2020 = void 0;
var core_1 = require_core();
var draft2020_1 = require_draft2020();
var discriminator_1 = require_discriminator();
var json_schema_2020_12_1 = require_json_schema_2020_12();
var META_SCHEMA_ID = "https://json-schema.org/draft/2020-12/schema";
var Ajv20202 = class extends core_1.default {
constructor(opts = {}) {
super({
...opts,
dynamicRef: true,
next: true,
unevaluated: true
});
}
_addVocabularies() {
super._addVocabularies();
draft2020_1.default.forEach((v) => this.addVocabulary(v));
if (this.opts.discriminator)
this.addKeyword(discriminator_1.default);
}
_addDefaultMetaSchema() {
super._addDefaultMetaSchema();
const { $data, meta } = this.opts;
if (!meta)
return;
json_schema_2020_12_1.default.call(this, $data);
this.refs["http://json-schema.org/schema"] = META_SCHEMA_ID;
}
defaultMeta() {
return this.opts.defaultMeta = super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : void 0);
}
};
exports.Ajv2020 = Ajv20202;
module.exports = exports = Ajv20202;
module.exports.Ajv2020 = Ajv20202;
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = Ajv20202;
var validate_1 = require_validate();
Object.defineProperty(exports, "KeywordCxt", { enumerable: true, get: function() {
return validate_1.KeywordCxt;
} });
var codegen_1 = require_codegen();
Object.defineProperty(exports, "_", { enumerable: true, get: function() {
return codegen_1._;
} });
Object.defineProperty(exports, "str", { enumerable: true, get: function() {
return codegen_1.str;
} });
Object.defineProperty(exports, "stringify", { enumerable: true, get: function() {
return codegen_1.stringify;
} });
Object.defineProperty(exports, "nil", { enumerable: true, get: function() {
return codegen_1.nil;
} });
Object.defineProperty(exports, "Name", { enumerable: true, get: function() {
return codegen_1.Name;
} });
Object.defineProperty(exports, "CodeGen", { enumerable: true, get: function() {
return codegen_1.CodeGen;
} });
var validation_error_1 = require_validation_error();
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function() {
return validation_error_1.default;
} });
var ref_error_1 = require_ref_error();
Object.defineProperty(exports, "MissingRefError", { enumerable: true, get: function() {
return ref_error_1.default;
} });
}
});
// node_modules/yaml/dist/nodes/identity.js
var require_identity = __commonJS({
"node_modules/yaml/dist/nodes/identity.js"(exports) {
"use strict";
var ALIAS = /* @__PURE__ */ Symbol.for("yaml.alias");
var DOC = /* @__PURE__ */ Symbol.for("yaml.document");
var MAP = /* @__PURE__ */ Symbol.for("yaml.map");
var PAIR = /* @__PURE__ */ Symbol.for("yaml.pair");
var SCALAR = /* @__PURE__ */ Symbol.for("yaml.scalar");
var SEQ = /* @__PURE__ */ Symbol.for("yaml.seq");
var NODE_TYPE = /* @__PURE__ */ Symbol.for("yaml.node.type");
var isAlias2 = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === ALIAS;
var isDocument = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === DOC;
var isMap2 = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === MAP;
var isPair = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === PAIR;
var isScalar2 = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === SCALAR;
var isSeq = (node) => !!node && typeof node === "object" && node[NODE_TYPE] === SEQ;
function isCollection2(node) {
if (node && typeof node === "object")
switch (node[NODE_TYPE]) {
case MAP:
case SEQ:
return true;
}
return false;
}
function isNode(node) {
if (node && typeof node === "object")
switch (node[NODE_TYPE]) {
case ALIAS:
case MAP:
case SCALAR:
case SEQ:
return true;
}
return false;
}
var hasAnchor = (node) => (isScalar2(node) || isCollection2(node)) && !!node.anchor;
exports.ALIAS = ALIAS;
exports.DOC = DOC;
exports.MAP = MAP;
exports.NODE_TYPE = NODE_TYPE;
exports.PAIR = PAIR;
exports.SCALAR = SCALAR;
exports.SEQ = SEQ;
exports.hasAnchor = hasAnchor;
exports.isAlias = isAlias2;
exports.isCollection = isCollection2;
exports.isDocument = isDocument;
exports.isMap = isMap2;
exports.isNode = isNode;
exports.isPair = isPair;
exports.isScalar = isScalar2;
exports.isSeq = isSeq;
}
});
// node_modules/yaml/dist/visit.js
var require_visit = __commonJS({
"node_modules/yaml/dist/visit.js"(exports) {
"use strict";
var identity = require_identity();
var BREAK = /* @__PURE__ */ Symbol("break visit");
var SKIP = /* @__PURE__ */ Symbol("skip children");
var REMOVE = /* @__PURE__ */ Symbol("remove node");
function visit2(node, visitor) {
const visitor_ = initVisitor(visitor);
if (identity.isDocument(node)) {
const cd = visit_(null, node.contents, visitor_, Object.freeze([node]));
if (cd === REMOVE)
node.contents = null;
} else
visit_(null, node, visitor_, Object.freeze([]));
}
visit2.BREAK = BREAK;
visit2.SKIP = SKIP;
visit2.REMOVE = REMOVE;
function visit_(key, node, visitor, path) {
const ctrl = callVisitor(key, node, visitor, path);
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
replaceNode(key, path, ctrl);
return visit_(key, ctrl, visitor, path);
}
if (typeof ctrl !== "symbol") {
if (identity.isCollection(node)) {
path = Object.freeze(path.concat(node));
for (let i = 0; i < node.items.length; ++i) {
const ci = visit_(i, node.items[i], visitor, path);
if (typeof ci === "number")
i = ci - 1;
else if (ci === BREAK)
return BREAK;
else if (ci === REMOVE) {
node.items.splice(i, 1);
i -= 1;
}
}
} else if (identity.isPair(node)) {
path = Object.freeze(path.concat(node));
const ck = visit_("key", node.key, visitor, path);
if (ck === BREAK)
return BREAK;
else if (ck === REMOVE)
node.key = null;
const cv = visit_("value", node.value, visitor, path);
if (cv === BREAK)
return BREAK;
else if (cv === REMOVE)
node.value = null;
}
}
return ctrl;
}
async function visitAsync(node, visitor) {
const visitor_ = initVisitor(visitor);
if (identity.isDocument(node)) {
const cd = await visitAsync_(null, node.contents, visitor_, Object.freeze([node]));
if (cd === REMOVE)
node.contents = null;
} else
await visitAsync_(null, node, visitor_, Object.freeze([]));
}
visitAsync.BREAK = BREAK;
visitAsync.SKIP = SKIP;
visitAsync.REMOVE = REMOVE;
async function visitAsync_(key, node, visitor, path) {
const ctrl = await callVisitor(key, node, visitor, path);
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
replaceNode(key, path, ctrl);
return visitAsync_(key, ctrl, visitor, path);
}
if (typeof ctrl !== "symbol") {
if (identity.isCollection(node)) {
path = Object.freeze(path.concat(node));
for (let i = 0; i < node.items.length; ++i) {
const ci = await visitAsync_(i, node.items[i], visitor, path);
if (typeof ci === "number")
i = ci - 1;
else if (ci === BREAK)
return BREAK;
else if (ci === REMOVE) {
node.items.splice(i, 1);
i -= 1;
}
}
} else if (identity.isPair(node)) {
path = Object.freeze(path.concat(node));
const ck = await visitAsync_("key", node.key, visitor, path);
if (ck === BREAK)
return BREAK;
else if (ck === REMOVE)
node.key = null;
const cv = await visitAsync_("value", node.value, visitor, path);
if (cv === BREAK)
return BREAK;
else if (cv === REMOVE)
node.value = null;
}
}
return ctrl;
}
function initVisitor(visitor) {
if (typeof visitor === "object" && (visitor.Collection || visitor.Node || visitor.Value)) {
return Object.assign({
Alias: visitor.Node,
Map: visitor.Node,
Scalar: visitor.Node,
Seq: visitor.Node
}, visitor.Value && {
Map: visitor.Value,
Scalar: visitor.Value,
Seq: visitor.Value
}, visitor.Collection && {
Map: visitor.Collection,
Seq: visitor.Collection
}, visitor);
}
return visitor;
}
function callVisitor(key, node, visitor, path) {
if (typeof visitor === "function")
return visitor(key, node, path);
if (identity.isMap(node))
return visitor.Map?.(key, node, path);
if (identity.isSeq(node))
return visitor.Seq?.(key, node, path);
if (identity.isPair(node))
return visitor.Pair?.(key, node, path);
if (identity.isScalar(node))
return visitor.Scalar?.(key, node, path);
if (identity.isAlias(node))
return visitor.Alias?.(key, node, path);
return void 0;
}
function replaceNode(key, path, node) {
const parent = path[path.length - 1];
if (identity.isCollection(parent)) {
parent.items[key] = node;
} else if (identity.isPair(parent)) {
if (key === "key")
parent.key = node;
else
parent.value = node;
} else if (identity.isDocument(parent)) {
parent.contents = node;
} else {
const pt = identity.isAlias(parent) ? "alias" : "scalar";
throw new Error(`Cannot replace node with ${pt} parent`);
}
}
exports.visit = visit2;
exports.visitAsync = visitAsync;
}
});
// node_modules/yaml/dist/doc/directives.js
var require_directives = __commonJS({
"node_modules/yaml/dist/doc/directives.js"(exports) {
"use strict";
var identity = require_identity();
var visit2 = require_visit();
var escapeChars = {
"!": "%21",
",": "%2C",
"[": "%5B",
"]": "%5D",
"{": "%7B",
"}": "%7D"
};
var escapeTagName = (tn) => tn.replace(/[!,[\]{}]/g, (ch) => escapeChars[ch]);
var Directives = class _Directives {
constructor(yaml, tags) {
this.docStart = null;
this.docEnd = false;
this.yaml = Object.assign({}, _Directives.defaultYaml, yaml);
this.tags = Object.assign({}, _Directives.defaultTags, tags);
}
clone() {
const copy = new _Directives(this.yaml, this.tags);
copy.docStart = this.docStart;
return copy;
}
/**
* During parsing, get a Directives instance for the current document and
* update the stream state according to the current version's spec.
*/
atDocument() {
const res = new _Directives(this.yaml, this.tags);
switch (this.yaml.version) {
case "1.1":
this.atNextDocument = true;
break;
case "1.2":
this.atNextDocument = false;
this.yaml = {
explicit: _Directives.defaultYaml.explicit,
version: "1.2"
};
this.tags = Object.assign({}, _Directives.defaultTags);
break;
}
return res;
}
/**
* @param onError - May be called even if the action was successful
* @returns `true` on success
*/
add(line, onError) {
if (this.atNextDocument) {
this.yaml = { explicit: _Directives.defaultYaml.explicit, version: "1.1" };
this.tags = Object.assign({}, _Directives.defaultTags);
this.atNextDocument = false;
}
const parts = line.trim().split(/[ \t]+/);
const name = parts.shift();
switch (name) {
case "%TAG": {
if (parts.length !== 2) {
onError(0, "%TAG directive should contain exactly two parts");
if (parts.length < 2)
return false;
}
const [handle, prefix] = parts;
this.tags[handle] = prefix;
return true;
}
case "%YAML": {
this.yaml.explicit = true;
if (parts.length !== 1) {
onError(0, "%YAML directive should contain exactly one part");
return false;
}
const [version] = parts;
if (version === "1.1" || version === "1.2") {
this.yaml.version = version;
return true;
} else {
const isValid = /^\d+\.\d+$/.test(version);
onError(6, `Unsupported YAML version ${version}`, isValid);
return false;
}
}
default:
onError(0, `Unknown directive ${name}`, true);
return false;
}
}
/**
* Resolves a tag, matching handles to those defined in %TAG directives.
*
* @returns Resolved tag, which may also be the non-specific tag `'!'` or a
* `'!local'` tag, or `null` if unresolvable.
*/
tagName(source, onError) {
if (source === "!")
return "!";
if (source[0] !== "!") {
onError(`Not a valid tag: ${source}`);
return null;
}
if (source[1] === "<") {
const verbatim = source.slice(2, -1);
if (verbatim === "!" || verbatim === "!!") {
onError(`Verbatim tags aren't resolved, so ${source} is invalid.`);
return null;
}
if (source[source.length - 1] !== ">")
onError("Verbatim tags must end with a >");
return verbatim;
}
const [, handle, suffix] = source.match(/^(.*!)([^!]*)$/s);
if (!suffix)
onError(`The ${source} tag has no suffix`);
const prefix = this.tags[handle];
if (prefix) {
try {
return prefix + decodeURIComponent(suffix);
} catch (error) {
onError(String(error));
return null;
}
}
if (handle === "!")
return source;
onError(`Could not resolve tag: ${source}`);
return null;
}
/**
* Given a fully resolved tag, returns its printable string form,
* taking into account current tag prefixes and defaults.
*/
tagString(tag) {
for (const [handle, prefix] of Object.entries(this.tags)) {
if (tag.startsWith(prefix))
return handle + escapeTagName(tag.substring(prefix.length));
}
return tag[0] === "!" ? tag : `!<${tag}>`;
}
toString(doc) {
const lines = this.yaml.explicit ? [`%YAML ${this.yaml.version || "1.2"}`] : [];
const tagEntries = Object.entries(this.tags);
let tagNames;
if (doc && tagEntries.length > 0 && identity.isNode(doc.contents)) {
const tags = {};
visit2.visit(doc.contents, (_key, node) => {
if (identity.isNode(node) && node.tag)
tags[node.tag] = true;
});
tagNames = Object.keys(tags);
} else
tagNames = [];
for (const [handle, prefix] of tagEntries) {
if (handle === "!!" && prefix === "tag:yaml.org,2002:")
continue;
if (!doc || tagNames.some((tn) => tn.startsWith(prefix)))
lines.push(`%TAG ${handle} ${prefix}`);
}
return lines.join("\n");
}
};
Directives.defaultYaml = { explicit: false, version: "1.2" };
Directives.defaultTags = { "!!": "tag:yaml.org,2002:" };
exports.Directives = Directives;
}
});
// node_modules/yaml/dist/doc/anchors.js
var require_anchors = __commonJS({
"node_modules/yaml/dist/doc/anchors.js"(exports) {
"use strict";
var identity = require_identity();
var visit2 = require_visit();
function anchorIsValid(anchor) {
if (/[\x00-\x19\s,[\]{}]/.test(anchor)) {
const sa = JSON.stringify(anchor);
const msg = `Anchor must not contain whitespace or control characters: ${sa}`;
throw new Error(msg);
}
return true;
}
function anchorNames(root) {
const anchors = /* @__PURE__ */ new Set();
visit2.visit(root, {
Value(_key, node) {
if (node.anchor)
anchors.add(node.anchor);
}
});
return anchors;
}
function findNewAnchor(prefix, exclude) {
for (let i = 1; true; ++i) {
const name = `${prefix}${i}`;
if (!exclude.has(name))
return name;
}
}
function createNodeAnchors(doc, prefix) {
const aliasObjects = [];
const sourceObjects = /* @__PURE__ */ new Map();
let prevAnchors = null;
return {
onAnchor: (source) => {
aliasObjects.push(source);
prevAnchors ?? (prevAnchors = anchorNames(doc));
const anchor = findNewAnchor(prefix, prevAnchors);
prevAnchors.add(anchor);
return anchor;
},
/**
* With circular references, the source node is only resolved after all
* of its child nodes are. This is why anchors are set only after all of
* the nodes have been created.
*/
setAnchors: () => {
for (const source of aliasObjects) {
const ref = sourceObjects.get(source);
if (typeof ref === "object" && ref.anchor && (identity.isScalar(ref.node) || identity.isCollection(ref.node))) {
ref.node.anchor = ref.anchor;
} else {
const error = new Error("Failed to resolve repeated object (this should not happen)");
error.source = source;
throw error;
}
}
},
sourceObjects
};
}
exports.anchorIsValid = anchorIsValid;
exports.anchorNames = anchorNames;
exports.createNodeAnchors = createNodeAnchors;
exports.findNewAnchor = findNewAnchor;
}
});
// node_modules/yaml/dist/doc/applyReviver.js
var require_applyReviver = __commonJS({
"node_modules/yaml/dist/doc/applyReviver.js"(exports) {
"use strict";
function applyReviver(reviver, obj, key, val) {
if (val && typeof val === "object") {
if (Array.isArray(val)) {
for (let i = 0, len = val.length; i < len; ++i) {
const v0 = val[i];
const v1 = applyReviver(reviver, val, String(i), v0);
if (v1 === void 0)
delete val[i];
else if (v1 !== v0)
val[i] = v1;
}
} else if (val instanceof Map) {
for (const k of Array.from(val.keys())) {
const v0 = val.get(k);
const v1 = applyReviver(reviver, val, k, v0);
if (v1 === void 0)
val.delete(k);
else if (v1 !== v0)
val.set(k, v1);
}
} else if (val instanceof Set) {
for (const v0 of Array.from(val)) {
const v1 = applyReviver(reviver, val, v0, v0);
if (v1 === void 0)
val.delete(v0);
else if (v1 !== v0) {
val.delete(v0);
val.add(v1);
}
}
} else {
for (const [k, v0] of Object.entries(val)) {
const v1 = applyReviver(reviver, val, k, v0);
if (v1 === void 0)
delete val[k];
else if (v1 !== v0)
val[k] = v1;
}
}
}
return reviver.call(obj, key, val);
}
exports.applyReviver = applyReviver;
}
});
// node_modules/yaml/dist/nodes/toJS.js
var require_toJS = __commonJS({
"node_modules/yaml/dist/nodes/toJS.js"(exports) {
"use strict";
var identity = require_identity();
function toJS(value, arg, ctx) {
if (Array.isArray(value))
return value.map((v, i) => toJS(v, String(i), ctx));
if (value && typeof value.toJSON === "function") {
if (!ctx || !identity.hasAnchor(value))
return value.toJSON(arg, ctx);
const data = { aliasCount: 0, count: 1, res: void 0 };
ctx.anchors.set(value, data);
ctx.onCreate = (res2) => {
data.res = res2;
delete ctx.onCreate;
};
const res = value.toJSON(arg, ctx);
if (ctx.onCreate)
ctx.onCreate(res);
return res;
}
if (typeof value === "bigint" && !ctx?.keep)
return Number(value);
return value;
}
exports.toJS = toJS;
}
});
// node_modules/yaml/dist/nodes/Node.js
var require_Node = __commonJS({
"node_modules/yaml/dist/nodes/Node.js"(exports) {
"use strict";
var applyReviver = require_applyReviver();
var identity = require_identity();
var toJS = require_toJS();
var NodeBase = class {
constructor(type) {
Object.defineProperty(this, identity.NODE_TYPE, { value: type });
}
/** Create a copy of this node. */
clone() {
const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
if (this.range)
copy.range = this.range.slice();
return copy;
}
/** A plain JavaScript representation of this node. */
toJS(doc, { mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
if (!identity.isDocument(doc))
throw new TypeError("A document argument is required");
const ctx = {
anchors: /* @__PURE__ */ new Map(),
doc,
keep: true,
mapAsMap: mapAsMap === true,
mapKeyWarned: false,
maxAliasCount: typeof maxAliasCount === "number" ? maxAliasCount : 100
};
const res = toJS.toJS(this, "", ctx);
if (typeof onAnchor === "function")
for (const { count, res: res2 } of ctx.anchors.values())
onAnchor(res2, count);
return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res;
}
};
exports.NodeBase = NodeBase;
}
});
// node_modules/yaml/dist/nodes/Alias.js
var require_Alias = __commonJS({
"node_modules/yaml/dist/nodes/Alias.js"(exports) {
"use strict";
var anchors = require_anchors();
var visit2 = require_visit();
var identity = require_identity();
var Node = require_Node();
var toJS = require_toJS();
var Alias = class extends Node.NodeBase {
constructor(source) {
super(identity.ALIAS);
this.source = source;
Object.defineProperty(this, "tag", {
set() {
throw new Error("Alias nodes cannot have tags");
}
});
}
/**
* Resolve the value of this alias within `doc`, finding the last
* instance of the `source` anchor before this node.
*/
resolve(doc, ctx) {
if (ctx?.maxAliasCount === 0)
throw new ReferenceError("Alias resolution is disabled");
let nodes;
if (ctx?.aliasResolveCache) {
nodes = ctx.aliasResolveCache;
} else {
nodes = [];
visit2.visit(doc, {
Node: (_key, node) => {
if (identity.isAlias(node) || identity.hasAnchor(node))
nodes.push(node);
}
});
if (ctx)
ctx.aliasResolveCache = nodes;
}
let found = void 0;
for (const node of nodes) {
if (node === this)
break;
if (node.anchor === this.source)
found = node;
}
if (found && ctx) {
const { anchors: anchors2, doc: doc2, maxAliasCount } = ctx;
let data = anchors2.get(found);
if (!data) {
toJS.toJS(found, null, ctx);
data = anchors2.get(found);
}
if (data?.res === void 0) {
const msg = "This should not happen: Alias anchor was not resolved?";
throw new ReferenceError(msg);
}
if (maxAliasCount >= 0) {
data.count += 1;
if (data.aliasCount === 0)
data.aliasCount = getAliasCount(doc2, found, anchors2);
if (data.count * data.aliasCount > maxAliasCount) {
const msg = "Excessive alias count indicates a resource exhaustion attack";
throw new ReferenceError(msg);
}
}
}
return found;
}
toJSON(_arg, ctx) {
if (!ctx)
return { source: this.source };
const source = this.resolve(ctx.doc, ctx);
if (!source) {
const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
throw new ReferenceError(msg);
}
return ctx.anchors.get(source).res;
}
toString(ctx, _onComment, _onChompKeep) {
const src = `*${this.source}`;
if (ctx) {
anchors.anchorIsValid(this.source);
if (ctx.options.verifyAliasOrder && !ctx.anchors.has(this.source)) {
const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
throw new Error(msg);
}
if (ctx.implicitKey)
return `${src} `;
}
return src;
}
};
function getAliasCount(doc, node, anchors2) {
if (identity.isAlias(node)) {
const source = node.resolve(doc);
const anchor = anchors2 && source && anchors2.get(source);
return anchor ? anchor.count * anchor.aliasCount : 0;
} else if (identity.isCollection(node)) {
let count = 0;
for (const item of node.items) {
const c = getAliasCount(doc, item, anchors2);
if (c > count)
count = c;
}
return count;
} else if (identity.isPair(node)) {
const kc = getAliasCount(doc, node.key, anchors2);
const vc = getAliasCount(doc, node.value, anchors2);
return Math.max(kc, vc);
}
return 1;
}
exports.Alias = Alias;
}
});
// node_modules/yaml/dist/nodes/Scalar.js
var require_Scalar = __commonJS({
"node_modules/yaml/dist/nodes/Scalar.js"(exports) {
"use strict";
var identity = require_identity();
var Node = require_Node();
var toJS = require_toJS();
var isScalarValue = (value) => !value || typeof value !== "function" && typeof value !== "object";
var Scalar = class extends Node.NodeBase {
constructor(value) {
super(identity.SCALAR);
this.value = value;
}
toJSON(arg, ctx) {
return ctx?.keep ? this.value : toJS.toJS(this.value, arg, ctx);
}
toString() {
return String(this.value);
}
};
Scalar.BLOCK_FOLDED = "BLOCK_FOLDED";
Scalar.BLOCK_LITERAL = "BLOCK_LITERAL";
Scalar.PLAIN = "PLAIN";
Scalar.QUOTE_DOUBLE = "QUOTE_DOUBLE";
Scalar.QUOTE_SINGLE = "QUOTE_SINGLE";
exports.Scalar = Scalar;
exports.isScalarValue = isScalarValue;
}
});
// node_modules/yaml/dist/doc/createNode.js
var require_createNode = __commonJS({
"node_modules/yaml/dist/doc/createNode.js"(exports) {
"use strict";
var Alias = require_Alias();
var identity = require_identity();
var Scalar = require_Scalar();
var defaultTagPrefix = "tag:yaml.org,2002:";
function findTagObject(value, tagName, tags) {
if (tagName) {
const match = tags.filter((t) => t.tag === tagName);
const tagObj = match.find((t) => !t.format) ?? match[0];
if (!tagObj)
throw new Error(`Tag ${tagName} not found`);
return tagObj;
}
return tags.find((t) => t.identify?.(value) && !t.format);
}
function createNode(value, tagName, ctx) {
if (identity.isDocument(value))
value = value.contents;
if (identity.isNode(value))
return value;
if (identity.isPair(value)) {
const map = ctx.schema[identity.MAP].createNode?.(ctx.schema, null, ctx);
map.items.push(value);
return map;
}
if (value instanceof String || value instanceof Number || value instanceof Boolean || typeof BigInt !== "undefined" && value instanceof BigInt) {
value = value.valueOf();
}
const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;
let ref = void 0;
if (aliasDuplicateObjects && value && typeof value === "object") {
ref = sourceObjects.get(value);
if (ref) {
ref.anchor ?? (ref.anchor = onAnchor(value));
return new Alias.Alias(ref.anchor);
} else {
ref = { anchor: null, node: null };
sourceObjects.set(value, ref);
}
}
if (tagName?.startsWith("!!"))
tagName = defaultTagPrefix + tagName.slice(2);
let tagObj = findTagObject(value, tagName, schema.tags);
if (!tagObj) {
if (value && typeof value.toJSON === "function") {
value = value.toJSON();
}
if (!value || typeof value !== "object") {
const node2 = new Scalar.Scalar(value);
if (ref)
ref.node = node2;
return node2;
}
tagObj = value instanceof Map ? schema[identity.MAP] : Symbol.iterator in Object(value) ? schema[identity.SEQ] : schema[identity.MAP];
}
if (onTagObj) {
onTagObj(tagObj);
delete ctx.onTagObj;
}
const node = tagObj?.createNode ? tagObj.createNode(ctx.schema, value, ctx) : typeof tagObj?.nodeClass?.from === "function" ? tagObj.nodeClass.from(ctx.schema, value, ctx) : new Scalar.Scalar(value);
if (tagName)
node.tag = tagName;
else if (!tagObj.default)
node.tag = tagObj.tag;
if (ref)
ref.node = node;
return node;
}
exports.createNode = createNode;
}
});
// node_modules/yaml/dist/nodes/Collection.js
var require_Collection = __commonJS({
"node_modules/yaml/dist/nodes/Collection.js"(exports) {
"use strict";
var createNode = require_createNode();
var identity = require_identity();
var Node = require_Node();
function collectionFromPath(schema, path, value) {
let v = value;
for (let i = path.length - 1; i >= 0; --i) {
const k = path[i];
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
const a = [];
a[k] = v;
v = a;
} else {
v = /* @__PURE__ */ new Map([[k, v]]);
}
}
return createNode.createNode(v, void 0, {
aliasDuplicateObjects: false,
keepUndefined: false,
onAnchor: () => {
throw new Error("This should not happen, please report a bug.");
},
schema,
sourceObjects: /* @__PURE__ */ new Map()
});
}
var isEmptyPath = (path) => path == null || typeof path === "object" && !!path[Symbol.iterator]().next().done;
var Collection = class extends Node.NodeBase {
constructor(type, schema) {
super(type);
Object.defineProperty(this, "schema", {
value: schema,
configurable: true,
enumerable: false,
writable: true
});
}
/**
* Create a copy of this collection.
*
* @param schema - If defined, overwrites the original's schema
*/
clone(schema) {
const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));
if (schema)
copy.schema = schema;
copy.items = copy.items.map((it) => identity.isNode(it) || identity.isPair(it) ? it.clone(schema) : it);
if (this.range)
copy.range = this.range.slice();
return copy;
}
/**
* Adds a value to the collection. For `!!map` and `!!omap` the value must
* be a Pair instance or a `{ key, value }` object, which may not have a key
* that already exists in the map.
*/
addIn(path, value) {
if (isEmptyPath(path))
this.add(value);
else {
const [key, ...rest] = path;
const node = this.get(key, true);
if (identity.isCollection(node))
node.addIn(rest, value);
else if (node === void 0 && this.schema)
this.set(key, collectionFromPath(this.schema, rest, value));
else
throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
}
}
/**
* Removes a value from the collection.
* @returns `true` if the item was found and removed.
*/
deleteIn(path) {
const [key, ...rest] = path;
if (rest.length === 0)
return this.delete(key);
const node = this.get(key, true);
if (identity.isCollection(node))
return node.deleteIn(rest);
else
throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
}
/**
* Returns item at `key`, or `undefined` if not found. By default unwraps
* scalar values from their surrounding node; to disable set `keepScalar` to
* `true` (collections are always returned intact).
*/
getIn(path, keepScalar) {
const [key, ...rest] = path;
const node = this.get(key, true);
if (rest.length === 0)
return !keepScalar && identity.isScalar(node) ? node.value : node;
else
return identity.isCollection(node) ? node.getIn(rest, keepScalar) : void 0;
}
hasAllNullValues(allowScalar) {
return this.items.every((node) => {
if (!identity.isPair(node))
return false;
const n = node.value;
return n == null || allowScalar && identity.isScalar(n) && n.value == null && !n.commentBefore && !n.comment && !n.tag;
});
}
/**
* Checks if the collection includes a value with the key `key`.
*/
hasIn(path) {
const [key, ...rest] = path;
if (rest.length === 0)
return this.has(key);
const node = this.get(key, true);
return identity.isCollection(node) ? node.hasIn(rest) : false;
}
/**
* Sets a value in this collection. For `!!set`, `value` needs to be a
* boolean to add/remove the item from the set.
*/
setIn(path, value) {
const [key, ...rest] = path;
if (rest.length === 0) {
this.set(key, value);
} else {
const node = this.get(key, true);
if (identity.isCollection(node))
node.setIn(rest, value);
else if (node === void 0 && this.schema)
this.set(key, collectionFromPath(this.schema, rest, value));
else
throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
}
}
};
exports.Collection = Collection;
exports.collectionFromPath = collectionFromPath;
exports.isEmptyPath = isEmptyPath;
}
});
// node_modules/yaml/dist/stringify/stringifyComment.js
var require_stringifyComment = __commonJS({
"node_modules/yaml/dist/stringify/stringifyComment.js"(exports) {
"use strict";
var stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#");
function indentComment(comment, indent) {
if (/^\n+$/.test(comment))
return comment.substring(1);
return indent ? comment.replace(/^(?! *$)/gm, indent) : comment;
}
var lineComment = (str, indent, comment) => str.endsWith("\n") ? indentComment(comment, indent) : comment.includes("\n") ? "\n" + indentComment(comment, indent) : (str.endsWith(" ") ? "" : " ") + comment;
exports.indentComment = indentComment;
exports.lineComment = lineComment;
exports.stringifyComment = stringifyComment;
}
});
// node_modules/yaml/dist/stringify/foldFlowLines.js
var require_foldFlowLines = __commonJS({
"node_modules/yaml/dist/stringify/foldFlowLines.js"(exports) {
"use strict";
var FOLD_FLOW = "flow";
var FOLD_BLOCK = "block";
var FOLD_QUOTED = "quoted";
function foldFlowLines(text2, indent, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
if (!lineWidth || lineWidth < 0)
return text2;
if (lineWidth < minContentWidth)
minContentWidth = 0;
const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);
if (text2.length <= endStep)
return text2;
const folds = [];
const escapedFolds = {};
let end = lineWidth - indent.length;
if (typeof indentAtStart === "number") {
if (indentAtStart > lineWidth - Math.max(2, minContentWidth))
folds.push(0);
else
end = lineWidth - indentAtStart;
}
let split = void 0;
let prev = void 0;
let overflow = false;
let i = -1;
let escStart = -1;
let escEnd = -1;
if (mode === FOLD_BLOCK) {
i = consumeMoreIndentedLines(text2, i, indent.length);
if (i !== -1)
end = i + endStep;
}
for (let ch; ch = text2[i += 1]; ) {
if (mode === FOLD_QUOTED && ch === "\\") {
escStart = i;
switch (text2[i + 1]) {
case "x":
i += 3;
break;
case "u":
i += 5;
break;
case "U":
i += 9;
break;
default:
i += 1;
}
escEnd = i;
}
if (ch === "\n") {
if (mode === FOLD_BLOCK)
i = consumeMoreIndentedLines(text2, i, indent.length);
end = i + indent.length + endStep;
split = void 0;
} else {
if (ch === " " && prev && prev !== " " && prev !== "\n" && prev !== " ") {
const next = text2[i + 1];
if (next && next !== " " && next !== "\n" && next !== " ")
split = i;
}
if (i >= end) {
if (split) {
folds.push(split);
end = split + endStep;
split = void 0;
} else if (mode === FOLD_QUOTED) {
while (prev === " " || prev === " ") {
prev = ch;
ch = text2[i += 1];
overflow = true;
}
const j = i > escEnd + 1 ? i - 2 : escStart - 1;
if (escapedFolds[j])
return text2;
folds.push(j);
escapedFolds[j] = true;
end = j + endStep;
split = void 0;
} else {
overflow = true;
}
}
}
prev = ch;
}
if (overflow && onOverflow)
onOverflow();
if (folds.length === 0)
return text2;
if (onFold)
onFold();
let res = text2.slice(0, folds[0]);
for (let i2 = 0; i2 < folds.length; ++i2) {
const fold = folds[i2];
const end2 = folds[i2 + 1] || text2.length;
if (fold === 0)
res = `
${indent}${text2.slice(0, end2)}`;
else {
if (mode === FOLD_QUOTED && escapedFolds[fold])
res += `${text2[fold]}\\`;
res += `
${indent}${text2.slice(fold + 1, end2)}`;
}
}
return res;
}
function consumeMoreIndentedLines(text2, i, indent) {
let end = i;
let start = i + 1;
let ch = text2[start];
while (ch === " " || ch === " ") {
if (i < start + indent) {
ch = text2[++i];
} else {
do {
ch = text2[++i];
} while (ch && ch !== "\n");
end = i;
start = i + 1;
ch = text2[start];
}
}
return end;
}
exports.FOLD_BLOCK = FOLD_BLOCK;
exports.FOLD_FLOW = FOLD_FLOW;
exports.FOLD_QUOTED = FOLD_QUOTED;
exports.foldFlowLines = foldFlowLines;
}
});
// node_modules/yaml/dist/stringify/stringifyString.js
var require_stringifyString = __commonJS({
"node_modules/yaml/dist/stringify/stringifyString.js"(exports) {
"use strict";
var Scalar = require_Scalar();
var foldFlowLines = require_foldFlowLines();
var getFoldOptions = (ctx, isBlock) => ({
indentAtStart: isBlock ? ctx.indent.length : ctx.indentAtStart,
lineWidth: ctx.options.lineWidth,
minContentWidth: ctx.options.minContentWidth
});
var containsDocumentMarker = (str) => /^(%|---|\.\.\.)/m.test(str);
function lineLengthOverLimit(str, lineWidth, indentLength) {
if (!lineWidth || lineWidth < 0)
return false;
const limit = lineWidth - indentLength;
const strLen = str.length;
if (strLen <= limit)
return false;
for (let i = 0, start = 0; i < strLen; ++i) {
if (str[i] === "\n") {
if (i - start > limit)
return true;
start = i + 1;
if (strLen - start <= limit)
return false;
}
}
return true;
}
function doubleQuotedString(value, ctx) {
const json2 = JSON.stringify(value);
if (ctx.options.doubleQuotedAsJSON)
return json2;
const { implicitKey } = ctx;
const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength;
const indent = ctx.indent || (containsDocumentMarker(value) ? " " : "");
let str = "";
let start = 0;
for (let i = 0, ch = json2[i]; ch; ch = json2[++i]) {
if (ch === " " && json2[i + 1] === "\\" && json2[i + 2] === "n") {
str += json2.slice(start, i) + "\\ ";
i += 1;
start = i;
ch = "\\";
}
if (ch === "\\")
switch (json2[i + 1]) {
case "u":
{
str += json2.slice(start, i);
const code = json2.substr(i + 2, 4);
switch (code) {
case "0000":
str += "\\0";
break;
case "0007":
str += "\\a";
break;
case "000b":
str += "\\v";
break;
case "001b":
str += "\\e";
break;
case "0085":
str += "\\N";
break;
case "00a0":
str += "\\_";
break;
case "2028":
str += "\\L";
break;
case "2029":
str += "\\P";
break;
default:
if (code.substr(0, 2) === "00")
str += "\\x" + code.substr(2);
else
str += json2.substr(i, 6);
}
i += 5;
start = i + 1;
}
break;
case "n":
if (implicitKey || json2[i + 2] === '"' || json2.length < minMultiLineLength) {
i += 1;
} else {
str += json2.slice(start, i) + "\n\n";
while (json2[i + 2] === "\\" && json2[i + 3] === "n" && json2[i + 4] !== '"') {
str += "\n";
i += 2;
}
str += indent;
if (json2[i + 2] === " ")
str += "\\";
i += 1;
start = i + 1;
}
break;
default:
i += 1;
}
}
str = start ? str + json2.slice(start) : json2;
return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));
}
function singleQuotedString(value, ctx) {
if (ctx.options.singleQuote === false || ctx.implicitKey && value.includes("\n") || /[ \t]\n|\n[ \t]/.test(value))
return doubleQuotedString(value, ctx);
const indent = ctx.indent || (containsDocumentMarker(value) ? " " : "");
const res = "'" + value.replace(/'/g, "''").replace(/\n+/g, `$&
${indent}`) + "'";
return ctx.implicitKey ? res : foldFlowLines.foldFlowLines(res, indent, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
}
function quotedString(value, ctx) {
const { singleQuote } = ctx.options;
let qs;
if (singleQuote === false)
qs = doubleQuotedString;
else {
const hasDouble = value.includes('"');
const hasSingle = value.includes("'");
if (hasDouble && !hasSingle)
qs = singleQuotedString;
else if (hasSingle && !hasDouble)
qs = doubleQuotedString;
else
qs = singleQuote ? singleQuotedString : doubleQuotedString;
}
return qs(value, ctx);
}
var blockEndNewlines;
try {
blockEndNewlines = new RegExp("(^|(?<!\n))\n+(?!\n|$)", "g");
} catch {
blockEndNewlines = /\n+(?!\n|$)/g;
}
function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
const { blockQuote, commentString, lineWidth } = ctx.options;
if (!blockQuote || /\n[\t ]+$/.test(value)) {
return quotedString(value, ctx);
}
const indent = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value) ? " " : "");
const literal = blockQuote === "literal" ? true : blockQuote === "folded" || type === Scalar.Scalar.BLOCK_FOLDED ? false : type === Scalar.Scalar.BLOCK_LITERAL ? true : !lineLengthOverLimit(value, lineWidth, indent.length);
if (!value)
return literal ? "|\n" : ">\n";
let chomp;
let endStart;
for (endStart = value.length; endStart > 0; --endStart) {
const ch = value[endStart - 1];
if (ch !== "\n" && ch !== " " && ch !== " ")
break;
}
let end = value.substring(endStart);
const endNlPos = end.indexOf("\n");
if (endNlPos === -1) {
chomp = "-";
} else if (value === end || endNlPos !== end.length - 1) {
chomp = "+";
if (onChompKeep)
onChompKeep();
} else {
chomp = "";
}
if (end) {
value = value.slice(0, -end.length);
if (end[end.length - 1] === "\n")
end = end.slice(0, -1);
end = end.replace(blockEndNewlines, `$&${indent}`);
}
let startWithSpace = false;
let startEnd;
let startNlPos = -1;
for (startEnd = 0; startEnd < value.length; ++startEnd) {
const ch = value[startEnd];
if (ch === " ")
startWithSpace = true;
else if (ch === "\n")
startNlPos = startEnd;
else
break;
}
let start = value.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd);
if (start) {
value = value.substring(start.length);
start = start.replace(/\n+/g, `$&${indent}`);
}
const indentSize = indent ? "2" : "1";
let header = (startWithSpace ? indentSize : "") + chomp;
if (comment) {
header += " " + commentString(comment.replace(/ ?[\r\n]+/g, " "));
if (onComment)
onComment();
}
if (!literal) {
const foldedValue = value.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${indent}`);
let literalFallback = false;
const foldOptions = getFoldOptions(ctx, true);
if (blockQuote !== "folded" && type !== Scalar.Scalar.BLOCK_FOLDED) {
foldOptions.onOverflow = () => {
literalFallback = true;
};
}
const body = foldFlowLines.foldFlowLines(`${start}${foldedValue}${end}`, indent, foldFlowLines.FOLD_BLOCK, foldOptions);
if (!literalFallback)
return `>${header}
${indent}${body}`;
}
value = value.replace(/\n+/g, `$&${indent}`);
return `|${header}
${indent}${start}${value}${end}`;
}
function plainString(item, ctx, onComment, onChompKeep) {
const { type, value } = item;
const { actualString, implicitKey, indent, indentStep, inFlow } = ctx;
if (implicitKey && value.includes("\n") || inFlow && /[[\]{},]/.test(value)) {
return quotedString(value, ctx);
}
if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) {
return implicitKey || inFlow || !value.includes("\n") ? quotedString(value, ctx) : blockString(item, ctx, onComment, onChompKeep);
}
if (!implicitKey && !inFlow && type !== Scalar.Scalar.PLAIN && value.includes("\n")) {
return blockString(item, ctx, onComment, onChompKeep);
}
if (containsDocumentMarker(value)) {
if (indent === "") {
ctx.forceBlockIndent = true;
return blockString(item, ctx, onComment, onChompKeep);
} else if (implicitKey && indent === indentStep) {
return quotedString(value, ctx);
}
}
const str = value.replace(/\n+/g, `$&
${indent}`);
if (actualString) {
const test = (tag) => tag.default && tag.tag !== "tag:yaml.org,2002:str" && tag.test?.test(str);
const { compat, tags } = ctx.doc.schema;
if (tags.some(test) || compat?.some(test))
return quotedString(value, ctx);
}
return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
}
function stringifyString(item, ctx, onComment, onChompKeep) {
const { implicitKey, inFlow } = ctx;
const ss = typeof item.value === "string" ? item : Object.assign({}, item, { value: String(item.value) });
let { type } = item;
if (type !== Scalar.Scalar.QUOTE_DOUBLE) {
if (/[\x00-\x08\x0b-\x1f\x7f-\x9f\u{D800}-\u{DFFF}]/u.test(ss.value))
type = Scalar.Scalar.QUOTE_DOUBLE;
}
const _stringify = (_type) => {
switch (_type) {
case Scalar.Scalar.BLOCK_FOLDED:
case Scalar.Scalar.BLOCK_LITERAL:
return implicitKey || inFlow ? quotedString(ss.value, ctx) : blockString(ss, ctx, onComment, onChompKeep);
case Scalar.Scalar.QUOTE_DOUBLE:
return doubleQuotedString(ss.value, ctx);
case Scalar.Scalar.QUOTE_SINGLE:
return singleQuotedString(ss.value, ctx);
case Scalar.Scalar.PLAIN:
return plainString(ss, ctx, onComment, onChompKeep);
default:
return null;
}
};
let res = _stringify(type);
if (res === null) {
const { defaultKeyType, defaultStringType } = ctx.options;
const t = implicitKey && defaultKeyType || defaultStringType;
res = _stringify(t);
if (res === null)
throw new Error(`Unsupported default string type ${t}`);
}
return res;
}
exports.stringifyString = stringifyString;
}
});
// node_modules/yaml/dist/stringify/stringify.js
var require_stringify = __commonJS({
"node_modules/yaml/dist/stringify/stringify.js"(exports) {
"use strict";
var anchors = require_anchors();
var identity = require_identity();
var stringifyComment = require_stringifyComment();
var stringifyString = require_stringifyString();
function createStringifyContext(doc, options) {
const opt = Object.assign({
blockQuote: true,
commentString: stringifyComment.stringifyComment,
defaultKeyType: null,
defaultStringType: "PLAIN",
directives: null,
doubleQuotedAsJSON: false,
doubleQuotedMinMultiLineLength: 40,
falseStr: "false",
flowCollectionPadding: true,
indentSeq: true,
lineWidth: 80,
minContentWidth: 20,
nullStr: "null",
simpleKeys: false,
singleQuote: null,
trailingComma: false,
trueStr: "true",
verifyAliasOrder: true
}, doc.schema.toStringOptions, options);
let inFlow;
switch (opt.collectionStyle) {
case "block":
inFlow = false;
break;
case "flow":
inFlow = true;
break;
default:
inFlow = null;
}
return {
anchors: /* @__PURE__ */ new Set(),
doc,
flowCollectionPadding: opt.flowCollectionPadding ? " " : "",
indent: "",
indentStep: typeof opt.indent === "number" ? " ".repeat(opt.indent) : " ",
inFlow,
options: opt
};
}
function getTagObject(tags, item) {
if (item.tag) {
const match = tags.filter((t) => t.tag === item.tag);
if (match.length > 0)
return match.find((t) => t.format === item.format) ?? match[0];
}
let tagObj = void 0;
let obj;
if (identity.isScalar(item)) {
obj = item.value;
let match = tags.filter((t) => t.identify?.(obj));
if (match.length > 1) {
const testMatch = match.filter((t) => t.test);
if (testMatch.length > 0)
match = testMatch;
}
tagObj = match.find((t) => t.format === item.format) ?? match.find((t) => !t.format);
} else {
obj = item;
tagObj = tags.find((t) => t.nodeClass && obj instanceof t.nodeClass);
}
if (!tagObj) {
const name = obj?.constructor?.name ?? (obj === null ? "null" : typeof obj);
throw new Error(`Tag not resolved for ${name} value`);
}
return tagObj;
}
function stringifyProps(node, tagObj, { anchors: anchors$1, doc }) {
if (!doc.directives)
return "";
const props = [];
const anchor = (identity.isScalar(node) || identity.isCollection(node)) && node.anchor;
if (anchor && anchors.anchorIsValid(anchor)) {
anchors$1.add(anchor);
props.push(`&${anchor}`);
}
const tag = node.tag ?? (tagObj.default ? null : tagObj.tag);
if (tag)
props.push(doc.directives.tagString(tag));
return props.join(" ");
}
function stringify4(item, ctx, onComment, onChompKeep) {
if (identity.isPair(item))
return item.toString(ctx, onComment, onChompKeep);
if (identity.isAlias(item)) {
if (ctx.doc.directives)
return item.toString(ctx);
if (ctx.resolvedAliases?.has(item)) {
throw new TypeError(`Cannot stringify circular structure without alias nodes`);
} else {
if (ctx.resolvedAliases)
ctx.resolvedAliases.add(item);
else
ctx.resolvedAliases = /* @__PURE__ */ new Set([item]);
item = item.resolve(ctx.doc);
}
}
let tagObj = void 0;
const node = identity.isNode(item) ? item : ctx.doc.createNode(item, { onTagObj: (o) => tagObj = o });
tagObj ?? (tagObj = getTagObject(ctx.doc.schema.tags, node));
const props = stringifyProps(node, tagObj, ctx);
if (props.length > 0)
ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;
const str = typeof tagObj.stringify === "function" ? tagObj.stringify(node, ctx, onComment, onChompKeep) : identity.isScalar(node) ? stringifyString.stringifyString(node, ctx, onComment, onChompKeep) : node.toString(ctx, onComment, onChompKeep);
if (!props)
return str;
return identity.isScalar(node) || str[0] === "{" || str[0] === "[" ? `${props} ${str}` : `${props}
${ctx.indent}${str}`;
}
exports.createStringifyContext = createStringifyContext;
exports.stringify = stringify4;
}
});
// node_modules/yaml/dist/stringify/stringifyPair.js
var require_stringifyPair = __commonJS({
"node_modules/yaml/dist/stringify/stringifyPair.js"(exports) {
"use strict";
var identity = require_identity();
var Scalar = require_Scalar();
var stringify4 = require_stringify();
var stringifyComment = require_stringifyComment();
function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
const { allNullValues, doc, indent, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
let keyComment = identity.isNode(key) && key.comment || null;
if (simpleKeys) {
if (keyComment) {
throw new Error("With simple keys, key nodes cannot have comments");
}
if (identity.isCollection(key) || !identity.isNode(key) && typeof key === "object") {
const msg = "With simple keys, collection cannot be used as a key value";
throw new Error(msg);
}
}
let explicitKey = !simpleKeys && (!key || keyComment && value == null && !ctx.inFlow || identity.isCollection(key) || (identity.isScalar(key) ? key.type === Scalar.Scalar.BLOCK_FOLDED || key.type === Scalar.Scalar.BLOCK_LITERAL : typeof key === "object"));
ctx = Object.assign({}, ctx, {
allNullValues: false,
implicitKey: !explicitKey && (simpleKeys || !allNullValues),
indent: indent + indentStep
});
let keyCommentDone = false;
let chompKeep = false;
let str = stringify4.stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true);
if (!explicitKey && !ctx.inFlow && str.length > 1024) {
if (simpleKeys)
throw new Error("With simple keys, single line scalar must not span more than 1024 characters");
explicitKey = true;
}
if (ctx.inFlow) {
if (allNullValues || value == null) {
if (keyCommentDone && onComment)
onComment();
return str === "" ? "?" : explicitKey ? `? ${str}` : str;
}
} else if (allNullValues && !simpleKeys || value == null && explicitKey) {
str = `? ${str}`;
if (keyComment && !keyCommentDone) {
str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
} else if (chompKeep && onChompKeep)
onChompKeep();
return str;
}
if (keyCommentDone)
keyComment = null;
if (explicitKey) {
if (keyComment)
str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
str = `? ${str}
${indent}:`;
} else {
str = `${str}:`;
if (keyComment)
str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
}
let vsb, vcb, valueComment;
if (identity.isNode(value)) {
vsb = !!value.spaceBefore;
vcb = value.commentBefore;
valueComment = value.comment;
} else {
vsb = false;
vcb = null;
valueComment = null;
if (value && typeof value === "object")
value = doc.createNode(value);
}
ctx.implicitKey = false;
if (!explicitKey && !keyComment && identity.isScalar(value))
ctx.indentAtStart = str.length + 1;
chompKeep = false;
if (!indentSeq && indentStep.length >= 2 && !ctx.inFlow && !explicitKey && identity.isSeq(value) && !value.flow && !value.tag && !value.anchor) {
ctx.indent = ctx.indent.substring(2);
}
let valueCommentDone = false;
const valueStr = stringify4.stringify(value, ctx, () => valueCommentDone = true, () => chompKeep = true);
let ws = " ";
if (keyComment || vsb || vcb) {
ws = vsb ? "\n" : "";
if (vcb) {
const cs = commentString(vcb);
ws += `
${stringifyComment.indentComment(cs, ctx.indent)}`;
}
if (valueStr === "" && !ctx.inFlow) {
if (ws === "\n" && valueComment)
ws = "\n\n";
} else {
ws += `
${ctx.indent}`;
}
} else if (!explicitKey && identity.isCollection(value)) {
const vs0 = valueStr[0];
const nl0 = valueStr.indexOf("\n");
const hasNewline = nl0 !== -1;
const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0;
if (hasNewline || !flow) {
let hasPropsLine = false;
if (hasNewline && (vs0 === "&" || vs0 === "!")) {
let sp0 = valueStr.indexOf(" ");
if (vs0 === "&" && sp0 !== -1 && sp0 < nl0 && valueStr[sp0 + 1] === "!") {
sp0 = valueStr.indexOf(" ", sp0 + 1);
}
if (sp0 === -1 || nl0 < sp0)
hasPropsLine = true;
}
if (!hasPropsLine)
ws = `
${ctx.indent}`;
}
} else if (valueStr === "" || valueStr[0] === "\n") {
ws = "";
}
str += ws + valueStr;
if (ctx.inFlow) {
if (valueCommentDone && onComment)
onComment();
} else if (valueComment && !valueCommentDone) {
str += stringifyComment.lineComment(str, ctx.indent, commentString(valueComment));
} else if (chompKeep && onChompKeep) {
onChompKeep();
}
return str;
}
exports.stringifyPair = stringifyPair;
}
});
// node_modules/yaml/dist/log.js
var require_log = __commonJS({
"node_modules/yaml/dist/log.js"(exports) {
"use strict";
var node_process = __require("process");
function debug(logLevel, ...messages) {
if (logLevel === "debug")
console.log(...messages);
}
function warn(logLevel, warning) {
if (logLevel === "debug" || logLevel === "warn") {
if (typeof node_process.emitWarning === "function")
node_process.emitWarning(warning);
else
console.warn(warning);
}
}
exports.debug = debug;
exports.warn = warn;
}
});
// node_modules/yaml/dist/schema/yaml-1.1/merge.js
var require_merge = __commonJS({
"node_modules/yaml/dist/schema/yaml-1.1/merge.js"(exports) {
"use strict";
var identity = require_identity();
var Scalar = require_Scalar();
var MERGE_KEY = "<<";
var merge = {
identify: (value) => value === MERGE_KEY || typeof value === "symbol" && value.description === MERGE_KEY,
default: "key",
tag: "tag:yaml.org,2002:merge",
test: /^<<$/,
resolve: () => Object.assign(new Scalar.Scalar(Symbol(MERGE_KEY)), {
addToJSMap: addMergeToJSMap
}),
stringify: () => MERGE_KEY
};
var isMergeKey = (ctx, key) => (merge.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge.identify(key.value)) && ctx?.doc.schema.tags.some((tag) => tag.tag === merge.tag && tag.default);
function addMergeToJSMap(ctx, map, value) {
const source = resolveAliasValue(ctx, value);
if (identity.isSeq(source))
for (const it of source.items)
mergeValue(ctx, map, it);
else if (Array.isArray(source))
for (const it of source)
mergeValue(ctx, map, it);
else
mergeValue(ctx, map, source);
}
function mergeValue(ctx, map, value) {
const source = resolveAliasValue(ctx, value);
if (!identity.isMap(source))
throw new Error("Merge sources must be maps or map aliases");
const srcMap = source.toJSON(null, ctx, Map);
for (const [key, value2] of srcMap) {
if (map instanceof Map) {
if (!map.has(key))
map.set(key, value2);
} else if (map instanceof Set) {
map.add(key);
} else if (!Object.prototype.hasOwnProperty.call(map, key)) {
Object.defineProperty(map, key, {
value: value2,
writable: true,
enumerable: true,
configurable: true
});
}
}
return map;
}
function resolveAliasValue(ctx, value) {
return ctx && identity.isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
}
exports.addMergeToJSMap = addMergeToJSMap;
exports.isMergeKey = isMergeKey;
exports.merge = merge;
}
});
// node_modules/yaml/dist/nodes/addPairToJSMap.js
var require_addPairToJSMap = __commonJS({
"node_modules/yaml/dist/nodes/addPairToJSMap.js"(exports) {
"use strict";
var log = require_log();
var merge = require_merge();
var stringify4 = require_stringify();
var identity = require_identity();
var toJS = require_toJS();
function addPairToJSMap(ctx, map, { key, value }) {
if (identity.isNode(key) && key.addToJSMap)
key.addToJSMap(ctx, map, value);
else if (merge.isMergeKey(ctx, key))
merge.addMergeToJSMap(ctx, map, value);
else {
const jsKey = toJS.toJS(key, "", ctx);
if (map instanceof Map) {
map.set(jsKey, toJS.toJS(value, jsKey, ctx));
} else if (map instanceof Set) {
map.add(jsKey);
} else {
const stringKey = stringifyKey(key, jsKey, ctx);
const jsValue = toJS.toJS(value, stringKey, ctx);
if (stringKey in map)
Object.defineProperty(map, stringKey, {
value: jsValue,
writable: true,
enumerable: true,
configurable: true
});
else
map[stringKey] = jsValue;
}
}
return map;
}
function stringifyKey(key, jsKey, ctx) {
if (jsKey === null)
return "";
if (typeof jsKey !== "object")
return String(jsKey);
if (identity.isNode(key) && ctx?.doc) {
const strCtx = stringify4.createStringifyContext(ctx.doc, {});
strCtx.anchors = /* @__PURE__ */ new Set();
for (const node of ctx.anchors.keys())
strCtx.anchors.add(node.anchor);
strCtx.inFlow = true;
strCtx.inStringifyKey = true;
const strKey = key.toString(strCtx);
if (!ctx.mapKeyWarned) {
let jsonStr = JSON.stringify(strKey);
if (jsonStr.length > 40)
jsonStr = jsonStr.substring(0, 36) + '..."';
log.warn(ctx.doc.options.logLevel, `Keys with collection values will be stringified due to JS Object restrictions: ${jsonStr}. Set mapAsMap: true to use object keys.`);
ctx.mapKeyWarned = true;
}
return strKey;
}
return JSON.stringify(jsKey);
}
exports.addPairToJSMap = addPairToJSMap;
}
});
// node_modules/yaml/dist/nodes/Pair.js
var require_Pair = __commonJS({
"node_modules/yaml/dist/nodes/Pair.js"(exports) {
"use strict";
var createNode = require_createNode();
var stringifyPair = require_stringifyPair();
var addPairToJSMap = require_addPairToJSMap();
var identity = require_identity();
function createPair(key, value, ctx) {
const k = createNode.createNode(key, void 0, ctx);
const v = createNode.createNode(value, void 0, ctx);
return new Pair(k, v);
}
var Pair = class _Pair {
constructor(key, value = null) {
Object.defineProperty(this, identity.NODE_TYPE, { value: identity.PAIR });
this.key = key;
this.value = value;
}
clone(schema) {
let { key, value } = this;
if (identity.isNode(key))
key = key.clone(schema);
if (identity.isNode(value))
value = value.clone(schema);
return new _Pair(key, value);
}
toJSON(_, ctx) {
const pair = ctx?.mapAsMap ? /* @__PURE__ */ new Map() : {};
return addPairToJSMap.addPairToJSMap(ctx, pair, this);
}
toString(ctx, onComment, onChompKeep) {
return ctx?.doc ? stringifyPair.stringifyPair(this, ctx, onComment, onChompKeep) : JSON.stringify(this);
}
};
exports.Pair = Pair;
exports.createPair = createPair;
}
});
// node_modules/yaml/dist/stringify/stringifyCollection.js
var require_stringifyCollection = __commonJS({
"node_modules/yaml/dist/stringify/stringifyCollection.js"(exports) {
"use strict";
var identity = require_identity();
var stringify4 = require_stringify();
var stringifyComment = require_stringifyComment();
function stringifyCollection(collection, ctx, options) {
const flow = ctx.inFlow ?? collection.flow;
const stringify5 = flow ? stringifyFlowCollection : stringifyBlockCollection;
return stringify5(collection, ctx, options);
}
function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) {
const { indent, options: { commentString } } = ctx;
const itemCtx = Object.assign({}, ctx, { indent: itemIndent, type: null });
let chompKeep = false;
const lines = [];
for (let i = 0; i < items.length; ++i) {
const item = items[i];
let comment2 = null;
if (identity.isNode(item)) {
if (!chompKeep && item.spaceBefore)
lines.push("");
addCommentBefore(ctx, lines, item.commentBefore, chompKeep);
if (item.comment)
comment2 = item.comment;
} else if (identity.isPair(item)) {
const ik = identity.isNode(item.key) ? item.key : null;
if (ik) {
if (!chompKeep && ik.spaceBefore)
lines.push("");
addCommentBefore(ctx, lines, ik.commentBefore, chompKeep);
}
}
chompKeep = false;
let str2 = stringify4.stringify(item, itemCtx, () => comment2 = null, () => chompKeep = true);
if (comment2)
str2 += stringifyComment.lineComment(str2, itemIndent, commentString(comment2));
if (chompKeep && comment2)
chompKeep = false;
lines.push(blockItemPrefix + str2);
}
let str;
if (lines.length === 0) {
str = flowChars.start + flowChars.end;
} else {
str = lines[0];
for (let i = 1; i < lines.length; ++i) {
const line = lines[i];
str += line ? `
${indent}${line}` : "\n";
}
}
if (comment) {
str += "\n" + stringifyComment.indentComment(commentString(comment), indent);
if (onComment)
onComment();
} else if (chompKeep && onChompKeep)
onChompKeep();
return str;
}
function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;
itemIndent += indentStep;
const itemCtx = Object.assign({}, ctx, {
indent: itemIndent,
inFlow: true,
type: null
});
let reqNewline = false;
let linesAtValue = 0;
const lines = [];
for (let i = 0; i < items.length; ++i) {
const item = items[i];
let comment = null;
if (identity.isNode(item)) {
if (item.spaceBefore)
lines.push("");
addCommentBefore(ctx, lines, item.commentBefore, false);
if (item.comment)
comment = item.comment;
} else if (identity.isPair(item)) {
const ik = identity.isNode(item.key) ? item.key : null;
if (ik) {
if (ik.spaceBefore)
lines.push("");
addCommentBefore(ctx, lines, ik.commentBefore, false);
if (ik.comment)
reqNewline = true;
}
const iv = identity.isNode(item.value) ? item.value : null;
if (iv) {
if (iv.comment)
comment = iv.comment;
if (iv.commentBefore)
reqNewline = true;
} else if (item.value == null && ik?.comment) {
comment = ik.comment;
}
}
if (comment)
reqNewline = true;
let str = stringify4.stringify(item, itemCtx, () => comment = null);
reqNewline || (reqNewline = lines.length > linesAtValue || str.includes("\n"));
if (i < items.length - 1) {
str += ",";
} else if (ctx.options.trailingComma) {
if (ctx.options.lineWidth > 0) {
reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + (str.length + 2) > ctx.options.lineWidth);
}
if (reqNewline) {
str += ",";
}
}
if (comment)
str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
lines.push(str);
linesAtValue = lines.length;
}
const { start, end } = flowChars;
if (lines.length === 0) {
return start + end;
} else {
if (!reqNewline) {
const len = lines.reduce((sum, line) => sum + line.length + 2, 2);
reqNewline = ctx.options.lineWidth > 0 && len > ctx.options.lineWidth;
}
if (reqNewline) {
let str = start;
for (const line of lines)
str += line ? `
${indentStep}${indent}${line}` : "\n";
return `${str}
${indent}${end}`;
} else {
return `${start}${fcPadding}${lines.join(" ")}${fcPadding}${end}`;
}
}
}
function addCommentBefore({ indent, options: { commentString } }, lines, comment, chompKeep) {
if (comment && chompKeep)
comment = comment.replace(/^\n+/, "");
if (comment) {
const ic = stringifyComment.indentComment(commentString(comment), indent);
lines.push(ic.trimStart());
}
}
exports.stringifyCollection = stringifyCollection;
}
});
// node_modules/yaml/dist/nodes/YAMLMap.js
var require_YAMLMap = __commonJS({
"node_modules/yaml/dist/nodes/YAMLMap.js"(exports) {
"use strict";
var stringifyCollection = require_stringifyCollection();
var addPairToJSMap = require_addPairToJSMap();
var Collection = require_Collection();
var identity = require_identity();
var Pair = require_Pair();
var Scalar = require_Scalar();
function findPair(items, key) {
const k = identity.isScalar(key) ? key.value : key;
for (const it of items) {
if (identity.isPair(it)) {
if (it.key === key || it.key === k)
return it;
if (identity.isScalar(it.key) && it.key.value === k)
return it;
}
}
return void 0;
}
var YAMLMap = class extends Collection.Collection {
static get tagName() {
return "tag:yaml.org,2002:map";
}
constructor(schema) {
super(identity.MAP, schema);
this.items = [];
}
/**
* A generic collection parsing method that can be extended
* to other node classes that inherit from YAMLMap
*/
static from(schema, obj, ctx) {
const { keepUndefined, replacer } = ctx;
const map = new this(schema);
const add = (key, value) => {
if (typeof replacer === "function")
value = replacer.call(obj, key, value);
else if (Array.isArray(replacer) && !replacer.includes(key))
return;
if (value !== void 0 || keepUndefined)
map.items.push(Pair.createPair(key, value, ctx));
};
if (obj instanceof Map) {
for (const [key, value] of obj)
add(key, value);
} else if (obj && typeof obj === "object") {
for (const key of Object.keys(obj))
add(key, obj[key]);
}
if (typeof schema.sortMapEntries === "function") {
map.items.sort(schema.sortMapEntries);
}
return map;
}
/**
* Adds a value to the collection.
*
* @param overwrite - If not set `true`, using a key that is already in the
* collection will throw. Otherwise, overwrites the previous value.
*/
add(pair, overwrite) {
let _pair;
if (identity.isPair(pair))
_pair = pair;
else if (!pair || typeof pair !== "object" || !("key" in pair)) {
_pair = new Pair.Pair(pair, pair?.value);
} else
_pair = new Pair.Pair(pair.key, pair.value);
const prev = findPair(this.items, _pair.key);
const sortEntries = this.schema?.sortMapEntries;
if (prev) {
if (!overwrite)
throw new Error(`Key ${_pair.key} already set`);
if (identity.isScalar(prev.value) && Scalar.isScalarValue(_pair.value))
prev.value.value = _pair.value;
else
prev.value = _pair.value;
} else if (sortEntries) {
const i = this.items.findIndex((item) => sortEntries(_pair, item) < 0);
if (i === -1)
this.items.push(_pair);
else
this.items.splice(i, 0, _pair);
} else {
this.items.push(_pair);
}
}
delete(key) {
const it = findPair(this.items, key);
if (!it)
return false;
const del = this.items.splice(this.items.indexOf(it), 1);
return del.length > 0;
}
get(key, keepScalar) {
const it = findPair(this.items, key);
const node = it?.value;
return (!keepScalar && identity.isScalar(node) ? node.value : node) ?? void 0;
}
has(key) {
return !!findPair(this.items, key);
}
set(key, value) {
this.add(new Pair.Pair(key, value), true);
}
/**
* @param ctx - Conversion context, originally set in Document#toJS()
* @param {Class} Type - If set, forces the returned collection type
* @returns Instance of Type, Map, or Object
*/
toJSON(_, ctx, Type) {
const map = Type ? new Type() : ctx?.mapAsMap ? /* @__PURE__ */ new Map() : {};
if (ctx?.onCreate)
ctx.onCreate(map);
for (const item of this.items)
addPairToJSMap.addPairToJSMap(ctx, map, item);
return map;
}
toString(ctx, onComment, onChompKeep) {
if (!ctx)
return JSON.stringify(this);
for (const item of this.items) {
if (!identity.isPair(item))
throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`);
}
if (!ctx.allNullValues && this.hasAllNullValues(false))
ctx = Object.assign({}, ctx, { allNullValues: true });
return stringifyCollection.stringifyCollection(this, ctx, {
blockItemPrefix: "",
flowChars: { start: "{", end: "}" },
itemIndent: ctx.indent || "",
onChompKeep,
onComment
});
}
};
exports.YAMLMap = YAMLMap;
exports.findPair = findPair;
}
});
// node_modules/yaml/dist/schema/common/map.js
var require_map = __commonJS({
"node_modules/yaml/dist/schema/common/map.js"(exports) {
"use strict";
var identity = require_identity();
var YAMLMap = require_YAMLMap();
var map = {
collection: "map",
default: true,
nodeClass: YAMLMap.YAMLMap,
tag: "tag:yaml.org,2002:map",
resolve(map2, onError) {
if (!identity.isMap(map2))
onError("Expected a mapping for this tag");
return map2;
},
createNode: (schema, obj, ctx) => YAMLMap.YAMLMap.from(schema, obj, ctx)
};
exports.map = map;
}
});
// node_modules/yaml/dist/nodes/YAMLSeq.js
var require_YAMLSeq = __commonJS({
"node_modules/yaml/dist/nodes/YAMLSeq.js"(exports) {
"use strict";
var createNode = require_createNode();
var stringifyCollection = require_stringifyCollection();
var Collection = require_Collection();
var identity = require_identity();
var Scalar = require_Scalar();
var toJS = require_toJS();
var YAMLSeq = class extends Collection.Collection {
static get tagName() {
return "tag:yaml.org,2002:seq";
}
constructor(schema) {
super(identity.SEQ, schema);
this.items = [];
}
add(value) {
this.items.push(value);
}
/**
* Removes a value from the collection.
*
* `key` must contain a representation of an integer for this to succeed.
* It may be wrapped in a `Scalar`.
*
* @returns `true` if the item was found and removed.
*/
delete(key) {
const idx = asItemIndex(key);
if (typeof idx !== "number")
return false;
const del = this.items.splice(idx, 1);
return del.length > 0;
}
get(key, keepScalar) {
const idx = asItemIndex(key);
if (typeof idx !== "number")
return void 0;
const it = this.items[idx];
return !keepScalar && identity.isScalar(it) ? it.value : it;
}
/**
* Checks if the collection includes a value with the key `key`.
*
* `key` must contain a representation of an integer for this to succeed.
* It may be wrapped in a `Scalar`.
*/
has(key) {
const idx = asItemIndex(key);
return typeof idx === "number" && idx < this.items.length;
}
/**
* Sets a value in this collection. For `!!set`, `value` needs to be a
* boolean to add/remove the item from the set.
*
* If `key` does not contain a representation of an integer, this will throw.
* It may be wrapped in a `Scalar`.
*/
set(key, value) {
const idx = asItemIndex(key);
if (typeof idx !== "number")
throw new Error(`Expected a valid index, not ${key}.`);
const prev = this.items[idx];
if (identity.isScalar(prev) && Scalar.isScalarValue(value))
prev.value = value;
else
this.items[idx] = value;
}
toJSON(_, ctx) {
const seq = [];
if (ctx?.onCreate)
ctx.onCreate(seq);
let i = 0;
for (const item of this.items)
seq.push(toJS.toJS(item, String(i++), ctx));
return seq;
}
toString(ctx, onComment, onChompKeep) {
if (!ctx)
return JSON.stringify(this);
return stringifyCollection.stringifyCollection(this, ctx, {
blockItemPrefix: "- ",
flowChars: { start: "[", end: "]" },
itemIndent: (ctx.indent || "") + " ",
onChompKeep,
onComment
});
}
static from(schema, obj, ctx) {
const { replacer } = ctx;
const seq = new this(schema);
if (obj && Symbol.iterator in Object(obj)) {
let i = 0;
for (let it of obj) {
if (typeof replacer === "function") {
const key = obj instanceof Set ? it : String(i++);
it = replacer.call(obj, key, it);
}
seq.items.push(createNode.createNode(it, void 0, ctx));
}
}
return seq;
}
};
function asItemIndex(key) {
let idx = identity.isScalar(key) ? key.value : key;
if (idx && typeof idx === "string")
idx = Number(idx);
return typeof idx === "number" && Number.isInteger(idx) && idx >= 0 ? idx : null;
}
exports.YAMLSeq = YAMLSeq;
}
});
// node_modules/yaml/dist/schema/common/seq.js
var require_seq = __commonJS({
"node_modules/yaml/dist/schema/common/seq.js"(exports) {
"use strict";
var identity = require_identity();
var YAMLSeq = require_YAMLSeq();
var seq = {
collection: "seq",
default: true,
nodeClass: YAMLSeq.YAMLSeq,
tag: "tag:yaml.org,2002:seq",
resolve(seq2, onError) {
if (!identity.isSeq(seq2))
onError("Expected a sequence for this tag");
return seq2;
},
createNode: (schema, obj, ctx) => YAMLSeq.YAMLSeq.from(schema, obj, ctx)
};
exports.seq = seq;
}
});
// node_modules/yaml/dist/schema/common/string.js
var require_string = __commonJS({
"node_modules/yaml/dist/schema/common/string.js"(exports) {
"use strict";
var stringifyString = require_stringifyString();
var string = {
identify: (value) => typeof value === "string",
default: true,
tag: "tag:yaml.org,2002:str",
resolve: (str) => str,
stringify(item, ctx, onComment, onChompKeep) {
ctx = Object.assign({ actualString: true }, ctx);
return stringifyString.stringifyString(item, ctx, onComment, onChompKeep);
}
};
exports.string = string;
}
});
// node_modules/yaml/dist/schema/common/null.js
var require_null = __commonJS({
"node_modules/yaml/dist/schema/common/null.js"(exports) {
"use strict";
var Scalar = require_Scalar();
var nullTag = {
identify: (value) => value == null,
createNode: () => new Scalar.Scalar(null),
default: true,
tag: "tag:yaml.org,2002:null",
test: /^(?:~|[Nn]ull|NULL)?$/,
resolve: () => new Scalar.Scalar(null),
stringify: ({ source }, ctx) => typeof source === "string" && nullTag.test.test(source) ? source : ctx.options.nullStr
};
exports.nullTag = nullTag;
}
});
// node_modules/yaml/dist/schema/core/bool.js
var require_bool = __commonJS({
"node_modules/yaml/dist/schema/core/bool.js"(exports) {
"use strict";
var Scalar = require_Scalar();
var boolTag = {
identify: (value) => typeof value === "boolean",
default: true,
tag: "tag:yaml.org,2002:bool",
test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,
resolve: (str) => new Scalar.Scalar(str[0] === "t" || str[0] === "T"),
stringify({ source, value }, ctx) {
if (source && boolTag.test.test(source)) {
const sv = source[0] === "t" || source[0] === "T";
if (value === sv)
return source;
}
return value ? ctx.options.trueStr : ctx.options.falseStr;
}
};
exports.boolTag = boolTag;
}
});
// node_modules/yaml/dist/stringify/stringifyNumber.js
var require_stringifyNumber = __commonJS({
"node_modules/yaml/dist/stringify/stringifyNumber.js"(exports) {
"use strict";
function stringifyNumber({ format, minFractionDigits, tag, value }) {
if (typeof value === "bigint")
return String(value);
const num = typeof value === "number" ? value : Number(value);
if (!isFinite(num))
return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
if (!format && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^-?\d/.test(n) && !n.includes("e")) {
let i = n.indexOf(".");
if (i < 0) {
i = n.length;
n += ".";
}
let d = minFractionDigits - (n.length - i - 1);
while (d-- > 0)
n += "0";
}
return n;
}
exports.stringifyNumber = stringifyNumber;
}
});
// node_modules/yaml/dist/schema/core/float.js
var require_float = __commonJS({
"node_modules/yaml/dist/schema/core/float.js"(exports) {
"use strict";
var Scalar = require_Scalar();
var stringifyNumber = require_stringifyNumber();
var floatNaN = {
identify: (value) => typeof value === "number",
default: true,
tag: "tag:yaml.org,2002:float",
test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
stringify: stringifyNumber.stringifyNumber
};
var floatExp = {
identify: (value) => typeof value === "number",
default: true,
tag: "tag:yaml.org,2002:float",
format: "EXP",
test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,
resolve: (str) => parseFloat(str),
stringify(node) {
const num = Number(node.value);
return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);
}
};
var float = {
identify: (value) => typeof value === "number",
default: true,
tag: "tag:yaml.org,2002:float",
test: /^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/,
resolve(str) {
const node = new Scalar.Scalar(parseFloat(str));
const dot = str.indexOf(".");
if (dot !== -1 && str[str.length - 1] === "0")
node.minFractionDigits = str.length - dot - 1;
return node;
},
stringify: stringifyNumber.stringifyNumber
};
exports.float = float;
exports.floatExp = floatExp;
exports.floatNaN = floatNaN;
}
});
// node_modules/yaml/dist/schema/core/int.js
var require_int = __commonJS({
"node_modules/yaml/dist/schema/core/int.js"(exports) {
"use strict";
var stringifyNumber = require_stringifyNumber();
var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
var intResolve = (str, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str.substring(offset), radix);
function intStringify(node, radix, prefix) {
const { value } = node;
if (intIdentify(value) && value >= 0)
return prefix + value.toString(radix);
return stringifyNumber.stringifyNumber(node);
}
var intOct = {
identify: (value) => intIdentify(value) && value >= 0,
default: true,
tag: "tag:yaml.org,2002:int",
format: "OCT",
test: /^0o[0-7]+$/,
resolve: (str, _onError, opt) => intResolve(str, 2, 8, opt),
stringify: (node) => intStringify(node, 8, "0o")
};
var int = {
identify: intIdentify,
default: true,
tag: "tag:yaml.org,2002:int",
test: /^[-+]?[0-9]+$/,
resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),
stringify: stringifyNumber.stringifyNumber
};
var intHex = {
identify: (value) => intIdentify(value) && value >= 0,
default: true,
tag: "tag:yaml.org,2002:int",
format: "HEX",
test: /^0x[0-9a-fA-F]+$/,
resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
stringify: (node) => intStringify(node, 16, "0x")
};
exports.int = int;
exports.intHex = intHex;
exports.intOct = intOct;
}
});
// node_modules/yaml/dist/schema/core/schema.js
var require_schema2 = __commonJS({
"node_modules/yaml/dist/schema/core/schema.js"(exports) {
"use strict";
var map = require_map();
var _null = require_null();
var seq = require_seq();
var string = require_string();
var bool = require_bool();
var float = require_float();
var int = require_int();
var schema = [
map.map,
seq.seq,
string.string,
_null.nullTag,
bool.boolTag,
int.intOct,
int.int,
int.intHex,
float.floatNaN,
float.floatExp,
float.float
];
exports.schema = schema;
}
});
// node_modules/yaml/dist/schema/json/schema.js
var require_schema3 = __commonJS({
"node_modules/yaml/dist/schema/json/schema.js"(exports) {
"use strict";
var Scalar = require_Scalar();
var map = require_map();
var seq = require_seq();
function intIdentify(value) {
return typeof value === "bigint" || Number.isInteger(value);
}
var stringifyJSON = ({ value }) => JSON.stringify(value);
var jsonScalars = [
{
identify: (value) => typeof value === "string",
default: true,
tag: "tag:yaml.org,2002:str",
resolve: (str) => str,
stringify: stringifyJSON
},
{
identify: (value) => value == null,
createNode: () => new Scalar.Scalar(null),
default: true,
tag: "tag:yaml.org,2002:null",
test: /^null$/,
resolve: () => null,
stringify: stringifyJSON
},
{
identify: (value) => typeof value === "boolean",
default: true,
tag: "tag:yaml.org,2002:bool",
test: /^true$|^false$/,
resolve: (str) => str === "true",
stringify: stringifyJSON
},
{
identify: intIdentify,
default: true,
tag: "tag:yaml.org,2002:int",
test: /^-?(?:0|[1-9][0-9]*)$/,
resolve: (str, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str, 10),
stringify: ({ value }) => intIdentify(value) ? value.toString() : JSON.stringify(value)
},
{
identify: (value) => typeof value === "number",
default: true,
tag: "tag:yaml.org,2002:float",
test: /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,
resolve: (str) => parseFloat(str),
stringify: stringifyJSON
}
];
var jsonError = {
default: true,
tag: "",
test: /^/,
resolve(str, onError) {
onError(`Unresolved plain scalar ${JSON.stringify(str)}`);
return str;
}
};
var schema = [map.map, seq.seq].concat(jsonScalars, jsonError);
exports.schema = schema;
}
});
// node_modules/yaml/dist/schema/yaml-1.1/binary.js
var require_binary = __commonJS({
"node_modules/yaml/dist/schema/yaml-1.1/binary.js"(exports) {
"use strict";
var node_buffer = __require("buffer");
var Scalar = require_Scalar();
var stringifyString = require_stringifyString();
var binary = {
identify: (value) => value instanceof Uint8Array,
// Buffer inherits from Uint8Array
default: false,
tag: "tag:yaml.org,2002:binary",
/**
* Returns a Buffer in node and an Uint8Array in browsers
*
* To use the resulting buffer as an image, you'll want to do something like:
*
* const blob = new Blob([buffer], { type: 'image/jpeg' })
* document.querySelector('#photo').src = URL.createObjectURL(blob)
*/
resolve(src, onError) {
if (typeof node_buffer.Buffer === "function") {
return node_buffer.Buffer.from(src, "base64");
} else if (typeof atob === "function") {
const str = atob(src.replace(/[\n\r]/g, ""));
const buffer = new Uint8Array(str.length);
for (let i = 0; i < str.length; ++i)
buffer[i] = str.charCodeAt(i);
return buffer;
} else {
onError("This environment does not support reading binary tags; either Buffer or atob is required");
return src;
}
},
stringify({ comment, type, value }, ctx, onComment, onChompKeep) {
if (!value)
return "";
const buf = value;
let str;
if (typeof node_buffer.Buffer === "function") {
str = buf instanceof node_buffer.Buffer ? buf.toString("base64") : node_buffer.Buffer.from(buf.buffer).toString("base64");
} else if (typeof btoa === "function") {
let s = "";
for (let i = 0; i < buf.length; ++i)
s += String.fromCharCode(buf[i]);
str = btoa(s);
} else {
throw new Error("This environment does not support writing binary tags; either Buffer or btoa is required");
}
type ?? (type = Scalar.Scalar.BLOCK_LITERAL);
if (type !== Scalar.Scalar.QUOTE_DOUBLE) {
const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth);
const n = Math.ceil(str.length / lineWidth);
const lines = new Array(n);
for (let i = 0, o = 0; i < n; ++i, o += lineWidth) {
lines[i] = str.substr(o, lineWidth);
}
str = lines.join(type === Scalar.Scalar.BLOCK_LITERAL ? "\n" : " ");
}
return stringifyString.stringifyString({ comment, type, value: str }, ctx, onComment, onChompKeep);
}
};
exports.binary = binary;
}
});
// node_modules/yaml/dist/schema/yaml-1.1/pairs.js
var require_pairs = __commonJS({
"node_modules/yaml/dist/schema/yaml-1.1/pairs.js"(exports) {
"use strict";
var identity = require_identity();
var Pair = require_Pair();
var Scalar = require_Scalar();
var YAMLSeq = require_YAMLSeq();
function resolvePairs(seq, onError) {
if (identity.isSeq(seq)) {
for (let i = 0; i < seq.items.length; ++i) {
let item = seq.items[i];
if (identity.isPair(item))
continue;
else if (identity.isMap(item)) {
if (item.items.length > 1)
onError("Each pair must have its own sequence indicator");
const pair = item.items[0] || new Pair.Pair(new Scalar.Scalar(null));
if (item.commentBefore)
pair.key.commentBefore = pair.key.commentBefore ? `${item.commentBefore}
${pair.key.commentBefore}` : item.commentBefore;
if (item.comment) {
const cn = pair.value ?? pair.key;
cn.comment = cn.comment ? `${item.comment}
${cn.comment}` : item.comment;
}
item = pair;
}
seq.items[i] = identity.isPair(item) ? item : new Pair.Pair(item);
}
} else
onError("Expected a sequence for this tag");
return seq;
}
function createPairs(schema, iterable, ctx) {
const { replacer } = ctx;
const pairs2 = new YAMLSeq.YAMLSeq(schema);
pairs2.tag = "tag:yaml.org,2002:pairs";
let i = 0;
if (iterable && Symbol.iterator in Object(iterable))
for (let it of iterable) {
if (typeof replacer === "function")
it = replacer.call(iterable, String(i++), it);
let key, value;
if (Array.isArray(it)) {
if (it.length === 2) {
key = it[0];
value = it[1];
} else
throw new TypeError(`Expected [key, value] tuple: ${it}`);
} else if (it && it instanceof Object) {
const keys = Object.keys(it);
if (keys.length === 1) {
key = keys[0];
value = it[key];
} else {
throw new TypeError(`Expected tuple with one key, not ${keys.length} keys`);
}
} else {
key = it;
}
pairs2.items.push(Pair.createPair(key, value, ctx));
}
return pairs2;
}
var pairs = {
collection: "seq",
default: false,
tag: "tag:yaml.org,2002:pairs",
resolve: resolvePairs,
createNode: createPairs
};
exports.createPairs = createPairs;
exports.pairs = pairs;
exports.resolvePairs = resolvePairs;
}
});
// node_modules/yaml/dist/schema/yaml-1.1/omap.js
var require_omap = __commonJS({
"node_modules/yaml/dist/schema/yaml-1.1/omap.js"(exports) {
"use strict";
var identity = require_identity();
var toJS = require_toJS();
var YAMLMap = require_YAMLMap();
var YAMLSeq = require_YAMLSeq();
var pairs = require_pairs();
var YAMLOMap = class _YAMLOMap extends YAMLSeq.YAMLSeq {
constructor() {
super();
this.add = YAMLMap.YAMLMap.prototype.add.bind(this);
this.delete = YAMLMap.YAMLMap.prototype.delete.bind(this);
this.get = YAMLMap.YAMLMap.prototype.get.bind(this);
this.has = YAMLMap.YAMLMap.prototype.has.bind(this);
this.set = YAMLMap.YAMLMap.prototype.set.bind(this);
this.tag = _YAMLOMap.tag;
}
/**
* If `ctx` is given, the return type is actually `Map<unknown, unknown>`,
* but TypeScript won't allow widening the signature of a child method.
*/
toJSON(_, ctx) {
if (!ctx)
return super.toJSON(_);
const map = /* @__PURE__ */ new Map();
if (ctx?.onCreate)
ctx.onCreate(map);
for (const pair of this.items) {
let key, value;
if (identity.isPair(pair)) {
key = toJS.toJS(pair.key, "", ctx);
value = toJS.toJS(pair.value, key, ctx);
} else {
key = toJS.toJS(pair, "", ctx);
}
if (map.has(key))
throw new Error("Ordered maps must not include duplicate keys");
map.set(key, value);
}
return map;
}
static from(schema, iterable, ctx) {
const pairs$1 = pairs.createPairs(schema, iterable, ctx);
const omap2 = new this();
omap2.items = pairs$1.items;
return omap2;
}
};
YAMLOMap.tag = "tag:yaml.org,2002:omap";
var omap = {
collection: "seq",
identify: (value) => value instanceof Map,
nodeClass: YAMLOMap,
default: false,
tag: "tag:yaml.org,2002:omap",
resolve(seq, onError) {
const pairs$1 = pairs.resolvePairs(seq, onError);
const seenKeys = [];
for (const { key } of pairs$1.items) {
if (identity.isScalar(key)) {
if (seenKeys.includes(key.value)) {
onError(`Ordered maps must not include duplicate keys: ${key.value}`);
} else {
seenKeys.push(key.value);
}
}
}
return Object.assign(new YAMLOMap(), pairs$1);
},
createNode: (schema, iterable, ctx) => YAMLOMap.from(schema, iterable, ctx)
};
exports.YAMLOMap = YAMLOMap;
exports.omap = omap;
}
});
// node_modules/yaml/dist/schema/yaml-1.1/bool.js
var require_bool2 = __commonJS({
"node_modules/yaml/dist/schema/yaml-1.1/bool.js"(exports) {
"use strict";
var Scalar = require_Scalar();
function boolStringify({ value, source }, ctx) {
const boolObj = value ? trueTag : falseTag;
if (source && boolObj.test.test(source))
return source;
return value ? ctx.options.trueStr : ctx.options.falseStr;
}
var trueTag = {
identify: (value) => value === true,
default: true,
tag: "tag:yaml.org,2002:bool",
test: /^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/,
resolve: () => new Scalar.Scalar(true),
stringify: boolStringify
};
var falseTag = {
identify: (value) => value === false,
default: true,
tag: "tag:yaml.org,2002:bool",
test: /^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/,
resolve: () => new Scalar.Scalar(false),
stringify: boolStringify
};
exports.falseTag = falseTag;
exports.trueTag = trueTag;
}
});
// node_modules/yaml/dist/schema/yaml-1.1/float.js
var require_float2 = __commonJS({
"node_modules/yaml/dist/schema/yaml-1.1/float.js"(exports) {
"use strict";
var Scalar = require_Scalar();
var stringifyNumber = require_stringifyNumber();
var floatNaN = {
identify: (value) => typeof value === "number",
default: true,
tag: "tag:yaml.org,2002:float",
test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
stringify: stringifyNumber.stringifyNumber
};
var floatExp = {
identify: (value) => typeof value === "number",
default: true,
tag: "tag:yaml.org,2002:float",
format: "EXP",
test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,
resolve: (str) => parseFloat(str.replace(/_/g, "")),
stringify(node) {
const num = Number(node.value);
return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);
}
};
var float = {
identify: (value) => typeof value === "number",
default: true,
tag: "tag:yaml.org,2002:float",
test: /^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/,
resolve(str) {
const node = new Scalar.Scalar(parseFloat(str.replace(/_/g, "")));
const dot = str.indexOf(".");
if (dot !== -1) {
const f = str.substring(dot + 1).replace(/_/g, "");
if (f[f.length - 1] === "0")
node.minFractionDigits = f.length;
}
return node;
},
stringify: stringifyNumber.stringifyNumber
};
exports.float = float;
exports.floatExp = floatExp;
exports.floatNaN = floatNaN;
}
});
// node_modules/yaml/dist/schema/yaml-1.1/int.js
var require_int2 = __commonJS({
"node_modules/yaml/dist/schema/yaml-1.1/int.js"(exports) {
"use strict";
var stringifyNumber = require_stringifyNumber();
var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
function intResolve(str, offset, radix, { intAsBigInt }) {
const sign = str[0];
if (sign === "-" || sign === "+")
offset += 1;
str = str.substring(offset).replace(/_/g, "");
if (intAsBigInt) {
switch (radix) {
case 2:
str = `0b${str}`;
break;
case 8:
str = `0o${str}`;
break;
case 16:
str = `0x${str}`;
break;
}
const n2 = BigInt(str);
return sign === "-" ? BigInt(-1) * n2 : n2;
}
const n = parseInt(str, radix);
return sign === "-" ? -1 * n : n;
}
function intStringify(node, radix, prefix) {
const { value } = node;
if (intIdentify(value)) {
const str = value.toString(radix);
return value < 0 ? "-" + prefix + str.substr(1) : prefix + str;
}
return stringifyNumber.stringifyNumber(node);
}
var intBin = {
identify: intIdentify,
default: true,
tag: "tag:yaml.org,2002:int",
format: "BIN",
test: /^[-+]?0b[0-1_]+$/,
resolve: (str, _onError, opt) => intResolve(str, 2, 2, opt),
stringify: (node) => intStringify(node, 2, "0b")
};
var intOct = {
identify: intIdentify,
default: true,
tag: "tag:yaml.org,2002:int",
format: "OCT",
test: /^[-+]?0[0-7_]+$/,
resolve: (str, _onError, opt) => intResolve(str, 1, 8, opt),
stringify: (node) => intStringify(node, 8, "0")
};
var int = {
identify: intIdentify,
default: true,
tag: "tag:yaml.org,2002:int",
test: /^[-+]?[0-9][0-9_]*$/,
resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),
stringify: stringifyNumber.stringifyNumber
};
var intHex = {
identify: intIdentify,
default: true,
tag: "tag:yaml.org,2002:int",
format: "HEX",
test: /^[-+]?0x[0-9a-fA-F_]+$/,
resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
stringify: (node) => intStringify(node, 16, "0x")
};
exports.int = int;
exports.intBin = intBin;
exports.intHex = intHex;
exports.intOct = intOct;
}
});
// node_modules/yaml/dist/schema/yaml-1.1/set.js
var require_set = __commonJS({
"node_modules/yaml/dist/schema/yaml-1.1/set.js"(exports) {
"use strict";
var identity = require_identity();
var Pair = require_Pair();
var YAMLMap = require_YAMLMap();
var YAMLSet = class _YAMLSet extends YAMLMap.YAMLMap {
constructor(schema) {
super(schema);
this.tag = _YAMLSet.tag;
}
add(key) {
let pair;
if (identity.isPair(key))
pair = key;
else if (key && typeof key === "object" && "key" in key && "value" in key && key.value === null)
pair = new Pair.Pair(key.key, null);
else
pair = new Pair.Pair(key, null);
const prev = YAMLMap.findPair(this.items, pair.key);
if (!prev)
this.items.push(pair);
}
/**
* If `keepPair` is `true`, returns the Pair matching `key`.
* Otherwise, returns the value of that Pair's key.
*/
get(key, keepPair) {
const pair = YAMLMap.findPair(this.items, key);
return !keepPair && identity.isPair(pair) ? identity.isScalar(pair.key) ? pair.key.value : pair.key : pair;
}
set(key, value) {
if (typeof value !== "boolean")
throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof value}`);
const prev = YAMLMap.findPair(this.items, key);
if (prev && !value) {
this.items.splice(this.items.indexOf(prev), 1);
} else if (!prev && value) {
this.items.push(new Pair.Pair(key));
}
}
toJSON(_, ctx) {
return super.toJSON(_, ctx, Set);
}
toString(ctx, onComment, onChompKeep) {
if (!ctx)
return JSON.stringify(this);
if (this.hasAllNullValues(true))
return super.toString(Object.assign({}, ctx, { allNullValues: true }), onComment, onChompKeep);
else
throw new Error("Set items must all have null values");
}
static from(schema, iterable, ctx) {
const { replacer } = ctx;
const set2 = new this(schema);
if (iterable && Symbol.iterator in Object(iterable))
for (let value of iterable) {
if (typeof replacer === "function")
value = replacer.call(iterable, value, value);
set2.items.push(Pair.createPair(value, null, ctx));
}
return set2;
}
};
YAMLSet.tag = "tag:yaml.org,2002:set";
var set = {
collection: "map",
identify: (value) => value instanceof Set,
nodeClass: YAMLSet,
default: false,
tag: "tag:yaml.org,2002:set",
createNode: (schema, iterable, ctx) => YAMLSet.from(schema, iterable, ctx),
resolve(map, onError) {
if (identity.isMap(map)) {
if (map.hasAllNullValues(true))
return Object.assign(new YAMLSet(), map);
else
onError("Set items must all have null values");
} else
onError("Expected a mapping for this tag");
return map;
}
};
exports.YAMLSet = YAMLSet;
exports.set = set;
}
});
// node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
var require_timestamp = __commonJS({
"node_modules/yaml/dist/schema/yaml-1.1/timestamp.js"(exports) {
"use strict";
var stringifyNumber = require_stringifyNumber();
function parseSexagesimal(str, asBigInt) {
const sign = str[0];
const parts = sign === "-" || sign === "+" ? str.substring(1) : str;
const num = (n) => asBigInt ? BigInt(n) : Number(n);
const res = parts.replace(/_/g, "").split(":").reduce((res2, p) => res2 * num(60) + num(p), num(0));
return sign === "-" ? num(-1) * res : res;
}
function stringifySexagesimal(node) {
let { value } = node;
let num = (n) => n;
if (typeof value === "bigint")
num = (n) => BigInt(n);
else if (isNaN(value) || !isFinite(value))
return stringifyNumber.stringifyNumber(node);
let sign = "";
if (value < 0) {
sign = "-";
value *= num(-1);
}
const _60 = num(60);
const parts = [value % _60];
if (value < 60) {
parts.unshift(0);
} else {
value = (value - parts[0]) / _60;
parts.unshift(value % _60);
if (value >= 60) {
value = (value - parts[0]) / _60;
parts.unshift(value);
}
}
return sign + parts.map((n) => String(n).padStart(2, "0")).join(":").replace(/000000\d*$/, "");
}
var intTime = {
identify: (value) => typeof value === "bigint" || Number.isInteger(value),
default: true,
tag: "tag:yaml.org,2002:int",
format: "TIME",
test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/,
resolve: (str, _onError, { intAsBigInt }) => parseSexagesimal(str, intAsBigInt),
stringify: stringifySexagesimal
};
var floatTime = {
identify: (value) => typeof value === "number",
default: true,
tag: "tag:yaml.org,2002:float",
format: "TIME",
test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*$/,
resolve: (str) => parseSexagesimal(str, false),
stringify: stringifySexagesimal
};
var timestamp = {
identify: (value) => value instanceof Date,
default: true,
tag: "tag:yaml.org,2002:timestamp",
// If the time zone is omitted, the timestamp is assumed to be specified in UTC. The time part
// may be omitted altogether, resulting in a date format. In such a case, the time part is
// assumed to be 00:00:00Z (start of day, UTC).
test: RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})(?:(?:t|T|[ \\t]+)([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?)?$"),
resolve(str) {
const match = str.match(timestamp.test);
if (!match)
throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");
const [, year, month, day, hour, minute, second] = match.map(Number);
const millisec = match[7] ? Number((match[7] + "00").substr(1, 3)) : 0;
let date = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec);
const tz = match[8];
if (tz && tz !== "Z") {
let d = parseSexagesimal(tz, false);
if (Math.abs(d) < 30)
d *= 60;
date -= 6e4 * d;
}
return new Date(date);
},
stringify: ({ value }) => value?.toISOString().replace(/(T00:00:00)?\.000Z$/, "") ?? ""
};
exports.floatTime = floatTime;
exports.intTime = intTime;
exports.timestamp = timestamp;
}
});
// node_modules/yaml/dist/schema/yaml-1.1/schema.js
var require_schema4 = __commonJS({
"node_modules/yaml/dist/schema/yaml-1.1/schema.js"(exports) {
"use strict";
var map = require_map();
var _null = require_null();
var seq = require_seq();
var string = require_string();
var binary = require_binary();
var bool = require_bool2();
var float = require_float2();
var int = require_int2();
var merge = require_merge();
var omap = require_omap();
var pairs = require_pairs();
var set = require_set();
var timestamp = require_timestamp();
var schema = [
map.map,
seq.seq,
string.string,
_null.nullTag,
bool.trueTag,
bool.falseTag,
int.intBin,
int.intOct,
int.int,
int.intHex,
float.floatNaN,
float.floatExp,
float.float,
binary.binary,
merge.merge,
omap.omap,
pairs.pairs,
set.set,
timestamp.intTime,
timestamp.floatTime,
timestamp.timestamp
];
exports.schema = schema;
}
});
// node_modules/yaml/dist/schema/tags.js
var require_tags = __commonJS({
"node_modules/yaml/dist/schema/tags.js"(exports) {
"use strict";
var map = require_map();
var _null = require_null();
var seq = require_seq();
var string = require_string();
var bool = require_bool();
var float = require_float();
var int = require_int();
var schema = require_schema2();
var schema$1 = require_schema3();
var binary = require_binary();
var merge = require_merge();
var omap = require_omap();
var pairs = require_pairs();
var schema$2 = require_schema4();
var set = require_set();
var timestamp = require_timestamp();
var schemas = /* @__PURE__ */ new Map([
["core", schema.schema],
["failsafe", [map.map, seq.seq, string.string]],
["json", schema$1.schema],
["yaml11", schema$2.schema],
["yaml-1.1", schema$2.schema]
]);
var tagsByName = {
binary: binary.binary,
bool: bool.boolTag,
float: float.float,
floatExp: float.floatExp,
floatNaN: float.floatNaN,
floatTime: timestamp.floatTime,
int: int.int,
intHex: int.intHex,
intOct: int.intOct,
intTime: timestamp.intTime,
map: map.map,
merge: merge.merge,
null: _null.nullTag,
omap: omap.omap,
pairs: pairs.pairs,
seq: seq.seq,
set: set.set,
timestamp: timestamp.timestamp
};
var coreKnownTags = {
"tag:yaml.org,2002:binary": binary.binary,
"tag:yaml.org,2002:merge": merge.merge,
"tag:yaml.org,2002:omap": omap.omap,
"tag:yaml.org,2002:pairs": pairs.pairs,
"tag:yaml.org,2002:set": set.set,
"tag:yaml.org,2002:timestamp": timestamp.timestamp
};
function getTags(customTags, schemaName, addMergeTag) {
const schemaTags = schemas.get(schemaName);
if (schemaTags && !customTags) {
return addMergeTag && !schemaTags.includes(merge.merge) ? schemaTags.concat(merge.merge) : schemaTags.slice();
}
let tags = schemaTags;
if (!tags) {
if (Array.isArray(customTags))
tags = [];
else {
const keys = Array.from(schemas.keys()).filter((key) => key !== "yaml11").map((key) => JSON.stringify(key)).join(", ");
throw new Error(`Unknown schema "${schemaName}"; use one of ${keys} or define customTags array`);
}
}
if (Array.isArray(customTags)) {
for (const tag of customTags)
tags = tags.concat(tag);
} else if (typeof customTags === "function") {
tags = customTags(tags.slice());
}
if (addMergeTag)
tags = tags.concat(merge.merge);
return tags.reduce((tags2, tag) => {
const tagObj = typeof tag === "string" ? tagsByName[tag] : tag;
if (!tagObj) {
const tagName = JSON.stringify(tag);
const keys = Object.keys(tagsByName).map((key) => JSON.stringify(key)).join(", ");
throw new Error(`Unknown custom tag ${tagName}; use one of ${keys}`);
}
if (!tags2.includes(tagObj))
tags2.push(tagObj);
return tags2;
}, []);
}
exports.coreKnownTags = coreKnownTags;
exports.getTags = getTags;
}
});
// node_modules/yaml/dist/schema/Schema.js
var require_Schema = __commonJS({
"node_modules/yaml/dist/schema/Schema.js"(exports) {
"use strict";
var identity = require_identity();
var map = require_map();
var seq = require_seq();
var string = require_string();
var tags = require_tags();
var sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
var Schema = class _Schema {
constructor({ compat, customTags, merge, resolveKnownTags, schema, sortMapEntries, toStringDefaults }) {
this.compat = Array.isArray(compat) ? tags.getTags(compat, "compat") : compat ? tags.getTags(null, compat) : null;
this.name = typeof schema === "string" && schema || "core";
this.knownTags = resolveKnownTags ? tags.coreKnownTags : {};
this.tags = tags.getTags(customTags, this.name, merge);
this.toStringOptions = toStringDefaults ?? null;
Object.defineProperty(this, identity.MAP, { value: map.map });
Object.defineProperty(this, identity.SCALAR, { value: string.string });
Object.defineProperty(this, identity.SEQ, { value: seq.seq });
this.sortMapEntries = typeof sortMapEntries === "function" ? sortMapEntries : sortMapEntries === true ? sortMapEntriesByKey : null;
}
clone() {
const copy = Object.create(_Schema.prototype, Object.getOwnPropertyDescriptors(this));
copy.tags = this.tags.slice();
return copy;
}
};
exports.Schema = Schema;
}
});
// node_modules/yaml/dist/stringify/stringifyDocument.js
var require_stringifyDocument = __commonJS({
"node_modules/yaml/dist/stringify/stringifyDocument.js"(exports) {
"use strict";
var identity = require_identity();
var stringify4 = require_stringify();
var stringifyComment = require_stringifyComment();
function stringifyDocument(doc, options) {
const lines = [];
let hasDirectives = options.directives === true;
if (options.directives !== false && doc.directives) {
const dir = doc.directives.toString(doc);
if (dir) {
lines.push(dir);
hasDirectives = true;
} else if (doc.directives.docStart)
hasDirectives = true;
}
if (hasDirectives)
lines.push("---");
const ctx = stringify4.createStringifyContext(doc, options);
const { commentString } = ctx.options;
if (doc.commentBefore) {
if (lines.length !== 1)
lines.unshift("");
const cs = commentString(doc.commentBefore);
lines.unshift(stringifyComment.indentComment(cs, ""));
}
let chompKeep = false;
let contentComment = null;
if (doc.contents) {
if (identity.isNode(doc.contents)) {
if (doc.contents.spaceBefore && hasDirectives)
lines.push("");
if (doc.contents.commentBefore) {
const cs = commentString(doc.contents.commentBefore);
lines.push(stringifyComment.indentComment(cs, ""));
}
ctx.forceBlockIndent = !!doc.comment;
contentComment = doc.contents.comment;
}
const onChompKeep = contentComment ? void 0 : () => chompKeep = true;
let body = stringify4.stringify(doc.contents, ctx, () => contentComment = null, onChompKeep);
if (contentComment)
body += stringifyComment.lineComment(body, "", commentString(contentComment));
if ((body[0] === "|" || body[0] === ">") && lines[lines.length - 1] === "---") {
lines[lines.length - 1] = `--- ${body}`;
} else
lines.push(body);
} else {
lines.push(stringify4.stringify(doc.contents, ctx));
}
if (doc.directives?.docEnd) {
if (doc.comment) {
const cs = commentString(doc.comment);
if (cs.includes("\n")) {
lines.push("...");
lines.push(stringifyComment.indentComment(cs, ""));
} else {
lines.push(`... ${cs}`);
}
} else {
lines.push("...");
}
} else {
let dc = doc.comment;
if (dc && chompKeep)
dc = dc.replace(/^\n+/, "");
if (dc) {
if ((!chompKeep || contentComment) && lines[lines.length - 1] !== "")
lines.push("");
lines.push(stringifyComment.indentComment(commentString(dc), ""));
}
}
return lines.join("\n") + "\n";
}
exports.stringifyDocument = stringifyDocument;
}
});
// node_modules/yaml/dist/doc/Document.js
var require_Document = __commonJS({
"node_modules/yaml/dist/doc/Document.js"(exports) {
"use strict";
var Alias = require_Alias();
var Collection = require_Collection();
var identity = require_identity();
var Pair = require_Pair();
var toJS = require_toJS();
var Schema = require_Schema();
var stringifyDocument = require_stringifyDocument();
var anchors = require_anchors();
var applyReviver = require_applyReviver();
var createNode = require_createNode();
var directives = require_directives();
var Document = class _Document {
constructor(value, replacer, options) {
this.commentBefore = null;
this.comment = null;
this.errors = [];
this.warnings = [];
Object.defineProperty(this, identity.NODE_TYPE, { value: identity.DOC });
let _replacer = null;
if (typeof replacer === "function" || Array.isArray(replacer)) {
_replacer = replacer;
} else if (options === void 0 && replacer) {
options = replacer;
replacer = void 0;
}
const opt = Object.assign({
intAsBigInt: false,
keepSourceTokens: false,
logLevel: "warn",
prettyErrors: true,
strict: true,
stringKeys: false,
uniqueKeys: true,
version: "1.2"
}, options);
this.options = opt;
let { version } = opt;
if (options?._directives) {
this.directives = options._directives.atDocument();
if (this.directives.yaml.explicit)
version = this.directives.yaml.version;
} else
this.directives = new directives.Directives({ version });
this.setSchema(version, options);
this.contents = value === void 0 ? null : this.createNode(value, _replacer, options);
}
/**
* Create a deep copy of this Document and its contents.
*
* Custom Node values that inherit from `Object` still refer to their original instances.
*/
clone() {
const copy = Object.create(_Document.prototype, {
[identity.NODE_TYPE]: { value: identity.DOC }
});
copy.commentBefore = this.commentBefore;
copy.comment = this.comment;
copy.errors = this.errors.slice();
copy.warnings = this.warnings.slice();
copy.options = Object.assign({}, this.options);
if (this.directives)
copy.directives = this.directives.clone();
copy.schema = this.schema.clone();
copy.contents = identity.isNode(this.contents) ? this.contents.clone(copy.schema) : this.contents;
if (this.range)
copy.range = this.range.slice();
return copy;
}
/** Adds a value to the document. */
add(value) {
if (assertCollection(this.contents))
this.contents.add(value);
}
/** Adds a value to the document. */
addIn(path, value) {
if (assertCollection(this.contents))
this.contents.addIn(path, value);
}
/**
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
*
* If `node` already has an anchor, `name` is ignored.
* Otherwise, the `node.anchor` value will be set to `name`,
* or if an anchor with that name is already present in the document,
* `name` will be used as a prefix for a new unique anchor.
* If `name` is undefined, the generated anchor will use 'a' as a prefix.
*/
createAlias(node, name) {
if (!node.anchor) {
const prev = anchors.anchorNames(this);
node.anchor = // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
!name || prev.has(name) ? anchors.findNewAnchor(name || "a", prev) : name;
}
return new Alias.Alias(node.anchor);
}
createNode(value, replacer, options) {
let _replacer = void 0;
if (typeof replacer === "function") {
value = replacer.call({ "": value }, "", value);
_replacer = replacer;
} else if (Array.isArray(replacer)) {
const keyToStr = (v) => typeof v === "number" || v instanceof String || v instanceof Number;
const asStr = replacer.filter(keyToStr).map(String);
if (asStr.length > 0)
replacer = replacer.concat(asStr);
_replacer = replacer;
} else if (options === void 0 && replacer) {
options = replacer;
replacer = void 0;
}
const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options ?? {};
const { onAnchor, setAnchors, sourceObjects } = anchors.createNodeAnchors(
this,
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
anchorPrefix || "a"
);
const ctx = {
aliasDuplicateObjects: aliasDuplicateObjects ?? true,
keepUndefined: keepUndefined ?? false,
onAnchor,
onTagObj,
replacer: _replacer,
schema: this.schema,
sourceObjects
};
const node = createNode.createNode(value, tag, ctx);
if (flow && identity.isCollection(node))
node.flow = true;
setAnchors();
return node;
}
/**
* Convert a key and a value into a `Pair` using the current schema,
* recursively wrapping all values as `Scalar` or `Collection` nodes.
*/
createPair(key, value, options = {}) {
const k = this.createNode(key, null, options);
const v = this.createNode(value, null, options);
return new Pair.Pair(k, v);
}
/**
* Removes a value from the document.
* @returns `true` if the item was found and removed.
*/
delete(key) {
return assertCollection(this.contents) ? this.contents.delete(key) : false;
}
/**
* Removes a value from the document.
* @returns `true` if the item was found and removed.
*/
deleteIn(path) {
if (Collection.isEmptyPath(path)) {
if (this.contents == null)
return false;
this.contents = null;
return true;
}
return assertCollection(this.contents) ? this.contents.deleteIn(path) : false;
}
/**
* Returns item at `key`, or `undefined` if not found. By default unwraps
* scalar values from their surrounding node; to disable set `keepScalar` to
* `true` (collections are always returned intact).
*/
get(key, keepScalar) {
return identity.isCollection(this.contents) ? this.contents.get(key, keepScalar) : void 0;
}
/**
* Returns item at `path`, or `undefined` if not found. By default unwraps
* scalar values from their surrounding node; to disable set `keepScalar` to
* `true` (collections are always returned intact).
*/
getIn(path, keepScalar) {
if (Collection.isEmptyPath(path))
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
return identity.isCollection(this.contents) ? this.contents.getIn(path, keepScalar) : void 0;
}
/**
* Checks if the document includes a value with the key `key`.
*/
has(key) {
return identity.isCollection(this.contents) ? this.contents.has(key) : false;
}
/**
* Checks if the document includes a value at `path`.
*/
hasIn(path) {
if (Collection.isEmptyPath(path))
return this.contents !== void 0;
return identity.isCollection(this.contents) ? this.contents.hasIn(path) : false;
}
/**
* Sets a value in this document. For `!!set`, `value` needs to be a
* boolean to add/remove the item from the set.
*/
set(key, value) {
if (this.contents == null) {
this.contents = Collection.collectionFromPath(this.schema, [key], value);
} else if (assertCollection(this.contents)) {
this.contents.set(key, value);
}
}
/**
* Sets a value in this document. For `!!set`, `value` needs to be a
* boolean to add/remove the item from the set.
*/
setIn(path, value) {
if (Collection.isEmptyPath(path)) {
this.contents = value;
} else if (this.contents == null) {
this.contents = Collection.collectionFromPath(this.schema, Array.from(path), value);
} else if (assertCollection(this.contents)) {
this.contents.setIn(path, value);
}
}
/**
* Change the YAML version and schema used by the document.
* A `null` version disables support for directives, explicit tags, anchors, and aliases.
* It also requires the `schema` option to be given as a `Schema` instance value.
*
* Overrides all previously set schema options.
*/
setSchema(version, options = {}) {
if (typeof version === "number")
version = String(version);
let opt;
switch (version) {
case "1.1":
if (this.directives)
this.directives.yaml.version = "1.1";
else
this.directives = new directives.Directives({ version: "1.1" });
opt = { resolveKnownTags: false, schema: "yaml-1.1" };
break;
case "1.2":
case "next":
if (this.directives)
this.directives.yaml.version = version;
else
this.directives = new directives.Directives({ version });
opt = { resolveKnownTags: true, schema: "core" };
break;
case null:
if (this.directives)
delete this.directives;
opt = null;
break;
default: {
const sv = JSON.stringify(version);
throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`);
}
}
if (options.schema instanceof Object)
this.schema = options.schema;
else if (opt)
this.schema = new Schema.Schema(Object.assign(opt, options));
else
throw new Error(`With a null YAML version, the { schema: Schema } option is required`);
}
// json & jsonArg are only used from toJSON()
toJS({ json: json2, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
const ctx = {
anchors: /* @__PURE__ */ new Map(),
doc: this,
keep: !json2,
mapAsMap: mapAsMap === true,
mapKeyWarned: false,
maxAliasCount: typeof maxAliasCount === "number" ? maxAliasCount : 100
};
const res = toJS.toJS(this.contents, jsonArg ?? "", ctx);
if (typeof onAnchor === "function")
for (const { count, res: res2 } of ctx.anchors.values())
onAnchor(res2, count);
return typeof reviver === "function" ? applyReviver.applyReviver(reviver, { "": res }, "", res) : res;
}
/**
* A JSON representation of the document `contents`.
*
* @param jsonArg Used by `JSON.stringify` to indicate the array index or
* property name.
*/
toJSON(jsonArg, onAnchor) {
return this.toJS({ json: true, jsonArg, mapAsMap: false, onAnchor });
}
/** A YAML representation of the document. */
toString(options = {}) {
if (this.errors.length > 0)
throw new Error("Document with errors cannot be stringified");
if ("indent" in options && (!Number.isInteger(options.indent) || Number(options.indent) <= 0)) {
const s = JSON.stringify(options.indent);
throw new Error(`"indent" option must be a positive integer, not ${s}`);
}
return stringifyDocument.stringifyDocument(this, options);
}
};
function assertCollection(contents) {
if (identity.isCollection(contents))
return true;
throw new Error("Expected a YAML collection as document contents");
}
exports.Document = Document;
}
});
// node_modules/yaml/dist/errors.js
var require_errors2 = __commonJS({
"node_modules/yaml/dist/errors.js"(exports) {
"use strict";
var YAMLError = class extends Error {
constructor(name, pos, code, message) {
super();
this.name = name;
this.code = code;
this.message = message;
this.pos = pos;
}
};
var YAMLParseError = class extends YAMLError {
constructor(pos, code, message) {
super("YAMLParseError", pos, code, message);
}
};
var YAMLWarning = class extends YAMLError {
constructor(pos, code, message) {
super("YAMLWarning", pos, code, message);
}
};
var prettifyError = (src, lc) => (error) => {
if (error.pos[0] === -1)
return;
error.linePos = error.pos.map((pos) => lc.linePos(pos));
const { line, col } = error.linePos[0];
error.message += ` at line ${line}, column ${col}`;
let ci = col - 1;
let lineStr = src.substring(lc.lineStarts[line - 1], lc.lineStarts[line]).replace(/[\n\r]+$/, "");
if (ci >= 60 && lineStr.length > 80) {
const trimStart = Math.min(ci - 39, lineStr.length - 79);
lineStr = "\u2026" + lineStr.substring(trimStart);
ci -= trimStart - 1;
}
if (lineStr.length > 80)
lineStr = lineStr.substring(0, 79) + "\u2026";
if (line > 1 && /^ *$/.test(lineStr.substring(0, ci))) {
let prev = src.substring(lc.lineStarts[line - 2], lc.lineStarts[line - 1]);
if (prev.length > 80)
prev = prev.substring(0, 79) + "\u2026\n";
lineStr = prev + lineStr;
}
if (/[^ ]/.test(lineStr)) {
let count = 1;
const end = error.linePos[1];
if (end?.line === line && end.col > col) {
count = Math.max(1, Math.min(end.col - col, 80 - ci));
}
const pointer = " ".repeat(ci) + "^".repeat(count);
error.message += `:
${lineStr}
${pointer}
`;
}
};
exports.YAMLError = YAMLError;
exports.YAMLParseError = YAMLParseError;
exports.YAMLWarning = YAMLWarning;
exports.prettifyError = prettifyError;
}
});
// node_modules/yaml/dist/compose/resolve-props.js
var require_resolve_props = __commonJS({
"node_modules/yaml/dist/compose/resolve-props.js"(exports) {
"use strict";
function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {
let spaceBefore = false;
let atNewline = startOnNewline;
let hasSpace = startOnNewline;
let comment = "";
let commentSep = "";
let hasNewline = false;
let reqSpace = false;
let tab = null;
let anchor = null;
let tag = null;
let newlineAfterProp = null;
let comma = null;
let found = null;
let start = null;
for (const token of tokens) {
if (reqSpace) {
if (token.type !== "space" && token.type !== "newline" && token.type !== "comma")
onError(token.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space");
reqSpace = false;
}
if (tab) {
if (atNewline && token.type !== "comment" && token.type !== "newline") {
onError(tab, "TAB_AS_INDENT", "Tabs are not allowed as indentation");
}
tab = null;
}
switch (token.type) {
case "space":
if (!flow && (indicator !== "doc-start" || next?.type !== "flow-collection") && token.source.includes(" ")) {
tab = token;
}
hasSpace = true;
break;
case "comment": {
if (!hasSpace)
onError(token, "MISSING_CHAR", "Comments must be separated from other tokens by white space characters");
const cb = token.source.substring(1) || " ";
if (!comment)
comment = cb;
else
comment += commentSep + cb;
commentSep = "";
atNewline = false;
break;
}
case "newline":
if (atNewline) {
if (comment)
comment += token.source;
else if (!found || indicator !== "seq-item-ind")
spaceBefore = true;
} else
commentSep += token.source;
atNewline = true;
hasNewline = true;
if (anchor || tag)
newlineAfterProp = token;
hasSpace = true;
break;
case "anchor":
if (anchor)
onError(token, "MULTIPLE_ANCHORS", "A node can have at most one anchor");
if (token.source.endsWith(":"))
onError(token.offset + token.source.length - 1, "BAD_ALIAS", "Anchor ending in : is ambiguous", true);
anchor = token;
start ?? (start = token.offset);
atNewline = false;
hasSpace = false;
reqSpace = true;
break;
case "tag": {
if (tag)
onError(token, "MULTIPLE_TAGS", "A node can have at most one tag");
tag = token;
start ?? (start = token.offset);
atNewline = false;
hasSpace = false;
reqSpace = true;
break;
}
case indicator:
if (anchor || tag)
onError(token, "BAD_PROP_ORDER", `Anchors and tags must be after the ${token.source} indicator`);
if (found)
onError(token, "UNEXPECTED_TOKEN", `Unexpected ${token.source} in ${flow ?? "collection"}`);
found = token;
atNewline = indicator === "seq-item-ind" || indicator === "explicit-key-ind";
hasSpace = false;
break;
case "comma":
if (flow) {
if (comma)
onError(token, "UNEXPECTED_TOKEN", `Unexpected , in ${flow}`);
comma = token;
atNewline = false;
hasSpace = false;
break;
}
// else fallthrough
default:
onError(token, "UNEXPECTED_TOKEN", `Unexpected ${token.type} token`);
atNewline = false;
hasSpace = false;
}
}
const last = tokens[tokens.length - 1];
const end = last ? last.offset + last.source.length : offset;
if (reqSpace && next && next.type !== "space" && next.type !== "newline" && next.type !== "comma" && (next.type !== "scalar" || next.source !== "")) {
onError(next.offset, "MISSING_CHAR", "Tags and anchors must be separated from the next token by white space");
}
if (tab && (atNewline && tab.indent <= parentIndent || next?.type === "block-map" || next?.type === "block-seq"))
onError(tab, "TAB_AS_INDENT", "Tabs are not allowed as indentation");
return {
comma,
found,
spaceBefore,
comment,
hasNewline,
anchor,
tag,
newlineAfterProp,
end,
start: start ?? end
};
}
exports.resolveProps = resolveProps;
}
});
// node_modules/yaml/dist/compose/util-contains-newline.js
var require_util_contains_newline = __commonJS({
"node_modules/yaml/dist/compose/util-contains-newline.js"(exports) {
"use strict";
function containsNewline(key) {
if (!key)
return null;
switch (key.type) {
case "alias":
case "scalar":
case "double-quoted-scalar":
case "single-quoted-scalar":
if (key.source.includes("\n"))
return true;
if (key.end) {
for (const st of key.end)
if (st.type === "newline")
return true;
}
return false;
case "flow-collection":
for (const it of key.items) {
for (const st of it.start)
if (st.type === "newline")
return true;
if (it.sep) {
for (const st of it.sep)
if (st.type === "newline")
return true;
}
if (containsNewline(it.key) || containsNewline(it.value))
return true;
}
return false;
default:
return true;
}
}
exports.containsNewline = containsNewline;
}
});
// node_modules/yaml/dist/compose/util-flow-indent-check.js
var require_util_flow_indent_check = __commonJS({
"node_modules/yaml/dist/compose/util-flow-indent-check.js"(exports) {
"use strict";
var utilContainsNewline = require_util_contains_newline();
function flowIndentCheck(indent, fc, onError) {
if (fc?.type === "flow-collection") {
const end = fc.end[0];
if (end.indent === indent && (end.source === "]" || end.source === "}") && utilContainsNewline.containsNewline(fc)) {
const msg = "Flow end indicator should be more indented than parent";
onError(end, "BAD_INDENT", msg, true);
}
}
}
exports.flowIndentCheck = flowIndentCheck;
}
});
// node_modules/yaml/dist/compose/util-map-includes.js
var require_util_map_includes = __commonJS({
"node_modules/yaml/dist/compose/util-map-includes.js"(exports) {
"use strict";
var identity = require_identity();
function mapIncludes(ctx, items, search) {
const { uniqueKeys } = ctx.options;
if (uniqueKeys === false)
return false;
const isEqual = typeof uniqueKeys === "function" ? uniqueKeys : (a, b) => a === b || identity.isScalar(a) && identity.isScalar(b) && a.value === b.value;
return items.some((pair) => isEqual(pair.key, search));
}
exports.mapIncludes = mapIncludes;
}
});
// node_modules/yaml/dist/compose/resolve-block-map.js
var require_resolve_block_map = __commonJS({
"node_modules/yaml/dist/compose/resolve-block-map.js"(exports) {
"use strict";
var Pair = require_Pair();
var YAMLMap = require_YAMLMap();
var resolveProps = require_resolve_props();
var utilContainsNewline = require_util_contains_newline();
var utilFlowIndentCheck = require_util_flow_indent_check();
var utilMapIncludes = require_util_map_includes();
var startColMsg = "All mapping items must start at the same column";
function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError, tag) {
const NodeClass = tag?.nodeClass ?? YAMLMap.YAMLMap;
const map = new NodeClass(ctx.schema);
if (ctx.atRoot)
ctx.atRoot = false;
let offset = bm.offset;
let commentEnd = null;
for (const collItem of bm.items) {
const { start, key, sep: sep3, value } = collItem;
const keyProps = resolveProps.resolveProps(start, {
indicator: "explicit-key-ind",
next: key ?? sep3?.[0],
offset,
onError,
parentIndent: bm.indent,
startOnNewline: true
});
const implicitKey = !keyProps.found;
if (implicitKey) {
if (key) {
if (key.type === "block-seq")
onError(offset, "BLOCK_AS_IMPLICIT_KEY", "A block sequence may not be used as an implicit map key");
else if ("indent" in key && key.indent !== bm.indent)
onError(offset, "BAD_INDENT", startColMsg);
}
if (!keyProps.anchor && !keyProps.tag && !sep3) {
commentEnd = keyProps.end;
if (keyProps.comment) {
if (map.comment)
map.comment += "\n" + keyProps.comment;
else
map.comment = keyProps.comment;
}
continue;
}
if (keyProps.newlineAfterProp || utilContainsNewline.containsNewline(key)) {
onError(key ?? start[start.length - 1], "MULTILINE_IMPLICIT_KEY", "Implicit keys need to be on a single line");
}
} else if (keyProps.found?.indent !== bm.indent) {
onError(offset, "BAD_INDENT", startColMsg);
}
ctx.atKey = true;
const keyStart = keyProps.end;
const keyNode = key ? composeNode(ctx, key, keyProps, onError) : composeEmptyNode(ctx, keyStart, start, null, keyProps, onError);
if (ctx.schema.compat)
utilFlowIndentCheck.flowIndentCheck(bm.indent, key, onError);
ctx.atKey = false;
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
const valueProps = resolveProps.resolveProps(sep3 ?? [], {
indicator: "map-value-ind",
next: value,
offset: keyNode.range[2],
onError,
parentIndent: bm.indent,
startOnNewline: !key || key.type === "block-scalar"
});
offset = valueProps.end;
if (valueProps.found) {
if (implicitKey) {
if (value?.type === "block-map" && !valueProps.hasNewline)
onError(offset, "BLOCK_AS_IMPLICIT_KEY", "Nested mappings are not allowed in compact mappings");
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
}
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep3, null, valueProps, onError);
if (ctx.schema.compat)
utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
offset = valueNode.range[2];
const pair = new Pair.Pair(keyNode, valueNode);
if (ctx.options.keepSourceTokens)
pair.srcToken = collItem;
map.items.push(pair);
} else {
if (implicitKey)
onError(keyNode.range, "MISSING_CHAR", "Implicit map keys need to be followed by map values");
if (valueProps.comment) {
if (keyNode.comment)
keyNode.comment += "\n" + valueProps.comment;
else
keyNode.comment = valueProps.comment;
}
const pair = new Pair.Pair(keyNode);
if (ctx.options.keepSourceTokens)
pair.srcToken = collItem;
map.items.push(pair);
}
}
if (commentEnd && commentEnd < offset)
onError(commentEnd, "IMPOSSIBLE", "Map comment with trailing content");
map.range = [bm.offset, offset, commentEnd ?? offset];
return map;
}
exports.resolveBlockMap = resolveBlockMap;
}
});
// node_modules/yaml/dist/compose/resolve-block-seq.js
var require_resolve_block_seq = __commonJS({
"node_modules/yaml/dist/compose/resolve-block-seq.js"(exports) {
"use strict";
var YAMLSeq = require_YAMLSeq();
var resolveProps = require_resolve_props();
var utilFlowIndentCheck = require_util_flow_indent_check();
function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError, tag) {
const NodeClass = tag?.nodeClass ?? YAMLSeq.YAMLSeq;
const seq = new NodeClass(ctx.schema);
if (ctx.atRoot)
ctx.atRoot = false;
if (ctx.atKey)
ctx.atKey = false;
let offset = bs.offset;
let commentEnd = null;
for (const { start, value } of bs.items) {
const props = resolveProps.resolveProps(start, {
indicator: "seq-item-ind",
next: value,
offset,
onError,
parentIndent: bs.indent,
startOnNewline: true
});
if (!props.found) {
if (props.anchor || props.tag || value) {
if (value?.type === "block-seq")
onError(props.end, "BAD_INDENT", "All sequence items must start at the same column");
else
onError(offset, "MISSING_CHAR", "Sequence item without - indicator");
} else {
commentEnd = props.end;
if (props.comment)
seq.comment = props.comment;
continue;
}
}
const node = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, start, null, props, onError);
if (ctx.schema.compat)
utilFlowIndentCheck.flowIndentCheck(bs.indent, value, onError);
offset = node.range[2];
seq.items.push(node);
}
seq.range = [bs.offset, offset, commentEnd ?? offset];
return seq;
}
exports.resolveBlockSeq = resolveBlockSeq;
}
});
// node_modules/yaml/dist/compose/resolve-end.js
var require_resolve_end = __commonJS({
"node_modules/yaml/dist/compose/resolve-end.js"(exports) {
"use strict";
function resolveEnd(end, offset, reqSpace, onError) {
let comment = "";
if (end) {
let hasSpace = false;
let sep3 = "";
for (const token of end) {
const { source, type } = token;
switch (type) {
case "space":
hasSpace = true;
break;
case "comment": {
if (reqSpace && !hasSpace)
onError(token, "MISSING_CHAR", "Comments must be separated from other tokens by white space characters");
const cb = source.substring(1) || " ";
if (!comment)
comment = cb;
else
comment += sep3 + cb;
sep3 = "";
break;
}
case "newline":
if (comment)
sep3 += source;
hasSpace = true;
break;
default:
onError(token, "UNEXPECTED_TOKEN", `Unexpected ${type} at node end`);
}
offset += source.length;
}
}
return { comment, offset };
}
exports.resolveEnd = resolveEnd;
}
});
// node_modules/yaml/dist/compose/resolve-flow-collection.js
var require_resolve_flow_collection = __commonJS({
"node_modules/yaml/dist/compose/resolve-flow-collection.js"(exports) {
"use strict";
var identity = require_identity();
var Pair = require_Pair();
var YAMLMap = require_YAMLMap();
var YAMLSeq = require_YAMLSeq();
var resolveEnd = require_resolve_end();
var resolveProps = require_resolve_props();
var utilContainsNewline = require_util_contains_newline();
var utilMapIncludes = require_util_map_includes();
var blockMsg = "Block collections are not allowed within flow collections";
var isBlock = (token) => token && (token.type === "block-map" || token.type === "block-seq");
function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onError, tag) {
const isMap2 = fc.start.source === "{";
const fcName = isMap2 ? "flow map" : "flow sequence";
const NodeClass = tag?.nodeClass ?? (isMap2 ? YAMLMap.YAMLMap : YAMLSeq.YAMLSeq);
const coll = new NodeClass(ctx.schema);
coll.flow = true;
const atRoot = ctx.atRoot;
if (atRoot)
ctx.atRoot = false;
if (ctx.atKey)
ctx.atKey = false;
let offset = fc.offset + fc.start.source.length;
for (let i = 0; i < fc.items.length; ++i) {
const collItem = fc.items[i];
const { start, key, sep: sep3, value } = collItem;
const props = resolveProps.resolveProps(start, {
flow: fcName,
indicator: "explicit-key-ind",
next: key ?? sep3?.[0],
offset,
onError,
parentIndent: fc.indent,
startOnNewline: false
});
if (!props.found) {
if (!props.anchor && !props.tag && !sep3 && !value) {
if (i === 0 && props.comma)
onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
else if (i < fc.items.length - 1)
onError(props.start, "UNEXPECTED_TOKEN", `Unexpected empty item in ${fcName}`);
if (props.comment) {
if (coll.comment)
coll.comment += "\n" + props.comment;
else
coll.comment = props.comment;
}
offset = props.end;
continue;
}
if (!isMap2 && ctx.options.strict && utilContainsNewline.containsNewline(key))
onError(
key,
// checked by containsNewline()
"MULTILINE_IMPLICIT_KEY",
"Implicit keys of flow sequence pairs need to be on a single line"
);
}
if (i === 0) {
if (props.comma)
onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
} else {
if (!props.comma)
onError(props.start, "MISSING_CHAR", `Missing , between ${fcName} items`);
if (props.comment) {
let prevItemComment = "";
loop: for (const st of start) {
switch (st.type) {
case "comma":
case "space":
break;
case "comment":
prevItemComment = st.source.substring(1);
break loop;
default:
break loop;
}
}
if (prevItemComment) {
let prev = coll.items[coll.items.length - 1];
if (identity.isPair(prev))
prev = prev.value ?? prev.key;
if (prev.comment)
prev.comment += "\n" + prevItemComment;
else
prev.comment = prevItemComment;
props.comment = props.comment.substring(prevItemComment.length + 1);
}
}
}
if (!isMap2 && !sep3 && !props.found) {
const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep3, null, props, onError);
coll.items.push(valueNode);
offset = valueNode.range[2];
if (isBlock(value))
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
} else {
ctx.atKey = true;
const keyStart = props.end;
const keyNode = key ? composeNode(ctx, key, props, onError) : composeEmptyNode(ctx, keyStart, start, null, props, onError);
if (isBlock(key))
onError(keyNode.range, "BLOCK_IN_FLOW", blockMsg);
ctx.atKey = false;
const valueProps = resolveProps.resolveProps(sep3 ?? [], {
flow: fcName,
indicator: "map-value-ind",
next: value,
offset: keyNode.range[2],
onError,
parentIndent: fc.indent,
startOnNewline: false
});
if (valueProps.found) {
if (!isMap2 && !props.found && ctx.options.strict) {
if (sep3)
for (const st of sep3) {
if (st === valueProps.found)
break;
if (st.type === "newline") {
onError(st, "MULTILINE_IMPLICIT_KEY", "Implicit keys of flow sequence pairs need to be on a single line");
break;
}
}
if (props.start < valueProps.found.offset - 1024)
onError(valueProps.found, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit flow sequence key");
}
} else if (value) {
if ("source" in value && value.source?.[0] === ":")
onError(value, "MISSING_CHAR", `Missing space after : in ${fcName}`);
else
onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
}
const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep3, null, valueProps, onError) : null;
if (valueNode) {
if (isBlock(value))
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
} else if (valueProps.comment) {
if (keyNode.comment)
keyNode.comment += "\n" + valueProps.comment;
else
keyNode.comment = valueProps.comment;
}
const pair = new Pair.Pair(keyNode, valueNode);
if (ctx.options.keepSourceTokens)
pair.srcToken = collItem;
if (isMap2) {
const map = coll;
if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))
onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
map.items.push(pair);
} else {
const map = new YAMLMap.YAMLMap(ctx.schema);
map.flow = true;
map.items.push(pair);
const endRange = (valueNode ?? keyNode).range;
map.range = [keyNode.range[0], endRange[1], endRange[2]];
coll.items.push(map);
}
offset = valueNode ? valueNode.range[2] : valueProps.end;
}
}
const expectedEnd = isMap2 ? "}" : "]";
const [ce, ...ee] = fc.end;
let cePos = offset;
if (ce?.source === expectedEnd)
cePos = ce.offset + ce.source.length;
else {
const name = fcName[0].toUpperCase() + fcName.substring(1);
const msg = atRoot ? `${name} must end with a ${expectedEnd}` : `${name} in block collection must be sufficiently indented and end with a ${expectedEnd}`;
onError(offset, atRoot ? "MISSING_CHAR" : "BAD_INDENT", msg);
if (ce && ce.source.length !== 1)
ee.unshift(ce);
}
if (ee.length > 0) {
const end = resolveEnd.resolveEnd(ee, cePos, ctx.options.strict, onError);
if (end.comment) {
if (coll.comment)
coll.comment += "\n" + end.comment;
else
coll.comment = end.comment;
}
coll.range = [fc.offset, cePos, end.offset];
} else {
coll.range = [fc.offset, cePos, cePos];
}
return coll;
}
exports.resolveFlowCollection = resolveFlowCollection;
}
});
// node_modules/yaml/dist/compose/compose-collection.js
var require_compose_collection = __commonJS({
"node_modules/yaml/dist/compose/compose-collection.js"(exports) {
"use strict";
var identity = require_identity();
var Scalar = require_Scalar();
var YAMLMap = require_YAMLMap();
var YAMLSeq = require_YAMLSeq();
var resolveBlockMap = require_resolve_block_map();
var resolveBlockSeq = require_resolve_block_seq();
var resolveFlowCollection = require_resolve_flow_collection();
function resolveCollection(CN, ctx, token, onError, tagName, tag) {
const coll = token.type === "block-map" ? resolveBlockMap.resolveBlockMap(CN, ctx, token, onError, tag) : token.type === "block-seq" ? resolveBlockSeq.resolveBlockSeq(CN, ctx, token, onError, tag) : resolveFlowCollection.resolveFlowCollection(CN, ctx, token, onError, tag);
const Coll = coll.constructor;
if (tagName === "!" || tagName === Coll.tagName) {
coll.tag = Coll.tagName;
return coll;
}
if (tagName)
coll.tag = tagName;
return coll;
}
function composeCollection(CN, ctx, token, props, onError) {
const tagToken = props.tag;
const tagName = !tagToken ? null : ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg));
if (token.type === "block-seq") {
const { anchor, newlineAfterProp: nl } = props;
const lastProp = anchor && tagToken ? anchor.offset > tagToken.offset ? anchor : tagToken : anchor ?? tagToken;
if (lastProp && (!nl || nl.offset < lastProp.offset)) {
const message = "Missing newline after block sequence props";
onError(lastProp, "MISSING_CHAR", message);
}
}
const expType = token.type === "block-map" ? "map" : token.type === "block-seq" ? "seq" : token.start.source === "{" ? "map" : "seq";
if (!tagToken || !tagName || tagName === "!" || tagName === YAMLMap.YAMLMap.tagName && expType === "map" || tagName === YAMLSeq.YAMLSeq.tagName && expType === "seq") {
return resolveCollection(CN, ctx, token, onError, tagName);
}
let tag = ctx.schema.tags.find((t) => t.tag === tagName && t.collection === expType);
if (!tag) {
const kt = ctx.schema.knownTags[tagName];
if (kt?.collection === expType) {
ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
tag = kt;
} else {
if (kt) {
onError(tagToken, "BAD_COLLECTION_TYPE", `${kt.tag} used for ${expType} collection, but expects ${kt.collection ?? "scalar"}`, true);
} else {
onError(tagToken, "TAG_RESOLVE_FAILED", `Unresolved tag: ${tagName}`, true);
}
return resolveCollection(CN, ctx, token, onError, tagName);
}
}
const coll = resolveCollection(CN, ctx, token, onError, tagName, tag);
const res = tag.resolve?.(coll, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg), ctx.options) ?? coll;
const node = identity.isNode(res) ? res : new Scalar.Scalar(res);
node.range = coll.range;
node.tag = tagName;
if (tag?.format)
node.format = tag.format;
return node;
}
exports.composeCollection = composeCollection;
}
});
// node_modules/yaml/dist/compose/resolve-block-scalar.js
var require_resolve_block_scalar = __commonJS({
"node_modules/yaml/dist/compose/resolve-block-scalar.js"(exports) {
"use strict";
var Scalar = require_Scalar();
function resolveBlockScalar(ctx, scalar, onError) {
const start = scalar.offset;
const header = parseBlockScalarHeader(scalar, ctx.options.strict, onError);
if (!header)
return { value: "", type: null, comment: "", range: [start, start, start] };
const type = header.mode === ">" ? Scalar.Scalar.BLOCK_FOLDED : Scalar.Scalar.BLOCK_LITERAL;
const lines = scalar.source ? splitLines(scalar.source) : [];
let chompStart = lines.length;
for (let i = lines.length - 1; i >= 0; --i) {
const content = lines[i][1];
if (content === "" || content === "\r")
chompStart = i;
else
break;
}
if (chompStart === 0) {
const value2 = header.chomp === "+" && lines.length > 0 ? "\n".repeat(Math.max(1, lines.length - 1)) : "";
let end2 = start + header.length;
if (scalar.source)
end2 += scalar.source.length;
return { value: value2, type, comment: header.comment, range: [start, end2, end2] };
}
let trimIndent = scalar.indent + header.indent;
let offset = scalar.offset + header.length;
let contentStart = 0;
for (let i = 0; i < chompStart; ++i) {
const [indent, content] = lines[i];
if (content === "" || content === "\r") {
if (header.indent === 0 && indent.length > trimIndent)
trimIndent = indent.length;
} else {
if (indent.length < trimIndent) {
const message = "Block scalars with more-indented leading empty lines must use an explicit indentation indicator";
onError(offset + indent.length, "MISSING_CHAR", message);
}
if (header.indent === 0)
trimIndent = indent.length;
contentStart = i;
if (trimIndent === 0 && !ctx.atRoot) {
const message = "Block scalar values in collections must be indented";
onError(offset, "BAD_INDENT", message);
}
break;
}
offset += indent.length + content.length + 1;
}
for (let i = lines.length - 1; i >= chompStart; --i) {
if (lines[i][0].length > trimIndent)
chompStart = i + 1;
}
let value = "";
let sep3 = "";
let prevMoreIndented = false;
for (let i = 0; i < contentStart; ++i)
value += lines[i][0].slice(trimIndent) + "\n";
for (let i = contentStart; i < chompStart; ++i) {
let [indent, content] = lines[i];
offset += indent.length + content.length + 1;
const crlf = content[content.length - 1] === "\r";
if (crlf)
content = content.slice(0, -1);
if (content && indent.length < trimIndent) {
const src = header.indent ? "explicit indentation indicator" : "first line";
const message = `Block scalar lines must not be less indented than their ${src}`;
onError(offset - content.length - (crlf ? 2 : 1), "BAD_INDENT", message);
indent = "";
}
if (type === Scalar.Scalar.BLOCK_LITERAL) {
value += sep3 + indent.slice(trimIndent) + content;
sep3 = "\n";
} else if (indent.length > trimIndent || content[0] === " ") {
if (sep3 === " ")
sep3 = "\n";
else if (!prevMoreIndented && sep3 === "\n")
sep3 = "\n\n";
value += sep3 + indent.slice(trimIndent) + content;
sep3 = "\n";
prevMoreIndented = true;
} else if (content === "") {
if (sep3 === "\n")
value += "\n";
else
sep3 = "\n";
} else {
value += sep3 + content;
sep3 = " ";
prevMoreIndented = false;
}
}
switch (header.chomp) {
case "-":
break;
case "+":
for (let i = chompStart; i < lines.length; ++i)
value += "\n" + lines[i][0].slice(trimIndent);
if (value[value.length - 1] !== "\n")
value += "\n";
break;
default:
value += "\n";
}
const end = start + header.length + scalar.source.length;
return { value, type, comment: header.comment, range: [start, end, end] };
}
function parseBlockScalarHeader({ offset, props }, strict, onError) {
if (props[0].type !== "block-scalar-header") {
onError(props[0], "IMPOSSIBLE", "Block scalar header not found");
return null;
}
const { source } = props[0];
const mode = source[0];
let indent = 0;
let chomp = "";
let error = -1;
for (let i = 1; i < source.length; ++i) {
const ch = source[i];
if (!chomp && (ch === "-" || ch === "+"))
chomp = ch;
else {
const n = Number(ch);
if (!indent && n)
indent = n;
else if (error === -1)
error = offset + i;
}
}
if (error !== -1)
onError(error, "UNEXPECTED_TOKEN", `Block scalar header includes extra characters: ${source}`);
let hasSpace = false;
let comment = "";
let length = source.length;
for (let i = 1; i < props.length; ++i) {
const token = props[i];
switch (token.type) {
case "space":
hasSpace = true;
// fallthrough
case "newline":
length += token.source.length;
break;
case "comment":
if (strict && !hasSpace) {
const message = "Comments must be separated from other tokens by white space characters";
onError(token, "MISSING_CHAR", message);
}
length += token.source.length;
comment = token.source.substring(1);
break;
case "error":
onError(token, "UNEXPECTED_TOKEN", token.message);
length += token.source.length;
break;
/* istanbul ignore next should not happen */
default: {
const message = `Unexpected token in block scalar header: ${token.type}`;
onError(token, "UNEXPECTED_TOKEN", message);
const ts = token.source;
if (ts && typeof ts === "string")
length += ts.length;
}
}
}
return { mode, indent, chomp, comment, length };
}
function splitLines(source) {
const split = source.split(/\n( *)/);
const first = split[0];
const m = first.match(/^( *)/);
const line0 = m?.[1] ? [m[1], first.slice(m[1].length)] : ["", first];
const lines = [line0];
for (let i = 1; i < split.length; i += 2)
lines.push([split[i], split[i + 1]]);
return lines;
}
exports.resolveBlockScalar = resolveBlockScalar;
}
});
// node_modules/yaml/dist/compose/resolve-flow-scalar.js
var require_resolve_flow_scalar = __commonJS({
"node_modules/yaml/dist/compose/resolve-flow-scalar.js"(exports) {
"use strict";
var Scalar = require_Scalar();
var resolveEnd = require_resolve_end();
function resolveFlowScalar(scalar, strict, onError) {
const { offset, type, source, end } = scalar;
let _type;
let value;
const _onError = (rel, code, msg) => onError(offset + rel, code, msg);
switch (type) {
case "scalar":
_type = Scalar.Scalar.PLAIN;
value = plainValue(source, _onError);
break;
case "single-quoted-scalar":
_type = Scalar.Scalar.QUOTE_SINGLE;
value = singleQuotedValue(source, _onError);
break;
case "double-quoted-scalar":
_type = Scalar.Scalar.QUOTE_DOUBLE;
value = doubleQuotedValue(source, _onError);
break;
/* istanbul ignore next should not happen */
default:
onError(scalar, "UNEXPECTED_TOKEN", `Expected a flow scalar value, but found: ${type}`);
return {
value: "",
type: null,
comment: "",
range: [offset, offset + source.length, offset + source.length]
};
}
const valueEnd = offset + source.length;
const re = resolveEnd.resolveEnd(end, valueEnd, strict, onError);
return {
value,
type: _type,
comment: re.comment,
range: [offset, valueEnd, re.offset]
};
}
function plainValue(source, onError) {
let badChar = "";
switch (source[0]) {
/* istanbul ignore next should not happen */
case " ":
badChar = "a tab character";
break;
case ",":
badChar = "flow indicator character ,";
break;
case "%":
badChar = "directive indicator character %";
break;
case "|":
case ">": {
badChar = `block scalar indicator ${source[0]}`;
break;
}
case "@":
case "`": {
badChar = `reserved character ${source[0]}`;
break;
}
}
if (badChar)
onError(0, "BAD_SCALAR_START", `Plain value cannot start with ${badChar}`);
return unfoldLines(source);
}
function singleQuotedValue(source, onError) {
if (source[source.length - 1] !== "'" || source.length === 1)
onError(source.length, "MISSING_CHAR", "Missing closing 'quote");
return unfoldLines(source.slice(1, -1)).replace(/''/g, "'");
}
function unfoldLines(source) {
const line = /(.*?)\r?\n/sy;
let match = line.exec(source);
if (!match)
return source;
let trimEnd, trimBoth;
try {
trimEnd = new RegExp("(?<![ ])[ ]+$");
trimBoth = new RegExp("^[ ]+|(?<![ ])[ ]+$", "g");
} catch {
trimEnd = /[ \t]+$/;
trimBoth = /^[ \t]+|[ \t]+$/g;
}
let res = match[1].replace(trimEnd, "");
let sep3 = " ";
let pos = line.lastIndex;
while (match = line.exec(source)) {
const lm = match[1].replace(trimBoth, "");
if (lm === "") {
if (sep3 === "\n")
res += sep3;
else
sep3 = "\n";
} else {
res += sep3 + lm;
sep3 = " ";
}
pos = line.lastIndex;
}
const last = /[ \t]*(.*)/sy;
last.lastIndex = pos;
match = last.exec(source);
return res + sep3 + (match?.[1] ?? "");
}
function doubleQuotedValue(source, onError) {
let res = "";
for (let i = 1; i < source.length - 1; ++i) {
const ch = source[i];
if (ch === "\r" && source[i + 1] === "\n")
continue;
if (ch === "\n") {
const { fold, offset } = foldNewline(source, i);
res += fold;
i = offset;
} else if (ch === "\\") {
let next = source[++i];
const cc = escapeCodes[next];
if (cc)
res += cc;
else if (next === "\n") {
next = source[i + 1];
while (next === " " || next === " ")
next = source[++i + 1];
} else if (next === "\r" && source[i + 1] === "\n") {
next = source[++i + 1];
while (next === " " || next === " ")
next = source[++i + 1];
} else if (next === "x" || next === "u" || next === "U") {
const length = next === "x" ? 2 : next === "u" ? 4 : 8;
res += parseCharCode(source, i + 1, length, onError);
i += length;
} else {
const raw = source.substr(i - 1, 2);
onError(i - 1, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
res += raw;
}
} else if (ch === " " || ch === " ") {
const wsStart = i;
let next = source[i + 1];
while (next === " " || next === " ")
next = source[++i + 1];
if (next !== "\n" && !(next === "\r" && source[i + 2] === "\n"))
res += i > wsStart ? source.slice(wsStart, i + 1) : ch;
} else {
res += ch;
}
}
if (source[source.length - 1] !== '"' || source.length === 1)
onError(source.length, "MISSING_CHAR", 'Missing closing "quote');
return res;
}
function foldNewline(source, offset) {
let fold = "";
let ch = source[offset + 1];
while (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
if (ch === "\r" && source[offset + 2] !== "\n")
break;
if (ch === "\n")
fold += "\n";
offset += 1;
ch = source[offset + 1];
}
if (!fold)
fold = " ";
return { fold, offset };
}
var escapeCodes = {
"0": "\0",
// null character
a: "\x07",
// bell character
b: "\b",
// backspace
e: "\x1B",
// escape character
f: "\f",
// form feed
n: "\n",
// line feed
r: "\r",
// carriage return
t: " ",
// horizontal tab
v: "\v",
// vertical tab
N: "\x85",
// Unicode next line
_: "\xA0",
// Unicode non-breaking space
L: "\u2028",
// Unicode line separator
P: "\u2029",
// Unicode paragraph separator
" ": " ",
'"': '"',
"/": "/",
"\\": "\\",
" ": " "
};
function parseCharCode(source, offset, length, onError) {
const cc = source.substr(offset, length);
const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
const code = ok ? parseInt(cc, 16) : NaN;
try {
return String.fromCodePoint(code);
} catch {
const raw = source.substr(offset - 2, length + 2);
onError(offset - 2, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
return raw;
}
}
exports.resolveFlowScalar = resolveFlowScalar;
}
});
// node_modules/yaml/dist/compose/compose-scalar.js
var require_compose_scalar = __commonJS({
"node_modules/yaml/dist/compose/compose-scalar.js"(exports) {
"use strict";
var identity = require_identity();
var Scalar = require_Scalar();
var resolveBlockScalar = require_resolve_block_scalar();
var resolveFlowScalar = require_resolve_flow_scalar();
function composeScalar(ctx, token, tagToken, onError) {
const { value, type, comment, range } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
const tagName = tagToken ? ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg)) : null;
let tag;
if (ctx.options.stringKeys && ctx.atKey) {
tag = ctx.schema[identity.SCALAR];
} else if (tagName)
tag = findScalarTagByName(ctx.schema, value, tagName, tagToken, onError);
else if (token.type === "scalar")
tag = findScalarTagByTest(ctx, value, token, onError);
else
tag = ctx.schema[identity.SCALAR];
let scalar;
try {
const res = tag.resolve(value, (msg) => onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg), ctx.options);
scalar = identity.isScalar(res) ? res : new Scalar.Scalar(res);
} catch (error) {
const msg = error instanceof Error ? error.message : String(error);
onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg);
scalar = new Scalar.Scalar(value);
}
scalar.range = range;
scalar.source = value;
if (type)
scalar.type = type;
if (tagName)
scalar.tag = tagName;
if (tag.format)
scalar.format = tag.format;
if (comment)
scalar.comment = comment;
return scalar;
}
function findScalarTagByName(schema, value, tagName, tagToken, onError) {
if (tagName === "!")
return schema[identity.SCALAR];
const matchWithTest = [];
for (const tag of schema.tags) {
if (!tag.collection && tag.tag === tagName) {
if (tag.default && tag.test)
matchWithTest.push(tag);
else
return tag;
}
}
for (const tag of matchWithTest)
if (tag.test?.test(value))
return tag;
const kt = schema.knownTags[tagName];
if (kt && !kt.collection) {
schema.tags.push(Object.assign({}, kt, { default: false, test: void 0 }));
return kt;
}
onError(tagToken, "TAG_RESOLVE_FAILED", `Unresolved tag: ${tagName}`, tagName !== "tag:yaml.org,2002:str");
return schema[identity.SCALAR];
}
function findScalarTagByTest({ atKey, directives, schema }, value, token, onError) {
const tag = schema.tags.find((tag2) => (tag2.default === true || atKey && tag2.default === "key") && tag2.test?.test(value)) || schema[identity.SCALAR];
if (schema.compat) {
const compat = schema.compat.find((tag2) => tag2.default && tag2.test?.test(value)) ?? schema[identity.SCALAR];
if (tag.tag !== compat.tag) {
const ts = directives.tagString(tag.tag);
const cs = directives.tagString(compat.tag);
const msg = `Value may be parsed as either ${ts} or ${cs}`;
onError(token, "TAG_RESOLVE_FAILED", msg, true);
}
}
return tag;
}
exports.composeScalar = composeScalar;
}
});
// node_modules/yaml/dist/compose/util-empty-scalar-position.js
var require_util_empty_scalar_position = __commonJS({
"node_modules/yaml/dist/compose/util-empty-scalar-position.js"(exports) {
"use strict";
function emptyScalarPosition(offset, before, pos) {
if (before) {
pos ?? (pos = before.length);
for (let i = pos - 1; i >= 0; --i) {
let st = before[i];
switch (st.type) {
case "space":
case "comment":
case "newline":
offset -= st.source.length;
continue;
}
st = before[++i];
while (st?.type === "space") {
offset += st.source.length;
st = before[++i];
}
break;
}
}
return offset;
}
exports.emptyScalarPosition = emptyScalarPosition;
}
});
// node_modules/yaml/dist/compose/compose-node.js
var require_compose_node = __commonJS({
"node_modules/yaml/dist/compose/compose-node.js"(exports) {
"use strict";
var Alias = require_Alias();
var identity = require_identity();
var composeCollection = require_compose_collection();
var composeScalar = require_compose_scalar();
var resolveEnd = require_resolve_end();
var utilEmptyScalarPosition = require_util_empty_scalar_position();
var CN = { composeNode, composeEmptyNode };
function composeNode(ctx, token, props, onError) {
const atKey = ctx.atKey;
const { spaceBefore, comment, anchor, tag } = props;
let node;
let isSrcToken = true;
switch (token.type) {
case "alias":
node = composeAlias(ctx, token, onError);
if (anchor || tag)
onError(token, "ALIAS_PROPS", "An alias node must not specify any properties");
break;
case "scalar":
case "single-quoted-scalar":
case "double-quoted-scalar":
case "block-scalar":
node = composeScalar.composeScalar(ctx, token, tag, onError);
if (anchor)
node.anchor = anchor.source.substring(1);
break;
case "block-map":
case "block-seq":
case "flow-collection":
try {
node = composeCollection.composeCollection(CN, ctx, token, props, onError);
if (anchor)
node.anchor = anchor.source.substring(1);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
onError(token, "RESOURCE_EXHAUSTION", message);
}
break;
default: {
const message = token.type === "error" ? token.message : `Unsupported token (type: ${token.type})`;
onError(token, "UNEXPECTED_TOKEN", message);
isSrcToken = false;
}
}
node ?? (node = composeEmptyNode(ctx, token.offset, void 0, null, props, onError));
if (anchor && node.anchor === "")
onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
if (atKey && ctx.options.stringKeys && (!identity.isScalar(node) || typeof node.value !== "string" || node.tag && node.tag !== "tag:yaml.org,2002:str")) {
const msg = "With stringKeys, all keys must be strings";
onError(tag ?? token, "NON_STRING_KEY", msg);
}
if (spaceBefore)
node.spaceBefore = true;
if (comment) {
if (token.type === "scalar" && token.source === "")
node.comment = comment;
else
node.commentBefore = comment;
}
if (ctx.options.keepSourceTokens && isSrcToken)
node.srcToken = token;
return node;
}
function composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anchor, tag, end }, onError) {
const token = {
type: "scalar",
offset: utilEmptyScalarPosition.emptyScalarPosition(offset, before, pos),
indent: -1,
source: ""
};
const node = composeScalar.composeScalar(ctx, token, tag, onError);
if (anchor) {
node.anchor = anchor.source.substring(1);
if (node.anchor === "")
onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
}
if (spaceBefore)
node.spaceBefore = true;
if (comment) {
node.comment = comment;
node.range[2] = end;
}
return node;
}
function composeAlias({ options }, { offset, source, end }, onError) {
const alias = new Alias.Alias(source.substring(1));
if (alias.source === "")
onError(offset, "BAD_ALIAS", "Alias cannot be an empty string");
if (alias.source.endsWith(":"))
onError(offset + source.length - 1, "BAD_ALIAS", "Alias ending in : is ambiguous", true);
const valueEnd = offset + source.length;
const re = resolveEnd.resolveEnd(end, valueEnd, options.strict, onError);
alias.range = [offset, valueEnd, re.offset];
if (re.comment)
alias.comment = re.comment;
return alias;
}
exports.composeEmptyNode = composeEmptyNode;
exports.composeNode = composeNode;
}
});
// node_modules/yaml/dist/compose/compose-doc.js
var require_compose_doc = __commonJS({
"node_modules/yaml/dist/compose/compose-doc.js"(exports) {
"use strict";
var Document = require_Document();
var composeNode = require_compose_node();
var resolveEnd = require_resolve_end();
var resolveProps = require_resolve_props();
function composeDoc(options, directives, { offset, start, value, end }, onError) {
const opts = Object.assign({ _directives: directives }, options);
const doc = new Document.Document(void 0, opts);
const ctx = {
atKey: false,
atRoot: true,
directives: doc.directives,
options: doc.options,
schema: doc.schema
};
const props = resolveProps.resolveProps(start, {
indicator: "doc-start",
next: value ?? end?.[0],
offset,
onError,
parentIndent: 0,
startOnNewline: true
});
if (props.found) {
doc.directives.docStart = true;
if (value && (value.type === "block-map" || value.type === "block-seq") && !props.hasNewline)
onError(props.end, "MISSING_CHAR", "Block collection cannot start on same line with directives-end marker");
}
doc.contents = value ? composeNode.composeNode(ctx, value, props, onError) : composeNode.composeEmptyNode(ctx, props.end, start, null, props, onError);
const contentEnd = doc.contents.range[2];
const re = resolveEnd.resolveEnd(end, contentEnd, false, onError);
if (re.comment)
doc.comment = re.comment;
doc.range = [offset, contentEnd, re.offset];
return doc;
}
exports.composeDoc = composeDoc;
}
});
// node_modules/yaml/dist/compose/composer.js
var require_composer = __commonJS({
"node_modules/yaml/dist/compose/composer.js"(exports) {
"use strict";
var node_process = __require("process");
var directives = require_directives();
var Document = require_Document();
var errors = require_errors2();
var identity = require_identity();
var composeDoc = require_compose_doc();
var resolveEnd = require_resolve_end();
function getErrorPos(src) {
if (typeof src === "number")
return [src, src + 1];
if (Array.isArray(src))
return src.length === 2 ? src : [src[0], src[1]];
const { offset, source } = src;
return [offset, offset + (typeof source === "string" ? source.length : 1)];
}
function parsePrelude(prelude) {
let comment = "";
let atComment = false;
let afterEmptyLine = false;
for (let i = 0; i < prelude.length; ++i) {
const source = prelude[i];
switch (source[0]) {
case "#":
comment += (comment === "" ? "" : afterEmptyLine ? "\n\n" : "\n") + (source.substring(1) || " ");
atComment = true;
afterEmptyLine = false;
break;
case "%":
if (prelude[i + 1]?.[0] !== "#")
i += 1;
atComment = false;
break;
default:
if (!atComment)
afterEmptyLine = true;
atComment = false;
}
}
return { comment, afterEmptyLine };
}
var Composer = class {
constructor(options = {}) {
this.doc = null;
this.atDirectives = false;
this.prelude = [];
this.errors = [];
this.warnings = [];
this.onError = (source, code, message, warning) => {
const pos = getErrorPos(source);
if (warning)
this.warnings.push(new errors.YAMLWarning(pos, code, message));
else
this.errors.push(new errors.YAMLParseError(pos, code, message));
};
this.directives = new directives.Directives({ version: options.version || "1.2" });
this.options = options;
}
decorate(doc, afterDoc) {
const { comment, afterEmptyLine } = parsePrelude(this.prelude);
if (comment) {
const dc = doc.contents;
if (afterDoc) {
doc.comment = doc.comment ? `${doc.comment}
${comment}` : comment;
} else if (afterEmptyLine || doc.directives.docStart || !dc) {
doc.commentBefore = comment;
} else if (identity.isCollection(dc) && !dc.flow && dc.items.length > 0) {
let it = dc.items[0];
if (identity.isPair(it))
it = it.key;
const cb = it.commentBefore;
it.commentBefore = cb ? `${comment}
${cb}` : comment;
} else {
const cb = dc.commentBefore;
dc.commentBefore = cb ? `${comment}
${cb}` : comment;
}
}
if (afterDoc) {
for (let i = 0; i < this.errors.length; ++i)
doc.errors.push(this.errors[i]);
for (let i = 0; i < this.warnings.length; ++i)
doc.warnings.push(this.warnings[i]);
} else {
doc.errors = this.errors;
doc.warnings = this.warnings;
}
this.prelude = [];
this.errors = [];
this.warnings = [];
}
/**
* Current stream status information.
*
* Mostly useful at the end of input for an empty stream.
*/
streamInfo() {
return {
comment: parsePrelude(this.prelude).comment,
directives: this.directives,
errors: this.errors,
warnings: this.warnings
};
}
/**
* Compose tokens into documents.
*
* @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.
* @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.
*/
*compose(tokens, forceDoc = false, endOffset = -1) {
for (const token of tokens)
yield* this.next(token);
yield* this.end(forceDoc, endOffset);
}
/** Advance the composer by one CST token. */
*next(token) {
if (node_process.env.LOG_STREAM)
console.dir(token, { depth: null });
switch (token.type) {
case "directive":
this.directives.add(token.source, (offset, message, warning) => {
const pos = getErrorPos(token);
pos[0] += offset;
this.onError(pos, "BAD_DIRECTIVE", message, warning);
});
this.prelude.push(token.source);
this.atDirectives = true;
break;
case "document": {
const doc = composeDoc.composeDoc(this.options, this.directives, token, this.onError);
if (this.atDirectives && !doc.directives.docStart)
this.onError(token, "MISSING_CHAR", "Missing directives-end/doc-start indicator line");
this.decorate(doc, false);
if (this.doc)
yield this.doc;
this.doc = doc;
this.atDirectives = false;
break;
}
case "byte-order-mark":
case "space":
break;
case "comment":
case "newline":
this.prelude.push(token.source);
break;
case "error": {
const msg = token.source ? `${token.message}: ${JSON.stringify(token.source)}` : token.message;
const error = new errors.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", msg);
if (this.atDirectives || !this.doc)
this.errors.push(error);
else
this.doc.errors.push(error);
break;
}
case "doc-end": {
if (!this.doc) {
const msg = "Unexpected doc-end without preceding document";
this.errors.push(new errors.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", msg));
break;
}
this.doc.directives.docEnd = true;
const end = resolveEnd.resolveEnd(token.end, token.offset + token.source.length, this.doc.options.strict, this.onError);
this.decorate(this.doc, true);
if (end.comment) {
const dc = this.doc.comment;
this.doc.comment = dc ? `${dc}
${end.comment}` : end.comment;
}
this.doc.range[2] = end.offset;
break;
}
default:
this.errors.push(new errors.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", `Unsupported token ${token.type}`));
}
}
/**
* Call at end of input to yield any remaining document.
*
* @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.
* @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.
*/
*end(forceDoc = false, endOffset = -1) {
if (this.doc) {
this.decorate(this.doc, true);
yield this.doc;
this.doc = null;
} else if (forceDoc) {
const opts = Object.assign({ _directives: this.directives }, this.options);
const doc = new Document.Document(void 0, opts);
if (this.atDirectives)
this.onError(endOffset, "MISSING_CHAR", "Missing directives-end indicator line");
doc.range = [0, endOffset, endOffset];
this.decorate(doc, false);
yield doc;
}
}
};
exports.Composer = Composer;
}
});
// node_modules/yaml/dist/parse/cst-scalar.js
var require_cst_scalar = __commonJS({
"node_modules/yaml/dist/parse/cst-scalar.js"(exports) {
"use strict";
var resolveBlockScalar = require_resolve_block_scalar();
var resolveFlowScalar = require_resolve_flow_scalar();
var errors = require_errors2();
var stringifyString = require_stringifyString();
function resolveAsScalar(token, strict = true, onError) {
if (token) {
const _onError = (pos, code, message) => {
const offset = typeof pos === "number" ? pos : Array.isArray(pos) ? pos[0] : pos.offset;
if (onError)
onError(offset, code, message);
else
throw new errors.YAMLParseError([offset, offset + 1], code, message);
};
switch (token.type) {
case "scalar":
case "single-quoted-scalar":
case "double-quoted-scalar":
return resolveFlowScalar.resolveFlowScalar(token, strict, _onError);
case "block-scalar":
return resolveBlockScalar.resolveBlockScalar({ options: { strict } }, token, _onError);
}
}
return null;
}
function createScalarToken(value, context) {
const { implicitKey = false, indent, inFlow = false, offset = -1, type = "PLAIN" } = context;
const source = stringifyString.stringifyString({ type, value }, {
implicitKey,
indent: indent > 0 ? " ".repeat(indent) : "",
inFlow,
options: { blockQuote: true, lineWidth: -1 }
});
const end = context.end ?? [
{ type: "newline", offset: -1, indent, source: "\n" }
];
switch (source[0]) {
case "|":
case ">": {
const he = source.indexOf("\n");
const head = source.substring(0, he);
const body = source.substring(he + 1) + "\n";
const props = [
{ type: "block-scalar-header", offset, indent, source: head }
];
if (!addEndtoBlockProps(props, end))
props.push({ type: "newline", offset: -1, indent, source: "\n" });
return { type: "block-scalar", offset, indent, props, source: body };
}
case '"':
return { type: "double-quoted-scalar", offset, indent, source, end };
case "'":
return { type: "single-quoted-scalar", offset, indent, source, end };
default:
return { type: "scalar", offset, indent, source, end };
}
}
function setScalarValue(token, value, context = {}) {
let { afterKey = false, implicitKey = false, inFlow = false, type } = context;
let indent = "indent" in token ? token.indent : null;
if (afterKey && typeof indent === "number")
indent += 2;
if (!type)
switch (token.type) {
case "single-quoted-scalar":
type = "QUOTE_SINGLE";
break;
case "double-quoted-scalar":
type = "QUOTE_DOUBLE";
break;
case "block-scalar": {
const header = token.props[0];
if (header.type !== "block-scalar-header")
throw new Error("Invalid block scalar header");
type = header.source[0] === ">" ? "BLOCK_FOLDED" : "BLOCK_LITERAL";
break;
}
default:
type = "PLAIN";
}
const source = stringifyString.stringifyString({ type, value }, {
implicitKey: implicitKey || indent === null,
indent: indent !== null && indent > 0 ? " ".repeat(indent) : "",
inFlow,
options: { blockQuote: true, lineWidth: -1 }
});
switch (source[0]) {
case "|":
case ">":
setBlockScalarValue(token, source);
break;
case '"':
setFlowScalarValue(token, source, "double-quoted-scalar");
break;
case "'":
setFlowScalarValue(token, source, "single-quoted-scalar");
break;
default:
setFlowScalarValue(token, source, "scalar");
}
}
function setBlockScalarValue(token, source) {
const he = source.indexOf("\n");
const head = source.substring(0, he);
const body = source.substring(he + 1) + "\n";
if (token.type === "block-scalar") {
const header = token.props[0];
if (header.type !== "block-scalar-header")
throw new Error("Invalid block scalar header");
header.source = head;
token.source = body;
} else {
const { offset } = token;
const indent = "indent" in token ? token.indent : -1;
const props = [
{ type: "block-scalar-header", offset, indent, source: head }
];
if (!addEndtoBlockProps(props, "end" in token ? token.end : void 0))
props.push({ type: "newline", offset: -1, indent, source: "\n" });
for (const key of Object.keys(token))
if (key !== "type" && key !== "offset")
delete token[key];
Object.assign(token, { type: "block-scalar", indent, props, source: body });
}
}
function addEndtoBlockProps(props, end) {
if (end)
for (const st of end)
switch (st.type) {
case "space":
case "comment":
props.push(st);
break;
case "newline":
props.push(st);
return true;
}
return false;
}
function setFlowScalarValue(token, source, type) {
switch (token.type) {
case "scalar":
case "double-quoted-scalar":
case "single-quoted-scalar":
token.type = type;
token.source = source;
break;
case "block-scalar": {
const end = token.props.slice(1);
let oa = source.length;
if (token.props[0].type === "block-scalar-header")
oa -= token.props[0].source.length;
for (const tok of end)
tok.offset += oa;
delete token.props;
Object.assign(token, { type, source, end });
break;
}
case "block-map":
case "block-seq": {
const offset = token.offset + source.length;
const nl = { type: "newline", offset, indent: token.indent, source: "\n" };
delete token.items;
Object.assign(token, { type, source, end: [nl] });
break;
}
default: {
const indent = "indent" in token ? token.indent : -1;
const end = "end" in token && Array.isArray(token.end) ? token.end.filter((st) => st.type === "space" || st.type === "comment" || st.type === "newline") : [];
for (const key of Object.keys(token))
if (key !== "type" && key !== "offset")
delete token[key];
Object.assign(token, { type, indent, source, end });
}
}
}
exports.createScalarToken = createScalarToken;
exports.resolveAsScalar = resolveAsScalar;
exports.setScalarValue = setScalarValue;
}
});
// node_modules/yaml/dist/parse/cst-stringify.js
var require_cst_stringify = __commonJS({
"node_modules/yaml/dist/parse/cst-stringify.js"(exports) {
"use strict";
var stringify4 = (cst) => "type" in cst ? stringifyToken(cst) : stringifyItem(cst);
function stringifyToken(token) {
switch (token.type) {
case "block-scalar": {
let res = "";
for (const tok of token.props)
res += stringifyToken(tok);
return res + token.source;
}
case "block-map":
case "block-seq": {
let res = "";
for (const item of token.items)
res += stringifyItem(item);
return res;
}
case "flow-collection": {
let res = token.start.source;
for (const item of token.items)
res += stringifyItem(item);
for (const st of token.end)
res += st.source;
return res;
}
case "document": {
let res = stringifyItem(token);
if (token.end)
for (const st of token.end)
res += st.source;
return res;
}
default: {
let res = token.source;
if ("end" in token && token.end)
for (const st of token.end)
res += st.source;
return res;
}
}
}
function stringifyItem({ start, key, sep: sep3, value }) {
let res = "";
for (const st of start)
res += st.source;
if (key)
res += stringifyToken(key);
if (sep3)
for (const st of sep3)
res += st.source;
if (value)
res += stringifyToken(value);
return res;
}
exports.stringify = stringify4;
}
});
// node_modules/yaml/dist/parse/cst-visit.js
var require_cst_visit = __commonJS({
"node_modules/yaml/dist/parse/cst-visit.js"(exports) {
"use strict";
var BREAK = /* @__PURE__ */ Symbol("break visit");
var SKIP = /* @__PURE__ */ Symbol("skip children");
var REMOVE = /* @__PURE__ */ Symbol("remove item");
function visit2(cst, visitor) {
if ("type" in cst && cst.type === "document")
cst = { start: cst.start, value: cst.value };
_visit(Object.freeze([]), cst, visitor);
}
visit2.BREAK = BREAK;
visit2.SKIP = SKIP;
visit2.REMOVE = REMOVE;
visit2.itemAtPath = (cst, path) => {
let item = cst;
for (const [field, index] of path) {
const tok = item?.[field];
if (tok && "items" in tok) {
item = tok.items[index];
} else
return void 0;
}
return item;
};
visit2.parentCollection = (cst, path) => {
const parent = visit2.itemAtPath(cst, path.slice(0, -1));
const field = path[path.length - 1][0];
const coll = parent?.[field];
if (coll && "items" in coll)
return coll;
throw new Error("Parent collection not found");
};
function _visit(path, item, visitor) {
let ctrl = visitor(item, path);
if (typeof ctrl === "symbol")
return ctrl;
for (const field of ["key", "value"]) {
const token = item[field];
if (token && "items" in token) {
for (let i = 0; i < token.items.length; ++i) {
const ci = _visit(Object.freeze(path.concat([[field, i]])), token.items[i], visitor);
if (typeof ci === "number")
i = ci - 1;
else if (ci === BREAK)
return BREAK;
else if (ci === REMOVE) {
token.items.splice(i, 1);
i -= 1;
}
}
if (typeof ctrl === "function" && field === "key")
ctrl = ctrl(item, path);
}
}
return typeof ctrl === "function" ? ctrl(item, path) : ctrl;
}
exports.visit = visit2;
}
});
// node_modules/yaml/dist/parse/cst.js
var require_cst = __commonJS({
"node_modules/yaml/dist/parse/cst.js"(exports) {
"use strict";
var cstScalar = require_cst_scalar();
var cstStringify = require_cst_stringify();
var cstVisit = require_cst_visit();
var BOM = "\uFEFF";
var DOCUMENT = "";
var FLOW_END = "";
var SCALAR = "";
var isCollection2 = (token) => !!token && "items" in token;
var isScalar2 = (token) => !!token && (token.type === "scalar" || token.type === "single-quoted-scalar" || token.type === "double-quoted-scalar" || token.type === "block-scalar");
function prettyToken(token) {
switch (token) {
case BOM:
return "<BOM>";
case DOCUMENT:
return "<DOC>";
case FLOW_END:
return "<FLOW_END>";
case SCALAR:
return "<SCALAR>";
default:
return JSON.stringify(token);
}
}
function tokenType(source) {
switch (source) {
case BOM:
return "byte-order-mark";
case DOCUMENT:
return "doc-mode";
case FLOW_END:
return "flow-error-end";
case SCALAR:
return "scalar";
case "---":
return "doc-start";
case "...":
return "doc-end";
case "":
case "\n":
case "\r\n":
return "newline";
case "-":
return "seq-item-ind";
case "?":
return "explicit-key-ind";
case ":":
return "map-value-ind";
case "{":
return "flow-map-start";
case "}":
return "flow-map-end";
case "[":
return "flow-seq-start";
case "]":
return "flow-seq-end";
case ",":
return "comma";
}
switch (source[0]) {
case " ":
case " ":
return "space";
case "#":
return "comment";
case "%":
return "directive-line";
case "*":
return "alias";
case "&":
return "anchor";
case "!":
return "tag";
case "'":
return "single-quoted-scalar";
case '"':
return "double-quoted-scalar";
case "|":
case ">":
return "block-scalar-header";
}
return null;
}
exports.createScalarToken = cstScalar.createScalarToken;
exports.resolveAsScalar = cstScalar.resolveAsScalar;
exports.setScalarValue = cstScalar.setScalarValue;
exports.stringify = cstStringify.stringify;
exports.visit = cstVisit.visit;
exports.BOM = BOM;
exports.DOCUMENT = DOCUMENT;
exports.FLOW_END = FLOW_END;
exports.SCALAR = SCALAR;
exports.isCollection = isCollection2;
exports.isScalar = isScalar2;
exports.prettyToken = prettyToken;
exports.tokenType = tokenType;
}
});
// node_modules/yaml/dist/parse/lexer.js
var require_lexer = __commonJS({
"node_modules/yaml/dist/parse/lexer.js"(exports) {
"use strict";
var cst = require_cst();
function isEmpty(ch) {
switch (ch) {
case void 0:
case " ":
case "\n":
case "\r":
case " ":
return true;
default:
return false;
}
}
var hexDigits = new Set("0123456789ABCDEFabcdef");
var tagChars = new Set("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()");
var flowIndicatorChars = new Set(",[]{}");
var invalidAnchorChars = new Set(" ,[]{}\n\r ");
var isNotAnchorChar = (ch) => !ch || invalidAnchorChars.has(ch);
var Lexer = class {
constructor() {
this.atEnd = false;
this.blockScalarIndent = -1;
this.blockScalarKeep = false;
this.buffer = "";
this.flowKey = false;
this.flowLevel = 0;
this.indentNext = 0;
this.indentValue = 0;
this.lineEndPos = null;
this.next = null;
this.pos = 0;
}
/**
* Generate YAML tokens from the `source` string. If `incomplete`,
* a part of the last line may be left as a buffer for the next call.
*
* @returns A generator of lexical tokens
*/
*lex(source, incomplete = false) {
if (source) {
if (typeof source !== "string")
throw TypeError("source is not a string");
this.buffer = this.buffer ? this.buffer + source : source;
this.lineEndPos = null;
}
this.atEnd = !incomplete;
let next = this.next ?? "stream";
while (next && (incomplete || this.hasChars(1)))
next = yield* this.parseNext(next);
}
atLineEnd() {
let i = this.pos;
let ch = this.buffer[i];
while (ch === " " || ch === " ")
ch = this.buffer[++i];
if (!ch || ch === "#" || ch === "\n")
return true;
if (ch === "\r")
return this.buffer[i + 1] === "\n";
return false;
}
charAt(n) {
return this.buffer[this.pos + n];
}
continueScalar(offset) {
let ch = this.buffer[offset];
if (this.indentNext > 0) {
let indent = 0;
while (ch === " ")
ch = this.buffer[++indent + offset];
if (ch === "\r") {
const next = this.buffer[indent + offset + 1];
if (next === "\n" || !next && !this.atEnd)
return offset + indent + 1;
}
return ch === "\n" || indent >= this.indentNext || !ch && !this.atEnd ? offset + indent : -1;
}
if (ch === "-" || ch === ".") {
const dt = this.buffer.substr(offset, 3);
if ((dt === "---" || dt === "...") && isEmpty(this.buffer[offset + 3]))
return -1;
}
return offset;
}
getLine() {
let end = this.lineEndPos;
if (typeof end !== "number" || end !== -1 && end < this.pos) {
end = this.buffer.indexOf("\n", this.pos);
this.lineEndPos = end;
}
if (end === -1)
return this.atEnd ? this.buffer.substring(this.pos) : null;
if (this.buffer[end - 1] === "\r")
end -= 1;
return this.buffer.substring(this.pos, end);
}
hasChars(n) {
return this.pos + n <= this.buffer.length;
}
setNext(state) {
this.buffer = this.buffer.substring(this.pos);
this.pos = 0;
this.lineEndPos = null;
this.next = state;
return null;
}
peek(n) {
return this.buffer.substr(this.pos, n);
}
*parseNext(next) {
switch (next) {
case "stream":
return yield* this.parseStream();
case "line-start":
return yield* this.parseLineStart();
case "block-start":
return yield* this.parseBlockStart();
case "doc":
return yield* this.parseDocument();
case "flow":
return yield* this.parseFlowCollection();
case "quoted-scalar":
return yield* this.parseQuotedScalar();
case "block-scalar":
return yield* this.parseBlockScalar();
case "plain-scalar":
return yield* this.parsePlainScalar();
}
}
*parseStream() {
let line = this.getLine();
if (line === null)
return this.setNext("stream");
if (line[0] === cst.BOM) {
yield* this.pushCount(1);
line = line.substring(1);
}
if (line[0] === "%") {
let dirEnd = line.length;
let cs = line.indexOf("#");
while (cs !== -1) {
const ch = line[cs - 1];
if (ch === " " || ch === " ") {
dirEnd = cs - 1;
break;
} else {
cs = line.indexOf("#", cs + 1);
}
}
while (true) {
const ch = line[dirEnd - 1];
if (ch === " " || ch === " ")
dirEnd -= 1;
else
break;
}
const n = (yield* this.pushCount(dirEnd)) + (yield* this.pushSpaces(true));
yield* this.pushCount(line.length - n);
this.pushNewline();
return "stream";
}
if (this.atLineEnd()) {
const sp = yield* this.pushSpaces(true);
yield* this.pushCount(line.length - sp);
yield* this.pushNewline();
return "stream";
}
yield cst.DOCUMENT;
return yield* this.parseLineStart();
}
*parseLineStart() {
const ch = this.charAt(0);
if (!ch && !this.atEnd)
return this.setNext("line-start");
if (ch === "-" || ch === ".") {
if (!this.atEnd && !this.hasChars(4))
return this.setNext("line-start");
const s = this.peek(3);
if ((s === "---" || s === "...") && isEmpty(this.charAt(3))) {
yield* this.pushCount(3);
this.indentValue = 0;
this.indentNext = 0;
return s === "---" ? "doc" : "stream";
}
}
this.indentValue = yield* this.pushSpaces(false);
if (this.indentNext > this.indentValue && !isEmpty(this.charAt(1)))
this.indentNext = this.indentValue;
return yield* this.parseBlockStart();
}
*parseBlockStart() {
const [ch0, ch1] = this.peek(2);
if (!ch1 && !this.atEnd)
return this.setNext("block-start");
if ((ch0 === "-" || ch0 === "?" || ch0 === ":") && isEmpty(ch1)) {
const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));
this.indentNext = this.indentValue + 1;
this.indentValue += n;
return "block-start";
}
return "doc";
}
*parseDocument() {
yield* this.pushSpaces(true);
const line = this.getLine();
if (line === null)
return this.setNext("doc");
let n = yield* this.pushIndicators();
switch (line[n]) {
case "#":
yield* this.pushCount(line.length - n);
// fallthrough
case void 0:
yield* this.pushNewline();
return yield* this.parseLineStart();
case "{":
case "[":
yield* this.pushCount(1);
this.flowKey = false;
this.flowLevel = 1;
return "flow";
case "}":
case "]":
yield* this.pushCount(1);
return "doc";
case "*":
yield* this.pushUntil(isNotAnchorChar);
return "doc";
case '"':
case "'":
return yield* this.parseQuotedScalar();
case "|":
case ">":
n += yield* this.parseBlockScalarHeader();
n += yield* this.pushSpaces(true);
yield* this.pushCount(line.length - n);
yield* this.pushNewline();
return yield* this.parseBlockScalar();
default:
return yield* this.parsePlainScalar();
}
}
*parseFlowCollection() {
let nl, sp;
let indent = -1;
do {
nl = yield* this.pushNewline();
if (nl > 0) {
sp = yield* this.pushSpaces(false);
this.indentValue = indent = sp;
} else {
sp = 0;
}
sp += yield* this.pushSpaces(true);
} while (nl + sp > 0);
const line = this.getLine();
if (line === null)
return this.setNext("flow");
if (indent !== -1 && indent < this.indentNext && line[0] !== "#" || indent === 0 && (line.startsWith("---") || line.startsWith("...")) && isEmpty(line[3])) {
const atFlowEndMarker = indent === this.indentNext - 1 && this.flowLevel === 1 && (line[0] === "]" || line[0] === "}");
if (!atFlowEndMarker) {
this.flowLevel = 0;
yield cst.FLOW_END;
return yield* this.parseLineStart();
}
}
let n = 0;
while (line[n] === ",") {
n += yield* this.pushCount(1);
n += yield* this.pushSpaces(true);
this.flowKey = false;
}
n += yield* this.pushIndicators();
switch (line[n]) {
case void 0:
return "flow";
case "#":
yield* this.pushCount(line.length - n);
return "flow";
case "{":
case "[":
yield* this.pushCount(1);
this.flowKey = false;
this.flowLevel += 1;
return "flow";
case "}":
case "]":
yield* this.pushCount(1);
this.flowKey = true;
this.flowLevel -= 1;
return this.flowLevel ? "flow" : "doc";
case "*":
yield* this.pushUntil(isNotAnchorChar);
return "flow";
case '"':
case "'":
this.flowKey = true;
return yield* this.parseQuotedScalar();
case ":": {
const next = this.charAt(1);
if (this.flowKey || isEmpty(next) || next === ",") {
this.flowKey = false;
yield* this.pushCount(1);
yield* this.pushSpaces(true);
return "flow";
}
}
// fallthrough
default:
this.flowKey = false;
return yield* this.parsePlainScalar();
}
}
*parseQuotedScalar() {
const quote = this.charAt(0);
let end = this.buffer.indexOf(quote, this.pos + 1);
if (quote === "'") {
while (end !== -1 && this.buffer[end + 1] === "'")
end = this.buffer.indexOf("'", end + 2);
} else {
while (end !== -1) {
let n = 0;
while (this.buffer[end - 1 - n] === "\\")
n += 1;
if (n % 2 === 0)
break;
end = this.buffer.indexOf('"', end + 1);
}
}
const qb = this.buffer.substring(0, end);
let nl = qb.indexOf("\n", this.pos);
if (nl !== -1) {
while (nl !== -1) {
const cs = this.continueScalar(nl + 1);
if (cs === -1)
break;
nl = qb.indexOf("\n", cs);
}
if (nl !== -1) {
end = nl - (qb[nl - 1] === "\r" ? 2 : 1);
}
}
if (end === -1) {
if (!this.atEnd)
return this.setNext("quoted-scalar");
end = this.buffer.length;
}
yield* this.pushToIndex(end + 1, false);
return this.flowLevel ? "flow" : "doc";
}
*parseBlockScalarHeader() {
this.blockScalarIndent = -1;
this.blockScalarKeep = false;
let i = this.pos;
while (true) {
const ch = this.buffer[++i];
if (ch === "+")
this.blockScalarKeep = true;
else if (ch > "0" && ch <= "9")
this.blockScalarIndent = Number(ch) - 1;
else if (ch !== "-")
break;
}
return yield* this.pushUntil((ch) => isEmpty(ch) || ch === "#");
}
*parseBlockScalar() {
let nl = this.pos - 1;
let indent = 0;
let ch;
loop: for (let i2 = this.pos; ch = this.buffer[i2]; ++i2) {
switch (ch) {
case " ":
indent += 1;
break;
case "\n":
nl = i2;
indent = 0;
break;
case "\r": {
const next = this.buffer[i2 + 1];
if (!next && !this.atEnd)
return this.setNext("block-scalar");
if (next === "\n")
break;
}
// fallthrough
default:
break loop;
}
}
if (!ch && !this.atEnd)
return this.setNext("block-scalar");
if (indent >= this.indentNext) {
if (this.blockScalarIndent === -1)
this.indentNext = indent;
else {
this.indentNext = this.blockScalarIndent + (this.indentNext === 0 ? 1 : this.indentNext);
}
do {
const cs = this.continueScalar(nl + 1);
if (cs === -1)
break;
nl = this.buffer.indexOf("\n", cs);
} while (nl !== -1);
if (nl === -1) {
if (!this.atEnd)
return this.setNext("block-scalar");
nl = this.buffer.length;
}
}
let i = nl + 1;
ch = this.buffer[i];
while (ch === " ")
ch = this.buffer[++i];
if (ch === " ") {
while (ch === " " || ch === " " || ch === "\r" || ch === "\n")
ch = this.buffer[++i];
nl = i - 1;
} else if (!this.blockScalarKeep) {
do {
let i2 = nl - 1;
let ch2 = this.buffer[i2];
if (ch2 === "\r")
ch2 = this.buffer[--i2];
const lastChar = i2;
while (ch2 === " ")
ch2 = this.buffer[--i2];
if (ch2 === "\n" && i2 >= this.pos && i2 + 1 + indent > lastChar)
nl = i2;
else
break;
} while (true);
}
yield cst.SCALAR;
yield* this.pushToIndex(nl + 1, true);
return yield* this.parseLineStart();
}
*parsePlainScalar() {
const inFlow = this.flowLevel > 0;
let end = this.pos - 1;
let i = this.pos - 1;
let ch;
while (ch = this.buffer[++i]) {
if (ch === ":") {
const next = this.buffer[i + 1];
if (isEmpty(next) || inFlow && flowIndicatorChars.has(next))
break;
end = i;
} else if (isEmpty(ch)) {
let next = this.buffer[i + 1];
if (ch === "\r") {
if (next === "\n") {
i += 1;
ch = "\n";
next = this.buffer[i + 1];
} else
end = i;
}
if (next === "#" || inFlow && flowIndicatorChars.has(next))
break;
if (ch === "\n") {
const cs = this.continueScalar(i + 1);
if (cs === -1)
break;
i = Math.max(i, cs - 2);
}
} else {
if (inFlow && flowIndicatorChars.has(ch))
break;
end = i;
}
}
if (!ch && !this.atEnd)
return this.setNext("plain-scalar");
yield cst.SCALAR;
yield* this.pushToIndex(end + 1, true);
return inFlow ? "flow" : "doc";
}
*pushCount(n) {
if (n > 0) {
yield this.buffer.substr(this.pos, n);
this.pos += n;
return n;
}
return 0;
}
*pushToIndex(i, allowEmpty) {
const s = this.buffer.slice(this.pos, i);
if (s) {
yield s;
this.pos += s.length;
return s.length;
} else if (allowEmpty)
yield "";
return 0;
}
*pushIndicators() {
let n = 0;
loop: while (true) {
switch (this.charAt(0)) {
case "!":
n += yield* this.pushTag();
n += yield* this.pushSpaces(true);
continue loop;
case "&":
n += yield* this.pushUntil(isNotAnchorChar);
n += yield* this.pushSpaces(true);
continue loop;
case "-":
// this is an error
case "?":
// this is an error outside flow collections
case ":": {
const inFlow = this.flowLevel > 0;
const ch1 = this.charAt(1);
if (isEmpty(ch1) || inFlow && flowIndicatorChars.has(ch1)) {
if (!inFlow)
this.indentNext = this.indentValue + 1;
else if (this.flowKey)
this.flowKey = false;
n += yield* this.pushCount(1);
n += yield* this.pushSpaces(true);
continue loop;
}
}
}
break loop;
}
return n;
}
*pushTag() {
if (this.charAt(1) === "<") {
let i = this.pos + 2;
let ch = this.buffer[i];
while (!isEmpty(ch) && ch !== ">")
ch = this.buffer[++i];
return yield* this.pushToIndex(ch === ">" ? i + 1 : i, false);
} else {
let i = this.pos + 1;
let ch = this.buffer[i];
while (ch) {
if (tagChars.has(ch))
ch = this.buffer[++i];
else if (ch === "%" && hexDigits.has(this.buffer[i + 1]) && hexDigits.has(this.buffer[i + 2])) {
ch = this.buffer[i += 3];
} else
break;
}
return yield* this.pushToIndex(i, false);
}
}
*pushNewline() {
const ch = this.buffer[this.pos];
if (ch === "\n")
return yield* this.pushCount(1);
else if (ch === "\r" && this.charAt(1) === "\n")
return yield* this.pushCount(2);
else
return 0;
}
*pushSpaces(allowTabs) {
let i = this.pos - 1;
let ch;
do {
ch = this.buffer[++i];
} while (ch === " " || allowTabs && ch === " ");
const n = i - this.pos;
if (n > 0) {
yield this.buffer.substr(this.pos, n);
this.pos = i;
}
return n;
}
*pushUntil(test) {
let i = this.pos;
let ch = this.buffer[i];
while (!test(ch))
ch = this.buffer[++i];
return yield* this.pushToIndex(i, false);
}
};
exports.Lexer = Lexer;
}
});
// node_modules/yaml/dist/parse/line-counter.js
var require_line_counter = __commonJS({
"node_modules/yaml/dist/parse/line-counter.js"(exports) {
"use strict";
var LineCounter = class {
constructor() {
this.lineStarts = [];
this.addNewLine = (offset) => this.lineStarts.push(offset);
this.linePos = (offset) => {
let low = 0;
let high = this.lineStarts.length;
while (low < high) {
const mid = low + high >> 1;
if (this.lineStarts[mid] < offset)
low = mid + 1;
else
high = mid;
}
if (this.lineStarts[low] === offset)
return { line: low + 1, col: 1 };
if (low === 0)
return { line: 0, col: offset };
const start = this.lineStarts[low - 1];
return { line: low, col: offset - start + 1 };
};
}
};
exports.LineCounter = LineCounter;
}
});
// node_modules/yaml/dist/parse/parser.js
var require_parser = __commonJS({
"node_modules/yaml/dist/parse/parser.js"(exports) {
"use strict";
var node_process = __require("process");
var cst = require_cst();
var lexer = require_lexer();
function includesToken(list, type) {
for (let i = 0; i < list.length; ++i)
if (list[i].type === type)
return true;
return false;
}
function findNonEmptyIndex(list) {
for (let i = 0; i < list.length; ++i) {
switch (list[i].type) {
case "space":
case "comment":
case "newline":
break;
default:
return i;
}
}
return -1;
}
function isFlowToken(token) {
switch (token?.type) {
case "alias":
case "scalar":
case "single-quoted-scalar":
case "double-quoted-scalar":
case "flow-collection":
return true;
default:
return false;
}
}
function getPrevProps(parent) {
switch (parent.type) {
case "document":
return parent.start;
case "block-map": {
const it = parent.items[parent.items.length - 1];
return it.sep ?? it.start;
}
case "block-seq":
return parent.items[parent.items.length - 1].start;
/* istanbul ignore next should not happen */
default:
return [];
}
}
function getFirstKeyStartProps(prev) {
if (prev.length === 0)
return [];
let i = prev.length;
loop: while (--i >= 0) {
switch (prev[i].type) {
case "doc-start":
case "explicit-key-ind":
case "map-value-ind":
case "seq-item-ind":
case "newline":
break loop;
}
}
while (prev[++i]?.type === "space") {
}
return prev.splice(i, prev.length);
}
function arrayPushArray(target, source) {
if (source.length < 1e5)
Array.prototype.push.apply(target, source);
else
for (let i = 0; i < source.length; ++i)
target.push(source[i]);
}
function fixFlowSeqItems(fc) {
if (fc.start.type === "flow-seq-start") {
for (const it of fc.items) {
if (it.sep && !it.value && !includesToken(it.start, "explicit-key-ind") && !includesToken(it.sep, "map-value-ind")) {
if (it.key)
it.value = it.key;
delete it.key;
if (isFlowToken(it.value)) {
if (it.value.end)
arrayPushArray(it.value.end, it.sep);
else
it.value.end = it.sep;
} else
arrayPushArray(it.start, it.sep);
delete it.sep;
}
}
}
}
var Parser = class {
/**
* @param onNewLine - If defined, called separately with the start position of
* each new line (in `parse()`, including the start of input).
*/
constructor(onNewLine) {
this.atNewLine = true;
this.atScalar = false;
this.indent = 0;
this.offset = 0;
this.onKeyLine = false;
this.stack = [];
this.source = "";
this.type = "";
this.lexer = new lexer.Lexer();
this.onNewLine = onNewLine;
}
/**
* Parse `source` as a YAML stream.
* If `incomplete`, a part of the last line may be left as a buffer for the next call.
*
* Errors are not thrown, but yielded as `{ type: 'error', message }` tokens.
*
* @returns A generator of tokens representing each directive, document, and other structure.
*/
*parse(source, incomplete = false) {
if (this.onNewLine && this.offset === 0)
this.onNewLine(0);
for (const lexeme of this.lexer.lex(source, incomplete))
yield* this.next(lexeme);
if (!incomplete)
yield* this.end();
}
/**
* Advance the parser by the `source` of one lexical token.
*/
*next(source) {
this.source = source;
if (node_process.env.LOG_TOKENS)
console.log("|", cst.prettyToken(source));
if (this.atScalar) {
this.atScalar = false;
yield* this.step();
this.offset += source.length;
return;
}
const type = cst.tokenType(source);
if (!type) {
const message = `Not a YAML token: ${source}`;
yield* this.pop({ type: "error", offset: this.offset, message, source });
this.offset += source.length;
} else if (type === "scalar") {
this.atNewLine = false;
this.atScalar = true;
this.type = "scalar";
} else {
this.type = type;
yield* this.step();
switch (type) {
case "newline":
this.atNewLine = true;
this.indent = 0;
if (this.onNewLine)
this.onNewLine(this.offset + source.length);
break;
case "space":
if (this.atNewLine && source[0] === " ")
this.indent += source.length;
break;
case "explicit-key-ind":
case "map-value-ind":
case "seq-item-ind":
if (this.atNewLine)
this.indent += source.length;
break;
case "doc-mode":
case "flow-error-end":
return;
default:
this.atNewLine = false;
}
this.offset += source.length;
}
}
/** Call at end of input to push out any remaining constructions */
*end() {
while (this.stack.length > 0)
yield* this.pop();
}
get sourceToken() {
const st = {
type: this.type,
offset: this.offset,
indent: this.indent,
source: this.source
};
return st;
}
*step() {
const top = this.peek(1);
if (this.type === "doc-end" && top?.type !== "doc-end") {
while (this.stack.length > 0)
yield* this.pop();
this.stack.push({
type: "doc-end",
offset: this.offset,
source: this.source
});
return;
}
if (!top)
return yield* this.stream();
switch (top.type) {
case "document":
return yield* this.document(top);
case "alias":
case "scalar":
case "single-quoted-scalar":
case "double-quoted-scalar":
return yield* this.scalar(top);
case "block-scalar":
return yield* this.blockScalar(top);
case "block-map":
return yield* this.blockMap(top);
case "block-seq":
return yield* this.blockSequence(top);
case "flow-collection":
return yield* this.flowCollection(top);
case "doc-end":
return yield* this.documentEnd(top);
}
yield* this.pop();
}
peek(n) {
return this.stack[this.stack.length - n];
}
*pop(error) {
const token = error ?? this.stack.pop();
if (!token) {
const message = "Tried to pop an empty stack";
yield { type: "error", offset: this.offset, source: "", message };
} else if (this.stack.length === 0) {
yield token;
} else {
const top = this.peek(1);
if (token.type === "block-scalar") {
token.indent = "indent" in top ? top.indent : 0;
} else if (token.type === "flow-collection" && top.type === "document") {
token.indent = 0;
}
if (token.type === "flow-collection")
fixFlowSeqItems(token);
switch (top.type) {
case "document":
top.value = token;
break;
case "block-scalar":
top.props.push(token);
break;
case "block-map": {
const it = top.items[top.items.length - 1];
if (it.value) {
top.items.push({ start: [], key: token, sep: [] });
this.onKeyLine = true;
return;
} else if (it.sep) {
it.value = token;
} else {
Object.assign(it, { key: token, sep: [] });
this.onKeyLine = !it.explicitKey;
return;
}
break;
}
case "block-seq": {
const it = top.items[top.items.length - 1];
if (it.value)
top.items.push({ start: [], value: token });
else
it.value = token;
break;
}
case "flow-collection": {
const it = top.items[top.items.length - 1];
if (!it || it.value)
top.items.push({ start: [], key: token, sep: [] });
else if (it.sep)
it.value = token;
else
Object.assign(it, { key: token, sep: [] });
return;
}
/* istanbul ignore next should not happen */
default:
yield* this.pop();
yield* this.pop(token);
}
if ((top.type === "document" || top.type === "block-map" || top.type === "block-seq") && (token.type === "block-map" || token.type === "block-seq")) {
const last = token.items[token.items.length - 1];
if (last && !last.sep && !last.value && last.start.length > 0 && findNonEmptyIndex(last.start) === -1 && (token.indent === 0 || last.start.every((st) => st.type !== "comment" || st.indent < token.indent))) {
if (top.type === "document")
top.end = last.start;
else
top.items.push({ start: last.start });
token.items.splice(-1, 1);
}
}
}
}
*stream() {
switch (this.type) {
case "directive-line":
yield { type: "directive", offset: this.offset, source: this.source };
return;
case "byte-order-mark":
case "space":
case "comment":
case "newline":
yield this.sourceToken;
return;
case "doc-mode":
case "doc-start": {
const doc = {
type: "document",
offset: this.offset,
start: []
};
if (this.type === "doc-start")
doc.start.push(this.sourceToken);
this.stack.push(doc);
return;
}
}
yield {
type: "error",
offset: this.offset,
message: `Unexpected ${this.type} token in YAML stream`,
source: this.source
};
}
*document(doc) {
if (doc.value)
return yield* this.lineEnd(doc);
switch (this.type) {
case "doc-start": {
if (findNonEmptyIndex(doc.start) !== -1) {
yield* this.pop();
yield* this.step();
} else
doc.start.push(this.sourceToken);
return;
}
case "anchor":
case "tag":
case "space":
case "comment":
case "newline":
doc.start.push(this.sourceToken);
return;
}
const bv = this.startBlockValue(doc);
if (bv)
this.stack.push(bv);
else {
yield {
type: "error",
offset: this.offset,
message: `Unexpected ${this.type} token in YAML document`,
source: this.source
};
}
}
*scalar(scalar) {
if (this.type === "map-value-ind") {
const prev = getPrevProps(this.peek(2));
const start = getFirstKeyStartProps(prev);
let sep3;
if (scalar.end) {
sep3 = scalar.end;
sep3.push(this.sourceToken);
delete scalar.end;
} else
sep3 = [this.sourceToken];
const map = {
type: "block-map",
offset: scalar.offset,
indent: scalar.indent,
items: [{ start, key: scalar, sep: sep3 }]
};
this.onKeyLine = true;
this.stack[this.stack.length - 1] = map;
} else
yield* this.lineEnd(scalar);
}
*blockScalar(scalar) {
switch (this.type) {
case "space":
case "comment":
case "newline":
scalar.props.push(this.sourceToken);
return;
case "scalar":
scalar.source = this.source;
this.atNewLine = true;
this.indent = 0;
if (this.onNewLine) {
let nl = this.source.indexOf("\n") + 1;
while (nl !== 0) {
this.onNewLine(this.offset + nl);
nl = this.source.indexOf("\n", nl) + 1;
}
}
yield* this.pop();
break;
/* istanbul ignore next should not happen */
default:
yield* this.pop();
yield* this.step();
}
}
*blockMap(map) {
const it = map.items[map.items.length - 1];
switch (this.type) {
case "newline":
this.onKeyLine = false;
if (it.value) {
const end = "end" in it.value ? it.value.end : void 0;
const last = Array.isArray(end) ? end[end.length - 1] : void 0;
if (last?.type === "comment")
end?.push(this.sourceToken);
else
map.items.push({ start: [this.sourceToken] });
} else if (it.sep) {
it.sep.push(this.sourceToken);
} else {
it.start.push(this.sourceToken);
}
return;
case "space":
case "comment":
if (it.value) {
map.items.push({ start: [this.sourceToken] });
} else if (it.sep) {
it.sep.push(this.sourceToken);
} else {
if (this.atIndentedComment(it.start, map.indent)) {
const prev = map.items[map.items.length - 2];
const end = prev?.value?.end;
if (Array.isArray(end)) {
arrayPushArray(end, it.start);
end.push(this.sourceToken);
map.items.pop();
return;
}
}
it.start.push(this.sourceToken);
}
return;
}
if (this.indent >= map.indent) {
const atMapIndent = !this.onKeyLine && this.indent === map.indent;
const atNextItem = atMapIndent && (it.sep || it.explicitKey) && this.type !== "seq-item-ind";
let start = [];
if (atNextItem && it.sep && !it.value) {
const nl = [];
for (let i = 0; i < it.sep.length; ++i) {
const st = it.sep[i];
switch (st.type) {
case "newline":
nl.push(i);
break;
case "space":
break;
case "comment":
if (st.indent > map.indent)
nl.length = 0;
break;
default:
nl.length = 0;
}
}
if (nl.length >= 2)
start = it.sep.splice(nl[1]);
}
switch (this.type) {
case "anchor":
case "tag":
if (atNextItem || it.value) {
start.push(this.sourceToken);
map.items.push({ start });
this.onKeyLine = true;
} else if (it.sep) {
it.sep.push(this.sourceToken);
} else {
it.start.push(this.sourceToken);
}
return;
case "explicit-key-ind":
if (!it.sep && !it.explicitKey) {
it.start.push(this.sourceToken);
it.explicitKey = true;
} else if (atNextItem || it.value) {
start.push(this.sourceToken);
map.items.push({ start, explicitKey: true });
} else {
this.stack.push({
type: "block-map",
offset: this.offset,
indent: this.indent,
items: [{ start: [this.sourceToken], explicitKey: true }]
});
}
this.onKeyLine = true;
return;
case "map-value-ind":
if (it.explicitKey) {
if (!it.sep) {
if (includesToken(it.start, "newline")) {
Object.assign(it, { key: null, sep: [this.sourceToken] });
} else {
const start2 = getFirstKeyStartProps(it.start);
this.stack.push({
type: "block-map",
offset: this.offset,
indent: this.indent,
items: [{ start: start2, key: null, sep: [this.sourceToken] }]
});
}
} else if (it.value) {
map.items.push({ start: [], key: null, sep: [this.sourceToken] });
} else if (includesToken(it.sep, "map-value-ind")) {
this.stack.push({
type: "block-map",
offset: this.offset,
indent: this.indent,
items: [{ start, key: null, sep: [this.sourceToken] }]
});
} else if (isFlowToken(it.key) && !includesToken(it.sep, "newline")) {
const start2 = getFirstKeyStartProps(it.start);
const key = it.key;
const sep3 = it.sep;
sep3.push(this.sourceToken);
delete it.key;
delete it.sep;
this.stack.push({
type: "block-map",
offset: this.offset,
indent: this.indent,
items: [{ start: start2, key, sep: sep3 }]
});
} else if (start.length > 0) {
it.sep = it.sep.concat(start, this.sourceToken);
} else {
it.sep.push(this.sourceToken);
}
} else {
if (!it.sep) {
Object.assign(it, { key: null, sep: [this.sourceToken] });
} else if (it.value || atNextItem) {
map.items.push({ start, key: null, sep: [this.sourceToken] });
} else if (includesToken(it.sep, "map-value-ind")) {
this.stack.push({
type: "block-map",
offset: this.offset,
indent: this.indent,
items: [{ start: [], key: null, sep: [this.sourceToken] }]
});
} else {
it.sep.push(this.sourceToken);
}
}
this.onKeyLine = true;
return;
case "alias":
case "scalar":
case "single-quoted-scalar":
case "double-quoted-scalar": {
const fs = this.flowScalar(this.type);
if (atNextItem || it.value) {
map.items.push({ start, key: fs, sep: [] });
this.onKeyLine = true;
} else if (it.sep) {
this.stack.push(fs);
} else {
Object.assign(it, { key: fs, sep: [] });
this.onKeyLine = true;
}
return;
}
default: {
const bv = this.startBlockValue(map);
if (bv) {
if (bv.type === "block-seq") {
if (!it.explicitKey && it.sep && !includesToken(it.sep, "newline")) {
yield* this.pop({
type: "error",
offset: this.offset,
message: "Unexpected block-seq-ind on same line with key",
source: this.source
});
return;
}
} else if (atMapIndent) {
map.items.push({ start });
}
this.stack.push(bv);
return;
}
}
}
}
yield* this.pop();
yield* this.step();
}
*blockSequence(seq) {
const it = seq.items[seq.items.length - 1];
switch (this.type) {
case "newline":
if (it.value) {
const end = "end" in it.value ? it.value.end : void 0;
const last = Array.isArray(end) ? end[end.length - 1] : void 0;
if (last?.type === "comment")
end?.push(this.sourceToken);
else
seq.items.push({ start: [this.sourceToken] });
} else
it.start.push(this.sourceToken);
return;
case "space":
case "comment":
if (it.value)
seq.items.push({ start: [this.sourceToken] });
else {
if (this.atIndentedComment(it.start, seq.indent)) {
const prev = seq.items[seq.items.length - 2];
const end = prev?.value?.end;
if (Array.isArray(end)) {
arrayPushArray(end, it.start);
end.push(this.sourceToken);
seq.items.pop();
return;
}
}
it.start.push(this.sourceToken);
}
return;
case "anchor":
case "tag":
if (it.value || this.indent <= seq.indent)
break;
it.start.push(this.sourceToken);
return;
case "seq-item-ind":
if (this.indent !== seq.indent)
break;
if (it.value || includesToken(it.start, "seq-item-ind"))
seq.items.push({ start: [this.sourceToken] });
else
it.start.push(this.sourceToken);
return;
}
if (this.indent > seq.indent) {
const bv = this.startBlockValue(seq);
if (bv) {
this.stack.push(bv);
return;
}
}
yield* this.pop();
yield* this.step();
}
*flowCollection(fc) {
const it = fc.items[fc.items.length - 1];
if (this.type === "flow-error-end") {
let top;
do {
yield* this.pop();
top = this.peek(1);
} while (top?.type === "flow-collection");
} else if (fc.end.length === 0) {
switch (this.type) {
case "comma":
case "explicit-key-ind":
if (!it || it.sep)
fc.items.push({ start: [this.sourceToken] });
else
it.start.push(this.sourceToken);
return;
case "map-value-ind":
if (!it || it.value)
fc.items.push({ start: [], key: null, sep: [this.sourceToken] });
else if (it.sep)
it.sep.push(this.sourceToken);
else
Object.assign(it, { key: null, sep: [this.sourceToken] });
return;
case "space":
case "comment":
case "newline":
case "anchor":
case "tag":
if (!it || it.value)
fc.items.push({ start: [this.sourceToken] });
else if (it.sep)
it.sep.push(this.sourceToken);
else
it.start.push(this.sourceToken);
return;
case "alias":
case "scalar":
case "single-quoted-scalar":
case "double-quoted-scalar": {
const fs = this.flowScalar(this.type);
if (!it || it.value)
fc.items.push({ start: [], key: fs, sep: [] });
else if (it.sep)
this.stack.push(fs);
else
Object.assign(it, { key: fs, sep: [] });
return;
}
case "flow-map-end":
case "flow-seq-end":
fc.end.push(this.sourceToken);
return;
}
const bv = this.startBlockValue(fc);
if (bv)
this.stack.push(bv);
else {
yield* this.pop();
yield* this.step();
}
} else {
const parent = this.peek(2);
if (parent.type === "block-map" && (this.type === "map-value-ind" && parent.indent === fc.indent || this.type === "newline" && !parent.items[parent.items.length - 1].sep)) {
yield* this.pop();
yield* this.step();
} else if (this.type === "map-value-ind" && parent.type !== "flow-collection") {
const prev = getPrevProps(parent);
const start = getFirstKeyStartProps(prev);
fixFlowSeqItems(fc);
const sep3 = fc.end.splice(1, fc.end.length);
sep3.push(this.sourceToken);
const map = {
type: "block-map",
offset: fc.offset,
indent: fc.indent,
items: [{ start, key: fc, sep: sep3 }]
};
this.onKeyLine = true;
this.stack[this.stack.length - 1] = map;
} else {
yield* this.lineEnd(fc);
}
}
}
flowScalar(type) {
if (this.onNewLine) {
let nl = this.source.indexOf("\n") + 1;
while (nl !== 0) {
this.onNewLine(this.offset + nl);
nl = this.source.indexOf("\n", nl) + 1;
}
}
return {
type,
offset: this.offset,
indent: this.indent,
source: this.source
};
}
startBlockValue(parent) {
switch (this.type) {
case "alias":
case "scalar":
case "single-quoted-scalar":
case "double-quoted-scalar":
return this.flowScalar(this.type);
case "block-scalar-header":
return {
type: "block-scalar",
offset: this.offset,
indent: this.indent,
props: [this.sourceToken],
source: ""
};
case "flow-map-start":
case "flow-seq-start":
return {
type: "flow-collection",
offset: this.offset,
indent: this.indent,
start: this.sourceToken,
items: [],
end: []
};
case "seq-item-ind":
return {
type: "block-seq",
offset: this.offset,
indent: this.indent,
items: [{ start: [this.sourceToken] }]
};
case "explicit-key-ind": {
this.onKeyLine = true;
const prev = getPrevProps(parent);
const start = getFirstKeyStartProps(prev);
start.push(this.sourceToken);
return {
type: "block-map",
offset: this.offset,
indent: this.indent,
items: [{ start, explicitKey: true }]
};
}
case "map-value-ind": {
this.onKeyLine = true;
const prev = getPrevProps(parent);
const start = getFirstKeyStartProps(prev);
return {
type: "block-map",
offset: this.offset,
indent: this.indent,
items: [{ start, key: null, sep: [this.sourceToken] }]
};
}
}
return null;
}
atIndentedComment(start, indent) {
if (this.type !== "comment")
return false;
if (this.indent <= indent)
return false;
return start.every((st) => st.type === "newline" || st.type === "space");
}
*documentEnd(docEnd) {
if (this.type !== "doc-mode") {
if (docEnd.end)
docEnd.end.push(this.sourceToken);
else
docEnd.end = [this.sourceToken];
if (this.type === "newline")
yield* this.pop();
}
}
*lineEnd(token) {
switch (this.type) {
case "comma":
case "doc-start":
case "doc-end":
case "flow-seq-end":
case "flow-map-end":
case "map-value-ind":
yield* this.pop();
yield* this.step();
break;
case "newline":
this.onKeyLine = false;
// fallthrough
case "space":
case "comment":
default:
if (token.end)
token.end.push(this.sourceToken);
else
token.end = [this.sourceToken];
if (this.type === "newline")
yield* this.pop();
}
}
};
exports.Parser = Parser;
}
});
// node_modules/yaml/dist/public-api.js
var require_public_api = __commonJS({
"node_modules/yaml/dist/public-api.js"(exports) {
"use strict";
var composer = require_composer();
var Document = require_Document();
var errors = require_errors2();
var log = require_log();
var identity = require_identity();
var lineCounter = require_line_counter();
var parser = require_parser();
function parseOptions(options) {
const prettyErrors = options.prettyErrors !== false;
const lineCounter$1 = options.lineCounter || prettyErrors && new lineCounter.LineCounter() || null;
return { lineCounter: lineCounter$1, prettyErrors };
}
function parseAllDocuments(source, options = {}) {
const { lineCounter: lineCounter2, prettyErrors } = parseOptions(options);
const parser$1 = new parser.Parser(lineCounter2?.addNewLine);
const composer$1 = new composer.Composer(options);
const docs = Array.from(composer$1.compose(parser$1.parse(source)));
if (prettyErrors && lineCounter2)
for (const doc of docs) {
doc.errors.forEach(errors.prettifyError(source, lineCounter2));
doc.warnings.forEach(errors.prettifyError(source, lineCounter2));
}
if (docs.length > 0)
return docs;
return Object.assign([], { empty: true }, composer$1.streamInfo());
}
function parseDocument2(source, options = {}) {
const { lineCounter: lineCounter2, prettyErrors } = parseOptions(options);
const parser$1 = new parser.Parser(lineCounter2?.addNewLine);
const composer$1 = new composer.Composer(options);
let doc = null;
for (const _doc of composer$1.compose(parser$1.parse(source), true, source.length)) {
if (!doc)
doc = _doc;
else if (doc.options.logLevel !== "silent") {
doc.errors.push(new errors.YAMLParseError(_doc.range.slice(0, 2), "MULTIPLE_DOCS", "Source contains multiple documents; please use YAML.parseAllDocuments()"));
break;
}
}
if (prettyErrors && lineCounter2) {
doc.errors.forEach(errors.prettifyError(source, lineCounter2));
doc.warnings.forEach(errors.prettifyError(source, lineCounter2));
}
return doc;
}
function parse4(src, reviver, options) {
let _reviver = void 0;
if (typeof reviver === "function") {
_reviver = reviver;
} else if (options === void 0 && reviver && typeof reviver === "object") {
options = reviver;
}
const doc = parseDocument2(src, options);
if (!doc)
return null;
doc.warnings.forEach((warning) => log.warn(doc.options.logLevel, warning));
if (doc.errors.length > 0) {
if (doc.options.logLevel !== "silent")
throw doc.errors[0];
else
doc.errors = [];
}
return doc.toJS(Object.assign({ reviver: _reviver }, options));
}
function stringify4(value, replacer, options) {
let _replacer = null;
if (typeof replacer === "function" || Array.isArray(replacer)) {
_replacer = replacer;
} else if (options === void 0 && replacer) {
options = replacer;
}
if (typeof options === "string")
options = options.length;
if (typeof options === "number") {
const indent = Math.round(options);
options = indent < 1 ? void 0 : indent > 8 ? { indent: 8 } : { indent };
}
if (value === void 0) {
const { keepUndefined } = options ?? replacer ?? {};
if (!keepUndefined)
return void 0;
}
if (identity.isDocument(value) && !_replacer)
return value.toString(options);
return new Document.Document(value, _replacer, options).toString(options);
}
exports.parse = parse4;
exports.parseAllDocuments = parseAllDocuments;
exports.parseDocument = parseDocument2;
exports.stringify = stringify4;
}
});
// node_modules/yaml/dist/index.js
var require_dist = __commonJS({
"node_modules/yaml/dist/index.js"(exports) {
"use strict";
var composer = require_composer();
var Document = require_Document();
var Schema = require_Schema();
var errors = require_errors2();
var Alias = require_Alias();
var identity = require_identity();
var Pair = require_Pair();
var Scalar = require_Scalar();
var YAMLMap = require_YAMLMap();
var YAMLSeq = require_YAMLSeq();
var cst = require_cst();
var lexer = require_lexer();
var lineCounter = require_line_counter();
var parser = require_parser();
var publicApi = require_public_api();
var visit2 = require_visit();
exports.Composer = composer.Composer;
exports.Document = Document.Document;
exports.Schema = Schema.Schema;
exports.YAMLError = errors.YAMLError;
exports.YAMLParseError = errors.YAMLParseError;
exports.YAMLWarning = errors.YAMLWarning;
exports.Alias = Alias.Alias;
exports.isAlias = identity.isAlias;
exports.isCollection = identity.isCollection;
exports.isDocument = identity.isDocument;
exports.isMap = identity.isMap;
exports.isNode = identity.isNode;
exports.isPair = identity.isPair;
exports.isScalar = identity.isScalar;
exports.isSeq = identity.isSeq;
exports.Pair = Pair.Pair;
exports.Scalar = Scalar.Scalar;
exports.YAMLMap = YAMLMap.YAMLMap;
exports.YAMLSeq = YAMLSeq.YAMLSeq;
exports.CST = cst;
exports.Lexer = lexer.Lexer;
exports.LineCounter = lineCounter.LineCounter;
exports.Parser = parser.Parser;
exports.parse = publicApi.parse;
exports.parseAllDocuments = publicApi.parseAllDocuments;
exports.parseDocument = publicApi.parseDocument;
exports.stringify = publicApi.stringify;
exports.visit = visit2.visit;
exports.visitAsync = visit2.visitAsync;
}
});
// plugins/kxm/src/hub.ts
import { createHash as createHash5, createHmac as createHmac2 } from "node:crypto";
import { existsSync as existsSync6 } from "node:fs";
import { createServer } from "node:http";
import { isIP } from "node:net";
import { dirname as dirname6, join as join6, resolve as resolve6 } from "node:path";
// plugins/kxm/src/protocol.ts
import { randomUUID } from "node:crypto";
var DEFAULT_PORT = 7331;
var DEFAULT_STALE_AFTER_MS = 3e4;
var DEFAULT_MAX_HOPS = 5;
var DEFAULT_MESSAGE_TTL_MS = 24 * 60 * 6e4;
var MIN_MESSAGE_TTL_MS = 1e3;
var MAX_MESSAGE_TTL_MS = 7 * 24 * 60 * 6e4;
var DEFAULT_MESSAGE_RETENTION_MS = 7 * 24 * 60 * 6e4;
var MIN_MESSAGE_RETENTION_MS = 1e3;
var DEFAULT_RATE_LIMIT_MAX = 600;
var DEFAULT_RATE_LIMIT_WINDOW_MS = 6e4;
var MAX_BODY_BYTES = 256 * 1024;
var MAX_CONTENT_CHARS = 32e3;
var MAX_AGENT_HOST_CHARS = 64;
var MIN_LEASE_TTL_MS = 5e3;
var MAX_LEASE_TTL_MS = 10 * 6e4;
var DEFAULT_LEASE_TTL_MS = 5 * 6e4;
var MAX_LEASE_RESOURCE_CHARS = 200;
function agentPresenceView(agent, staleAfterMs = DEFAULT_STALE_AFTER_MS, now = Date.now()) {
const lastSeenMs = Date.parse(agent.lastSeenAt);
const leaseExpiresAtMs = (Number.isFinite(lastSeenMs) ? lastSeenMs : 0) + staleAfterMs;
const leaseExpiresAt = new Date(leaseExpiresAtMs).toISOString();
if (!agent.online) return { leaseExpiresAt, presence: "offline" };
return { leaseExpiresAt, presence: now < leaseExpiresAtMs ? "online" : "stale" };
}
function toAgentRecord(agent, staleAfterMs, now) {
return { ...agent, ...agentPresenceView(agent, staleAfterMs, now) };
}
var MAX_SYNC_BATCH_EVENTS = 100;
var IMPROVEMENT_AREAS = [
"harness",
"gates",
"implementation",
"workflow",
"documentation",
"security",
"other"
];
var ProtocolError = class extends Error {
statusCode;
code;
extras;
constructor(statusCode, message, code = "protocol_error", extras) {
super(message);
this.name = "ProtocolError";
this.statusCode = statusCode;
this.code = code;
if (extras) this.extras = extras;
}
};
function nowIso() {
return (/* @__PURE__ */ new Date()).toISOString();
}
function newId(prefix) {
return `${prefix}_${randomUUID().replaceAll("-", "")}`;
}
function requireString(value, field, options = {}) {
if (typeof value !== "string") {
throw new ProtocolError(400, `${field} must be a string`);
}
const result = value.trim();
if (!options.allowEmpty && result.length === 0) {
throw new ProtocolError(400, `${field} cannot be empty`);
}
if (options.max !== void 0 && result.length > options.max) {
throw new ProtocolError(400, `${field} exceeds ${options.max} characters`);
}
return result;
}
function optionalString(value, field, max) {
if (value === void 0 || value === null || value === "") return void 0;
return requireString(value, field, { max });
}
function parseDeliveryMode(value) {
if (value === void 0) return "followUp";
if (value === "steer" || value === "followUp" || value === "nextTurn") return value;
throw new ProtocolError(400, "delivery must be steer, followUp, or nextTurn");
}
function parseBoundedInteger(value, field, fallback, min, max) {
if (value === void 0) return fallback;
if (!Number.isInteger(value) || value < min || value > max) {
throw new ProtocolError(400, `${field} must be an integer between ${min} and ${max}`);
}
return value;
}
var TERMINAL_RECEIPT_SCHEMA = "kxm.terminal-receipt.v1";
var VALID_TERMINAL_STATUSES = /* @__PURE__ */ new Set(["accepted", "audit_escalation", "rejected", "error"]);
function validateTerminalReceipt(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new ProtocolError(400, "terminal receipt must be an object", "invalid_terminal_receipt");
}
const record = value;
if (record.schema !== void 0 && record.schema !== TERMINAL_RECEIPT_SCHEMA) {
throw new ProtocolError(400, `terminal receipt schema must be ${TERMINAL_RECEIPT_SCHEMA}`, "invalid_terminal_receipt");
}
const status = record.status;
if (!status || !VALID_TERMINAL_STATUSES.has(status)) {
throw new ProtocolError(
400,
`terminal receipt status must be one of: ${Array.from(VALID_TERMINAL_STATUSES).join(", ")}`,
"invalid_terminal_receipt"
);
}
const seat = requireString(record.seat, "seat", { max: 64 });
const runId = requireString(record.runId, "runId", { max: 128 });
const stageId = requireString(record.stageId, "stageId", { max: 128 });
const timestamp = requireString(record.timestamp, "timestamp", { max: 64 });
const host2 = requireString(record.host, "host", { max: 64 });
const model = requireString(record.model, "model", { max: 128 });
let evidence;
if (record.evidence !== void 0) {
if (!record.evidence || typeof record.evidence !== "object" || Array.isArray(record.evidence)) {
throw new ProtocolError(400, "terminal receipt evidence must be an object", "invalid_terminal_receipt");
}
evidence = record.evidence;
}
let metrics;
if (record.metrics !== void 0) {
if (!record.metrics || typeof record.metrics !== "object" || Array.isArray(record.metrics)) {
throw new ProtocolError(400, "terminal receipt metrics must be an object", "invalid_terminal_receipt");
}
metrics = record.metrics;
}
const escalationReason = optionalString(record.escalationReason, "escalationReason", 1024);
const ruling = optionalString(record.ruling, "ruling", 2048);
return {
schema: TERMINAL_RECEIPT_SCHEMA,
status,
seat,
runId,
stageId,
timestamp,
host: host2,
model,
...evidence ? { evidence } : {},
...metrics ? { metrics } : {},
...escalationReason ? { escalationReason } : {},
...ruling ? { ruling } : {}
};
}
// plugins/kxm/src/project-config.ts
var import__ = __toESM(require__(), 1);
import { existsSync as existsSync2, lstatSync, readFileSync, readdirSync, realpathSync } from "node:fs";
import { basename, dirname as dirname2, extname, isAbsolute, join as join2, relative, resolve, sep } from "node:path";
// plugins/kxm/src/restricted-yaml.mjs
var import_yaml = __toESM(require_dist(), 1);
var KXM_YAML_LIMITS = Object.freeze({
maxDocumentBytes: 256 * 1024,
maxDepth: 32,
maxScalarBytes: 64 * 1024,
maxCollectionItems: 4096,
maxTotalNodes: 16384,
maxKeys: 8192
});
// plugins/kxm/src/policy-draft.mjs
var POLICY_DRAFT_PURPOSES = Object.freeze([
"writer",
"planner",
"reviewer-arch",
"reviewer-cli",
"experiment"
]);
var POLICY_DRAFT_PERMISSIONS = Object.freeze(["edit", "read-only"]);
var POLICY_DRAFT_STATUSES = Object.freeze(["admitted", "candidate", "retired"]);
var EFFORTS = Object.freeze(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
var MODES = Object.freeze(["headless", "interactive", "either"]);
var MODEL_KEYS = Object.freeze([
"schema",
"id",
"aliases",
"harness",
"model",
"vendor",
"status",
"permissions",
"origin",
"thinking",
"tags",
"capabilities",
"priority",
"fallbacks",
"limits"
]);
var ROLE_KEYS = Object.freeze([
"schema",
"id",
"purpose",
"permission",
"description",
"extends",
"roster",
"skills",
"tools",
"produces",
"consumes",
"policy"
]);
var ORIGIN_KEYS = Object.freeze(["source", "sha256"]);
var LIMIT_KEYS = Object.freeze(["contextTokens", "outputTokens", "timeoutMs"]);
var TOOL_KEYS = Object.freeze(["preset", "allow", "deny"]);
var TEMPLATE_KEYS = Object.freeze(["template", "schema"]);
var POLICY_KEYS = Object.freeze(["vendorIndependenceRequired", "maxTransitions", "requiresGateVerification", "fallback"]);
var FALLBACK_KEYS = Object.freeze(["onError", "maxSwitches", "revert"]);
var FALLBACK_ERRORS = Object.freeze(["rate_limit", "transport", "provider_unavailable", "context_overflow"]);
var FALLBACK_REVERT = Object.freeze(["next_run", "never"]);
var ROSTER_ENTRY_KEYS = Object.freeze(["route", "effort", "mode"]);
var CRITIC_PURPOSES = Object.freeze(["reviewer-arch", "reviewer-cli"]);
// plugins/kxm/src/workforce-names.mjs
var import_yaml2 = __toESM(require_dist(), 1);
var ROLE_IDS = Object.freeze([
"writer",
"planner",
"reviewer-arch",
"reviewer-cli",
"experiment"
]);
var ROUTE_RENAMES = Object.freeze([
["grok-native", "grok-grok-4-7"],
["qwen-openrouter-pi", "pi-qwen3-coder-plus-openrouter"],
["gemini-agy", "agy-gemini-3-8-flash-high"],
["fable-claude", "claude-fable"],
["sol-codex", "codex-gpt-5-6-sol"],
["grok-default", "grok-grok-4-6"],
["fable-default", "claude-fable"]
]);
var AGENT_RENAMES = Object.freeze([
["coordinator", "planner"],
["implementer", "writer"],
["critic-arch", "reviewer-arch"],
["critic-cli", "reviewer-cli"]
]);
var WORKFLOW_RENAMES = Object.freeze([
["implement-only", "writer-only"],
["review-arch-only", "reviewer-arch-only"],
["review-cli-only", "reviewer-cli-only"]
]);
var STEP_RENAMES = Object.freeze([
["implement", "writer"],
["critic-arch", "reviewer-arch"],
["review-arch", "reviewer-arch"],
["critic-cli", "reviewer-cli"],
["review-cli", "reviewer-cli"]
]);
var RENAMES = Object.freeze({
route: ROUTE_RENAMES,
agent: AGENT_RENAMES,
workflow: WORKFLOW_RENAMES,
step: STEP_RENAMES
});
// plugins/kxm/src/template.ts
var import_yaml3 = __toESM(require_dist(), 1);
// plugins/kxm/src/repo-root.ts
import { existsSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
var ROOT_MARKERS = ["scripts/kxm-hub.mjs", "scripts/kxm.mjs"];
var MAX_WALK_DEPTH = 10;
function tryFindKxmRepoRoot(fromUrl = import.meta.url) {
let dir = dirname(fileURLToPath(fromUrl));
for (let depth = 0; depth < MAX_WALK_DEPTH; depth += 1) {
if (ROOT_MARKERS.some((marker) => existsSync(join(dir, marker)))) return dir;
const parent = dirname(dir);
if (parent === dir) break;
dir = parent;
}
return void 0;
}
function findKxmRepoRoot(fromUrl = import.meta.url) {
const found = tryFindKxmRepoRoot(fromUrl);
if (found !== void 0) return found;
throw new Error(
`kxm: cannot locate the KXM repo root from ${fileURLToPath(fromUrl)} (walked ${MAX_WALK_DEPTH} levels looking for ${ROOT_MARKERS[0]})`
);
}
// plugins/kxm/src/oneshot-process.ts
var OUTPUT_LIMIT = 8 * 1024 * 1024;
// plugins/kxm/src/harness.ts
var NATIVE_HARNESS_PROVIDERS = Object.freeze({
claude: "anthropic",
codex: "openai",
grok: "xai",
agy: "google",
kimi: "moonshot",
deepseek: "deepseek"
});
var PI_ALLOWED_PROVIDERS = Object.freeze([
"openrouter",
"nous-portal",
"nous",
"nous-proxy"
]);
var PI_NATIVE_BRAKE_PROVIDERS = Object.freeze([
"anthropic",
"openai",
"xai",
"moonshot",
"google",
"deepseek"
]);
var PI_VENDOR_OWNED_PROVIDERS = Object.freeze({
"openai-codex": "openai",
moonshotai: "moonshot",
"moonshotai-cn": "moonshot",
"kimi-coding": "moonshot",
"google-vertex": "google",
// Claude subscription via the Agent SDK: experiment-only, never a product route.
"claude-bridge": "anthropic",
// The decided Google route, for Gemini ids only (see PI_ANTIGRAVITY_MODEL_ID).
antigravity: "google"
});
var PI_VENDOR_SEGMENT_ALIASES = Object.freeze({
"x-ai": "xai",
moonshotai: "moonshot",
"google-ai": "google"
});
function reportedModelId(value) {
return typeof value === "string" && /^[a-z0-9][a-z0-9._:/-]{0,199}$/i.test(value) ? value : void 0;
}
function parseClaudeOneShotUsage(stdout, stderr, requestedModel) {
const trimmed = stdout.trim();
if (!trimmed) {
return {
text: "",
isError: true,
errorMessage: stderr.trim() || "empty stdout from claude"
};
}
try {
const payload = JSON.parse(trimmed);
const usage = payload.usage ?? {};
const entries = payload.modelUsage && typeof payload.modelUsage === "object" && !Array.isArray(payload.modelUsage) ? Object.entries(payload.modelUsage).filter(([, value]) => value && typeof value === "object") : [];
const matches = entries.filter(([model]) => model === requestedModel || requestedModel && (model.startsWith(`${requestedModel}-`) || model.startsWith(`claude-${requestedModel}-`)));
const selected = matches.length === 1 ? matches[0] : entries.length === 1 ? entries[0] : void 0;
const modelUsageDetail = selected?.[1];
const effectiveModel = reportedModelId(payload.model) ?? reportedModelId(selected?.[0]);
const tokensIn = (typeof usage.input_tokens === "number" ? usage.input_tokens : void 0) ?? (typeof modelUsageDetail?.inputTokens === "number" ? modelUsageDetail.inputTokens : null);
const tokensOut = (typeof usage.output_tokens === "number" ? usage.output_tokens : void 0) ?? (typeof modelUsageDetail?.outputTokens === "number" ? modelUsageDetail.outputTokens : null);
const cacheReadTokens = (typeof usage.cache_read_input_tokens === "number" ? usage.cache_read_input_tokens : void 0) ?? (typeof modelUsageDetail?.cacheReadInputTokens === "number" ? modelUsageDetail.cacheReadInputTokens : null);
const cacheWriteTokens = (typeof usage.cache_creation_input_tokens === "number" ? usage.cache_creation_input_tokens : void 0) ?? (typeof modelUsageDetail?.cacheCreationInputTokens === "number" ? modelUsageDetail.cacheCreationInputTokens : null);
const costUsd = typeof payload.total_cost_usd === "number" ? payload.total_cost_usd : typeof modelUsageDetail?.costUSD === "number" ? modelUsageDetail.costUSD : null;
const isError = Boolean(payload.is_error || payload.error || ["error", "aborted", "failed", "max_tokens", "length"].includes(String(payload.stopReason ?? payload.stop_reason ?? "")));
const text2 = typeof payload.result === "string" ? payload.result : typeof payload.text === "string" ? payload.text : "";
const errorMessage = isError ? typeof payload.error === "string" ? payload.error : typeof payload.error?.message === "string" ? payload.error.message : text2 : void 0;
return {
text: text2,
effectiveModel,
isError,
errorMessage,
usage: {
tokensIn,
tokensOut,
cacheReadTokens,
cacheWriteTokens,
contextTokens: null,
costUsd
}
};
} catch {
return {
text: trimmed,
isError: true,
errorMessage: "invalid Claude JSON response",
usage: {}
};
}
}
function parseGrokOneShotUsage(stdout, stderr, requestedModel) {
return parseClaudeOneShotUsage(stdout, stderr, requestedModel);
}
function parseCodexOneShotUsage(stdout, stderr) {
const lines = stdout.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
if (lines.length === 0) {
return {
text: "",
isError: true,
errorMessage: stderr.trim() || "empty stdout from codex"
};
}
const events = [];
for (const line of lines) {
try {
const parsed = JSON.parse(line);
if (parsed && typeof parsed === "object") events.push(parsed);
} catch {
}
}
const messageTexts = [];
let usage;
let hasError = false;
let errorMessage;
for (const ev of events) {
if (ev.type === "turn.failed" || ev.type === "error") {
hasError = true;
errorMessage = typeof ev.message === "string" ? ev.message : typeof ev.error?.message === "string" ? ev.error.message : "turn_failed";
}
if (ev.type === "item.completed" && ev.item && typeof ev.item === "object" && ev.item.type === "agent_message") {
const t = ev.item.text;
if (typeof t === "string") messageTexts.push(t);
}
if (ev.type === "turn.completed" && ev.usage && typeof ev.usage === "object") {
usage = ev.usage;
}
}
const text2 = (messageTexts.at(-1) ?? "").trim();
if (!events.some((event) => event.type === "turn.completed") || !text2) hasError = true;
const tokensIn = typeof usage?.input_tokens === "number" ? usage.input_tokens : null;
const tokensOut = typeof usage?.output_tokens === "number" ? usage.output_tokens : null;
const cacheReadTokens = typeof usage?.cached_input_tokens === "number" ? usage.cached_input_tokens : null;
const cacheWriteTokens = typeof usage?.cache_write_input_tokens === "number" ? usage.cache_write_input_tokens : null;
return {
text: text2,
isError: hasError,
errorMessage,
usage: {
tokensIn,
tokensOut,
cacheReadTokens,
cacheWriteTokens,
contextTokens: null,
costUsd: null
}
};
}
function parsePiOneShotUsage(stdout, _stderr) {
let finalMessage;
for (const line of stdout.split("\n")) {
const trimmed = line.trim();
if (!trimmed.startsWith("{")) continue;
try {
const event = JSON.parse(trimmed);
if (event.type !== "message_end" && event.type !== "turn_end") continue;
const message = event.message;
if (!message || message.role !== "assistant") continue;
finalMessage = message;
} catch {
}
}
if (!finalMessage) {
return { text: "", isError: true, usage: {} };
}
const content = Array.isArray(finalMessage.content) ? finalMessage.content : [];
const text2 = content.map((part) => part && typeof part === "object" && part.type === "text" ? String(part.text ?? "") : "").filter((part) => part.length > 0).join("\n");
const effectiveModel = reportedModelId(finalMessage.model);
const rawUsage = finalMessage.usage;
const usage = rawUsage && typeof rawUsage === "object" ? {
tokensIn: typeof rawUsage.input === "number" ? rawUsage.input : null,
tokensOut: typeof rawUsage.output === "number" ? rawUsage.output : null,
cacheReadTokens: typeof rawUsage.cacheRead === "number" ? rawUsage.cacheRead : null,
cacheWriteTokens: typeof rawUsage.cacheWrite === "number" ? rawUsage.cacheWrite : null,
contextTokens: null,
costUsd: null
} : {};
const stopReason = typeof finalMessage.stopReason === "string" ? finalMessage.stopReason : void 0;
const terminalError = stopReason === "error" || stopReason === "aborted";
if (terminalError || text2.length === 0) {
return { text: text2, isError: true, ...effectiveModel !== void 0 ? { effectiveModel } : {}, usage };
}
return { text: text2, ...effectiveModel !== void 0 ? { effectiveModel } : {}, usage };
}
function parseGenericOneShotUsage(stdout, _stderr) {
const trimmed = stdout.trim();
try {
const parsed = JSON.parse(trimmed);
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
const rec = parsed;
const text2 = typeof rec.result === "string" ? rec.result : typeof rec.text === "string" ? rec.text : typeof rec.response === "string" ? rec.response : trimmed;
const u = rec.usage && typeof rec.usage === "object" ? rec.usage : {};
return { text: text2, effectiveModel: reportedModelId(rec.model), isError: Boolean(rec.is_error || rec.error || rec.success === false), usage: {
tokensIn: typeof u.input_tokens === "number" ? u.input_tokens : null,
tokensOut: typeof u.output_tokens === "number" ? u.output_tokens : null,
cacheReadTokens: typeof u.cache_read_input_tokens === "number" ? u.cache_read_input_tokens : null,
cacheWriteTokens: typeof u.cache_creation_input_tokens === "number" ? u.cache_creation_input_tokens : null,
contextTokens: null,
costUsd: typeof rec.total_cost_usd === "number" ? rec.total_cost_usd : null
} };
}
} catch {
}
return { text: trimmed, usage: {} };
}
function parseKimiOneShotUsage(stdout, _stderr) {
const trimmed = stdout.trim();
const assistantTexts = [];
let isError = false;
let errorMessage;
for (const line of trimmed.split("\n")) {
const lineTrimmed = line.trim();
if (!lineTrimmed) continue;
try {
const parsed = JSON.parse(lineTrimmed);
if (parsed && typeof parsed === "object") {
const rec = parsed;
if (rec.role === "assistant" && typeof rec.content === "string") {
assistantTexts.push(rec.content);
} else if (rec.role === "error" || rec.type === "error") {
isError = true;
errorMessage = typeof rec.message === "string" ? rec.message : typeof rec.content === "string" ? rec.content : "kimi_error";
}
}
} catch {
}
}
const text2 = assistantTexts.length > 0 ? assistantTexts.join("\n") : trimmed;
return {
text: text2,
isError,
errorMessage,
usage: {
tokensIn: null,
tokensOut: null,
cacheReadTokens: null,
cacheWriteTokens: null,
contextTokens: null,
costUsd: null
}
};
}
function parseAgyOneShotUsage(stdout, _stderr) {
const trimmed = stdout.trim();
try {
const parsed = JSON.parse(trimmed);
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
const rec = parsed;
const text2 = typeof rec.response === "string" ? rec.response : typeof rec.result === "string" ? rec.result : trimmed;
const isError = rec.status === "ERROR";
const rawError = rec.error;
const errorMessage = isError ? typeof rawError === "string" ? rawError : typeof rawError?.message === "string" ? rawError.message : "agy_error" : void 0;
const usageRec = rec.usage && typeof rec.usage === "object" ? rec.usage : {};
const tokensIn = typeof usageRec.input_tokens === "number" ? usageRec.input_tokens : null;
const tokensOut = typeof usageRec.output_tokens === "number" ? usageRec.output_tokens : null;
const cacheReadTokens = typeof usageRec.cache_read_tokens === "number" ? usageRec.cache_read_tokens : null;
const contextTokens = typeof usageRec.total_tokens === "number" ? usageRec.total_tokens : tokensIn;
return {
text: text2,
isError,
errorMessage,
usage: {
tokensIn,
tokensOut,
cacheReadTokens,
cacheWriteTokens: null,
contextTokens,
costUsd: null
}
};
}
} catch {
}
return {
text: trimmed,
usage: {
tokensIn: null,
tokensOut: null,
cacheReadTokens: null,
cacheWriteTokens: null,
contextTokens: null
}
};
}
var READ_ONLY_ONESHOT_ARGS = Object.freeze({
// pi: total containment for a one-shot witness — no tools (built-in, extension and
// custom), no ambient extension/hook discovery, no skills, no prompt templates, no
// AGENTS.md/CLAUDE.md context discovery, and an ephemeral session. `--no-tools` alone
// is not enough: extensions and hooks can still run with their own permissions.
pi: Object.freeze(["--no-tools", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-context-files", "--no-session"]),
omp: Object.freeze(["--no-tools", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-context-files", "--no-session"]),
claude: Object.freeze(["--tools", "Read,Glob,Grep", "--restricted", "--safe-mode", "--permission-mode", "plan", "--permission-prompts", "none", "--strict-mcp-config", "--mcp-config", '{"mcpServers":{}}', "--disable-slash-commands", "--no-session-persistence"]),
codex: Object.freeze(["--sandbox", "read-only", "--ignore-user-config", "-c", 'approval_policy="never"']),
grok: Object.freeze(["--sandbox", "read-only", "--permission-mode", "plan", "--tools", "Read,Glob,Grep", "--no-subagents", "--disable-web-search"]),
agy: Object.freeze(["--mode", "plan", "--sandbox", "--disable-slash-commands"]),
kimi: Object.freeze(["--plan"])
});
function oneShotReadOnlyArgs(harness) {
return Object.hasOwn(READ_ONLY_ONESHOT_ARGS, harness) ? READ_ONLY_ONESHOT_ARGS[harness] : void 0;
}
var WRITER_ONESHOT_ARGS = Object.freeze({
pi: Object.freeze(["-a", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session"]),
omp: Object.freeze(["-a", "--no-extensions", "--no-skills", "--no-prompt-templates", "--no-session"]),
grok: Object.freeze(["--always-approve", "--no-subagents", "--disable-web-search"])
});
var BUILTIN_HARNESSES = Object.freeze([
{
id: "pi",
label: "Pi",
default: true,
mode: "headless",
commands: ["pi"],
versionArgs: ["--version"],
update: {
self: ["update", "--self"],
extensions: ["update", "--extensions"],
models: ["update", "--models"]
},
oneShot: {
argv: ["-p", "--mode", "json"],
promptVia: "arg",
outputFormat: "json",
usageParser: parsePiOneShotUsage
}
},
{
id: "omp",
label: "Oh My Pi",
default: false,
mode: "headless",
commands: ["omp"],
versionArgs: ["--version"],
authArgs: ["models", "--json"],
update: {
self: ["update"],
extensions: ["plugin", "upgrade"],
models: ["models", "refresh"]
},
oneShot: {
argv: ["-p", ...oneShotReadOnlyArgs("omp"), "--mode", "json"],
promptVia: "arg",
outputFormat: "json",
usageParser: parsePiOneShotUsage
}
},
{
id: "claude",
label: "Claude Code",
default: false,
mode: "either",
commands: ["claude"],
versionArgs: ["--version"],
authArgs: ["auth", "status"],
update: {
self: ["update"],
extensions: ["plugin", "update", "kxm", "-y"]
},
oneShot: {
argv: ["-p", ...oneShotReadOnlyArgs("claude"), "--output-format", "json"],
promptVia: "stdin",
outputFormat: "json",
usageParser: parseClaudeOneShotUsage
}
},
{
id: "kimi",
label: "Kimi Code",
default: false,
mode: "either",
commands: ["kimi"],
versionArgs: ["--version"],
authArgs: ["provider", "list"],
update: { self: ["upgrade"] },
oneShot: {
argv: [...oneShotReadOnlyArgs("kimi"), "--output-format", "stream-json", "-p"],
promptVia: "arg",
outputFormat: "stream-json",
usageParser: parseKimiOneShotUsage
}
},
{
id: "codex",
label: "Codex",
default: false,
mode: "either",
commands: ["codex"],
versionArgs: ["--version"],
authArgs: ["login", "status"],
update: { self: ["update"] },
oneShot: {
argv: ["exec", ...oneShotReadOnlyArgs("codex"), "--json", "-"],
promptVia: "stdin",
outputFormat: "json",
usageParser: parseCodexOneShotUsage
}
},
{
id: "deepseek",
label: "DeepSeek",
default: false,
mode: "either",
commands: ["deepseek"],
versionArgs: ["--version"],
update: { self: ["update"] },
oneShot: {
argv: ["--json"],
promptVia: "stdin",
outputFormat: "json",
usageParser: parseGenericOneShotUsage
}
},
{
id: "grok",
label: "Grok CLI",
default: false,
mode: "either",
commands: ["grok"],
versionArgs: ["--version"],
authArgs: ["models"],
update: { self: ["update"] },
oneShot: {
argv: [...oneShotReadOnlyArgs("grok"), "--output-format", "json", "--single"],
promptVia: "arg",
outputFormat: "json",
usageParser: parseGrokOneShotUsage
}
},
{
id: "agy",
label: "Antigravity CLI",
default: false,
mode: "either",
commands: ["agy"],
versionArgs: ["--version"],
authArgs: ["models"],
update: { self: ["update"] },
oneShot: {
argv: [...oneShotReadOnlyArgs("agy"), "--output-format", "json", "-p"],
promptVia: "arg",
outputFormat: "json",
usageParser: parseAgyOneShotUsage
}
}
]);
var BUILTIN_HARNESS_IDS = BUILTIN_HARNESSES.map((entry) => entry.id);
var WIN_NPM_INNER_EXE = Object.freeze({
claude: Object.freeze(["node_modules", "@anthropic-ai", "claude-code", "bin", "claude.exe"])
});
// plugins/kxm/src/project-config.ts
var KxmConfigError = class extends Error {
issues;
constructor(issues) {
const sorted = sortIssues(issues);
super(sorted.map((issue2) => `${issue2.file}: ${issue2.code}: ${issue2.message}`).join("\n"));
this.name = "KxmConfigError";
this.issues = sorted;
}
};
function defaultKxmSchemaDir() {
return join2(findKxmRepoRoot(import.meta.url), "schemas");
}
var DEFAULT_SCHEMA_DIR = defaultKxmSchemaDir();
var RESOURCE_SCHEMA = Object.freeze({
project: { identity: "kxm.project.v1", file: "project.schema.json" },
repository: { identity: "kxm.repository.v1", file: "repository.schema.json" },
agent: { identity: "kxm.agent.v1", file: "agent.schema.json" },
model: { identity: "kxm.model.v2", file: "model.schema.json" },
role: { identity: "kxm.role.v2", file: "role.schema.json" },
environment: { identity: "kxm.environment.v1", file: "environment.schema.json" },
workflow: { identity: "kxm.workflow.v1", file: "workflow.schema.json" },
"gate-registry": { identity: "kxm.gate-registry.v1", file: "gate-registry.schema.json" }
});
var TOOL_PRESET_PROFILES = Object.freeze({
coordinator: "read-only",
"read-only": "read-only",
"workspace-writer": "edit",
"tests-writer": "edit"
});
var BUILTIN_TOOL_PRESETS = Object.keys(TOOL_PRESET_PROFILES);
function compareCodeUnits(left, right) {
return left < right ? -1 : left > right ? 1 : 0;
}
function sortIssues(issues) {
return [...issues].sort((left, right) => compareCodeUnits(left.file, right.file) || compareCodeUnits(left.phase, right.phase) || compareCodeUnits(left.code, right.code) || compareCodeUnits(left.message, right.message));
}
function issue(phase, code, file, message) {
return { phase, code, file, message };
}
function readJsonObject(file) {
const parsed = JSON.parse(readFileSync(file, "utf8"));
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`${file} is not a JSON object`);
return parsed;
}
var KxmSchemaRegistry = class {
schemasDir;
ajv;
validators = /* @__PURE__ */ new Map();
localBindingsValidator;
templateProvenanceValidator;
initOperationValidator;
permissionDiffValidator;
runEventValidator;
driveReceiptValidator;
coordinatorValidator;
intakeMessageValidator;
syncEventValidator;
constructor(schemasDir = DEFAULT_SCHEMA_DIR) {
this.schemasDir = resolve(schemasDir);
this.ajv = new import__.Ajv2020({ allErrors: true, strict: true, strictRequired: false });
const common = readJsonObject(join2(this.schemasDir, "common.schema.json"));
this.ajv.addSchema(common);
for (const definition of Object.values(RESOURCE_SCHEMA)) {
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, definition.file)));
}
const localBindingsFile = "local-repository-bindings.schema.json";
const templateProvenanceFile = "template-provenance.schema.json";
const initOperationFile = "init-operation.schema.json";
const permissionDiffFile = "permission-diff.schema.json";
const runEventFile = "run-event.schema.json";
const driveReceiptFile = "drive-receipt.schema.json";
const coordinatorFile = "coordinator.schema.json";
const intakeMessageFile = "intake-message.schema.json";
const syncEventFile = "sync-event.schema.json";
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, localBindingsFile)));
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, templateProvenanceFile)));
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, initOperationFile)));
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, permissionDiffFile)));
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, runEventFile)));
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, driveReceiptFile)));
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, coordinatorFile)));
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, intakeMessageFile)));
this.ajv.addSchema(readJsonObject(join2(this.schemasDir, syncEventFile)));
for (const [kind, definition] of Object.entries(RESOURCE_SCHEMA)) {
const validator = this.ajv.getSchema(`https://schemas.kxm.dev/${definition.file}`);
if (!validator) throw new Error(`schema did not compile: ${definition.file}`);
this.validators.set(kind, validator);
}
const localBindingsValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${localBindingsFile}`);
const templateProvenanceValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${templateProvenanceFile}`);
const initOperationValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${initOperationFile}`);
const permissionDiffValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${permissionDiffFile}`);
const runEventValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${runEventFile}`);
const driveReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${driveReceiptFile}`);
const coordinatorValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${coordinatorFile}`);
const intakeMessageValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${intakeMessageFile}`);
const syncEventValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${syncEventFile}`);
if (!localBindingsValidator) throw new Error(`schema did not compile: ${localBindingsFile}`);
if (!templateProvenanceValidator) throw new Error(`schema did not compile: ${templateProvenanceFile}`);
if (!initOperationValidator) throw new Error(`schema did not compile: ${initOperationFile}`);
if (!permissionDiffValidator) throw new Error(`schema did not compile: ${permissionDiffFile}`);
if (!runEventValidator) throw new Error(`schema did not compile: ${runEventFile}`);
if (!driveReceiptValidator) throw new Error(`schema did not compile: ${driveReceiptFile}`);
if (!coordinatorValidator) throw new Error(`schema did not compile: ${coordinatorFile}`);
if (!intakeMessageValidator) throw new Error(`schema did not compile: ${intakeMessageFile}`);
if (!syncEventValidator) throw new Error(`schema did not compile: ${syncEventFile}`);
this.localBindingsValidator = localBindingsValidator;
this.templateProvenanceValidator = templateProvenanceValidator;
this.initOperationValidator = initOperationValidator;
this.permissionDiffValidator = permissionDiffValidator;
this.runEventValidator = runEventValidator;
this.driveReceiptValidator = driveReceiptValidator;
this.coordinatorValidator = coordinatorValidator;
this.intakeMessageValidator = intakeMessageValidator;
this.syncEventValidator = syncEventValidator;
}
validate(kind, value, file) {
const definition = RESOURCE_SCHEMA[kind];
if (value.schema !== definition.identity) {
return [issue("schema", "schema_identity_mismatch", file, `expected ${definition.identity}, received ${String(value.schema)}`)];
}
const validator = this.validators.get(kind);
if (!validator) throw new Error(`missing KXM validator for ${kind}`);
if (validator(value)) return [];
return (validator.errors ?? []).map((error) => schemaIssue(file, error));
}
validateLocalBindings(value, file) {
return this.validateAuxiliary(value, file, "kxm.local-repository-bindings.v1", this.localBindingsValidator);
}
validateTemplateProvenance(value, file) {
return this.validateAuxiliary(value, file, "kxm.template-provenance.v1", this.templateProvenanceValidator);
}
validateInitOperation(value, file) {
return this.validateAuxiliary(value, file, "kxm.init-operation.v1", this.initOperationValidator);
}
validatePermissionDiff(value, file) {
return this.validateAuxiliary(value, file, "kxm.permission-diff.v1", this.permissionDiffValidator);
}
validateDriveReceipt(value, file) {
return this.validateAuxiliary(value, file, "kxm.drive-receipt.v1", this.driveReceiptValidator);
}
validateAuxiliary(value, file, identity, validator) {
if (value.schema !== identity) {
return [issue("schema", "schema_identity_mismatch", file, `expected ${identity}, received ${String(value.schema)}`)];
}
if (validator(value)) return [];
return (validator.errors ?? []).map((error) => schemaIssue(file, error));
}
};
var cachedRunEventRegistry;
function syncEventSchemaErrors(value) {
const registry = cachedRunEventRegistry ??= new KxmSchemaRegistry();
if (registry.syncEventValidator(value)) return void 0;
return registry.ajv.errorsText(registry.syncEventValidator.errors, { separator: "; " });
}
function schemaIssue(file, error) {
const location = error.instancePath || "/";
const suffix = error.params && "additionalProperty" in error.params ? ` (${String(error.params.additionalProperty)})` : "";
return issue("schema", `schema_${error.keyword}`, file, `${location} ${error.message ?? "is invalid"}${suffix}`);
}
function kxmCanonicalJson(value) {
if (value === null || typeof value !== "object") return JSON.stringify(value);
if (Array.isArray(value)) return `[${value.map((candidate) => kxmCanonicalJson(candidate)).join(",")}]`;
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${kxmCanonicalJson(value[key])}`).join(",")}}`;
}
// plugins/kxm/src/sync-transform.ts
import { createHash } from "node:crypto";
// plugins/kxm/src/redact.ts
var SECRET_PATTERNS = [
/\bsk-[A-Za-z0-9_-]{8,}\b/g,
/\bsk-ant-[A-Za-z0-9_-]{8,}\b/g,
/\bghp_[A-Za-z0-9_]{20,}\b/g,
/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,
/\bxox[baprs]-[A-Za-z0-9-]{10,}\b/gi,
/\bBearer\s+[A-Za-z0-9._~+/=-]+\b/gi,
/\bya29\.[A-Za-z0-9._~+/-]+=*/g,
/\b1\/\/[A-Za-z0-9_-]+/g,
/\b1\/[A-Za-z0-9_-]{20,}/g,
/("?(?:access_token|refresh_token|id_token|sessionKey|session_key|claude_oauth_token|anthropicApiKey)"?\s*[:=]\s*")[^"]*(")/gi,
/\bKXM_[A-Z0-9_]*(TOKEN|SECRET|KEY)[A-Z0-9_]*=\S+/gi,
/\b(GITHUB_TOKEN|GH_TOKEN|KXM_AUTH_TOKEN|KXM_WORKFLOW_SIGNAL_SECRET|ANTHROPIC_API_KEY|ANTHROPIC_AUTH_TOKEN|CLAUDE_API_KEY)=\S+/gi,
/\b[A-Fa-f0-9]{64}\b/g
];
function redactSecrets(value) {
let result = value;
for (const pattern of SECRET_PATTERNS) {
result = result.replace(pattern, "[redacted]");
}
return result;
}
function redactStringList(values, maxItems = 32) {
return values.slice(0, maxItems).map((value) => redactSecrets(value).slice(0, 500));
}
// plugins/kxm/src/sync-transform.ts
var KXM_DEFAULT_SYNC_POLICY = Object.freeze({
prompts: "title-only",
results: "bounded-summary",
evidence: "references",
artifacts: "metadata",
fileChanges: "paths-only",
rawLogs: false,
diffs: false,
environmentValues: false
});
var KXM_DEFAULT_SYNC_POLICY_REVISION = `sha256:${createHash("sha256").update(kxmCanonicalJson(KXM_DEFAULT_SYNC_POLICY), "utf8").digest("hex")}`;
var SCALAR_FIELDS = [
"workflowId",
"promptHash",
"status",
"previousStatus",
"outcome",
"stepId",
"stepAttempt",
"fromStepId",
"toStepId",
"assignmentId",
"attemptId",
"agentId",
"instanceNo",
"scopeEpoch",
"resolutionAction"
];
var CARRIED_FIELDS = /* @__PURE__ */ new Set([
...SCALAR_FIELDS,
"displayTitle",
"summary",
"reason",
"executor",
"model",
"timing",
"usage",
"evidenceRefs",
"artifacts",
"receipt",
"error",
"effect",
"lease",
"actor",
"resolvedBy",
"suppliedRefs",
"counts"
]);
function kxmSyncEventHash(bytes) {
return `sha256:${createHash("sha256").update(bytes, "utf8").digest("hex")}`;
}
// plugins/kxm/src/diagnostics.ts
function workflowScopeExtras(operation, assignedCoordinatorName) {
return {
operation,
assignedCoordinatorName,
nextAction: "use_assigned_coordinator"
};
}
// plugins/kxm/src/commands.ts
import { createHash as createHash3, randomUUID as randomUUID2, timingSafeEqual } from "node:crypto";
// plugins/kxm/src/workflow.ts
import { createHash as createHash2, createHmac } from "node:crypto";
// plugins/kxm/src/relevance.ts
var RELEVANCE_STOPWORDS = Object.freeze(/* @__PURE__ */ new Set([
"a",
"an",
"and",
"are",
"as",
"at",
"be",
"been",
"but",
"by",
"can",
"could",
"did",
"do",
"does",
"for",
"from",
"had",
"has",
"have",
"how",
"if",
"in",
"into",
"is",
"it",
"its",
"of",
"on",
"or",
"our",
"should",
"so",
"than",
"that",
"the",
"their",
"them",
"then",
"there",
"these",
"they",
"this",
"those",
"to",
"was",
"we",
"were",
"what",
"when",
"where",
"which",
"while",
"who",
"why",
"will",
"with",
"would",
"you",
"your"
]));
var RELEVANCE_K1 = 1.2;
var RELEVANCE_B = 0.75;
var MIN_TOKEN_CHARS = 2;
var MAX_TOKEN_CHARS = 64;
function foldPlural(token) {
if (new RegExp("^\\p{N}+$", "u").test(token)) return token;
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
if (token.length > 4 && token.endsWith("sses")) return token.slice(0, -2);
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is")) {
return token.slice(0, -1);
}
return token;
}
function relevanceTokens(text2) {
const tokens = [];
for (const raw of text2.normalize("NFKC").toLowerCase().split(/[^\p{L}\p{N}]+/u)) {
if (raw.length < MIN_TOKEN_CHARS || raw.length > MAX_TOKEN_CHARS) continue;
if (RELEVANCE_STOPWORDS.has(raw)) continue;
tokens.push(foldPlural(raw));
}
return tokens;
}
function scoreRelevance(query, documents) {
const scores = documents.map(() => 0);
const terms = [...new Set(relevanceTokens(query))];
if (terms.length === 0 || documents.length === 0) return scores;
const indexed = documents.map((document) => {
const tokens = relevanceTokens(document);
const frequencies = /* @__PURE__ */ new Map();
for (const token of tokens) frequencies.set(token, (frequencies.get(token) ?? 0) + 1);
return { length: tokens.length, frequencies };
});
const count = indexed.length;
let totalLength = 0;
for (const document of indexed) totalLength += document.length;
const averageLength = totalLength > 0 ? totalLength / count : 1;
const inverseFrequency = /* @__PURE__ */ new Map();
for (const term of terms) {
let documentFrequency = 0;
for (const document of indexed) {
if (document.frequencies.has(term)) documentFrequency += 1;
}
inverseFrequency.set(term, Math.log(1 + (count - documentFrequency + 0.5) / (documentFrequency + 0.5)));
}
indexed.forEach((document, index) => {
let score = 0;
for (const term of terms) {
const frequency = document.frequencies.get(term) ?? 0;
if (frequency === 0) continue;
const lengthNorm = 1 - RELEVANCE_B + RELEVANCE_B * (document.length / averageLength);
score += inverseFrequency.get(term) * (frequency * (RELEVANCE_K1 + 1) / (frequency + RELEVANCE_K1 * lengthNorm));
}
scores[index] = score;
});
return scores;
}
function roundRelevance(score) {
return Math.round(score * 1e3) / 1e3;
}
function contextItemRelevanceText(item) {
return item.stateKey !== void 0 ? `${item.summary} ${item.stateKey}` : item.summary;
}
function compareCodeUnitIds(left, right) {
return left < right ? -1 : left > right ? 1 : 0;
}
function rankRecall(query, items, limit) {
const needle = query.toLowerCase();
const scores = scoreRelevance(query, items.map(contextItemRelevanceText));
const ranked = [];
items.forEach((item, index) => {
const score = scores[index] ?? 0;
const phraseHit = needle === "" || item.summary.toLowerCase().includes(needle) || (item.stateKey ?? "").toLowerCase().includes(needle);
if (phraseHit || score > 0) ranked.push({ item, score, phraseHit });
});
ranked.sort(
(left, right) => (right.phraseHit ? 1 : 0) - (left.phraseHit ? 1 : 0) || right.score - left.score || compareCodeUnitIds(left.item.id, right.item.id)
);
return ranked.slice(0, limit).map(({ item, score }) => ({ item, relevance: roundRelevance(score) }));
}
// plugins/kxm/src/workflow.ts
var JOURNAL_CATEGORIES = [
"plan",
"decision",
"contradiction",
"error",
"lesson",
"observation",
"hypothesis",
"experiment",
"state-change",
"skill-candidate"
];
var EVIDENCE_REQUIRED_JOURNAL_CATEGORIES = ["lesson", "skill-candidate"];
var PROMOTABLE_JOURNAL_CATEGORIES = ["skill-candidate", "hypothesis", "experiment"];
function parseJournalCategory(value) {
if (typeof value !== "string" || !JOURNAL_CATEGORIES.includes(value)) {
throw new ProtocolError(
400,
`invalid journal category: must be one of ${JOURNAL_CATEGORIES.join(", ")}`,
"invalid_journal_category"
);
}
return value;
}
function journalEvidenceRequired(category) {
return EVIDENCE_REQUIRED_JOURNAL_CATEGORIES.includes(category);
}
var WORKFLOW_TERMINAL_TARGET = "$terminal";
function normalizeOutcomeValue(value, field) {
if (typeof value === "string") return { target: value };
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new Error(`${field} must be a stage ID, "$terminal", or a { target, maxTransitions } rule`);
}
const rule = value;
if (typeof rule.target !== "string" || !rule.target.trim()) {
throw new Error(`${field}.target must be a non-empty stage ID or "$terminal"`);
}
if (rule.maxTransitions !== void 0 && (!Number.isInteger(rule.maxTransitions) || rule.maxTransitions < 1 || rule.maxTransitions > 100)) {
throw new Error(`${field}.maxTransitions must be an integer between 1 and 100`);
}
return { target: rule.target, ...rule.maxTransitions !== void 0 ? { maxTransitions: rule.maxTransitions } : {} };
}
function journalPromotionState(entry) {
if (!PROMOTABLE_JOURNAL_CATEGORIES.includes(entry.category)) return void 0;
const records = entry.promotion ?? [];
return records.length === 0 ? "proposed" : records[records.length - 1]?.to;
}
function applyJournalPromotion(entry, decision, decidedAt) {
if (!PROMOTABLE_JOURNAL_CATEGORIES.includes(entry.category)) {
throw new ProtocolError(
400,
`journal entries of category ${entry.category} do not participate in promotion`,
"journal_promotion_invalid"
);
}
if (decision.decidedBy === entry.agentId) {
throw new ProtocolError(
400,
"the author of a journal entry cannot decide its promotion",
"journal_promotion_invalid"
);
}
if (!Array.isArray(decision.evidenceRefs) || decision.evidenceRefs.length < 1 || decision.evidenceRefs.some((ref) => typeof ref !== "string" || !ref.trim())) {
throw new ProtocolError(
400,
"journal promotion requires at least one durable evidence reference",
"journal_promotion_invalid"
);
}
const current = journalPromotionState(entry);
if (current !== "proposed") {
throw new ProtocolError(
400,
`journal entry promotion already reached terminal state ${current}`,
"journal_promotion_invalid"
);
}
const record = {
schema: "kxm.journal-promotion.v1",
from: "proposed",
to: decision.to,
evidenceRefs: decision.evidenceRefs.map((ref) => ref.trim()),
decidedBy: decision.decidedBy,
reason: decision.reason,
decidedAt
};
return { ...entry, promotion: [...entry.promotion ?? [], record] };
}
function improvementReport(entries) {
const severityWeight = { error: 3, warning: 2, info: 1 };
return IMPROVEMENT_AREAS.map((area) => {
const matching = entries.filter((entry) => entry.area === area);
const priorities = [...matching].filter((entry) => entry.category === "error" || entry.category === "contradiction" || entry.category === "lesson" || entry.category === "skill-candidate").sort((left, right) => severityWeight[right.severity] - severityWeight[left.severity]).slice(0, 10);
return {
area,
total: matching.length,
errors: matching.filter((entry) => entry.category === "error").length,
contradictions: matching.filter((entry) => entry.category === "contradiction").length,
lessons: matching.filter((entry) => entry.category === "lesson").length,
priorities
};
}).filter((report) => report.total > 0);
}
var SECURITY_SIGNAL_CLASSES = ["invalid_auth", "invalid_identity", "signal_mismatch"];
var SIGNAL_CATEGORIES = ["error", "contradiction", "lesson", "skill-candidate"];
var SIGNAL_SEVERITY_WEIGHT = { error: 3, warning: 2, info: 1 };
var SIGNAL_CLASS = /^[a-z0-9_]{1,64}$/;
var MAX_SIGNAL_IDS = 16;
var MAX_SIGNAL_SUMMARY_KEY_CHARS = 160;
function normalizeSignalSummary(summary) {
return summary.toLowerCase().replace(/\b[a-z]+_[0-9a-f]{8,}\b/g, "<id>").replace(/\b\d{4}-\d{2}-\d{2}t\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:z|[+-]\d{2}:?\d{2})?/g, "<ts>").replace(/\b[0-9a-f]{7,}\b/g, "<hex>").replace(/\d+/g, "#").replace(/\s+/g, " ").trim().slice(0, MAX_SIGNAL_SUMMARY_KEY_CHARS);
}
function round3(value) {
return Math.round(value * 1e3) / 1e3;
}
function signalKeyOf(entry, runs) {
const classRef = entry.evidence.find((ref) => ref.startsWith("class:"));
const signalClass = classRef?.slice("class:".length);
if (signalClass !== void 0 && SIGNAL_CLASS.test(signalClass) && signalClass !== "unknown") {
return { key: `${entry.category}|class:${signalClass}`, basis: "class", signalClass };
}
const run = runs.get(entry.runId);
if (entry.category === "error" && entry.stageId !== void 0 && run) {
return { key: `error|stage:${run.definitionId}/${entry.stageId}`, basis: "stage" };
}
return {
key: `${entry.category}|summary:${normalizeSignalSummary(redactSecrets(entry.summary))}`,
basis: "summary"
};
}
function runAttemptCost(run) {
let attempts = 0;
for (const stage of run.stages) attempts += stage.attempts;
return Math.max(1, attempts + (run.transitions?.length ?? 0));
}
function rankImprovementSignals(entries, runs, limit = 20) {
const resolvedContradictions = /* @__PURE__ */ new Set();
for (const entry of entries) {
if (entry.category !== "decision" && entry.category !== "lesson") continue;
for (const related of entry.relatedEntryIds) resolvedContradictions.add(`${entry.runId}\0${related}`);
}
const groups = /* @__PURE__ */ new Map();
for (const entry of entries) {
if (!SIGNAL_CATEGORIES.includes(entry.category)) continue;
if (entry.category === "contradiction" && resolvedContradictions.has(`${entry.runId}\0${entry.id}`)) continue;
const promotionState = journalPromotionState(entry);
if (promotionState !== void 0 && promotionState !== "proposed") continue;
const { key, basis, signalClass } = signalKeyOf(entry, runs);
const group = groups.get(key);
if (group) group.entries.push(entry);
else groups.set(key, { basis, category: entry.category, ...signalClass !== void 0 ? { signalClass } : {}, entries: [entry] });
}
const areaRank = (area) => {
const index = IMPROVEMENT_AREAS.indexOf(area);
return index === -1 ? IMPROVEMENT_AREAS.length : index;
};
const signals = [];
for (const [key, group] of groups) {
const runIds = [...new Set(group.entries.map((entry) => entry.runId))].sort(compareCodeUnitIds);
const entryIds = group.entries.map((entry) => entry.id).sort(compareCodeUnitIds);
let severity = "info";
for (const entry of group.entries) {
if ((SIGNAL_SEVERITY_WEIGHT[entry.severity] ?? 0) > SIGNAL_SEVERITY_WEIGHT[severity]) severity = entry.severity;
}
const severityWeight = SIGNAL_SEVERITY_WEIGHT[severity];
const knownRuns = runIds.map((runId) => runs.get(runId)).filter((run) => run !== void 0);
const workflowCost = knownRuns.length > 0 ? knownRuns.reduce((total, run) => total + runAttemptCost(run), 0) / knownRuns.length : null;
const withEvidence = group.entries.filter((entry) => entry.evidence.length > 0).length;
const confidence = 0.5 + 0.5 * (withEvidence / group.entries.length);
const areaCounts = /* @__PURE__ */ new Map();
for (const entry of group.entries) areaCounts.set(entry.area, (areaCounts.get(entry.area) ?? 0) + 1);
const area = [...areaCounts].sort((left, right) => right[1] - left[1] || areaRank(left[0]) - areaRank(right[0]))[0][0];
const latest = [...group.entries].sort((left, right) => compareCodeUnitIds(left.createdAt, right.createdAt) || compareCodeUnitIds(left.id, right.id)).at(-1);
const security = area === "security" || group.signalClass !== void 0 && SECURITY_SIGNAL_CLASSES.includes(group.signalClass);
signals.push({
key,
basis: group.basis,
category: group.category,
area,
...security ? { overrideTier: "security" } : {},
frequency: runIds.length,
runIds: runIds.slice(0, MAX_SIGNAL_IDS),
entryIds: entryIds.slice(0, MAX_SIGNAL_IDS),
severity,
severityWeight,
workflowCost,
costBasis: workflowCost === null ? "unknown" : "run-attempts",
confidence,
priority: round3(runIds.length * severityWeight * (workflowCost ?? 1) * confidence),
summary: redactSecrets(latest.summary)
});
}
return signals.sort((left, right) => (right.overrideTier === "security" ? 1 : 0) - (left.overrideTier === "security" ? 1 : 0) || right.priority - left.priority || right.frequency - left.frequency || compareCodeUnitIds(left.key, right.key)).slice(0, limit);
}
function object(value, name) {
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${name} must be an object`);
return value;
}
function stringArray(value, name) {
if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || !item.trim())) {
throw new Error(`${name} must be an array of non-empty strings`);
}
return value.map((item) => item.trim());
}
function canonicalWorkflowEvidenceKey(value) {
return value.trim().replace(/\s+/gu, " ").toLowerCase();
}
function normalizeWorkflowEvidence(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
const normalized = /* @__PURE__ */ new Map();
for (const [requirement, candidate] of Object.entries(value)) {
const key = canonicalWorkflowEvidenceKey(requirement);
if (!key) continue;
const values = Array.isArray(candidate) ? candidate : [candidate];
const safeValues = values.filter((item) => typeof item === "string" && Boolean(item.trim())).map((item) => item.trim());
if (safeValues.length > 0) {
normalized.set(key, [.../* @__PURE__ */ new Set([...normalized.get(key) ?? [], ...safeValues])]);
}
}
return Object.fromEntries(normalized);
}
function normalizeVerifiedWorkflowEvidence(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
const result = /* @__PURE__ */ new Map();
for (const [rawRequirement, rawSnapshots] of Object.entries(value)) {
const requirement = canonicalWorkflowEvidenceKey(rawRequirement);
if (!requirement || !Array.isArray(rawSnapshots)) continue;
const snapshots = rawSnapshots.filter((candidate) => {
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return false;
const snapshot = candidate;
return snapshot.schema === "pi-mesh.verified-peer-evidence.v1" && typeof snapshot.messageId === "string" && typeof snapshot.producerId === "string" && typeof snapshot.producerName === "string" && snapshot.status === "replied" && typeof snapshot.requestSha256 === "string" && typeof snapshot.replySha256 === "string" && typeof snapshot.createdAt === "string" && typeof snapshot.replyCreatedAt === "string" && typeof snapshot.repliedAt === "string" && typeof snapshot.verifiedAt === "string" && snapshot.context?.schema === "pi-mesh.workflow-message-context.v1";
});
if (snapshots.length) result.set(requirement, snapshots);
}
return Object.fromEntries(result);
}
function mergeVerifiedWorkflowEvidence(current, incoming = {}) {
const merged = new Map(Object.entries(normalizeVerifiedWorkflowEvidence(current)));
for (const [rawRequirement, snapshots] of Object.entries(incoming)) {
const requirement = canonicalWorkflowEvidenceKey(rawRequirement);
if (!requirement) continue;
const values = [...merged.get(requirement) ?? []];
for (const snapshot of snapshots) {
if (!values.some((candidate) => candidate.messageId === snapshot.messageId)) values.push(snapshot);
}
if (values.length) merged.set(requirement, values);
}
return Object.fromEntries(merged);
}
function mergeWorkflowEvidence(current, incoming = {}) {
const merged = new Map(Object.entries(normalizeWorkflowEvidence(current)));
const seen = /* @__PURE__ */ new Set();
for (const [rawRequirement, rawValue] of Object.entries(incoming)) {
const requirement = canonicalWorkflowEvidenceKey(rawRequirement);
if (!requirement || typeof rawValue !== "string" || !rawValue.trim()) {
throw new ProtocolError(400, "evidence must contain non-empty keyed string values", "invalid_workflow_evidence");
}
if (seen.has(requirement)) {
throw new ProtocolError(
400,
`evidence contains duplicate normalized requirement identity: ${requirement}`,
"invalid_workflow_evidence"
);
}
seen.add(requirement);
const value = rawValue.trim();
const values = merged.get(requirement) ?? [];
if (!values.includes(value)) values.push(value);
merged.set(requirement, values);
}
return Object.fromEntries(merged);
}
function workflowEvidenceStrings(evidence) {
return Object.entries(evidence).flatMap(([requirement, candidate]) => {
const values = Array.isArray(candidate) ? candidate : [candidate];
return values.map((value) => `${requirement}: ${value}`);
});
}
function activeWorkflowAttempt(stage) {
return stage.attempts + 1;
}
function journalAttemptFor(stage) {
switch (stage.status) {
case "in_progress":
case "waiting":
return stage.attempts + 1;
case "pending":
return stage.attempts > 0 ? stage.attempts : void 0;
case "passed":
case "warning":
case "failed":
return Math.max(1, stage.attempts);
}
}
function validIsoTimestamp(value) {
if (!value) return void 0;
const parsed = Date.parse(value);
return Number.isFinite(parsed) ? parsed : void 0;
}
function verifyWorkflowEvidenceReferences(run, stage, references, lookup, verifiedAt) {
const expectedAttempt = activeWorkflowAttempt(stage);
const result = /* @__PURE__ */ new Map();
const seenRequirements = /* @__PURE__ */ new Set();
const seenMessageIds = /* @__PURE__ */ new Set();
for (const [rawRequirement, reference] of Object.entries(references)) {
const requirementKey = canonicalWorkflowEvidenceKey(rawRequirement);
if (!requirementKey || seenRequirements.has(requirementKey)) {
throw new ProtocolError(
400,
`evidenceRefs contains duplicate or empty requirement identity: ${requirementKey || "(empty)"}`,
"invalid_workflow_evidence_refs"
);
}
seenRequirements.add(requirementKey);
const policy = stage.resolvedEvidencePolicies?.[requirementKey];
if (!policy) {
throw new ProtocolError(
400,
`requirement ${requirementKey} does not declare a resolved peer evidence policy`,
"workflow_evidence_policy_missing"
);
}
if (!reference || !Array.isArray(reference.messageIds) || reference.messageIds.length < 1 || reference.messageIds.length > 16) {
throw new ProtocolError(
400,
`evidenceRefs.${requirementKey}.messageIds must contain between 1 and 16 message IDs`,
"invalid_workflow_evidence_refs"
);
}
const eligibleProducerIds = new Set(policy.eligibleProducers.map((producer) => producer.id));
const snapshots = [];
for (const rawMessageId of reference.messageIds) {
const messageId = typeof rawMessageId === "string" ? rawMessageId.trim() : "";
if (!messageId || seenMessageIds.has(messageId)) {
throw new ProtocolError(
400,
`evidenceRefs contains an empty or duplicate message ID: ${messageId || "(empty)"}`,
"invalid_workflow_evidence_refs"
);
}
seenMessageIds.add(messageId);
const message = lookup.getMessage(messageId);
if (!message) {
throw new ProtocolError(400, `peer evidence message not found: ${messageId}`, "workflow_provenance_invalid");
}
const context = message.workflowContext;
if (context?.schema !== "pi-mesh.workflow-message-context.v1" || context.runId !== run.id || context.stageId !== stage.id || context.requirementKey !== requirementKey || context.attempt !== expectedAttempt) {
throw new ProtocolError(
400,
`peer evidence message ${messageId} is not bound to ${run.id}/${stage.id}/${requirementKey}/attempt-${expectedAttempt}`,
"workflow_provenance_invalid"
);
}
if (message.project !== run.project || message.from !== run.targetAgentId || message.to === run.targetAgentId) {
throw new ProtocolError(
400,
`peer evidence message ${messageId} has an invalid project or direction`,
"workflow_provenance_invalid"
);
}
if (!eligibleProducerIds.has(message.to)) {
throw new ProtocolError(
400,
`peer evidence producer ${message.toName} is not eligible for ${requirementKey}`,
"workflow_provenance_invalid"
);
}
if (message.correlationId !== run.id || message.status !== "replied" || !message.reply?.content.trim()) {
throw new ProtocolError(
400,
`peer evidence message ${messageId} is not a replied message for run ${run.id}`,
"workflow_provenance_invalid"
);
}
const createdAt = validIsoTimestamp(message.createdAt);
const deliveredAt = message.deliveredAt === void 0 ? void 0 : validIsoTimestamp(message.deliveredAt);
const replyCreatedAt = validIsoTimestamp(message.reply.createdAt);
const repliedAt = validIsoTimestamp(message.repliedAt);
if (createdAt === void 0 || replyCreatedAt === void 0 || repliedAt === void 0 || message.deliveredAt !== void 0 && deliveredAt === void 0 || deliveredAt !== void 0 && (deliveredAt < createdAt || deliveredAt > repliedAt) || replyCreatedAt < createdAt || repliedAt < replyCreatedAt) {
throw new ProtocolError(
400,
`peer evidence message ${messageId} has incoherent reply timestamps`,
"workflow_provenance_invalid"
);
}
snapshots.push({
schema: "pi-mesh.verified-peer-evidence.v1",
messageId: message.id,
producerId: message.to,
producerName: message.toName,
context: { ...context },
status: "replied",
requestSha256: createHash2("sha256").update(message.content, "utf8").digest("hex"),
replySha256: createHash2("sha256").update(message.reply.content, "utf8").digest("hex"),
createdAt: message.createdAt,
replyCreatedAt: message.reply.createdAt,
repliedAt: message.repliedAt,
verifiedAt
});
}
result.set(requirementKey, snapshots);
}
return Object.fromEntries(result);
}
function peerEvidenceRequirementStatus(stage, requirementKey, runId, verifiedEvidence = normalizeVerifiedWorkflowEvidence(stage.verifiedEvidence)) {
const canonicalKey = canonicalWorkflowEvidenceKey(requirementKey);
const policy = stage.resolvedEvidencePolicies?.[canonicalKey];
if (!policy) return void 0;
const attempt = activeWorkflowAttempt(stage);
const eligibleIds = new Set(policy.eligibleProducers.map((producer) => producer.id));
const producers = /* @__PURE__ */ new Set();
for (const snapshot of verifiedEvidence[canonicalKey] ?? []) {
if (snapshot.schema === "pi-mesh.verified-peer-evidence.v1" && snapshot.status === "replied" && snapshot.context?.schema === "pi-mesh.workflow-message-context.v1" && snapshot.context.runId === runId && snapshot.context.stageId === stage.id && snapshot.context.requirementKey === canonicalKey && snapshot.context.attempt === attempt && eligibleIds.has(snapshot.producerId) && /^[a-f0-9]{64}$/.test(snapshot.requestSha256) && /^[a-f0-9]{64}$/.test(snapshot.replySha256) && validIsoTimestamp(snapshot.createdAt) !== void 0 && validIsoTimestamp(snapshot.replyCreatedAt) !== void 0 && validIsoTimestamp(snapshot.repliedAt) !== void 0 && validIsoTimestamp(snapshot.verifiedAt) !== void 0) producers.add(snapshot.producerId);
}
const approval = stage.degradationApprovals?.find(
(candidate) => candidate.requirementKey === canonicalKey && candidate.attempt === attempt
);
const effectiveMinProducers = approval?.approvedMinProducers ?? policy.minProducers;
return {
requirementKey: canonicalKey,
policyMinProducers: policy.minProducers,
effectiveMinProducers,
producers: [...producers],
met: producers.size >= effectiveMinProducers,
degraded: Boolean(approval && producers.size < policy.minProducers && producers.size >= effectiveMinProducers),
...approval ? { approval } : {}
};
}
function requireCompleteEvidence(stage, evidence, verifiedEvidence, runId) {
const missing = [];
const peerStatuses = [];
for (const rawRequirement of stage.requiredEvidence) {
const requirement = canonicalWorkflowEvidenceKey(rawRequirement);
const peerStatus = peerEvidenceRequirementStatus(stage, requirement, runId, verifiedEvidence);
if (peerStatus) {
peerStatuses.push(peerStatus);
if (!peerStatus.met) missing.push(requirement);
} else if (stage.evidencePolicies?.[requirement]) {
throw new ProtocolError(
409,
`stage ${stage.id} evidence policy ${requirement} was not resolved when the run started`,
"workflow_evidence_policy_unresolved"
);
} else if (!evidence[requirement]?.length) {
missing.push(requirement);
}
}
if (missing.length === 0) return peerStatuses;
throw new ProtocolError(
400,
`stage ${stage.id} is missing required evidence: ${missing.join(", ")}`,
"workflow_evidence_incomplete",
{
missingRequirements: missing,
providedRequirements: Object.keys(evidence),
peerRequirements: peerStatuses
}
);
}
function parseWorkflowEvidencePolicies(value, stageId, requiredEvidence, workflowId, targetName, warn) {
if (value === void 0) return void 0;
const rawPolicies = object(value, `stage ${stageId} evidencePolicies`);
const policies = /* @__PURE__ */ new Map();
for (const [rawRequirement, rawPolicy] of Object.entries(rawPolicies)) {
const requirementKey = canonicalWorkflowEvidenceKey(
requireString(rawRequirement, `stage ${stageId} evidencePolicies requirement`, { max: 128 })
);
if (!requiredEvidence.includes(requirementKey)) {
throw new Error(`stage ${stageId} evidence policy ${requirementKey} must match requiredEvidence`);
}
if (policies.has(requirementKey)) {
throw new Error(`stage ${stageId} evidencePolicies keys must be unique after normalization`);
}
const policy = object(rawPolicy, `stage ${stageId} evidencePolicies.${requirementKey}`);
const supportedPolicyFields = /* @__PURE__ */ new Set([
"kind",
"minProducers",
"eligibleAgents",
"acceptedStatuses",
"degradation"
]);
const unsupportedPolicyFields = Object.keys(policy).filter((field) => !supportedPolicyFields.has(field));
if (unsupportedPolicyFields.length) {
throw new Error(
`stage ${stageId} evidencePolicies.${requirementKey} contains unsupported fields: ${unsupportedPolicyFields.join(", ")}`
);
}
if (policy.kind !== "peer-reply") {
throw new Error(`stage ${stageId} evidencePolicies.${requirementKey}.kind must be peer-reply`);
}
const minProducers = policy.minProducers;
if (!Number.isInteger(minProducers) || minProducers < 1 || minProducers > 8) {
throw new Error(`stage ${stageId} evidencePolicies.${requirementKey}.minProducers must be an integer between 1 and 8`);
}
const eligibleAgents = stringArray(
policy.eligibleAgents,
`stage ${stageId} evidencePolicies.${requirementKey}.eligibleAgents`
);
if (eligibleAgents.length < 1 || eligibleAgents.length > 16) {
throw new Error(`stage ${stageId} evidencePolicies.${requirementKey}.eligibleAgents must contain between 1 and 16 selectors`);
}
const normalizedSelectors = eligibleAgents.map((selector) => selector.toLowerCase());
if (new Set(normalizedSelectors).size !== normalizedSelectors.length) {
throw new Error(`stage ${stageId} evidencePolicies.${requirementKey}.eligibleAgents must be unique`);
}
if (normalizedSelectors.includes(targetName)) {
throw new Error(
`workflow ${workflowId} stage ${stageId} evidencePolicies.${requirementKey}.eligibleAgents must not include the workflow target ${targetName}: the target cannot produce peer evidence for its own run`
);
}
if (minProducers > normalizedSelectors.length) {
throw new Error(`stage ${stageId} evidencePolicies.${requirementKey}.minProducers exceeds eligibleAgents`);
}
if (policy.acceptedStatuses !== void 0) {
const statuses = stringArray(
policy.acceptedStatuses,
`stage ${stageId} evidencePolicies.${requirementKey}.acceptedStatuses`
);
if (statuses.length !== 1 || statuses[0] !== "replied") {
throw new Error(`stage ${stageId} evidencePolicies.${requirementKey}.acceptedStatuses must be ["replied"]`);
}
}
let degradation;
if (policy.degradation !== void 0) {
const rawDegradation = object(
policy.degradation,
`stage ${stageId} evidencePolicies.${requirementKey}.degradation`
);
const unsupportedDegradationFields = Object.keys(rawDegradation).filter((field) => field !== "minProducers");
if (unsupportedDegradationFields.length) {
throw new Error(
`stage ${stageId} evidencePolicies.${requirementKey}.degradation contains unsupported fields: ${unsupportedDegradationFields.join(", ")}`
);
}
const degradedMin = rawDegradation.minProducers;
if (!Number.isInteger(degradedMin) || degradedMin < 1 || degradedMin >= minProducers) {
throw new Error(
`stage ${stageId} evidencePolicies.${requirementKey}.degradation.minProducers must be at least 1 and lower than minProducers`
);
}
degradation = { minProducers: degradedMin };
if (degradation.minProducers < 2) {
warn(
`workflow ${workflowId} stage ${stageId} evidence policy ${requirementKey}: degradation.minProducers is ${degradation.minProducers} (< 2); a single producer can satisfy the degraded peer-reply quorum`
);
}
}
policies.set(requirementKey, {
kind: "peer-reply",
minProducers,
eligibleAgents,
acceptedStatuses: ["replied"],
...degradation ? { degradation } : {}
});
}
return policies.size ? Object.fromEntries(policies) : void 0;
}
function parseWorkflowDefinitions(raw, environment = process.env, onWarning) {
if (!raw?.trim()) return [];
const parsed = JSON.parse(raw);
if (!Array.isArray(parsed)) throw new Error("KXM_WEBHOOK_WORKFLOWS must be a JSON array");
const warn = (message) => {
onWarning?.(message);
};
const ids = /* @__PURE__ */ new Set();
return parsed.map((entry, definitionIndex) => {
const value = object(entry, `workflow ${definitionIndex}`);
const id = requireString(value.id, "workflow.id", { max: 64 });
if (ids.has(id)) throw new Error(`duplicate workflow id: ${id}`);
ids.add(id);
const source = value.source ?? "generic";
if (source !== "jira" && source !== "github" && source !== "generic") {
throw new Error(`workflow ${id} source must be jira, github, or generic`);
}
const delivery = value.delivery ?? "followUp";
if (delivery !== "steer" && delivery !== "followUp") {
throw new Error(`workflow ${id} delivery must be steer or followUp`);
}
const secretEnv = value.secretEnv === void 0 ? void 0 : requireString(value.secretEnv, "workflow.secretEnv", { max: 128 });
if (value.secret !== void 0 && secretEnv) {
throw new Error(`workflow ${id} must configure only one of secret or secretEnv`);
}
const secret = requireString(secretEnv ? environment[secretEnv] : value.secret, "workflow.secret", { max: 512 });
if (secret.length < 16) throw new Error(`workflow ${id} secret must contain at least 16 characters`);
const signalSecretEnv = value.signalSecretEnv === void 0 ? void 0 : requireString(value.signalSecretEnv, "workflow.signalSecretEnv", { max: 128 });
if (value.signalSecret !== void 0 && signalSecretEnv) {
throw new Error(`workflow ${id} must configure only one of signalSecret or signalSecretEnv`);
}
const signalSecret = signalSecretEnv ? requireString(environment[signalSecretEnv], "workflow.signalSecret", { max: 512 }) : value.signalSecret === void 0 ? void 0 : requireString(value.signalSecret, "workflow.signalSecret", { max: 512 });
if (signalSecret && signalSecret.length < 16) {
throw new Error(`workflow ${id} signalSecret must contain at least 16 characters`);
}
const target = requireString(value.target, "workflow.target", { max: 80 });
const targetName = target.toLowerCase();
if (!Array.isArray(value.stages) || value.stages.length === 0 || value.stages.length > 32) {
throw new Error(`workflow ${id} must define between 1 and 32 stages`);
}
const stageIds = /* @__PURE__ */ new Set();
const stages = value.stages.map((stageEntry, stageIndex) => {
const stage = object(stageEntry, `workflow ${id} stage ${stageIndex}`);
const stageId = requireString(stage.id, "stage.id", { max: 64 });
if (stageIds.has(stageId)) throw new Error(`duplicate stage id ${stageId} in workflow ${id}`);
stageIds.add(stageId);
const maxAttempts = stage.maxAttempts ?? 3;
if (!Number.isInteger(maxAttempts) || maxAttempts < 1 || maxAttempts > 20) {
throw new Error(`stage ${stageId} maxAttempts must be an integer between 1 and 20`);
}
const area = stage.area ? requireString(stage.area, "stage.area", { max: 24 }) : void 0;
if (area && !IMPROVEMENT_AREAS.includes(area)) {
throw new Error(`stage ${stageId} area is invalid`);
}
const requiredEvidence = stringArray(stage.requiredEvidence ?? [], "stage.requiredEvidence").map((requirement, requirementIndex) => canonicalWorkflowEvidenceKey(
requireString(requirement, `stage.requiredEvidence[${requirementIndex}]`, { max: 128 })
));
if (requiredEvidence.length > 32) throw new Error(`stage ${stageId} may require at most 32 evidence keys`);
if (new Set(requiredEvidence).size !== requiredEvidence.length) {
throw new Error(`stage ${stageId} requiredEvidence keys must be unique`);
}
const evidencePolicies = parseWorkflowEvidencePolicies(
stage.evidencePolicies,
stageId,
requiredEvidence,
id,
targetName,
warn
);
const on = parseOutcomeMap(stageId, stage.on);
const stageMaxTransitions = stage.maxTransitions;
if (stageMaxTransitions !== void 0 && (!Number.isInteger(stageMaxTransitions) || stageMaxTransitions < 1 || stageMaxTransitions > 100)) {
throw new Error(`stage ${stageId} maxTransitions must be an integer between 1 and 100`);
}
const autoResumeLimit = stage.autoResumeLimit;
if (autoResumeLimit !== void 0 && (!Number.isInteger(autoResumeLimit) || autoResumeLimit < 1 || autoResumeLimit > 20)) {
throw new Error(`stage ${stageId} autoResumeLimit must be an integer between 1 and 20`);
}
return {
id: stageId,
label: requireString(stage.label ?? stageId, "stage.label", { max: 128 }),
instructions: requireString(stage.instructions, "stage.instructions", { max: 4e3 }),
requiredEvidence,
maxAttempts,
...autoResumeLimit !== void 0 ? { autoResumeLimit } : {},
...area ? { area } : {},
...evidencePolicies ? { evidencePolicies } : {},
...on ? { on } : {},
...stageMaxTransitions !== void 0 ? { maxTransitions: stageMaxTransitions } : {}
};
});
const definitionMaxTransitions = value.maxTransitions;
if (definitionMaxTransitions !== void 0) validateWorkflowTransitions({ id, stages, maxTransitions: definitionMaxTransitions });
else validateWorkflowTransitions({ id, stages });
const stageIdSet = new Set(stages.map((stage) => stage.id));
const parseOracleConfig = (raw2, field) => {
if (raw2 === void 0) return void 0;
const candidate = object(raw2, `workflow ${id} ${field}`);
const stageId = requireString(candidate.stageId, `workflow ${id} ${field}.stageId`, { max: 64 });
if (!stageIdSet.has(stageId)) {
throw new Error(`workflow ${id} ${field}.stageId references unknown stage ${stageId}`);
}
const evidenceKey = canonicalWorkflowEvidenceKey(requireString(candidate.evidenceKey, `workflow ${id} ${field}.evidenceKey`, { max: 128 }));
return { stageId, evidenceKey };
};
const reproOracle = parseOracleConfig(value.reproOracle, "reproOracle");
const planHash = parseOracleConfig(value.planHash, "planHash");
let requirePlanHash;
if (value.requirePlanHash !== void 0) {
const required = stringArray(value.requirePlanHash, `workflow ${id} requirePlanHash`);
for (const stageId of required) {
if (!stageIdSet.has(stageId)) {
throw new Error(`workflow ${id} requirePlanHash references unknown stage ${stageId}`);
}
}
requirePlanHash = [...new Set(required)].sort();
}
let filter;
if (value.filter !== void 0) {
const candidate = object(value.filter, `workflow ${id} filter`);
filter = {
path: requireString(candidate.path, "filter.path", { max: 256 }),
equals: requireString(candidate.equals, "filter.equals", { max: 512 })
};
}
if (value.ttlMs !== void 0 && (!Number.isInteger(value.ttlMs) || value.ttlMs < MIN_MESSAGE_TTL_MS || value.ttlMs > MAX_MESSAGE_TTL_MS)) {
throw new Error(`workflow ${id} ttlMs must be an integer between ${MIN_MESSAGE_TTL_MS} and ${MAX_MESSAGE_TTL_MS}`);
}
return {
id,
source,
project: requireString(value.project, "workflow.project", { max: 128 }),
target,
secret,
...signalSecret ? { signalSecret } : {},
...value.event ? { event: requireString(value.event, "workflow.event", { max: 128 }) } : {},
...filter ? { filter } : {},
delivery,
...value.ttlMs !== void 0 ? { ttlMs: value.ttlMs } : {},
...value.maxTransitions !== void 0 ? { maxTransitions: value.maxTransitions } : {},
...reproOracle ? { reproOracle } : {},
...planHash ? { planHash } : {},
...requirePlanHash ? { requirePlanHash } : {},
promptTemplate: requireString(value.promptTemplate, "workflow.promptTemplate", { max: 2e4 }),
stages
};
});
}
function validateWorkflowTransitions(definition) {
const stageIndex = new Map(definition.stages.map((stage, index) => [stage.id, index]));
let hasBackEdge = false;
for (const stage of definition.stages) {
if (!stage.on) continue;
for (const [outcome, rawValue] of Object.entries(stage.on)) {
if (!outcome.trim()) throw new Error(`stage ${stage.id} declares an empty outcome key`);
const rule = normalizeOutcomeValue(rawValue, `stage ${stage.id} on.${outcome}`);
if (rule.target === WORKFLOW_TERMINAL_TARGET) continue;
const targetIndex = stageIndex.get(rule.target);
if (targetIndex === void 0) {
throw new Error(`stage ${stage.id} on.${outcome} targets unknown stage ${rule.target}`);
}
const sourceIndex = stageIndex.get(stage.id);
if (targetIndex > sourceIndex + 1) {
throw new Error(
`stage ${stage.id} on.${outcome} skips intermediate stages by targeting ${rule.target}; forward transitions must target the next stage so approvals and gates cannot be bypassed`
);
}
if (targetIndex <= sourceIndex) hasBackEdge = true;
}
}
if (definition.maxTransitions !== void 0 && (!Number.isInteger(definition.maxTransitions) || definition.maxTransitions < 1 || definition.maxTransitions > 200)) {
throw new Error(`workflow ${definition.id} maxTransitions must be an integer between 1 and 200`);
}
if (hasBackEdge && (definition.maxTransitions === void 0 || definition.maxTransitions < 1)) {
throw new Error(`workflow ${definition.id} declares a back-edge but no maxTransitions budget; cycles without budgets are rejected`);
}
}
function parseOutcomeMap(stageId, raw) {
if (raw === void 0) return void 0;
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
throw new Error(`stage ${stageId} on must be an object`);
}
const map = {};
for (const [outcome, value] of Object.entries(raw)) {
map[outcome] = normalizeOutcomeValue(value, `stage ${stageId} on.${outcome}`);
}
return map;
}
function valueAtPath(payload, path) {
let current = payload;
for (const part of path.split(".")) {
if (!current || typeof current !== "object" || Array.isArray(current)) return void 0;
current = current[part];
}
return current;
}
function renderWorkflowPrompt(template, payload) {
return template.replace(/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g, (_match, path) => {
const value = valueAtPath(payload, path);
if (value === void 0 || value === null) return "";
return typeof value === "object" ? JSON.stringify(value) : String(value);
});
}
function canonicalizeForHash(value) {
if (Array.isArray(value)) return value.map(canonicalizeForHash);
if (value && typeof value === "object") {
return Object.fromEntries(
Object.entries(value).filter(([, candidate]) => candidate !== void 0).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, candidate]) => [key, canonicalizeForHash(candidate)])
);
}
return value;
}
function canonicalWorkflowDefinitionJson(definition) {
const { secret: _secret, signalSecret: _signalSecret, ...publicDefinition } = definition;
return JSON.stringify(canonicalizeForHash(publicDefinition));
}
function workflowDefinitionHash(definition) {
return createHash2("sha256").update(canonicalWorkflowDefinitionJson(definition), "utf8").digest("hex");
}
var WORKFLOW_WEBHOOK_SIGNATURE_VERSION = "kxm-webhook-v1";
var WORKFLOW_WEBHOOK_MAX_SKEW_SECONDS = 300;
function workflowWebhookSignedMaterial(scope, timestamp, deliveryId, body) {
const fields = [
WORKFLOW_WEBHOOK_SIGNATURE_VERSION,
scope.runId === void 0 ? "start" : "signal",
timestamp,
deliveryId,
scope.definitionId,
scope.runId ?? "",
scope.signalKey ?? ""
];
if (fields.some((field) => /[\r\n]/.test(field))) {
throw new ProtocolError(400, "webhook signature fields must not contain line breaks", "webhook_signature_field_invalid");
}
return Buffer.concat([
Buffer.from(`${fields.join("\n")}
`, "utf8"),
typeof body === "string" ? Buffer.from(body, "utf8") : Buffer.from(body)
]);
}
function workflowWebhookSignature(secret, scope, timestamp, deliveryId, body) {
return `sha256=${createHmac("sha256", secret).update(workflowWebhookSignedMaterial(scope, timestamp, deliveryId, body)).digest("hex")}`;
}
function resolveOutcomeRule(stage, outcomeKey) {
const raw = stage.on?.[outcomeKey];
return raw === void 0 ? void 0 : normalizeOutcomeValue(raw, `stage ${stage.id} on.${outcomeKey}`);
}
function transitionCounts(run, fromStage, outcome, target) {
const records = run.transitions ?? [];
return {
total: records.length,
fromStage: records.filter((record) => record.fromStage === fromStage).length,
forEdge: records.filter((record) => record.fromStage === fromStage && record.outcome === outcome && record.toStage === target).length
};
}
function recordTransition(run, fromStage, rule, outcome, attempt, evidenceKeys, timestamp) {
const record = {
id: newId("trans"),
fromStage,
toStage: rule.target,
outcome,
attempt,
evidenceKeys,
at: timestamp
};
run.transitions = [...run.transitions ?? [], record];
return record;
}
function enterStage(run, stage, timestamp) {
stage.status = "in_progress";
stage.attempts = 0;
stage.evidence = {};
stage.verifiedEvidence = {};
stage.startedAt = timestamp;
stage.updatedAt = timestamp;
delete stage.summary;
run.currentStage = stage.id;
run.updatedAt = timestamp;
}
function takeDeclaredTransition(run, stage, rule, outcome, summary, attempt, timestamp, evidenceKeys) {
const definitionBudget = run.maxTransitions;
const counts = transitionCounts(run, stage.id, outcome, rule.target);
const edgeExhausted = rule.maxTransitions !== void 0 && counts.forEdge >= rule.maxTransitions;
const stageExhausted = stage.maxTransitions !== void 0 && counts.fromStage >= stage.maxTransitions;
const globalExhausted = definitionBudget !== void 0 && counts.total >= definitionBudget;
if (edgeExhausted || stageExhausted || globalExhausted) {
stage.completedAt = timestamp;
run.status = "failed";
delete run.currentStage;
run.updatedAt = timestamp;
return {
retry: false,
completed: false,
run,
exhausted: true
};
}
const record = recordTransition(run, stage.id, rule, outcome, attempt, evidenceKeys.slice(0, 32), timestamp);
if (rule.target === WORKFLOW_TERMINAL_TARGET) {
stage.completedAt = timestamp;
run.status = "completed";
delete run.currentStage;
run.completedAt = timestamp;
run.updatedAt = timestamp;
return { retry: false, completed: true, run, transition: record };
}
const target = run.stages.find((candidate) => candidate.id === rule.target);
if (!target) {
run.status = "failed";
delete run.currentStage;
return { retry: false, completed: false, run, exhausted: true };
}
stage.summary = summary;
enterStage(run, target, timestamp);
return { retry: false, completed: false, run, transition: record };
}
function evidenceValueSha256(evidence, key) {
const values = evidence[canonicalWorkflowEvidenceKey(key)];
if (!values || values.length === 0) return void 0;
return createHash2("sha256").update([...values].sort().join("\n"), "utf8").digest("hex");
}
function enforceOracles(run, stageId, evidence) {
if (run.oracle) {
const presented = evidenceValueSha256(evidence, run.oracle.evidenceKey);
if (presented !== void 0 && presented !== run.oracle.sha256) {
throw new ProtocolError(
400,
`evidence ${run.oracle.evidenceKey} does not match the immutable reproduction oracle captured at ${run.oracle.capturedAt}; the confirmed reproduction may not be weakened`,
"weakened_reproduction"
);
}
}
if (run.requirePlanHash?.includes(stageId) && !run.planHash) {
throw new ProtocolError(
400,
`stage ${stageId} requires an approved plan hash before it can checkpoint`,
"plan_hash_required"
);
}
}
function captureOracles(run, stageId, evidence, timestamp) {
if (run.reproOracle?.stageId === stageId) {
const sha256 = evidenceValueSha256(evidence, run.reproOracle.evidenceKey);
if (sha256 !== void 0) {
run.oracle = { evidenceKey: run.reproOracle.evidenceKey, sha256, capturedAt: timestamp };
}
}
if (run.planHashConfig?.stageId === stageId) {
const sha256 = evidenceValueSha256(evidence, run.planHashConfig.evidenceKey);
if (sha256 !== void 0) {
run.planHash = { evidenceKey: run.planHashConfig.evidenceKey, sha256, capturedAt: timestamp };
}
}
}
function checkpointRun(run, stageId, status, summary, evidence, timestamp, verifiedEvidence = {}, outcome) {
if (run.status !== "running") throw new ProtocolError(409, `workflow is ${run.status}`, "workflow_terminal");
const stage = run.stages.find((candidate) => candidate.id === stageId);
if (!stage) throw new ProtocolError(404, `workflow stage not found: ${stageId}`, "workflow_stage_not_found");
if (stage.id !== run.currentStage || stage.status !== "in_progress") {
throw new ProtocolError(409, `stage ${stageId} is not currently active`, "workflow_stage_out_of_order");
}
const accumulatedEvidence = mergeWorkflowEvidence(stage.evidence, evidence);
const accumulatedVerifiedEvidence = mergeVerifiedWorkflowEvidence(stage.verifiedEvidence, verifiedEvidence);
enforceOracles(run, stageId, accumulatedEvidence);
const peerStatuses = status === "passed" ? requireCompleteEvidence(stage, accumulatedEvidence, accumulatedVerifiedEvidence, run.id) : [];
const degradedRequirements = peerStatuses.filter((peerStatus) => peerStatus.degraded);
stage.attempts += 1;
stage.summary = summary;
if (status === "passed") {
stage.evidence = accumulatedEvidence;
if (Object.keys(accumulatedVerifiedEvidence).length) stage.verifiedEvidence = accumulatedVerifiedEvidence;
captureOracles(run, stageId, accumulatedEvidence, timestamp);
if (degradedRequirements.length) {
stage.degraded = true;
stage.degradedRequirements = degradedRequirements.map((peerStatus) => peerStatus.requirementKey);
}
}
stage.updatedAt = timestamp;
run.updatedAt = timestamp;
if (status !== "passed") {
stage.status = status;
if (stage.attempts >= stage.maxAttempts) {
stage.completedAt = timestamp;
run.status = "failed";
delete run.currentStage;
return { retry: false, completed: false, run };
}
if (stage.autoResumeLimit !== void 0 && stage.attempts >= stage.autoResumeLimit) {
stage.status = "in_progress";
const reason = summary || `autoResumeLimit of ${stage.autoResumeLimit} reached on stage ${stage.id}`;
const receipt = validateTerminalReceipt({
schema: TERMINAL_RECEIPT_SCHEMA,
status: "audit_escalation",
seat: stage.id,
runId: run.id,
stageId: stage.id,
timestamp,
host: "pi",
model: "default",
escalationReason: reason
});
const expiresAt = new Date(Date.parse(timestamp) + 24 * 60 * 60 * 1e3).toISOString();
waitForWorkflowSignal(run, stage.id, "audit_escalation", reason, timestamp, expiresAt);
stage.receipt = receipt;
stage.auditEscalation = {
reason,
timestamp,
receipt
};
return { retry: false, completed: false, run };
}
stage.status = status;
const outcomeKey = outcome ?? status;
const rule = resolveOutcomeRule(stage, outcomeKey);
if (rule && stage.attempts < stage.maxAttempts) {
const result = takeDeclaredTransition(run, stage, rule, outcomeKey, summary, stage.attempts, timestamp, Object.keys(accumulatedEvidence));
if (result.transition !== void 0 && !result.completed && rule.target !== stage.id) {
stage.status = "pending";
}
return result;
}
stage.status = "in_progress";
return { retry: true, completed: false, run };
}
stage.status = "passed";
stage.completedAt = timestamp;
const passedRule = resolveOutcomeRule(stage, outcome ?? "passed");
if (passedRule) {
return takeDeclaredTransition(run, stage, passedRule, outcome ?? "passed", summary, stage.attempts, timestamp, Object.keys(accumulatedEvidence));
}
const next = run.stages.find((candidate) => candidate.status === "pending");
if (next) {
next.status = "in_progress";
next.startedAt = timestamp;
next.updatedAt = timestamp;
run.currentStage = next.id;
return {
retry: false,
completed: false,
run,
...degradedRequirements.length ? { degraded: true } : {}
};
}
run.status = "completed";
delete run.currentStage;
run.completedAt = timestamp;
return {
retry: false,
completed: true,
run,
...degradedRequirements.length ? { degraded: true } : {}
};
}
function waitForWorkflowSignal(run, stageId, signalKey, summary, timestamp, expiresAt, evidence = {}, verifiedEvidence = {}) {
if (run.status !== "running") throw new ProtocolError(409, `workflow is ${run.status}`, "workflow_not_running");
const stage = run.stages.find((candidate) => candidate.id === stageId);
if (!stage) throw new ProtocolError(404, `workflow stage not found: ${stageId}`, "workflow_stage_not_found");
if (stage.id !== run.currentStage || stage.status !== "in_progress") {
throw new ProtocolError(409, `stage ${stageId} is not currently active`, "workflow_stage_out_of_order");
}
if (Date.parse(expiresAt) <= Date.parse(timestamp)) {
throw new ProtocolError(400, "workflow signal expiry must be in the future", "workflow_wait_invalid");
}
stage.evidence = mergeWorkflowEvidence(stage.evidence, evidence);
const accumulatedVerifiedEvidence = mergeVerifiedWorkflowEvidence(stage.verifiedEvidence, verifiedEvidence);
if (Object.keys(accumulatedVerifiedEvidence).length) stage.verifiedEvidence = accumulatedVerifiedEvidence;
stage.status = "waiting";
stage.updatedAt = timestamp;
run.status = "waiting";
run.waiting = { stageId, signalKey, summary, createdAt: timestamp, expiresAt };
run.updatedAt = timestamp;
return run;
}
function resumeWorkflowFromSignal(run, signalKey, status, summary, evidence, timestamp) {
if (run.status !== "waiting" || !run.waiting) {
throw new ProtocolError(409, `workflow is ${run.status}`, "workflow_not_waiting");
}
if (run.waiting.signalKey !== signalKey) {
throw new ProtocolError(409, `workflow is waiting for ${run.waiting.signalKey}`, "workflow_signal_mismatch");
}
const stageId = run.waiting.stageId;
const stage = run.stages.find((candidate) => candidate.id === stageId);
if (!stage || stage.id !== run.currentStage || stage.status !== "waiting") {
throw new ProtocolError(409, "workflow wait state is inconsistent", "workflow_wait_inconsistent");
}
const accumulatedEvidence = mergeWorkflowEvidence(stage.evidence, evidence);
if (status === "passed") {
requireCompleteEvidence(
stage,
accumulatedEvidence,
normalizeVerifiedWorkflowEvidence(stage.verifiedEvidence),
run.id
);
}
run.status = "running";
stage.status = "in_progress";
delete run.waiting;
const result = checkpointRun(run, stageId, status, summary, evidence, timestamp);
return { ...result, stageId };
}
function approveWorkflowDegradation(run, stageId, requirement, reason, approvalId, timestamp) {
if (run.status !== "running" && run.status !== "waiting") {
throw new ProtocolError(409, `workflow is ${run.status}`, "workflow_terminal");
}
const stage = run.stages.find((candidate) => candidate.id === stageId);
if (!stage) throw new ProtocolError(404, `workflow stage not found: ${stageId}`, "workflow_stage_not_found");
if (stage.id !== run.currentStage || stage.status !== "in_progress" && stage.status !== "waiting") {
throw new ProtocolError(409, `stage ${stageId} is not currently active`, "workflow_stage_out_of_order");
}
const requirementKey = canonicalWorkflowEvidenceKey(requirement);
const policy = stage.resolvedEvidencePolicies?.[requirementKey];
if (!policy?.degradation) {
throw new ProtocolError(
400,
`requirement ${requirementKey} does not permit degraded quorum`,
"workflow_degradation_forbidden"
);
}
const attempt = activeWorkflowAttempt(stage);
const existing = stage.degradationApprovals?.find(
(candidate) => candidate.requirementKey === requirementKey && candidate.attempt === attempt
);
if (existing) {
if (existing.reason !== reason.trim()) {
throw new ProtocolError(
409,
`degradation was already approved for ${requirementKey} attempt ${attempt}`,
"workflow_degradation_conflict"
);
}
return { run, approval: existing, created: false };
}
const approval = {
schema: "pi-mesh.workflow-degradation-approval.v1",
id: approvalId,
requirementKey,
attempt,
policyMinProducers: policy.minProducers,
approvedMinProducers: policy.degradation.minProducers,
approvedBy: "kxm-admin",
reason: requireString(reason, "reason", { max: 1e3 }),
approvedAt: timestamp
};
(stage.degradationApprovals ??= []).push(approval);
stage.updatedAt = timestamp;
run.updatedAt = timestamp;
return { run, approval, created: true };
}
// plugins/kxm/src/client.ts
var HubHttpError = class extends Error {
statusCode;
code;
requestId;
extras;
constructor(statusCode, message, code, requestId, extras) {
super(message);
this.name = "HubHttpError";
this.statusCode = statusCode;
if (code) this.code = code;
if (requestId) this.requestId = requestId;
if (extras) this.extras = extras;
}
};
// plugins/kxm/src/commands.ts
function forwardedHops(handling) {
if (!handling?.length) return void 0;
return {
hops: Math.max(...handling.map((message) => message.hops)) + 1,
maxHops: Math.min(...handling.map((message) => message.maxHops))
};
}
function requiredString(value, name) {
if (typeof value !== "string" || value.trim() === "") throw new Error(`${name} is required`);
return value.trim();
}
function optionalString2(value) {
return typeof value === "string" && value.trim() ? value.trim() : void 0;
}
function asRecord(value) {
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
}
function optionalWorkflowContext(value) {
if (value === void 0) return void 0;
const context = asRecord(value);
if (!Number.isInteger(context.attempt) || context.attempt < 1 || context.attempt > 20) {
throw new Error("workflowContext.attempt must be an integer between 1 and 20");
}
return {
runId: requiredString(context.runId, "workflowContext.runId"),
stageId: requiredString(context.stageId, "workflowContext.stageId"),
requirementKey: requiredString(context.requirementKey, "workflowContext.requirementKey"),
attempt: context.attempt
};
}
function optionalEvidenceRefs(value) {
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
}
function isTerminalMessageError(error) {
return error instanceof HubHttpError && (error.statusCode === 409 || error.statusCode === 404 && error.code === "message_not_found");
}
function isTerminalMessage(message) {
return message.status === "replied" || message.status === "cancelled" || message.status === "expired" || message.status === "error";
}
async function reconcileInbox(client, inbox, notifiedInbox) {
await Promise.all(
[...inbox.keys()].map(async (messageId) => {
try {
const current = await client.getMessage(messageId);
if (isTerminalMessage(current)) {
inbox.delete(messageId);
notifiedInbox?.delete(messageId);
} else {
inbox.set(messageId, current);
}
} catch (error) {
if (isTerminalMessageError(error)) {
inbox.delete(messageId);
notifiedInbox?.delete(messageId);
return;
}
throw error;
}
})
);
}
function resolveProject(client, projectArg) {
const proj = optionalString2(projectArg) ?? client.agent?.project;
if (!proj) {
throw new Error('missing required parameter "project"');
}
return proj;
}
var AGENT_COMMANDS = [
{
name: "kxm_list",
group: "peer",
verb: "list",
label: "List hub peers",
description: "List peer agents in this project's hub pool with their names, purposes, host label, and hub-clocked presence (online, stale, offline). Registered offline peers are listed only when includeOffline is set.",
parameters: {
type: "object",
properties: {
includeOffline: {
type: "boolean",
description: "Also list registered peers whose hub lease has expired"
}
},
additionalProperties: false
},
async execute(client, args) {
return { agents: await client.listAgents({ includeOffline: args.includeOffline === true }) };
}
},
{
name: "kxm_send",
group: "peer",
verb: "send",
label: "Send peer request",
description: "Send a focused request to a peer agent. Returns a message ID for kxm_get or kxm_await. For durable peer evidence, workflowContext is the hub-authorized provenance scope; correlation and idempotency are transport concerns and do not establish evidence provenance.",
parameters: {
type: "object",
properties: {
target: { type: "string", description: "Peer name or agent ID" },
content: { type: "string", description: "Focused request with the expected response or artifact" },
delivery: {
type: "string",
enum: ["steer", "followUp", "nextTurn"],
default: "followUp",
description: "followUp is the safe default; use steer only for active blockers"
},
correlationId: {
type: "string",
description: "Optional task grouping; the hub binds it to runId when workflowContext is supplied"
},
idempotencyKey: {
type: "string",
description: "Retry/deduplication key only; not a workflow security or evidence binding"
},
workflowContext: {
type: "object",
description: "Requested provenance scope; the hub authorizes and persists the canonical binding",
properties: {
runId: { type: "string", description: "Active durable workflow run ID" },
stageId: { type: "string", description: "Active workflow stage ID" },
requirementKey: { type: "string", description: "Required evidence identity this peer reply may satisfy" },
attempt: { type: "integer", minimum: 1, maximum: 20, description: "Current one-based stage attempt" }
},
required: ["runId", "stageId", "requirementKey", "attempt"],
additionalProperties: false
},
ttlMs: { type: "number", minimum: 1e3, maximum: 6048e5, description: "Message TTL in milliseconds" },
allowOffline: {
type: "boolean",
default: false,
description: "Queue the request if the target is a registered offline agent in this project"
}
},
required: ["target", "content"],
additionalProperties: false
},
async execute(client, args, context) {
const delivery = optionalString2(args.delivery);
const correlationId = optionalString2(args.correlationId);
const idempotencyKey = optionalString2(args.idempotencyKey);
const workflowContext = optionalWorkflowContext(args.workflowContext);
const message = await client.send({
...forwardedHops(context?.handling),
target: requiredString(args.target, "target"),
content: requiredString(args.content, "content"),
...delivery ? { delivery } : {},
...correlationId ? { correlationId } : {},
...idempotencyKey ? { idempotencyKey } : {},
...workflowContext ? { workflowContext } : {},
...typeof args.ttlMs === "number" ? { ttlMs: args.ttlMs } : {},
...args.allowOffline === true ? { allowOffline: true } : {}
});
return { messageId: message.id, status: message.status, target: message.toName };
}
},
{
name: "kxm_get",
group: "peer",
verb: "get",
label: "Get peer request",
description: "Check the status and optional reply for a previously sent request.",
parameters: {
type: "object",
properties: {
messageId: { type: "string", description: "Message ID of the sent request" }
},
required: ["messageId"],
additionalProperties: false
},
async execute(client, args) {
return await client.getMessage(requiredString(args.messageId, "messageId"));
}
},
{
name: "kxm_fanout",
group: "peer",
verb: "fanout",
label: "Fanout peer requests",
description: "Ask one through three peers independently and return replies for comparison and synthesis. A local timeout or request cancellation returns a pending response with a durable messageId for kxm_get or an exact retry.",
parameters: {
type: "object",
properties: {
targets: {
type: "array",
items: { type: "string" },
minItems: 1,
maxItems: 3,
description: "One through three target peer names or agent IDs"
},
content: { type: "string", description: "Task description sent to all targets" },
correlationId: {
type: "string",
description: "Optional task grouping; the hub binds it to runId when workflowContext is supplied"
},
idempotencyKeyPrefix: {
type: "string",
description: "Stable retry/deduplication prefix only; not a workflow security or evidence binding"
},
workflowContext: {
type: "object",
description: "Requested provenance scope shared by each request",
properties: {
runId: { type: "string", description: "Active durable workflow run ID" },
stageId: { type: "string", description: "Active workflow stage ID" },
requirementKey: { type: "string", description: "Required evidence identity these peer replies may satisfy" },
attempt: { type: "integer", minimum: 1, maximum: 20, description: "Current one-based stage attempt" }
},
required: ["runId", "stageId", "requirementKey", "attempt"],
additionalProperties: false
},
ttlMs: { type: "number", minimum: 1e3, maximum: 6048e5, description: "Message TTL in milliseconds" },
timeoutMs: { type: "number", minimum: 100, maximum: 18e5, description: "Client wait timeout in milliseconds" }
},
required: ["targets", "content"],
additionalProperties: false
},
async execute(client, args, context) {
const targets = Array.isArray(args.targets) ? args.targets.map((t) => requiredString(t, "target")) : [];
return {
responses: await client.fanout({
...forwardedHops(context?.handling),
targets,
content: requiredString(args.content, "content"),
...optionalString2(args.correlationId) ? { correlationId: optionalString2(args.correlationId) } : {},
...optionalString2(args.idempotencyKeyPrefix) ? { idempotencyKeyPrefix: optionalString2(args.idempotencyKeyPrefix) } : {},
...optionalWorkflowContext(args.workflowContext) ? { workflowContext: optionalWorkflowContext(args.workflowContext) } : {},
...typeof args.ttlMs === "number" ? { ttlMs: args.ttlMs } : {},
...typeof args.timeoutMs === "number" ? { timeoutMs: args.timeoutMs } : {},
...context?.signal ? { signal: context.signal } : {}
})
};
}
},
{
name: "kxm_await",
group: "peer",
verb: "await",
label: "Await peer response",
description: "Wait until a sent request receives a reply or reaches a terminal error. Capped at 60 seconds (60000ms); longer waits are workflow wait steps.",
parameters: {
type: "object",
properties: {
messageId: { type: "string", description: "Message ID of the sent request" },
timeoutMs: {
type: "number",
minimum: 100,
maximum: 6e4,
default: 6e4,
description: "Timeout in milliseconds (capped at 60 seconds)"
}
},
required: ["messageId"],
additionalProperties: false
},
async execute(client, args, context) {
const timeoutMs = Math.min(
typeof args.timeoutMs === "number" ? args.timeoutMs : 6e4,
6e4
);
return await client.awaitResponse(
requiredString(args.messageId, "messageId"),
timeoutMs,
context?.signal
);
}
},
{
name: "kxm_cancel",
group: "peer",
verb: "cancel",
label: "Cancel peer request",
description: "Cancel a queued or delivered request sent by this agent.",
parameters: {
type: "object",
properties: {
messageId: { type: "string", description: "Message ID of the request to cancel" }
},
required: ["messageId"],
additionalProperties: false
},
async execute(client, args) {
return await client.cancel(requiredString(args.messageId, "messageId"));
}
},
{
name: "kxm_inbox",
group: "peer",
verb: "inbox",
label: "List inbound requests",
description: "List inbound peer requests awaiting a reply.",
parameters: {
type: "object",
properties: {},
additionalProperties: false
},
async execute(client, _args, context) {
if (context?.inbox) {
await reconcileInbox(client, context.inbox, context.notifiedInbox);
return { messages: [...context.inbox.values()] };
}
if (context?.hubInbox) return { messages: await client.listInbox() };
throw new Error(
"kxm_inbox is not available in this session: it activates each inbound request as a turn, and that turn's final response is the reply"
);
}
},
{
name: "kxm_reply",
group: "peer",
verb: "reply",
label: "Reply to peer request",
description: "Reply to an inbound peer request using its message ID.",
parameters: {
type: "object",
properties: {
messageId: { type: "string", description: "Message ID of the inbound request" },
content: { type: "string", description: "Final response with evidence and remaining risks" }
},
required: ["messageId", "content"],
additionalProperties: false
},
async execute(client, args, context) {
const messageId = requiredString(args.messageId, "messageId");
try {
const message = await client.reply(messageId, requiredString(args.content, "content"));
if (context?.inbox) {
context.inbox.delete(messageId);
context.notifiedInbox?.delete(messageId);
}
return { messageId, status: message.status, recipient: message.fromName };
} catch (error) {
if (context?.inbox && isTerminalMessageError(error)) {
context.inbox.delete(messageId);
context.notifiedInbox?.delete(messageId);
}
throw error;
}
}
},
{
name: "kxm_workflow_list",
group: "workflow",
verb: "runs",
label: "List workflow runs",
description: "List durable webhook workflows assigned to this agent.",
parameters: {
type: "object",
properties: {},
additionalProperties: false
},
async execute(client) {
return { runs: await client.listWorkflows() };
}
},
{
name: "kxm_workflow_get",
group: "workflow",
verb: "run",
label: "Get workflow run",
description: "Get a workflow's stages and its learning journal (plans, decisions, contradictions, errors, lessons, and the other journal categories).",
parameters: {
type: "object",
properties: {
runId: { type: "string", description: "Workflow run ID" }
},
required: ["runId"],
additionalProperties: false
},
async execute(client, args) {
return await client.getWorkflow(requiredString(args.runId, "runId"));
}
},
{
name: "kxm_workflow_checkpoint",
group: "workflow",
verb: "checkpoint",
label: "Checkpoint workflow stage",
description: "Record a stage result with evidence keyed by the stage's required evidence identities. Cite peer-reply requirements through evidenceRefs so the hub can verify provenance and quorum; caller-authored evidence strings cannot satisfy those policies. Warnings and failures require another attempt until passed or exhausted.",
parameters: {
type: "object",
properties: {
runId: { type: "string", description: "Active durable workflow run ID" },
stageId: { type: "string", description: "Active stage ID" },
status: { type: "string", enum: ["passed", "warning", "failed"], description: "Stage outcome" },
summary: { type: "string", description: "Summary of changes, verification, and remaining risks" },
evidence: {
type: "object",
additionalProperties: { type: "string" },
maxProperties: 64,
description: "Key-value evidence mapping required keys to proof strings"
},
evidenceRefs: {
type: "object",
description: "Peer evidence references keyed by required evidence identity",
patternProperties: {
"^(.*)$": {
type: "object",
properties: {
messageIds: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 16 }
},
required: ["messageIds"],
additionalProperties: false
}
},
additionalProperties: {
type: "object",
properties: {
messageIds: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 16 }
},
required: ["messageIds"],
additionalProperties: false
},
maxProperties: 32
}
},
required: ["runId", "stageId", "status", "summary"],
additionalProperties: false
},
async execute(client, args) {
return await client.checkpointWorkflow(requiredString(args.runId, "runId"), {
stageId: requiredString(args.stageId, "stageId"),
status: requiredString(args.status, "status"),
summary: requiredString(args.summary, "summary"),
...args.evidence && typeof args.evidence === "object" && !Array.isArray(args.evidence) ? { evidence: args.evidence } : {},
...optionalEvidenceRefs(args.evidenceRefs) ? { evidenceRefs: optionalEvidenceRefs(args.evidenceRefs) } : {}
});
}
},
{
name: "kxm_workflow_record",
group: "workflow",
verb: "record",
label: "Record workflow journal entry",
description: "Record a plan, decision, contradiction, error, lesson, observation, hypothesis, experiment, state-change, or skill-candidate for continuous improvement. Pass stageId to bind the entry to that stage: the hub derives the attempt, and area defaults to the stage's declared area. Lessons and skill-candidates require evidence.",
parameters: {
type: "object",
properties: {
runId: { type: "string", description: "Active durable workflow run ID" },
category: {
type: "string",
enum: [...JOURNAL_CATEGORIES],
description: "Category of journal entry"
},
area: {
type: "string",
enum: [...IMPROVEMENT_AREAS],
description: "System area; required unless stageId names a stage that declares an area"
},
stageId: {
type: "string",
description: "Stage the entry belongs to; the hub binds the attempt from the stage's state"
},
severity: {
type: "string",
enum: ["info", "warning", "error"],
default: "info",
description: "Severity level"
},
summary: { type: "string", description: "Concise description of the observation or decision" },
details: { type: "string", description: "Extended details, context, and reasoning" },
evidence: {
type: "array",
items: { type: "string" },
maxItems: 32,
description: "Durable evidence strings or URIs"
},
relatedEntryIds: {
type: "array",
items: { type: "string" },
maxItems: 16,
description: "Related previous journal entry IDs"
}
},
required: ["runId", "category", "summary"],
additionalProperties: false
},
async execute(client, args) {
return await client.recordWorkflowEntry(requiredString(args.runId, "runId"), {
category: requiredString(args.category, "category"),
...optionalString2(args.area) ? { area: optionalString2(args.area) } : {},
...optionalString2(args.stageId) ? { stageId: optionalString2(args.stageId) } : {},
...optionalString2(args.severity) ? { severity: optionalString2(args.severity) } : {},
summary: requiredString(args.summary, "summary"),
...optionalString2(args.details) ? { details: optionalString2(args.details) } : {},
...Array.isArray(args.evidence) ? { evidence: args.evidence } : {},
...Array.isArray(args.relatedEntryIds) ? { relatedEntryIds: args.relatedEntryIds } : {}
});
}
},
{
name: "kxm_workflow_wait",
group: "workflow",
verb: "wait",
label: "Wait for workflow signal",
description: "Pause the active stage until a signed external callback checkpoints it and resumes the coordinator. Cite peer-reply requirements through evidenceRefs so the hub can verify provenance and quorum; verified evidence is accumulated with callback evidence.",
parameters: {
type: "object",
properties: {
runId: { type: "string", description: "Active durable workflow run ID" },
stageId: { type: "string", description: "Active stage ID" },
signalKey: { type: "string", description: "Stable callback key, such as github-pr-42-checks" },
summary: { type: "string", description: "What is running externally and what result is expected" },
evidence: {
type: "object",
additionalProperties: { type: "string" },
maxProperties: 64,
description: "Evidence gathered before the wait"
},
evidenceRefs: {
type: "object",
description: "Peer evidence references verified before waiting",
patternProperties: {
"^(.*)$": {
type: "object",
properties: {
messageIds: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 16 }
},
required: ["messageIds"],
additionalProperties: false
}
},
additionalProperties: {
type: "object",
properties: {
messageIds: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 16 }
},
required: ["messageIds"],
additionalProperties: false
},
maxProperties: 32
},
timeoutMs: {
type: "number",
minimum: 1e3,
maximum: 2592e6,
description: "Maximum wait duration in milliseconds"
}
},
required: ["runId", "stageId", "signalKey", "summary"],
additionalProperties: false
},
async execute(client, args) {
return await client.waitForWorkflowSignal(requiredString(args.runId, "runId"), {
stageId: requiredString(args.stageId, "stageId"),
signalKey: requiredString(args.signalKey, "signalKey"),
summary: requiredString(args.summary, "summary"),
...args.evidence && typeof args.evidence === "object" && !Array.isArray(args.evidence) ? { evidence: args.evidence } : {},
...optionalEvidenceRefs(args.evidenceRefs) ? { evidenceRefs: optionalEvidenceRefs(args.evidenceRefs) } : {},
...typeof args.timeoutMs === "number" ? { timeoutMs: args.timeoutMs } : {}
});
}
},
{
name: "kxm_improvement_report",
group: "workflow",
verb: "improve-report",
label: "Summarize improvement report",
description: "Summarize workflow errors, contradictions, lessons, and skill candidates by improvement area, plus ranked cross-run signals: duplicates merged across runs and scored by frequency x severity x run-attempt cost x evidence confidence, security first, with redacted text.",
parameters: {
type: "object",
properties: {},
additionalProperties: false
},
async execute(client) {
return await client.improvementReport();
}
},
{
name: "kxm_context",
group: "context",
verb: "get",
label: "Get KXM context packet",
description: "Normal entry point for KXM context. Assembles a token-budgeted role-aware context packet from durable journal evidence, temporal state, knowledge, episodes, and skills. Superseded and rejected records are excluded. Use KXM context tools instead of provider-specific memory APIs.",
parameters: {
type: "object",
properties: {
project: { type: "string", description: "Project scope (must be the client's project)" },
role: {
type: "string",
description: "Requesting role: repro, planner, critic, implementer, verifier, or custom"
},
task: { type: "string", description: "What the role is trying to accomplish" },
workflowRunId: { type: "string", description: "Workflow run scope" },
stageId: { type: "string", description: "Workflow stage scope" },
budgetTokens: { type: "integer", description: "Token budget; defaults to the role policy" },
includeKinds: {
type: "array",
items: { type: "string", enum: ["evidence", "state", "episode", "knowledge", "skill"] },
description: "Restrict packet to these item kinds"
}
},
required: ["role", "task"],
additionalProperties: false
},
async execute(client, args) {
return await client.contextGet({
project: resolveProject(client, args.project),
role: requiredString(args.role, "role"),
task: requiredString(args.task, "task"),
...optionalString2(args.workflowRunId) ? { workflowRunId: optionalString2(args.workflowRunId) } : {},
...optionalString2(args.stageId) ? { stageId: optionalString2(args.stageId) } : {},
...typeof args.budgetTokens === "number" ? { budgetTokens: args.budgetTokens } : {},
...Array.isArray(args.includeKinds) ? { includeKinds: args.includeKinds } : {}
});
}
},
{
name: "kxm_recall",
group: "context",
verb: "recall",
label: "Recall context metadata",
description: "Search durable context records for a project by query. Ranks exact-phrase matches first, then token relevance, then id; returns bounded metadata with a numeric relevance per item, never summaries.",
parameters: {
type: "object",
properties: {
project: { type: "string", description: "Project identifier" },
query: { type: "string", description: "Query string" },
kinds: { type: "array", items: { type: "string" }, description: "Kinds filter" },
limit: { type: "integer", minimum: 1, maximum: 100, description: "Maximum results" }
},
additionalProperties: false
},
async execute(client, args) {
return await client.contextRecall({
project: resolveProject(client, args.project),
...optionalString2(args.query) ? { query: optionalString2(args.query) } : {},
...Array.isArray(args.kinds) ? { kinds: args.kinds } : {},
...typeof args.limit === "number" ? { limit: args.limit } : {}
});
}
},
{
name: "kxm_state",
group: "context",
verb: "state",
label: "Get temporal state",
description: "Current value for one temporal state key, optionally as of a historical timestamp.",
parameters: {
type: "object",
properties: {
project: { type: "string", description: "Project identifier" },
key: { type: "string", description: "State key" },
asOf: { type: "string", description: "ISO-8601 timestamp for historical queries" }
},
required: ["key"],
additionalProperties: false
},
async execute(client, args) {
return await client.contextState({
project: resolveProject(client, args.project),
key: requiredString(args.key, "key"),
...optionalString2(args.asOf) ? { asOf: optionalString2(args.asOf) } : {}
});
}
},
{
name: "kxm_episode",
group: "context",
verb: "episode",
label: "Get workflow episodes",
description: "Episodic learning from workflow journals: errors, lessons, observations, experiments for a project.",
parameters: {
type: "object",
properties: {
project: { type: "string", description: "Project identifier" },
workflowRunId: { type: "string", description: "Optional workflow run scope" }
},
additionalProperties: false
},
async execute(client, args) {
return await client.contextEpisode({
project: resolveProject(client, args.project),
...optionalString2(args.workflowRunId) ? { workflowRunId: optionalString2(args.workflowRunId) } : {}
});
}
},
{
name: "kxm_promote",
group: "context",
verb: "promote",
label: "Propose state promotion",
description: "Propose a change to one authoritative state key. Promotion requires durable evidence.",
parameters: {
type: "object",
properties: {
project: { type: "string", description: "Project identifier" },
key: { type: "string", description: "State key to promote" },
summary: { type: "string", description: "Promotion summary" },
authority: {
type: "string",
enum: ["evidence", "hypothesis"],
description: "Authority class; an agent's proposal is peer origin, so evidence at most"
},
confidence: {
type: "string",
enum: ["verified", "probable", "uncertain"],
description: "Confidence level"
},
evidenceRefs: {
type: "array",
items: { type: "string" },
minItems: 1,
maxItems: 32,
description: "Evidence item references backing the promotion"
}
},
required: ["key", "summary", "authority", "confidence", "evidenceRefs"],
additionalProperties: false
},
async execute(client, args) {
return await client.contextStatePropose({
project: resolveProject(client, args.project),
key: requiredString(args.key, "key"),
summary: requiredString(args.summary, "summary"),
authority: requiredString(args.authority, "authority"),
confidence: requiredString(args.confidence, "confidence"),
evidenceRefs: Array.isArray(args.evidenceRefs) ? args.evidenceRefs : []
});
}
}
];
var AGENT_COMMANDS_MAP = new Map(
AGENT_COMMANDS.map((cmd) => [cmd.name, cmd])
);
function timingSafeStringCompare(a, b) {
if (typeof a !== "string" || typeof b !== "string") return false;
const hashA = createHash3("sha256").update(a).digest();
const hashB = createHash3("sha256").update(b).digest();
return timingSafeEqual(hashA, hashB);
}
// plugins/kxm/src/context.ts
var MAX_CONTEXT_SUMMARY_CHARS = 4e3;
var MAX_CONTEXT_ID_REFS = 64;
var MAX_CONTEXT_ITEMS = 256;
var MIN_CONTEXT_BUDGET_TOKENS = 512;
var MAX_CONTEXT_BUDGET_TOKENS = 2e5;
var DEFAULT_CONTEXT_BUDGET_TOKENS = 32e3;
var MAX_CONTEXT_ROLE_CHARS = 64;
var MAX_CONTEXT_TASK_CHARS = 2e3;
var AUTHORITY_GRANT_FLOOR = {
human: "policy",
workflow: "policy",
git: "instruction",
peer: "evidence",
tool: "evidence",
external: "evidence",
derived: "evidence"
};
function authorityGrantFloor(sourceType) {
return AUTHORITY_GRANT_FLOOR[sourceType];
}
var RESERVED_CONTROL_PLANE_FIELDS = /* @__PURE__ */ new Set([
"permissions",
"tools",
"allow",
"deny",
"grants",
"approval",
"policy",
"scopes",
"credentials",
"secrets",
"token",
"apiKey",
"password"
]);
var CONTEXT_ITEM_KINDS = ["evidence", "state", "episode", "knowledge", "skill"];
var CONTEXT_SOURCE_TYPES = [
"human",
"git",
"workflow",
"tool",
"peer",
"external",
"derived"
];
var CONTEXT_AUTHORITIES = ["policy", "instruction", "evidence", "hypothesis"];
var CONTEXT_CONFIDENCES = ["verified", "probable", "uncertain"];
var CONTEXT_SCOPES = ["agent", "project", "run", "operator"];
function oneOf(value, field, allowed) {
if (typeof value !== "string" || !allowed.includes(value)) {
throw new ProtocolError(400, `${field} must be one of ${allowed.join(", ")}`, "invalid_context_field");
}
return value;
}
function idRefs(value, field, required = false) {
if (value === void 0 || value === null) return required ? [] : void 0;
if (!Array.isArray(value)) {
throw new ProtocolError(400, `${field} must be an array of identifiers`, "invalid_context_field");
}
if (value.length > MAX_CONTEXT_ID_REFS) {
throw new ProtocolError(
400,
`${field} exceeds ${MAX_CONTEXT_ID_REFS} references`,
"context_limits_exceeded"
);
}
const seen = /* @__PURE__ */ new Set();
const refs = [];
for (const candidate of value) {
if (typeof candidate !== "string" || !candidate.trim()) {
throw new ProtocolError(400, `${field} must contain non-empty identifiers`, "invalid_context_field");
}
const ref = candidate.trim();
if (seen.has(ref)) {
throw new ProtocolError(400, `${field} contains duplicate reference ${ref}`, "invalid_context_field");
}
seen.add(ref);
refs.push(ref);
}
return refs;
}
function optionalIsoTimestamp(value, field) {
if (value === void 0 || value === null) return void 0;
if (typeof value !== "string" || !Number.isFinite(Date.parse(value))) {
throw new ProtocolError(400, `${field} must be an ISO-8601 timestamp`, "invalid_context_field");
}
return value;
}
function parseContextItem(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new ProtocolError(400, "context item must be an object", "invalid_context_item");
}
const input = value;
for (const field of Object.keys(input)) {
if (RESERVED_CONTROL_PLANE_FIELDS.has(field)) {
throw new ProtocolError(
403,
`context items may not carry control-plane field "${field}"`,
"context_authority_violation"
);
}
}
const item = {
id: requireString(input.id, "context item id", { max: 128 }),
kind: oneOf(input.kind, "context item kind", CONTEXT_ITEM_KINDS),
project: requireString(input.project, "context item project", { max: 200 }),
summary: redactSecrets(requireString(input.summary, "context item summary", { max: MAX_CONTEXT_SUMMARY_CHARS })),
provenance: parseContextProvenance(input.provenance),
authority: oneOf(input.authority, "context item authority", CONTEXT_AUTHORITIES),
confidence: oneOf(input.confidence, "context item confidence", CONTEXT_CONFIDENCES)
};
if (input.scope !== void 0 && input.scope !== null) {
item.scope = oneOf(input.scope, "context item scope", CONTEXT_SCOPES);
}
const observedAt = optionalIsoTimestamp(input.observedAt, "context item observedAt");
const validFrom = optionalIsoTimestamp(input.validFrom, "context item validFrom");
const validUntil = optionalIsoTimestamp(input.validUntil, "context item validUntil");
if (observedAt !== void 0) item.observedAt = observedAt;
if (validFrom !== void 0) item.validFrom = validFrom;
if (validUntil !== void 0) item.validUntil = validUntil;
if (input.status !== void 0 && input.status !== null) {
item.status = oneOf(input.status, "context item status", ["current", "superseded", "proposed", "rejected"]);
}
const supersedes = idRefs(input.supersedes, "context item supersedes");
if (supersedes !== void 0) {
if (supersedes.includes(item.id)) {
throw new ProtocolError(400, "context item cannot supersede itself", "invalid_context_item");
}
item.supersedes = supersedes;
}
const evidenceRefs = idRefs(input.evidenceRefs, "context item evidenceRefs");
if (evidenceRefs !== void 0) item.evidenceRefs = evidenceRefs;
const stateKey = input.stateKey === void 0 || input.stateKey === null ? void 0 : requireString(input.stateKey, "context item stateKey", { max: 200 });
if (stateKey !== void 0) item.stateKey = stateKey;
if (item.kind === "state" && item.stateKey === void 0) {
throw new ProtocolError(400, "state items require a stateKey", "invalid_context_item");
}
if (item.kind === "state" && item.status === void 0) {
throw new ProtocolError(400, "state items require an explicit lifecycle status", "invalid_context_item");
}
const grantFloor = authorityRank(authorityGrantFloor(item.provenance.sourceType));
if (authorityRank(item.authority) > grantFloor) {
throw new ProtocolError(
403,
`content of origin ${item.provenance.sourceType} cannot claim ${item.authority} authority`,
"context_authority_violation"
);
}
return item;
}
function parseContextProvenance(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new ProtocolError(400, "context provenance must be an object", "invalid_context_item");
}
const input = value;
const provenance = {
sourceType: oneOf(input.sourceType, "context provenance sourceType", CONTEXT_SOURCE_TYPES)
};
const sourceRef = input.sourceRef === void 0 || input.sourceRef === null ? void 0 : requireString(input.sourceRef, "context provenance sourceRef", { max: 512 });
if (sourceRef !== void 0) provenance.sourceRef = redactSecrets(sourceRef);
const derivedFrom = idRefs(input.derivedFrom, "context provenance derivedFrom");
if (derivedFrom !== void 0) provenance.derivedFrom = derivedFrom;
return provenance;
}
function parseContextRequest(value) {
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new ProtocolError(400, "context request must be an object", "invalid_context_request");
}
const input = value;
const request = {
project: requireString(input.project, "context request project", { max: 200 }),
role: requireString(input.role, "context request role", { max: MAX_CONTEXT_ROLE_CHARS }),
task: requireString(input.task, "context request task", { max: MAX_CONTEXT_TASK_CHARS })
};
const workflowRunId = input.workflowRunId === void 0 || input.workflowRunId === null ? void 0 : requireString(input.workflowRunId, "context request workflowRunId", { max: 128 });
if (workflowRunId !== void 0) request.workflowRunId = workflowRunId;
const stageId = input.stageId === void 0 || input.stageId === null ? void 0 : requireString(input.stageId, "context request stageId", { max: 128 });
if (stageId !== void 0) request.stageId = stageId;
if (input.budgetTokens !== void 0 && input.budgetTokens !== null) {
const budget = input.budgetTokens;
if (!Number.isInteger(budget) || budget < MIN_CONTEXT_BUDGET_TOKENS || budget > MAX_CONTEXT_BUDGET_TOKENS) {
throw new ProtocolError(
400,
`context request budgetTokens must be an integer between ${MIN_CONTEXT_BUDGET_TOKENS} and ${MAX_CONTEXT_BUDGET_TOKENS}`,
"invalid_context_request"
);
}
request.budgetTokens = budget;
}
if (input.includeKinds !== void 0 && input.includeKinds !== null) {
if (!Array.isArray(input.includeKinds) || input.includeKinds.length < 1 || input.includeKinds.length > CONTEXT_ITEM_KINDS.length) {
throw new ProtocolError(
400,
"context request includeKinds must be a non-empty array of item kinds",
"invalid_context_request"
);
}
request.includeKinds = input.includeKinds.map((kind) => oneOf(kind, "context request includeKinds", CONTEXT_ITEM_KINDS));
}
return request;
}
function validateContextPacketContents(request, packet) {
const items = [
...packet.currentState,
...packet.knowledge,
...packet.evidence,
...packet.episodes,
...packet.skills,
...packet.contradictions
];
if (items.length > MAX_CONTEXT_ITEMS) {
throw new ProtocolError(400, `context packet exceeds ${MAX_CONTEXT_ITEMS} items`, "context_limits_exceeded");
}
const allowed = request.includeKinds ? new Set(request.includeKinds) : void 0;
for (const item of items) {
if (item.project !== request.project && item.project !== "_shared") {
throw new ProtocolError(
400,
`context packet contains cross-project item ${item.id}`,
"context_isolation_violation"
);
}
if (allowed && !allowed.has(item.kind)) {
throw new ProtocolError(
400,
`context packet contains item ${item.id} of unrequested kind ${item.kind}`,
"context_isolation_violation"
);
}
}
}
function contextItemCharacters(item) {
return item.summary.length + item.id.length + item.kind.length + (item.provenance.sourceRef?.length ?? 0);
}
function estimateContextTokens(items) {
let characters = 0;
for (const item of items) characters += contextItemCharacters(item);
return Math.ceil(characters / 4);
}
function authorityRank(authority) {
switch (authority) {
case "policy":
return 3;
case "instruction":
return 2;
case "evidence":
return 1;
case "hypothesis":
return 0;
}
}
function contextItemAuditMetadata(item) {
const metadata = {
id: item.id,
kind: item.kind,
authority: item.authority,
confidence: item.confidence,
sourceType: item.provenance.sourceType,
derived: item.provenance.sourceType === "derived" || (item.provenance.derivedFrom?.length ?? 0) > 0,
lineageDepth: item.provenance.derivedFrom?.length ?? 0
};
if (item.status !== void 0) metadata.status = item.status;
if (item.provenance.sourceRef !== void 0) metadata.sourceRef = item.provenance.sourceRef;
return metadata;
}
function provenanceSummaryOf(items) {
const summary = {};
for (const item of items) {
summary[item.provenance.sourceType] = (summary[item.provenance.sourceType] ?? 0) + 1;
}
for (const key of Object.keys(summary).sort()) {
if (summary[key] === 0) delete summary[key];
}
return summary;
}
// plugins/kxm/src/arbiter.ts
var ROLE_POLICIES = [
{
role: "repro",
label: "Reproduction specialist",
kinds: ["episode", "knowledge", "evidence"],
journalCategories: ["error", "lesson", "observation", "contradiction"],
budgetTokens: 8e3
},
{
role: "planner",
label: "Planner",
kinds: ["state", "knowledge", "evidence"],
journalCategories: ["plan", "decision", "contradiction", "observation", "hypothesis", "experiment"],
budgetTokens: 16e3
},
{
role: "critic",
label: "Independent critic",
kinds: ["knowledge", "evidence", "episode"],
journalCategories: ["contradiction", "error", "lesson", "experiment"],
budgetTokens: 12e3
},
{
role: "implementer",
label: "Implementer",
kinds: ["knowledge", "state", "skill", "episode", "evidence"],
journalCategories: ["plan", "decision", "lesson", "state-change"],
budgetTokens: 16e3
},
{
role: "verifier",
label: "Verifier",
kinds: ["evidence", "knowledge", "episode"],
journalCategories: ["plan", "error", "lesson", "contradiction"],
budgetTokens: 8e3
}
];
function rolePolicy(role) {
return ROLE_POLICIES.find((policy) => policy.role === role) ?? {
role,
label: role,
kinds: ["knowledge", "evidence"],
journalCategories: ["lesson", "observation"],
budgetTokens: DEFAULT_CONTEXT_BUDGET_TOKENS
};
}
var CONFIDENCE_RANK = { verified: 3, probable: 2, uncertain: 1 };
var AUTHORITY_WEIGHT = { policy: 3, instruction: 2, evidence: 1, hypothesis: 0 };
function arbitrate(requestInput, pool, options = {}) {
const request = parseContextRequest(requestInput);
const policy = rolePolicy(request.role);
const budget = request.budgetTokens ?? policy.budgetTokens;
const contradictions = new Set(options.contradictionIds ?? []);
const candidates = [];
let excludedSuperseded = 0;
for (const candidate of pool) {
if (candidate.project !== request.project && candidate.project !== "_shared") {
throw new ProtocolError(
403,
`context pool contains cross-project item ${candidate.id}`,
"context_isolation_violation"
);
}
if (candidate.status === "superseded" || candidate.status === "rejected") {
excludedSuperseded += 1;
continue;
}
candidates.push(candidate);
}
if (options.skillLifecycle) {
for (const metadata of options.skillLifecycle.list("promoted")) {
try {
options.skillLifecycle.verify("promoted", metadata.id);
candidates.push(parseContextItem({
id: `skill_${metadata.id}`,
kind: "skill",
project: request.project,
summary: metadata.description ? `${metadata.name}: ${metadata.description}` : metadata.name,
provenance: {
sourceType: "git",
sourceRef: `skill:${metadata.id}@${metadata.contentSha256}`
},
authority: "instruction",
confidence: "verified",
status: "current"
}));
} catch {
}
}
}
const kindRank = /* @__PURE__ */ new Map();
const requestedKinds = request.includeKinds ?? policy.kinds;
requestedKinds.forEach((kind, index) => kindRank.set(kind, index));
const kindPreference = (item) => {
const rank = kindRank.get(item.kind);
return rank === void 0 ? requestedKinds.length : rank;
};
const allowedKinds = new Set(requestedKinds);
const inertProposal = (item) => item.kind === "state" && item.status !== void 0 && item.status !== "current" || item.kind === "skill" && item.status === "proposed";
const eligible = candidates.filter((item) => contradictions.has(item.id) || allowedKinds.has(item.kind) && !inertProposal(item));
const scoreList = scoreRelevance(request.task, eligible.map(contextItemRelevanceText));
const scores = /* @__PURE__ */ new Map();
eligible.forEach((item, index) => scores.set(item, scoreList[index] ?? 0));
const scoreOf = (item) => scores.get(item) ?? 0;
const when = (item) => {
const parsed = Date.parse(item.observedAt ?? item.validFrom ?? "");
return Number.isFinite(parsed) ? parsed : 0;
};
const ordered = [...eligible].sort(
(left, right) => (contradictions.has(right.id) ? 1 : 0) - (contradictions.has(left.id) ? 1 : 0) || (left.project === request.project ? 0 : 1) - (right.project === request.project ? 0 : 1) || (scoreOf(right) > 0 ? 1 : 0) - (scoreOf(left) > 0 ? 1 : 0) || kindPreference(left) - kindPreference(right) || scoreOf(right) - scoreOf(left) || CONFIDENCE_RANK[right.confidence] - CONFIDENCE_RANK[left.confidence] || AUTHORITY_WEIGHT[right.authority] - AUTHORITY_WEIGHT[left.authority] || when(right) - when(left) || compareCodeUnitIds(left.id, right.id)
);
const selected = [];
const unresolvedGaps = [];
let characters = 0;
let deferredForBudget = 0;
for (const item of ordered) {
if (selected.length >= MAX_CONTEXT_ITEMS) {
unresolvedGaps.push("context item limit reached; refine the task or kinds");
break;
}
const itemCharacters = contextItemCharacters(item);
if (Math.ceil((characters + itemCharacters) / 4) > budget) {
deferredForBudget += 1;
continue;
}
characters += itemCharacters;
selected.push(item);
}
if (deferredForBudget > 0) {
unresolvedGaps.push(selected.length === 0 ? `budget of ${budget} tokens cannot fit any selected context` : `budget of ${budget} tokens reached; ${deferredForBudget} candidates deferred`);
}
if (candidates.length === 0) {
unresolvedGaps.push("no context records exist for this project yet");
}
const bySection = (kind) => selected.filter((item) => item.kind === kind && !contradictions.has(item.id));
const packet = {
workingState: options.workingState ?? {},
currentState: bySection("state").filter((item) => item.status === "current" || item.status === void 0),
knowledge: bySection("knowledge"),
evidence: bySection("evidence"),
episodes: bySection("episode"),
skills: bySection("skill").filter((item) => item.status !== "proposed"),
contradictions: selected.filter((item) => contradictions.has(item.id)),
unresolvedGaps,
provenanceSummary: provenanceSummaryOf(selected),
estimatedTokens: estimateContextTokens(selected)
};
validateContextPacketContents(request, packet);
return {
packet,
audit: {
request: {
project: request.project,
role: request.role,
task: request.task,
...request.workflowRunId !== void 0 ? { workflowRunId: request.workflowRunId } : {},
...request.stageId !== void 0 ? { stageId: request.stageId } : {}
},
selectedIds: selected.map((item) => item.id),
provenanceSummary: packet.provenanceSummary,
estimatedTokens: packet.estimatedTokens,
budgetTokens: budget,
candidateCount: candidates.length,
excludedSuperseded,
unresolvedGaps,
relevance: {
taskTokens: new Set(relevanceTokens(request.task)).size,
matchedCandidates: scoreList.filter((score) => score > 0).length,
selected: selected.map((item) => roundRelevance(scoreOf(item)))
}
}
};
}
function journalEntryToContextItem(entry, project) {
const kind = entry.category === "plan" || entry.category === "decision" || entry.category === "lesson" ? "knowledge" : entry.category === "skill-candidate" ? "skill" : "evidence";
const item = {
id: `journal_${entry.id}`,
kind,
project,
summary: entry.summary,
provenance: {
sourceType: "workflow",
sourceRef: `journal:${entry.id}`
},
authority: entry.category === "decision" || entry.category === "plan" ? "evidence" : "evidence",
confidence: entry.severity === "error" ? "probable" : "probable",
observedAt: entry.createdAt,
evidenceRefs: entry.evidence.filter((ref) => ref.length > 0 && ref.length <= 200).slice(0, 16)
};
if (kind === "skill") item.status = "proposed";
return parseContextItem(item);
}
function memoryRecordToContextItem(record, project) {
let authority = "instruction";
if (record.authority === "evidence") {
authority = "evidence";
}
const sourceType = CONTEXT_SOURCE_TYPES.includes(record.provenance?.sourceType) ? record.provenance.sourceType : "git";
const targetProject = record.scope === "operator" ? "_shared" : project;
return parseContextItem({
id: `mem_${record.id}`,
kind: "knowledge",
scope: record.scope,
project: targetProject,
summary: record.summary,
provenance: {
sourceType,
sourceRef: record.provenance?.sourceRef ?? `memory:${record.id}.md`
},
authority,
confidence: record.confidence,
status: record.lifecycle === "active" ? "current" : "superseded",
evidenceRefs: record.evidenceRefs && record.evidenceRefs.length > 0 ? record.evidenceRefs : void 0
});
}
function explainContextItem(id, pool) {
const byId = new Map(pool.map((item2) => [item2.id, item2]));
const item = byId.get(id);
if (!item) return { item: void 0, lineage: [], evidenceRefs: [], sources: [] };
const lineage = [];
const queue = [...item.provenance.derivedFrom ?? []];
const seen = /* @__PURE__ */ new Set();
while (queue.length > 0) {
const ancestorId = queue.shift();
if (seen.has(ancestorId)) continue;
seen.add(ancestorId);
lineage.push(ancestorId);
const ancestor = byId.get(ancestorId);
for (const older of ancestor?.provenance.derivedFrom ?? []) queue.push(older);
}
lineage.sort();
const sources = [item, ...lineage.map((ancestorId) => byId.get(ancestorId))].filter((candidate) => candidate !== void 0).map((candidate) => ({
id: candidate.id,
sourceType: candidate.provenance.sourceType,
...candidate.provenance.sourceRef !== void 0 ? { sourceRef: candidate.provenance.sourceRef } : {}
}));
return {
item,
lineage,
evidenceRefs: item.evidenceRefs ?? [],
sources
};
}
// plugins/kxm/src/memory.ts
var import_yaml4 = __toESM(require_dist(), 1);
import { existsSync as existsSync3, mkdirSync, readdirSync as readdirSync2, readFileSync as readFileSync2, writeFileSync } from "node:fs";
import { extname as extname2, join as join3, resolve as resolve2 } from "node:path";
var MEMORY_SCHEMA = "kxm.memory.v1";
var VALID_SCOPES = /* @__PURE__ */ new Set(["agent", "project", "run", "operator"]);
var VALID_AUTHORITIES = /* @__PURE__ */ new Set(["instruction", "evidence", "promoted"]);
var VALID_CONFIDENCES = /* @__PURE__ */ new Set(["verified", "probable", "uncertain"]);
var VALID_LIFECYCLES = /* @__PURE__ */ new Set(["active", "deprecated", "superseded"]);
var BANNED_CONTROL_PLANE_FIELDS = /* @__PURE__ */ new Set([
"permissions",
"tools",
"allow",
"deny",
"grants",
"approval",
"policy",
"scopes",
"credentials",
"secrets",
"token",
"apiKey",
"password"
]);
function parseFrontmatter(content) {
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
if (!match) {
throw new Error("memory file must contain YAML frontmatter enclosed in '---'");
}
return { frontmatter: match[1] ?? "", body: match[2]?.trim() ?? "" };
}
function parseMemoryRecord(raw, filename = "memory.md") {
const { frontmatter, body } = parseFrontmatter(raw);
const data = (0, import_yaml4.parse)(frontmatter);
if (!data || typeof data !== "object" || Array.isArray(data)) {
throw new Error(`invalid YAML frontmatter in ${filename}`);
}
for (const field of BANNED_CONTROL_PLANE_FIELDS) {
if (field in data) {
throw new Error(`memory record ${filename} may not carry control-plane field '${field}'`);
}
}
if (data.schema !== MEMORY_SCHEMA) {
throw new Error(`memory record ${filename} has unsupported schema: expected ${MEMORY_SCHEMA}, got ${String(data.schema)}`);
}
const id = typeof data.id === "string" ? data.id.trim() : "";
if (!id || !/^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/i.test(id)) {
throw new Error(`memory record ${filename} has invalid id: ${String(data.id)}`);
}
const scope = data.scope;
if (!VALID_SCOPES.has(scope)) {
throw new Error(`memory record ${filename} has invalid scope: must be one of agent, project, run, operator`);
}
const kind = typeof data.kind === "string" ? data.kind.trim() : "";
if (!kind) {
throw new Error(`memory record ${filename} is missing kind`);
}
const rawSummary = typeof data.summary === "string" ? data.summary.trim() : "";
if (!rawSummary) {
throw new Error(`memory record ${filename} is missing summary`);
}
const summary = redactSecrets(rawSummary);
const rawProv = data.provenance;
if (!rawProv || typeof rawProv !== "object" || typeof rawProv.sourceType !== "string" || !rawProv.sourceType.trim()) {
throw new Error(`memory record ${filename} is missing provenance.sourceType`);
}
const provenance = {
sourceType: rawProv.sourceType.trim(),
...typeof rawProv.sourceRef === "string" ? { sourceRef: redactSecrets(rawProv.sourceRef.trim()) } : {},
...typeof rawProv.runId === "string" ? { runId: rawProv.runId.trim() } : {},
...typeof rawProv.timestamp === "string" ? { timestamp: rawProv.timestamp.trim() } : {}
};
const authority = data.authority;
if (!VALID_AUTHORITIES.has(authority)) {
throw new Error(`memory record ${filename} has invalid authority: ${String(data.authority)}`);
}
const confidence = data.confidence;
if (!VALID_CONFIDENCES.has(confidence)) {
throw new Error(`memory record ${filename} has invalid confidence: ${String(data.confidence)}`);
}
const lifecycle = data.lifecycle;
if (!VALID_LIFECYCLES.has(lifecycle)) {
throw new Error(`memory record ${filename} has invalid lifecycle: ${String(data.lifecycle)}`);
}
const rawRefs = Array.isArray(data.evidenceRefs) ? data.evidenceRefs : [];
const evidenceRefs = rawRefs.map(String);
return {
schema: MEMORY_SCHEMA,
id,
scope,
kind,
summary,
provenance,
authority,
confidence,
lifecycle,
evidenceRefs,
...body ? { body } : {}
};
}
function memoryDirectories(repoRoot) {
const root = resolve2(repoRoot);
const memoryDir = join3(root, ".kxm", "memory");
const candidatesDir = join3(memoryDir, "candidates");
return { memoryDir, candidatesDir };
}
function loadAuthoredMemory(repoRoot) {
const { memoryDir } = memoryDirectories(repoRoot);
if (!existsSync3(memoryDir)) return [];
const records = [];
const entries = readdirSync2(memoryDir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isFile() && extname2(entry.name) === ".md") {
const fullPath = join3(memoryDir, entry.name);
try {
const text2 = readFileSync2(fullPath, "utf8");
const record = parseMemoryRecord(text2, entry.name);
if (record.lifecycle === "active") {
records.push(record);
}
} catch (error) {
throw new Error(`failed to parse authored memory file ${entry.name}: ${error instanceof Error ? error.message : String(error)}`);
}
}
}
return records.sort((left, right) => left.id.localeCompare(right.id));
}
// plugins/kxm/src/state.ts
var MAX_STATE_EVIDENCE_REFS = 32;
function timestampMs(value) {
if (value === void 0) return Number.NEGATIVE_INFINITY;
const parsed = Date.parse(value);
return Number.isFinite(parsed) ? parsed : Number.NEGATIVE_INFINITY;
}
function stateActiveAt(item, atMs) {
if (item.kind !== "state") return false;
if (item.status !== "current" && item.status !== "superseded") return false;
const from = timestampMs(item.validFrom);
const until = item.validUntil === void 0 ? Number.POSITIVE_INFINITY : timestampMs(item.validUntil);
return from <= atMs && atMs < until;
}
function latestActive(items) {
let best;
for (const item of items) {
if (best === void 0 || timestampMs(item.validFrom) > timestampMs(best.validFrom) || timestampMs(item.validFrom) === timestampMs(best.validFrom) && item.id > best.id) {
best = item;
}
}
return best;
}
function findSuperseder(items, id) {
return items.find((item) => (item.supersedes ?? []).includes(id));
}
function detectStateContradictions(project, items, setValuedKeys = /* @__PURE__ */ new Set()) {
const byKey = /* @__PURE__ */ new Map();
for (const item of items) {
if (item.kind !== "state" || item.project !== project) continue;
const key = item.stateKey ?? "";
const bucket = byKey.get(key) ?? [];
bucket.push(item);
byKey.set(key, bucket);
}
const contradictions = [];
for (const [stateKey, bucket] of [...byKey.entries()].sort(([left], [right]) => left.localeCompare(right))) {
if (setValuedKeys.has(stateKey)) continue;
const competingCurrentIds = bucket.filter((item) => item.status === "current").map((item) => item.id).sort();
const competingProposalIds = bucket.filter((item) => item.status === "proposed").map((item) => item.id).sort();
if (competingCurrentIds.length > 1 || competingProposalIds.length > 1) {
contradictions.push({ project, stateKey, competingCurrentIds, competingProposalIds });
}
}
return contradictions;
}
function parseStateItem(value) {
const item = parseContextItem(value);
if (item.kind !== "state") {
throw new ProtocolError(400, "state layer accepts only state items", "invalid_state_item");
}
return item;
}
var NativeStateProvider = class {
name = "native-sqlite";
store;
now;
setValuedKeys;
constructor(store, options = {}) {
this.store = store;
this.now = options.now ?? nowIso;
this.setValuedKeys = options.setValuedKeys ?? /* @__PURE__ */ new Set();
}
projectState(project) {
return this.store.listContextItems(project, ["state"]);
}
itemsForKey(project, key) {
return this.projectState(project).filter((item) => item.stateKey === key);
}
/** Current value for a key at a point in time. Superseded values never
* appear as current: historical queries return the item that *was* current
* at `asOf` via its validity window. Fails closed when a single-valued key
* holds competing current items. */
async get(project, key, asOf) {
const scopedProject = requireNonEmpty(project, "project");
const scopedKey = requireNonEmpty(key, "key");
if (this.setValuedKeys.has(scopedKey)) {
throw new ProtocolError(
400,
`state key ${scopedKey} is set-valued; use currentSet`,
"state_key_set_valued"
);
}
const atMs = asOf === void 0 ? Date.parse(this.now()) : requireIso(asOf, "asOf");
const active = this.itemsForKey(scopedProject, scopedKey).filter((item) => stateActiveAt(item, atMs));
const currents = active.filter((item) => item.status === "current");
if (currents.length > 1) {
throw new ProtocolError(
409,
`state key ${scopedKey} has competing current items; resolve the contradiction first`,
"state_contradiction"
);
}
const winner = currents.length === 1 ? currents[0] : latestActive(active);
return winner ?? null;
}
/** All current items for a set-valued key. */
async currentSet(project, key) {
const scopedProject = requireNonEmpty(project, "project");
const scopedKey = requireNonEmpty(key, "key");
if (!this.setValuedKeys.has(scopedKey)) {
throw new ProtocolError(400, `state key ${scopedKey} is single-valued`, "state_key_single_valued");
}
return this.itemsForKey(scopedProject, scopedKey).filter((item) => item.status === "current").sort((left, right) => left.id.localeCompare(right.id));
}
/** Record a proposal. Proposing changes nothing until an authorized,
* evidence-bound promotion runs. Returns the durable proposal item ID. */
async propose(change) {
if (change?.schema !== "kxm.state-change-proposal.v1") {
throw new ProtocolError(400, "invalid state change proposal schema", "invalid_state_proposal");
}
if (change.origin !== "peer" && change.origin !== "human") {
throw new ProtocolError(400, "state change proposal origin must be peer or human", "invalid_state_proposal");
}
const project = requireNonEmpty(change.project, "proposal project");
const key = requireNonEmpty(change.key, "proposal key");
const evidenceRefs = boundedRefs(change.evidenceRefs, "proposal evidenceRefs");
const proposal = parseStateItem({
id: newId("ctx"),
kind: "state",
project,
summary: change.summary,
provenance: {
sourceType: change.origin,
sourceRef: `proposed-by:${change.proposedBy}`
},
authority: change.authority,
confidence: change.confidence,
stateKey: key,
status: "proposed",
validFrom: this.now(),
evidenceRefs,
...change.supersedes ? { supersedes: boundedRefs(change.supersedes, "proposal supersedes") } : {}
});
this.store.saveContextItem(proposal);
return proposal.id;
}
/** Promote a proposal to current with durable evidence. The promoter must
* differ from the proposal author (agents may propose but never silently
* promote). Superseded previous values get an explicit validity window so
* historical queries stay deterministic. */
async promote(proposalId, evidence, promotedBy) {
const id = requireNonEmpty(proposalId, "proposalId");
const promoter = requireNonEmpty(promotedBy, "promotedBy");
const evidenceRefs = boundedRefs(evidence, "promotion evidence");
const proposal = this.store.getContextItem(id);
if (!proposal || proposal.kind !== "state") {
throw new ProtocolError(404, `state proposal ${id} not found`, "state_proposal_not_found");
}
if (proposal.status !== "proposed") {
throw new ProtocolError(
400,
`state proposal ${id} already reached lifecycle state ${proposal.status}`,
"state_proposal_not_promotable"
);
}
const proposedBy = proposal.provenance.sourceRef?.startsWith("proposed-by:") ? proposal.provenance.sourceRef.slice("proposed-by:".length) : void 0;
if (proposedBy === promoter) {
throw new ProtocolError(
400,
"the author of a state proposal cannot promote it",
"state_promotion_invalid"
);
}
const now = this.now();
const key = proposal.stateKey ?? "";
if (!key) {
throw new ProtocolError(400, "state proposal has no stateKey", "state_promotion_invalid");
}
let supersededIds = [];
if (!this.setValuedKeys.has(key)) {
const atMs = Date.parse(now);
const supersededItems = this.itemsForKey(proposal.project, key).filter((item) => item.status === "current" && stateActiveAt(item, atMs));
supersededIds = supersededItems.map((item) => item.id);
for (const item of supersededItems) {
this.store.saveContextItem({
...item,
status: "superseded",
validUntil: now
});
}
}
const promoted = parseStateItem({
...proposal,
id: newId("ctx"),
status: "current",
validFrom: now,
validUntil: void 0,
supersedes: [.../* @__PURE__ */ new Set([...proposal.supersedes ?? [], ...supersededIds])].sort(),
evidenceRefs: [.../* @__PURE__ */ new Set([...proposal.evidenceRefs ?? [], ...evidenceRefs])].sort(),
provenance: {
...proposal.provenance,
sourceRef: `promoted-by:${promoter}`
}
});
this.store.saveContextItem({ ...proposal, status: "rejected", validUntil: now });
this.store.saveContextItem(promoted);
return promoted;
}
/** Which item superseded `id`, if any. */
async supersededBy(project, id) {
const scopedProject = requireNonEmpty(project, "project");
const superseder = findSuperseder(this.projectState(scopedProject), id);
return superseder ?? null;
}
/** Audit trail for one key: proposals, promotions, and supersessions in
* deterministic order. */
stateHistory(project, key) {
return this.itemsForKey(project, key).sort(
(left, right) => timestampMs(left.validFrom) - timestampMs(right.validFrom) || left.id.localeCompare(right.id)
);
}
contradictions() {
const projects = [...new Set([...this.store.contextItems.values()].map((item) => item.project))];
return projects.flatMap((project) => detectStateContradictions(project, this.projectState(project), this.setValuedKeys));
}
};
function requireNonEmpty(value, field) {
if (typeof value !== "string" || !value.trim()) {
throw new ProtocolError(400, `${field} cannot be empty`, "invalid_state_request");
}
return value.trim();
}
function requireIso(value, field) {
const parsed = Date.parse(value);
if (!Number.isFinite(parsed)) {
throw new ProtocolError(400, `${field} must be an ISO-8601 timestamp`, "invalid_state_request");
}
return parsed;
}
function boundedRefs(value, field) {
if (!Array.isArray(value) || value.length < 1 || value.length > MAX_STATE_EVIDENCE_REFS) {
throw new ProtocolError(
400,
`${field} must contain between 1 and ${MAX_STATE_EVIDENCE_REFS} references`,
"state_promotion_invalid"
);
}
return value.map((ref) => requireNonEmpty(ref, `${field} entry`));
}
// plugins/kxm/src/skills.ts
var import_yaml5 = __toESM(require_dist(), 1);
import { createHash as createHash4 } from "node:crypto";
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readdirSync as readdirSync3, readFileSync as readFileSync3, renameSync, rmSync, statSync, writeFileSync as writeFileSync2 } from "node:fs";
import { dirname as dirname4, join as join4 } from "node:path";
var SKILL_CANDIDATE_SCHEMA = "kxm.skill-candidate.v1";
var SKILL_EVALUATION_SCHEMA = "kxm.skill-evaluation.v1";
var SKILL_DECISION_SCHEMA = "kxm.skill-decision.v1";
var MAX_SKILL_NAME_CHARS = 64;
var MAX_SKILL_CONTENT_CHARS = 32e3;
var MAX_SKILL_EVIDENCE_REFS = 32;
var MAX_SKILL_MODELS = 16;
var PROMOTION_REQUIRED_EVALUATIONS = [
"static-review",
"sandbox",
"functional",
"safety"
];
var SkillLifecycleError = class extends Error {
code;
constructor(code, message) {
super(message);
this.name = "SkillLifecycleError";
this.code = code;
}
};
function skillContentSha256(content) {
return createHash4("sha256").update(content, "utf8").digest("hex");
}
function skillIdFor(name, contentSha256) {
const slug = name.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
if (!slug) throw new SkillLifecycleError("invalid_skill_name", "skill name must contain alphanumeric characters");
return `${slug}.${contentSha256.slice(0, 12)}`;
}
function parseSkillFrontmatter(content) {
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
if (!match) {
return { frontmatter: null, body: content };
}
const rawFm = match[1];
const rawBody = match[2];
if (rawFm === void 0 || rawBody === void 0) {
return { frontmatter: null, body: content };
}
try {
const parsed = (0, import_yaml5.parse)(rawFm);
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
return { frontmatter: parsed, body: rawBody };
}
} catch {
}
return { frontmatter: null, body: content };
}
function ensureSkillFrontmatter(content, name, description) {
const parsed = parseSkillFrontmatter(content);
if (parsed.frontmatter) {
const fmName = typeof parsed.frontmatter.name === "string" && parsed.frontmatter.name.trim() ? parsed.frontmatter.name.trim() : name;
const fmDesc = typeof parsed.frontmatter.description === "string" && parsed.frontmatter.description.trim() ? parsed.frontmatter.description.trim() : description || `Governed skill for ${fmName}`;
const rest2 = parsed.body.replace(/^(\r?\n)+/, "");
return `---
name: ${fmName}
description: ${fmDesc}
---
${rest2}`;
}
const desc = description || `Governed skill for ${name}`;
const rest = content.replace(/^(\r?\n)+/, "");
return `---
name: ${name}
description: ${desc}
---
${rest}`;
}
function createUnifiedPatch(relativePath, content) {
const lines = content.split("\n");
const count = lines.length;
const header = [
`diff --git a/${relativePath} b/${relativePath}`,
"new file mode 100644",
"--- /dev/null",
`+++ b/${relativePath}`,
`@@ -0,0 +1,${count} @@`
];
const body = lines.map((l) => `+${l}`);
return [...header, ...body, ""].join("\n");
}
var SkillLifecycle = class {
root;
now;
allowOptimizationEvals;
dryRun;
/** What a `dryRun` lifecycle would have written or moved, in order. */
planned = [];
constructor(root, options = {}) {
this.root = root;
this.now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
this.allowOptimizationEvals = options.allowOptimizationEvals === true;
this.dryRun = options.dryRun === true;
}
write(file, content) {
if (this.dryRun) {
this.planned.push({ action: "write", target: file });
return;
}
mkdirSync2(dirname4(file), { recursive: true });
writeFileSync2(file, content);
}
dir(state) {
return join4(this.root, state === "candidate" ? "candidates" : `${state}s`.replace("rejecteds", "rejected").replace("promoteds", "promoted"));
}
historyFile(id) {
return join4(this.root, "history", `${id}.jsonl`);
}
paths(state, id) {
const dir = join4(this.dir(state), id);
return { dir, metadata: join4(dir, "metadata.json"), skill: join4(dir, "SKILL.md") };
}
appendHistory(id, record) {
const line = `${JSON.stringify(record)}
`;
if (existsSync4(this.historyFile(id))) {
const existing = readFileSync3(this.historyFile(id), "utf8");
const lines = existing.split("\n").filter((entry) => entry.trim());
this.write(this.historyFile(id), [...lines.slice(-499), line.trim()].join("\n") + "\n");
} else {
this.write(this.historyFile(id), line);
}
}
history(id) {
const file = this.historyFile(id);
if (!existsSync4(file)) return [];
return readFileSync3(file, "utf8").split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
}
readMetadata(state, id) {
const { metadata } = this.paths(state, id);
if (!existsSync4(metadata)) {
throw new SkillLifecycleError("skill_not_found", `skill ${id} not found in ${state}`);
}
return JSON.parse(readFileSync3(metadata, "utf8"));
}
move(from, to, id) {
const fromDir = join4(this.dir(from), id);
const toDir = join4(this.dir(to), id);
if (!existsSync4(fromDir)) {
throw new SkillLifecycleError("skill_not_found", `skill ${id} not found in ${from}`);
}
if (this.dryRun) {
this.planned.push({ action: "move", target: `${fromDir} -> ${toDir}` });
return;
}
mkdirSync2(this.dir(to), { recursive: true });
if (existsSync4(toDir)) rmSync(toDir, { recursive: true, force: true });
renameSync(fromDir, toDir);
}
/** Submit a new skill candidate. Content is redacted of secret material at
* creation; the ID is derived from name + content hash. */
create(input) {
const name = input.name?.trim();
if (!name || name.length > MAX_SKILL_NAME_CHARS) {
throw new SkillLifecycleError("invalid_skill_name", `skill name must be 1-${MAX_SKILL_NAME_CHARS} characters`);
}
const rawContent = redactSecrets(input.content ?? "");
if (!rawContent.trim() || rawContent.length > MAX_SKILL_CONTENT_CHARS) {
throw new SkillLifecycleError("invalid_skill_content", `skill content must be 1-${MAX_SKILL_CONTENT_CHARS} characters`);
}
const rawDesc = redactSecrets(input.description?.trim() ?? "");
const content = ensureSkillFrontmatter(rawContent, name, rawDesc);
if (content.length > MAX_SKILL_CONTENT_CHARS) {
throw new SkillLifecycleError("invalid_skill_content", `skill content must be 1-${MAX_SKILL_CONTENT_CHARS} characters`);
}
const { frontmatter } = parseSkillFrontmatter(content);
const description = typeof frontmatter?.description === "string" && frontmatter.description.trim() ? frontmatter.description.trim() : rawDesc || `Governed skill for ${name}`;
const sources = {
runIds: boundedList(input.sources?.runIds, "runIds"),
journalEntryIds: boundedList(input.sources?.journalEntryIds, "journalEntryIds"),
evidenceReceipts: boundedList(input.sources?.evidenceReceipts, "evidenceReceipts")
};
if (sources.runIds.length === 0 && sources.journalEntryIds.length === 0 && sources.evidenceReceipts.length === 0) {
throw new SkillLifecycleError(
"skill_sources_required",
"a skill candidate must reference at least one source run, journal entry, or evidence receipt"
);
}
const createdBy = input.createdBy?.trim();
if (!createdBy) throw new SkillLifecycleError("invalid_skill_author", "createdBy is required");
const models = boundedList(input.compatibility?.models, "compatibility.models");
if (models.length === 0 || models.length > MAX_SKILL_MODELS) {
throw new SkillLifecycleError("invalid_skill_compatibility", `compatibility.models must list 1-${MAX_SKILL_MODELS} models`);
}
const harness = input.compatibility?.harness?.trim();
if (!harness) throw new SkillLifecycleError("invalid_skill_compatibility", "compatibility.harness is required");
const contentSha256 = skillContentSha256(content);
const id = skillIdFor(name, contentSha256);
const { metadata, skill } = this.paths("candidate", id);
if (existsSync4(metadata)) {
throw new SkillLifecycleError(
"skill_candidate_exists",
`identical candidate ${id} already exists; changed behavior requires changed content`
);
}
const record = {
schema: SKILL_CANDIDATE_SCHEMA,
id,
name,
description,
contentSha256,
version: input.version ?? 1,
sources,
compatibility: { harness, models },
createdBy,
createdAt: this.now(),
...input.supersedes ? { supersedes: input.supersedes } : {}
};
this.write(skill, content);
this.write(metadata, `${JSON.stringify(record, null, 2)}
`);
this.appendHistory(id, { schema: "kxm.skill-history-event.v1", event: "candidate_created", by: createdBy, supersedes: input.supersedes, at: record.createdAt });
return record;
}
/** Record a protected evaluation. A failed functional or safety evaluation
* deterministically quarantines the candidate. */
evaluate(candidateId, input) {
if (input.kind === "optimization" && !this.allowOptimizationEvals) {
throw new SkillLifecycleError(
"skill_optimization_disabled",
"optimization evaluations are disabled; enable them explicitly behind protected evals"
);
}
const metadata = this.readMetadata("candidate", candidateId);
const evaluatorVersion = input.evaluatorVersion?.trim();
if (!evaluatorVersion) throw new SkillLifecycleError("invalid_skill_evaluation", "evaluatorVersion is required");
const evaluation = {
schema: SKILL_EVALUATION_SCHEMA,
candidateId,
kind: input.kind,
evaluatorVersion,
passed: input.passed === true,
...input.score !== void 0 ? { score: input.score } : {},
...input.details ? { details: redactSecrets(input.details.slice(0, 2e3)) } : {},
evaluatedAt: this.now()
};
this.appendHistory(candidateId, evaluation);
let quarantined = false;
if (!evaluation.passed && (input.kind === "functional" || input.kind === "safety")) {
const decision = {
schema: SKILL_DECISION_SCHEMA,
candidateId,
decision: "quarantined",
decidedBy: input.evaluatedBy?.trim() || `evaluator:${evaluatorVersion}`,
reason: `automatic quarantine: ${input.kind} evaluation failed (${evaluatorVersion})`,
evidenceRefs: [`evaluation:${input.kind}:${evaluatorVersion}`],
decidedAt: this.now()
};
this.move("candidate", "quarantined", candidateId);
this.appendHistory(candidateId, decision);
quarantined = true;
}
return { evaluation, quarantined };
}
evaluationsFor(candidateId) {
return this.history(candidateId).filter(
(record) => record.schema === SKILL_EVALUATION_SCHEMA
);
}
/** Promote a candidate that passed every protected evaluation. The
* promoter must differ from the author, cite durable evidence, and the
* promoted content is hash-pinned and immutable. Emits a unified diff patch
* instead of moving the candidate directory. */
promote(candidateId, decision) {
const metadata = this.readMetadata("candidate", candidateId);
const decidedBy = decision.decidedBy?.trim();
if (!decidedBy) throw new SkillLifecycleError("invalid_skill_decision", "decidedBy is required");
if (decidedBy === metadata.createdBy) {
throw new SkillLifecycleError("skill_promotion_invalid", "the author of a skill candidate cannot promote it");
}
const evidenceRefs = boundedList(decision.evidenceRefs, "evidenceRefs");
if (evidenceRefs.length === 0) {
throw new SkillLifecycleError("skill_promotion_invalid", "promotion requires durable evidence references");
}
const evaluations = this.evaluationsFor(candidateId);
const missing = [];
for (const kind of PROMOTION_REQUIRED_EVALUATIONS) {
const latest = [...evaluations].reverse().find((record2) => record2.kind === kind);
if (!latest || !latest.passed) missing.push(kind);
}
if (missing.length > 0) {
throw new SkillLifecycleError(
"skill_evaluations_incomplete",
`promotion requires passing ${missing.join(", ")} evaluations`
);
}
this.verify("candidate", candidateId);
const record = {
schema: SKILL_DECISION_SCHEMA,
candidateId,
decision: "promoted",
decidedBy,
reason: decision.reason?.trim() || "passed protected evaluation",
evidenceRefs,
decidedAt: this.now()
};
const candidatePaths = this.paths("candidate", candidateId);
const promotedPaths = this.paths("promoted", candidateId);
const skillContent = readFileSync3(candidatePaths.skill, "utf8");
const metadataContent = readFileSync3(candidatePaths.metadata, "utf8");
this.write(promotedPaths.skill, skillContent);
this.write(promotedPaths.metadata, metadataContent);
const patchPath = join4(this.root, "patches", `${candidateId}.patch`);
const relSkillPath = `.kxm/skills/promoted/${candidateId}/SKILL.md`;
const relMetaPath = `.kxm/skills/promoted/${candidateId}/metadata.json`;
const patch = `${createUnifiedPatch(relSkillPath, skillContent)}${createUnifiedPatch(relMetaPath, metadataContent)}`;
this.write(patchPath, patch);
this.appendHistory(candidateId, record);
return { ...metadata, patch, patchPath };
}
reject(candidateId, decision) {
const metadata = this.readMetadata("candidate", candidateId);
const record = {
schema: SKILL_DECISION_SCHEMA,
candidateId,
decision: "rejected",
decidedBy: decision.decidedBy?.trim() || "kxm-admin",
reason: decision.reason?.trim() || "rejected",
evidenceRefs: [],
decidedAt: this.now()
};
this.move("candidate", "rejected", candidateId);
this.appendHistory(candidateId, record);
return metadata;
}
/** Verify content integrity of a stored skill (any state). Detects
* out-of-band edits to promoted skills and verifies standard YAML frontmatter. */
verify(state, id) {
const metadata = this.readMetadata(state, id);
const { skill } = this.paths(state, id);
const content = readFileSync3(skill, "utf8");
if (skillContentSha256(content) !== metadata.contentSha256) {
throw new SkillLifecycleError(
"skill_integrity_violation",
`skill ${id} content does not match its pinned hash; promoted skills are immutable and require a new candidate/eval cycle`
);
}
const { frontmatter } = parseSkillFrontmatter(content);
if (!frontmatter || typeof frontmatter.name !== "string" || !frontmatter.name.trim() || typeof frontmatter.description !== "string" || !frontmatter.description.trim()) {
throw new SkillLifecycleError(
"invalid_skill_frontmatter",
`skill ${id} must contain valid YAML frontmatter with 'name' and 'description'`
);
}
return metadata;
}
list(state) {
const dir = this.dir(state);
if (!existsSync4(dir)) return [];
const ids = readdirSorted(dir);
return ids.map((id) => {
try {
return this.readMetadata(state, id);
} catch {
return void 0;
}
}).filter((metadata) => metadata !== void 0);
}
read(state, id) {
const metadata = this.readMetadata(state, id);
const { skill } = this.paths(state, id);
return { metadata, content: readFileSync3(skill, "utf8") };
}
};
function boundedList(value, field) {
if (value === void 0) return [];
if (!Array.isArray(value)) {
throw new SkillLifecycleError("invalid_skill_input", `${field} must be an array of strings`);
}
const refs = value.map((ref) => String(ref).trim()).filter((ref) => ref.length > 0);
if (refs.length > MAX_SKILL_EVIDENCE_REFS) {
throw new SkillLifecycleError("invalid_skill_input", `${field} exceeds ${MAX_SKILL_EVIDENCE_REFS} references`);
}
return [...new Set(refs)];
}
function readdirSorted(dir) {
return readdirSync3(dir).filter((entry) => statSync(join4(dir, entry)).isDirectory()).sort();
}
// plugins/kxm/src/wiki.ts
var WIKI_ROOT = ".kxm/knowledge/wiki";
var SECTION_BY_KIND = {
knowledge: "architecture",
decision: "decisions",
episode: "incidents",
skill: "patterns"
};
function wikiSectionFor(item) {
if (SECTION_BY_KIND[item.kind]) return SECTION_BY_KIND[item.kind];
if (item.provenance.sourceRef?.startsWith("journal:")) {
return "incidents";
}
return "patterns";
}
function claimLine(item) {
const refs = [`\`${item.id}\``];
if (item.provenance.sourceRef) refs.push(`source: \`${item.provenance.sourceRef}\``);
const lineage = item.provenance.derivedFrom ?? [];
if (lineage.length > 0) refs.push(`derived from: ${lineage.map((id) => `\`${id}\``).join(", ")}`);
const authority = item.authority === "policy" || item.authority === "instruction" ? ` (${item.authority})` : "";
return `- ${redactSecrets(item.summary)}${authority} \u2014 ${refs.join(" \xB7 ")}`;
}
function page(title, heading, claims, footer) {
const lines = [
`# ${title}`,
"",
heading,
"",
...claims.length > 0 ? claims.map(claimLine) : ["_No reviewed records yet._"],
"",
footer
];
return `${lines.join("\n")}
`;
}
var GENERATED_FOOTER = "<!-- generated by kxm context wiki-compile; the wiki is a compiled view, not the authoritative database -->";
function compileKnowledgeWiki(pool) {
const pages = /* @__PURE__ */ new Map();
const live = pool.contextItems.filter(
(item) => item.status !== "superseded" && item.status !== "rejected"
);
const superseded = pool.contextItems.filter((item) => item.status === "superseded");
const sections = /* @__PURE__ */ new Map();
for (const item of live) {
const section = wikiSectionFor(item);
const bucket = sections.get(section) ?? [];
bucket.push(item);
sections.set(section, bucket);
}
const indexLines = [
`# ${pool.project} knowledge wiki`,
"",
"Compiled synthesis of durable journal evidence, temporal state, and governed records. Every claim links back to its evidence; open contradictions are listed, never silently resolved.",
""
];
for (const section of [...sections.keys()].sort()) {
const items = sections.get(section).sort((left, right) => left.id.localeCompare(right.id));
const path = `${WIKI_ROOT}/${section}/${pool.project}.md`;
pages.set(
path,
page(
`${pool.project} \u2014 ${section}`,
`Claims below are compiled from reviewed records. Each line links the record ID and source.`,
items,
GENERATED_FOOTER
)
);
indexLines.push(`- [${section}](${section}/${pool.project}.md) \u2014 ${items.length} claim(s)`);
}
const currentState = pool.stateItems.filter((item) => item.status === "current");
const supersededState = pool.stateItems.filter((item) => item.status === "superseded");
const statePath = `${WIKI_ROOT}/architecture/${pool.project}-state.md`;
const stateLines = [
`# ${pool.project} \u2014 temporal state`,
"",
"Rendered from the authoritative state layer. Current values are live; superseded values are kept visible with their validity window and successor link.",
"",
"## Current",
"",
...currentState.length > 0 ? currentState.sort((left, right) => (left.stateKey ?? "").localeCompare(right.stateKey ?? "")).map((item) => claimLine(item)) : ["_No current state records._"],
"",
"## Superseded",
"",
...supersededState.length > 0 ? supersededState.sort((left, right) => (left.stateKey ?? "").localeCompare(right.stateKey ?? "")).map((item) => claimLine(item)) : ["_No superseded state records._"],
"",
GENERATED_FOOTER
];
pages.set(statePath, `${stateLines.join("\n")}
`);
indexLines.push(`- [temporal state](${pool.project}-state.md) \u2014 ${currentState.length} current, ${supersededState.length} superseded`);
const decisions = live.filter((item) => item.kind === "knowledge" && item.provenance.sourceRef?.startsWith("journal:") === false);
if (decisions.length > 0) {
pages.set(
`${WIKI_ROOT}/decisions/${pool.project}.md`,
page(
`${pool.project} \u2014 decisions`,
"Decision records with their evidence links.",
decisions.sort((left, right) => left.id.localeCompare(right.id)),
GENERATED_FOOTER
)
);
indexLines.push(`- [decisions (tracked records)](decisions/${pool.project}.md) \u2014 ${decisions.length}`);
}
const contradictionLines = [
`# ${pool.project} \u2014 open contradictions`,
"",
"These remain unresolved by compilation. Resolution happens through evidence-backed state promotion or journal decisions, never through re-generating this page.",
""
];
let contradictionCount = 0;
for (const contradiction of [...pool.contradictions].sort((left, right) => left.stateKey.localeCompare(right.stateKey))) {
contradictionCount += 1;
contradictionLines.push(
`## \`${contradiction.stateKey}\``,
"",
`- Competing current records: ${contradiction.competingCurrentIds.map((id) => `\`${id}\``).join(", ") || "none"}`,
`- Competing proposals: ${contradiction.competingProposalIds.map((id) => `\`${id}\``).join(", ") || "none"}`,
""
);
}
for (const id of [...pool.openContradictionItemIds].sort()) {
contradictionCount += 1;
contradictionLines.push(`- Unresolved journal contradiction: \`${id}\``);
}
if (contradictionCount === 0) contradictionLines.push("_No open contradictions._");
contradictionLines.push("", GENERATED_FOOTER);
pages.set(`${WIKI_ROOT}/contradictions/${pool.project}.md`, `${contradictionLines.join("\n")}
`);
indexLines.push(`- [contradictions](contradictions/${pool.project}.md) \u2014 ${contradictionCount} open`);
if (superseded.length > 0) {
pages.set(
`${WIKI_ROOT}/incidents/${pool.project}-history.md`,
page(
`${pool.project} \u2014 superseded knowledge history`,
"Superseded records retained for learning. Never presented as current truth.",
superseded.sort((left, right) => left.id.localeCompare(right.id)),
GENERATED_FOOTER
)
);
indexLines.push(`- [superseded history](incidents/${pool.project}-history.md) \u2014 ${superseded.length}`);
}
indexLines.push("", GENERATED_FOOTER);
const index = `${indexLines.join("\n")}
`;
pages.set(`${WIKI_ROOT}/index.md`, index);
return {
pages,
index,
audit: {
project: pool.project,
pages: [...pages.keys()].sort(),
stateItems: pool.stateItems.length,
contextItems: pool.contextItems.length,
contradictions: contradictionCount,
compiledAt: pool.compiledAt
}
};
}
function lintKnowledgeWiki(pages, pool) {
const issues = [];
const knownIds = /* @__PURE__ */ new Set([
...pool.stateItems.map((item) => item.id),
...pool.contextItems.map((item) => item.id)
]);
const index = pages.get(`${WIKI_ROOT}/index.md`);
for (const [path, content] of pages) {
if (path.endsWith("index.md")) continue;
for (const match of content.matchAll(/`((?:ctx|journal)_[A-Za-z0-9_]+)`/g)) {
const id = match[1];
if (!knownIds.has(id)) {
issues.push({ severity: "error", rule: "broken_ref", path, message: `references unknown record ${id}` });
}
}
if (index && !index.includes(path.split("/").pop())) {
issues.push({ severity: "warning", rule: "orphan_page", path, message: "not linked from index.md" });
}
for (const item of pool.stateItems) {
if (item.status !== "superseded" || !item.stateKey) continue;
const claimPattern = new RegExp(`Current[\\s\\S]{0,400}\`${item.id}\``, "u");
if (claimPattern.test(content)) {
issues.push({
severity: "error",
rule: "stale_state_link",
path,
message: `renders superseded state item ${item.id} (key ${item.stateKey}) as current`
});
}
}
}
const hasContradictions = pool.contradictions.length > 0 || pool.openContradictionItemIds.length > 0;
if (hasContradictions && index && !index.includes("contradictions")) {
issues.push({
severity: "error",
rule: "unresolved_contradiction",
path: `${WIKI_ROOT}/index.md`,
message: "open contradictions exist but the index does not surface them"
});
}
return issues.sort((left, right) => left.path.localeCompare(right.path) || left.message.localeCompare(right.message));
}
// plugins/kxm/src/retrospective.ts
import { mkdirSync as mkdirSync3, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "node:fs";
import { resolve as resolve3 } from "node:path";
var MAX_RETROSPECTIVE_ENTRIES = 500;
var SAFE_RUN_ID = /^run_[A-Za-z0-9_-]{1,120}$/;
function durationMs(startedAt, completedAt) {
if (!startedAt || !completedAt) return void 0;
const value = Date.parse(completedAt) - Date.parse(startedAt);
return Number.isFinite(value) && value >= 0 ? value : void 0;
}
function increment(map, key) {
map[key] = (map[key] ?? 0) + 1;
}
function classFromEvidence(evidence) {
const match = evidence.find((item) => item.startsWith("class:"));
return match?.slice("class:".length) || "unknown";
}
function buildEvidenceAudit(run) {
const audit = [];
for (const stage of run.stages) {
const verifiedEvidence = normalizeVerifiedWorkflowEvidence(stage.verifiedEvidence);
const degradedRequirements = new Set(
(stage.degradedRequirements ?? []).map(canonicalWorkflowEvidenceKey)
);
const policies = Object.entries(stage.resolvedEvidencePolicies ?? {}).sort(([left], [right]) => left.localeCompare(right));
for (const [rawRequirement, policy] of policies) {
const requirementKey = canonicalWorkflowEvidenceKey(rawRequirement);
const attempt = stage.status === "passed" || stage.status === "failed" ? Math.max(1, stage.attempts) : stage.attempts + 1;
const verifiedMessages = [...verifiedEvidence[requirementKey] ?? []].filter((snapshot) => snapshot.context.runId === run.id && snapshot.context.stageId === stage.id && snapshot.context.requirementKey === requirementKey && snapshot.context.attempt === attempt).sort((left, right) => left.messageId.localeCompare(right.messageId)).map((snapshot) => ({
schema: snapshot.schema,
messageId: snapshot.messageId,
producerId: snapshot.producerId,
producerName: snapshot.producerName,
context: {
schema: snapshot.context.schema,
runId: snapshot.context.runId,
stageId: snapshot.context.stageId,
requirementKey: snapshot.context.requirementKey,
attempt: snapshot.context.attempt
},
status: snapshot.status,
hashes: {
requestSha256: snapshot.requestSha256,
replySha256: snapshot.replySha256
},
timestamps: {
createdAt: snapshot.createdAt,
replyCreatedAt: snapshot.replyCreatedAt,
repliedAt: snapshot.repliedAt,
verifiedAt: snapshot.verifiedAt
}
}));
const degradationApprovals = (stage.degradationApprovals ?? []).filter((approval) => approval.schema === "pi-mesh.workflow-degradation-approval.v1" && approval.requirementKey === requirementKey && approval.attempt === attempt).sort((left, right) => left.attempt - right.attempt || left.approvedAt.localeCompare(right.approvedAt) || left.id.localeCompare(right.id)).map((approval) => ({
schema: approval.schema,
id: approval.id,
requirementKey: approval.requirementKey,
attempt: approval.attempt,
policyMinProducers: approval.policyMinProducers,
approvedMinProducers: approval.approvedMinProducers,
approvedBy: approval.approvedBy,
reason: redactSecrets(approval.reason).replace(/\s+/gu, " ").trim(),
approvedAt: approval.approvedAt
}));
const degraded = Boolean(stage.degraded && degradedRequirements.has(requirementKey));
const appliedApproval = degradationApprovals.at(-1);
audit.push({
stageId: stage.id,
requirementKey,
attempt,
policy: {
kind: policy.kind,
minProducers: policy.minProducers,
effectiveMinProducers: appliedApproval?.approvedMinProducers ?? policy.minProducers,
acceptedStatuses: ["replied"]
},
eligibleProducers: [...policy.eligibleProducers].sort((left, right) => left.id.localeCompare(right.id) || left.name.localeCompare(right.name)).map((producer) => ({ id: producer.id, name: producer.name })),
verifiedProducerIds: [...new Set(verifiedMessages.map((snapshot) => snapshot.producerId))].sort(),
verifiedMessages,
degraded,
degradationApprovals
});
}
}
return audit;
}
function buildRetrospective(run, journal, exportedAt = (/* @__PURE__ */ new Date()).toISOString()) {
if (!SAFE_RUN_ID.test(run.id)) throw new Error("invalid retrospective run id");
const entries = journal.filter((entry) => entry.runId === run.id).sort((left, right) => left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id)).slice(-MAX_RETROSPECTIVE_ENTRIES).map((entry) => {
const promotionState = journalPromotionState(entry);
const exported = {
id: entry.id,
category: entry.category,
area: entry.area,
severity: entry.severity,
summary: redactSecrets(entry.summary),
evidence: redactStringList(entry.evidence),
relatedEntryIds: entry.relatedEntryIds.slice(0, 16),
createdAt: entry.createdAt
};
if (entry.stageId !== void 0) exported.stageId = entry.stageId;
if (entry.attempt !== void 0) exported.attempt = entry.attempt;
if (promotionState !== void 0) exported.promotionState = promotionState;
return exported;
});
const byCategory = {};
const byArea = {};
const byClass = {};
const byErrorClass = {};
for (const entry of entries) {
increment(byCategory, entry.category);
increment(byArea, entry.area);
increment(byClass, classFromEvidence(entry.evidence));
if (entry.category === "error") increment(byErrorClass, classFromEvidence(entry.evidence));
}
const recurringErrorClasses = Object.entries(byErrorClass).map(([errorClass, count]) => ({ class: errorClass, count })).sort((left, right) => right.count - left.count || left.class.localeCompare(right.class));
const resolvedContradictions = new Set(entries.filter((entry) => entry.category === "decision" || entry.category === "lesson").flatMap((entry) => entry.relatedEntryIds));
const openContradictions = entries.filter((entry) => entry.category === "contradiction" && !resolvedContradictions.has(entry.id)).map((entry) => ({ id: entry.id, summary: entry.summary, area: entry.area }));
const decisions = entries.filter((entry) => entry.category === "decision").map((entry) => ({ id: entry.id, summary: entry.summary, area: entry.area }));
const proposedImprovements = rankImprovementSignals(
journal.filter((entry) => entry.runId === run.id && (entry.category === "error" || entry.category === "lesson")),
/* @__PURE__ */ new Map([[run.id, run]]),
12
).map((signal) => ({
area: signal.area,
summary: signal.summary,
successMeasure: redactSecrets(`no recurrence of ${signal.key} in the next ${run.definitionId} run`),
status: "proposed"
}));
const evidenceAudit = buildEvidenceAudit(run);
const degradedStageIds = run.stages.filter((stage) => stage.degraded).map((stage) => stage.id);
return {
schema: "pi-mesh.retrospective.v1",
runId: run.id,
definitionId: run.definitionId,
status: run.status,
exportedAt,
reviewDecision: "proposed",
stages: run.stages.map((stage) => {
const elapsed = durationMs(stage.startedAt, stage.completedAt);
return { id: stage.id, ...stage.area ? { area: stage.area } : {}, status: stage.status, attempts: stage.attempts, ...stage.startedAt ? { startedAt: stage.startedAt } : {}, ...stage.completedAt ? { completedAt: stage.completedAt } : {}, ...elapsed !== void 0 ? { durationMs: elapsed } : {}, ...stage.updatedAt ? { updatedAt: stage.updatedAt } : {}, ...stage.summary ? { summary: redactSecrets(stage.summary) } : {} };
}),
counts: { byCategory, byArea, byClass },
openContradictions,
decisions,
recurringErrorClasses,
entries,
proposedImprovements,
...evidenceAudit.length ? { evidenceAudit } : {},
...degradedStageIds.length ? { degradedStageIds } : {}
};
}
function renderRetrospectiveMarkdown(doc) {
const stageRows = doc.stages.map((stage) => `| ${stage.id} | ${stage.area ?? ""} | ${stage.status} | ${stage.attempts} | ${stage.durationMs ?? ""} |`).join("\n");
const contradictionRows = doc.openContradictions.map((entry) => `- ${entry.id} (${entry.area}): ${entry.summary}`).join("\n") || "- none";
const decisionRows = doc.decisions.map((entry) => `- ${entry.id} (${entry.area}): ${entry.summary}`).join("\n") || "- none";
const classRows = doc.recurringErrorClasses.map((entry) => `- ${entry.class}: ${entry.count}`).join("\n") || "- none";
const entryRows = doc.entries.map((entry) => {
const related = entry.relatedEntryIds.length > 0 ? `; related: ${entry.relatedEntryIds.join(", ")}` : "";
const evidence = entry.evidence.length > 0 ? `; evidence: ${entry.evidence.join(", ")}` : "";
return `- ${entry.id} [${entry.category}/${entry.area}/${entry.severity}]: ${entry.summary}${related}${evidence}`;
}).join("\n") || "- none";
const evidenceAuditRows = (doc.evidenceAudit ?? []).flatMap((audit) => {
const producerNames = audit.eligibleProducers.map((producer) => `${producer.name} (${producer.id})`).join(", ") || "none";
const verified = audit.verifiedMessages.length ? audit.verifiedMessages.map((snapshot) => ` - ${snapshot.messageId}: producer ${snapshot.producerName} (${snapshot.producerId}), attempt ${snapshot.context.attempt}, request ${snapshot.hashes.requestSha256}, reply ${snapshot.hashes.replySha256}, replied ${snapshot.timestamps.repliedAt}, verified ${snapshot.timestamps.verifiedAt}`) : [" - no verified messages"];
const approvals = audit.degradationApprovals.map((approval) => ` - approval ${approval.id}: attempt ${approval.attempt}, ${approval.policyMinProducers} -> ${approval.approvedMinProducers} producers, ${approval.approvedBy}, ${approval.approvedAt}; reason: ${approval.reason}`);
return [
`- ${audit.stageId} / ${audit.requirementKey} / attempt ${audit.attempt}: ${audit.verifiedProducerIds.length}/${audit.policy.effectiveMinProducers} verified producers; policy minimum ${audit.policy.minProducers}; degraded: ${audit.degraded}`,
` - eligible: ${producerNames}`,
...verified,
...approvals.length ? [" - degradation approvals:", ...approvals] : []
];
});
return [
`# Workflow retrospective ${doc.runId}`,
"",
`- Definition: ${doc.definitionId}`,
`- Status: ${doc.status}`,
`- Exported: ${doc.exportedAt}`,
`- Review decision: ${doc.reviewDecision}`,
"",
"## Stages",
"",
"| id | area | status | attempts | duration ms |",
"|---|---|---|---|---|",
stageRows,
"",
"## Decisions",
"",
decisionRows,
"",
"## Open contradictions",
"",
contradictionRows,
"",
"## Recurring error classes",
"",
classRows,
"",
"## Bounded journal evidence",
"",
entryRows,
"",
...doc.evidenceAudit?.length ? [
"## Peer-evidence audit",
"",
"This section contains immutable provenance metadata and content hashes only; prompt and reply bodies are excluded.",
"",
...evidenceAuditRows,
""
] : [],
"## Proposed improvements",
"",
...doc.proposedImprovements.map((item) => `- [${item.status}] (${item.area}) ${item.summary}`),
"",
"Proposed improvements are evidence, not policy. Do not apply them until an explicit review decision.",
""
].join("\n");
}
function writeRetrospective(outDir, doc) {
if (!SAFE_RUN_ID.test(doc.runId)) throw new Error("invalid retrospective run id");
mkdirSync3(outDir, { recursive: true });
const root = resolve3(outDir);
const jsonPath = resolve3(root, `${doc.runId}.json`);
const mdPath = resolve3(root, `${doc.runId}.md`);
const prefix = `${root}${process.platform === "win32" ? "\\" : "/"}`;
if (!jsonPath.startsWith(prefix) || !mdPath.startsWith(prefix)) throw new Error("retrospective path escaped output directory");
const jsonTmp = `${jsonPath}.tmp`;
const mdTmp = `${mdPath}.tmp`;
writeFileSync3(jsonTmp, `${JSON.stringify(doc, null, 2)}
`, { encoding: "utf8", mode: 384 });
writeFileSync3(mdTmp, renderRetrospectiveMarkdown(doc), { encoding: "utf8", mode: 384 });
renameSync2(jsonTmp, jsonPath);
renameSync2(mdTmp, mdPath);
return { jsonPath, mdPath };
}
// plugins/kxm/src/store.ts
import { resolve as resolve5 } from "node:path";
// plugins/kxm/src/database.ts
import {
chmodSync,
copyFileSync,
existsSync as existsSync5,
lstatSync as lstatSync2,
mkdirSync as mkdirSync4,
readdirSync as readdirSync4,
readFileSync as readFileSync4,
unlinkSync,
writeFileSync as writeFileSync4
} from "node:fs";
import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute2, join as join5, relative as relative2, resolve as resolve4, sep as sep2 } from "node:path";
// plugins/kxm/src/sqlite.ts
import { createRequire } from "node:module";
var requireFromHere = createRequire(import.meta.url);
function loadNative() {
try {
const mod = requireFromHere("node:sqlite");
if (mod.DatabaseSync) return { Ctor: mod.DatabaseSync, bun: false };
} catch {
}
try {
const mod = requireFromHere("bun:sqlite");
const Ctor = mod?.DatabaseSync ?? mod?.Database;
if (Ctor) return { Ctor, bun: true };
} catch {
}
throw new Error("kxm: no supported sqlite module found (need node:sqlite or bun:sqlite)");
}
var native = loadNative();
var DatabaseSync = class {
inner;
constructor(path, options) {
let normalized = options;
if (native.bun && options) {
const { readOnly, ...rest } = options;
normalized = readOnly === void 0 ? rest : { ...rest, readonly: readOnly };
}
this.inner = normalized === void 0 ? new native.Ctor(path) : new native.Ctor(path, normalized);
}
prepare(sql) {
return this.inner.prepare(sql);
}
exec(sql) {
return this.inner.exec(sql);
}
close() {
this.inner.close();
}
};
// plugins/kxm/src/bindings.ts
var MAX_BINDING_RECORD_BYTES = 256 * 1024;
// plugins/kxm/src/database.ts
function databaseError(code, file, message) {
const issue2 = { phase: "semantic", code, file, message };
return new KxmConfigError([issue2]);
}
function checkedParent(path, description) {
const parent = dirname5(path);
if (!existsSync5(parent)) mkdirSync4(parent, { recursive: true, mode: 448 });
const stat = lstatSync2(parent, { throwIfNoEntry: false });
if (!stat || stat.isSymbolicLink() || !stat.isDirectory()) {
throw databaseError("runtime_path_invalid", description, `${description} parent must be a regular directory, not a link`);
}
}
function userTables(database) {
const rows = database.prepare(
"SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name"
).all();
return rows.map((row) => row.name);
}
function tableColumns(database, table) {
const rows = database.prepare(`PRAGMA table_info(${table})`).all();
return rows.map((row) => row.name).sort();
}
function verifyExpectedTables(database, file, description, expected) {
const present = new Set(userTables(database));
for (const [table, columns] of Object.entries(expected)) {
if (!present.has(table)) {
throw databaseError("runtime_schema_shape_invalid", file, `${description} is missing table ${table}`);
}
const actual = tableColumns(database, table);
const missing = columns.filter((column) => !actual.includes(column));
if (missing.length > 0) {
throw databaseError("runtime_schema_shape_invalid", file, `${description} table ${table} is missing columns ${missing.join(", ")}`);
}
}
}
function ensureWalJournalMode(database, file, description, timeoutMs = 5e3) {
const deadline = Date.now() + timeoutMs;
const sleeper = new Int32Array(new SharedArrayBuffer(4));
while (true) {
try {
const current = database.prepare("PRAGMA journal_mode").get();
if (current?.journal_mode === "wal") {
return;
}
const updated = database.prepare("PRAGMA journal_mode = WAL").get();
if (updated?.journal_mode === "wal") {
return;
}
} catch (error) {
const sqliteError = error;
if (sqliteError.code === "ERR_SQLITE_ERROR" && sqliteError.errcode === 5 && Date.now() < deadline) {
Atomics.wait(sleeper, 0, 0, 10);
continue;
}
throw error;
}
if (Date.now() >= deadline) {
throw databaseError("runtime_timeout", file, `${description} timed out enabling WAL journal mode`);
}
Atomics.wait(sleeper, 0, 0, 10);
}
}
function assertDatabaseFile(file, description) {
checkedParent(file, description);
const stat = lstatSync2(file, { throwIfNoEntry: false });
if (stat) {
if (stat.isSymbolicLink() || !stat.isFile()) {
throw databaseError("runtime_path_invalid", description, `${description} must be a regular file, not a link or directory`);
}
}
for (const sidecar of [`${file}-wal`, `${file}-shm`]) {
const info = lstatSync2(sidecar, { throwIfNoEntry: false });
if (info?.isSymbolicLink()) {
throw databaseError("runtime_path_invalid", description, `${description} sidecar must not be a link`);
}
}
}
function openDatabase(file, description, spec) {
const isMemory = file === ":memory:";
if (!isMemory) {
assertDatabaseFile(file, description);
}
const database = new DatabaseSync(file);
let transaction = false;
try {
database.exec(`PRAGMA busy_timeout = ${spec.timeoutMs ?? 5e3}`);
if (!isMemory) {
ensureWalJournalMode(database, file, description, spec.timeoutMs);
}
database.exec("PRAGMA synchronous = NORMAL");
database.exec("PRAGMA foreign_keys = ON");
database.exec("BEGIN IMMEDIATE");
transaction = true;
const row = database.prepare("PRAGMA user_version").get();
const version = row?.user_version ?? 0;
if (version > spec.version) {
throw databaseError("runtime_schema_newer", file, `${description} schema version ${version} is newer than this runtime supports`);
}
if (version === 0) {
const existing = userTables(database);
if (existing.length > 0) {
throw databaseError("runtime_schema_shape_invalid", file, `${description} has tables at schema version 0`);
}
database.exec(spec.schema);
database.exec(`PRAGMA user_version = ${spec.version}`);
} else if (version < spec.version) {
throw databaseError(
"runtime_schema_outdated",
file,
`${description} is schema version ${version}; this build requires ${spec.version}. Delete the state file to start fresh and let its owning process recreate it (\`kxm hub start\` for hub state, the Runtime for event stores). The Runtime registry copy from schema 1 to 2 is the one exception. \`kxm init\` is project-only and rebuilds no database. Upgrading any other old state in place is deliberately unsupported`
);
}
if (spec.tables) {
verifyExpectedTables(database, file, description, spec.tables);
}
database.exec("COMMIT");
transaction = false;
return database;
} catch (error) {
if (transaction) {
try {
database.exec("ROLLBACK");
} catch {
}
}
database.close();
throw error;
}
}
var activeTransactions = /* @__PURE__ */ new WeakSet();
var TRANSACTION_BUSY_BACKOFF_MS = 1e3;
function monotonicNowMs() {
return Number(process.hrtime.bigint() / 1000000n);
}
var transactionThrottles = /* @__PURE__ */ new WeakMap();
function finiteNow(clock, label) {
const now = clock();
if (typeof now !== "number" || !Number.isFinite(now)) {
throw databaseError(
"runtime_transaction_clock_invalid",
"transaction",
`${label} must return a finite monotonic number; got ${String(now)}`
);
}
return now;
}
var CONTENTION_PRIMARY_CODES = [5, 6, 15];
var CONTENTION_SYMBOLIC_NAMES = /^SQLITE_(?:BUSY|LOCKED|PROTOCOL)(?:_[A-Z0-9]+)?$/;
var SQLITE_RESULT_NAMES = /^SQLITE_[A-Z][A-Z0-9_]*$/;
var CONTENTION_MESSAGES = /^(?:database is locked|database table is locked|locking protocol|SQLITE_BUSY|SQLITE_LOCKED|SQLITE_PROTOCOL)(?:$|[\s.:])/i;
function isTransactionContention(error) {
const carrier = error;
for (const value of [carrier?.errcode, carrier?.errCode, carrier?.errno]) {
if (typeof value === "number" && Number.isInteger(value)) return CONTENTION_PRIMARY_CODES.includes(value & 255);
}
for (const value of [carrier?.code, carrier?.name]) {
if (typeof value === "string" && SQLITE_RESULT_NAMES.test(value)) {
return CONTENTION_SYMBOLIC_NAMES.test(value);
}
}
return CONTENTION_MESSAGES.test(error instanceof Error ? error.message : String(error));
}
function withDatabaseTransaction(database, work, mode = "IMMEDIATE", clock = monotonicNowMs) {
if (activeTransactions.has(database)) {
throw databaseError("runtime_transaction_nested", "transaction", "nested transactions are not allowed");
}
if (mode !== "DEFERRED") {
const deadlines = transactionThrottles.get(database);
const until = deadlines?.get(clock);
if (until !== void 0) {
const remaining = until - finiteNow(clock, "the transaction clock");
if (remaining > 0) {
throw databaseError(
"runtime_transaction_busy",
"transaction",
`a previous BEGIN was blocked on this database; retry deferred ${String(remaining)}ms`
);
}
deadlines?.delete(clock);
}
}
try {
database.exec(`BEGIN ${mode}`);
} catch (error) {
if (!isTransactionContention(error)) throw error;
const now = finiteNow(clock, "the transaction clock");
let deadlines = transactionThrottles.get(database);
if (deadlines === void 0) {
deadlines = /* @__PURE__ */ new WeakMap();
transactionThrottles.set(database, deadlines);
}
deadlines.set(clock, now + TRANSACTION_BUSY_BACKOFF_MS);
throw databaseError(
"runtime_transaction_busy",
"transaction",
`BEGIN ${mode} blocked by another transaction: ${error instanceof Error ? error.message : String(error)}`
);
}
activeTransactions.add(database);
if (mode !== "DEFERRED") transactionThrottles.get(database)?.delete(clock);
try {
const result = work();
database.exec("COMMIT");
return result;
} catch (error) {
try {
database.exec("ROLLBACK");
} catch {
}
throw error;
} finally {
activeTransactions.delete(database);
}
}
// plugins/kxm/src/store.ts
var HUB_STORE_SCHEMA_VERSION = 5;
var HUB_STORE_TABLES = Object.freeze({
agents: Object.freeze(["id", "record"]),
messages: Object.freeze(["id", "record"]),
consumer_cursors: Object.freeze(["agent_id", "cursor"]),
agent_sequences: Object.freeze(["agent_id", "next_seq"]),
workflow_runs: Object.freeze(["id", "definition_id", "delivery_id", "record"]),
workflow_journal: Object.freeze(["id", "run_id", "category", "area", "record"]),
context_items: Object.freeze(["id", "project", "kind", "record"]),
leases: Object.freeze(["resource", "holder_agent_id", "fencing_token", "expires_at", "record"]),
sync_events: Object.freeze([
"project_id",
"run_id",
"sequence",
"hub_project",
"home_runtime_id",
"event_type",
"content_hash",
"received_at",
"record"
]),
runtime_presence: Object.freeze(["runtime_id", "hub_project", "host", "heartbeat", "record"])
});
var HUB_STORE_SCHEMA_V5 = `
CREATE TABLE IF NOT EXISTS agents (
id TEXT PRIMARY KEY,
record TEXT NOT NULL
) STRICT;
CREATE TABLE IF NOT EXISTS messages (
id TEXT PRIMARY KEY,
record TEXT NOT NULL
) STRICT;
CREATE UNIQUE INDEX IF NOT EXISTS messages_from_idempotency
ON messages(
json_extract(record, '$.from'),
json_extract(record, '$.idempotencyKey')
) WHERE json_extract(record, '$.idempotencyKey') IS NOT NULL;
CREATE INDEX IF NOT EXISTS messages_to_seq
ON messages(
json_extract(record, '$.to'),
COALESCE(json_extract(record, '$.seq'), 0)
);
CREATE TABLE IF NOT EXISTS consumer_cursors (
agent_id TEXT PRIMARY KEY,
cursor INTEGER NOT NULL
) STRICT;
CREATE TABLE IF NOT EXISTS agent_sequences (
agent_id TEXT PRIMARY KEY,
next_seq INTEGER NOT NULL
) STRICT;
CREATE TABLE IF NOT EXISTS workflow_runs (
id TEXT PRIMARY KEY,
definition_id TEXT NOT NULL,
delivery_id TEXT NOT NULL,
record TEXT NOT NULL,
UNIQUE(definition_id, delivery_id)
) STRICT;
CREATE TABLE IF NOT EXISTS workflow_journal (
id TEXT PRIMARY KEY,
run_id TEXT NOT NULL,
category TEXT NOT NULL,
area TEXT NOT NULL,
record TEXT NOT NULL
) STRICT;
CREATE INDEX IF NOT EXISTS workflow_journal_run_id ON workflow_journal(run_id);
CREATE TABLE IF NOT EXISTS context_items (
id TEXT PRIMARY KEY,
project TEXT NOT NULL,
kind TEXT NOT NULL,
record TEXT NOT NULL
) STRICT;
CREATE INDEX IF NOT EXISTS context_items_project ON context_items(project);
CREATE TABLE IF NOT EXISTS leases (
resource TEXT PRIMARY KEY,
holder_agent_id TEXT NOT NULL,
fencing_token INTEGER NOT NULL,
expires_at TEXT NOT NULL,
record TEXT NOT NULL
) STRICT;
CREATE TABLE IF NOT EXISTS sync_events (
project_id TEXT NOT NULL,
run_id TEXT NOT NULL,
sequence INTEGER NOT NULL,
hub_project TEXT NOT NULL,
home_runtime_id TEXT NOT NULL,
event_type TEXT NOT NULL,
content_hash TEXT NOT NULL,
received_at TEXT NOT NULL,
record TEXT NOT NULL,
PRIMARY KEY (project_id, run_id, sequence)
) STRICT;
CREATE INDEX IF NOT EXISTS sync_events_hub_project ON sync_events(hub_project, run_id, sequence);
CREATE TABLE IF NOT EXISTS runtime_presence (
runtime_id TEXT NOT NULL,
hub_project TEXT NOT NULL,
host TEXT,
heartbeat TEXT NOT NULL,
record TEXT NOT NULL,
PRIMARY KEY (hub_project, runtime_id)
) STRICT;
`;
var HUB_STORE_SCHEMA_SPEC = Object.freeze({
schema: HUB_STORE_SCHEMA_V5,
version: HUB_STORE_SCHEMA_VERSION,
tables: HUB_STORE_TABLES
});
function syncKey(projectId, runId, sequence) {
return `${projectId}\0${runId}\0${sequence}`;
}
function parseLeaseRecord(record) {
try {
return JSON.parse(record);
} catch {
return void 0;
}
}
function leaseHasLapsed(lease, nowMs) {
const expiresAtMs = Date.parse(lease.expiresAt);
return !Number.isFinite(expiresAtMs) || expiresAtMs <= nowMs;
}
function syncEventFromRow(row) {
return {
projectId: row.project_id,
runId: row.run_id,
sequence: row.sequence,
hubProject: row.hub_project,
homeRuntimeId: row.home_runtime_id,
eventType: row.event_type,
contentHash: row.content_hash,
receivedAt: row.received_at,
bytes: row.record
};
}
var MessageMap = class extends Map {
store;
constructor(store) {
super();
this.store = store;
}
get(id) {
const cached = super.get(id);
if (cached) return cached;
return this.store.loadMessageFromDb(id);
}
has(id) {
if (super.has(id)) return true;
return this.store.hasMessage(id);
}
delete(id) {
this.store.deleteMessage(id);
return super.delete(id);
}
get size() {
return this.store.countMessages();
}
get cachedSize() {
return super.size;
}
};
var MeshStore = class {
agents = /* @__PURE__ */ new Map();
messages;
workflowRuns = /* @__PURE__ */ new Map();
journal = /* @__PURE__ */ new Map();
contextItems = /* @__PURE__ */ new Map();
leases = /* @__PURE__ */ new Map();
/** Memory-only stores keep sync state here; a database store reads SQLite. */
syncEvents = /* @__PURE__ */ new Map();
runtimePresence = /* @__PURE__ */ new Map();
path;
database;
agentSequences = /* @__PURE__ */ new Map();
consumerCursors = /* @__PURE__ */ new Map();
constructor(path) {
this.messages = new MessageMap(this);
if (!path) return;
this.path = path === ":memory:" ? path : resolve5(path);
this.database = openDatabase(this.path, "hub database", HUB_STORE_SCHEMA_SPEC);
this.load();
}
get persistent() {
return Boolean(this.database && this.path !== ":memory:");
}
saveAgent(agent) {
this.agents.set(agent.id, agent);
this.database?.prepare(`
INSERT INTO agents (id, record) VALUES (?, ?)
ON CONFLICT(id) DO UPDATE SET record = excluded.record
`).run(agent.id, JSON.stringify(agent));
}
saveMessage(message) {
Map.prototype.set.call(this.messages, message.id, message);
this.database?.prepare(`
INSERT INTO messages (id, record) VALUES (?, ?)
ON CONFLICT(id) DO UPDATE SET record = excluded.record
`).run(message.id, JSON.stringify(message));
}
deleteMessage(messageId) {
Map.prototype.delete.call(this.messages, messageId);
this.database?.prepare("DELETE FROM messages WHERE id = ?").run(messageId);
}
loadMessageFromDb(id) {
if (!this.database) return void 0;
const row = this.database.prepare("SELECT record FROM messages WHERE id = ?").get(id);
if (!row) return void 0;
try {
const msg = JSON.parse(row.record);
Map.prototype.set.call(this.messages, msg.id, msg);
return msg;
} catch {
return void 0;
}
}
hasMessage(id) {
if (Map.prototype.has.call(this.messages, id)) return true;
if (!this.database) return false;
const row = this.database.prepare("SELECT 1 AS ok FROM messages WHERE id = ?").get(id);
return Boolean(row?.ok);
}
countMessages() {
if (!this.database) return [...Map.prototype.keys.call(this.messages)].length;
const row = this.database.prepare("SELECT COUNT(*) AS total FROM messages").get();
return Number(row?.total ?? 0);
}
nextAgentSequence(agentId) {
if (!this.database) {
const current = this.agentSequences.get(agentId) ?? 0;
const next = current + 1;
this.agentSequences.set(agentId, next);
return next;
}
this.database.exec("BEGIN IMMEDIATE");
try {
const row = this.database.prepare("SELECT next_seq FROM agent_sequences WHERE agent_id = ?").get(agentId);
let next = row?.next_seq;
if (next === void 0) {
const maxRow = this.database.prepare(`
SELECT COALESCE(MAX(json_extract(record, '$.seq')), 0) AS max_seq
FROM messages WHERE json_extract(record, '$.to') = ?
`).get(agentId);
next = Number(maxRow?.max_seq ?? 0) + 1;
}
this.database.prepare(`
INSERT INTO agent_sequences (agent_id, next_seq) VALUES (?, ?)
ON CONFLICT(agent_id) DO UPDATE SET next_seq = excluded.next_seq
`).run(agentId, next + 1);
this.database.exec("COMMIT");
this.agentSequences.set(agentId, next + 1);
return next;
} catch (err) {
try {
this.database.exec("ROLLBACK");
} catch {
}
throw err;
}
}
getConsumerCursor(agentId) {
if (!this.database) {
return this.consumerCursors.get(agentId) ?? 0;
}
const row = this.database.prepare("SELECT cursor FROM consumer_cursors WHERE agent_id = ?").get(agentId);
const cursor = Number(row?.cursor ?? 0);
this.consumerCursors.set(agentId, cursor);
return cursor;
}
advanceCursor(agentId, seq) {
if (!this.database) {
const current = this.consumerCursors.get(agentId) ?? 0;
const next = Math.max(current, seq);
this.consumerCursors.set(agentId, next);
return next;
}
this.database.prepare(`
INSERT INTO consumer_cursors (agent_id, cursor) VALUES (?, ?)
ON CONFLICT(agent_id) DO UPDATE SET cursor = MAX(consumer_cursors.cursor, excluded.cursor)
`).run(agentId, seq);
return this.getConsumerCursor(agentId);
}
getPendingMessages(agentId, cursor = 0) {
if (!this.database) {
return [...Map.prototype.values.call(this.messages)].filter((m) => m.to === agentId && (m.status === "queued" || m.status === "delivered") && (m.seq ?? 0) > cursor).sort((a, b) => (a.seq ?? 0) - (b.seq ?? 0));
}
const rows = this.database.prepare(`
SELECT record FROM messages
WHERE json_extract(record, '$.to') = ?
AND json_extract(record, '$.status') IN ('queued', 'delivered')
AND COALESCE(json_extract(record, '$.seq'), 0) > ?
ORDER BY COALESCE(json_extract(record, '$.seq'), 0) ASC
`).all(agentId, cursor);
const result = [];
for (const row of rows) {
try {
const msg = JSON.parse(row.record);
Map.prototype.set.call(this.messages, msg.id, msg);
result.push(msg);
} catch {
}
}
return result;
}
findMessageByIdempotency(fromId, idempotencyKey) {
for (const m of Map.prototype.values.call(this.messages)) {
if (m.from === fromId && m.idempotencyKey === idempotencyKey) return m;
}
if (!this.database) return void 0;
const row = this.database.prepare(`
SELECT record FROM messages
WHERE json_extract(record, '$.from') = ? AND json_extract(record, '$.idempotencyKey') = ?
`).get(fromId, idempotencyKey);
if (!row) return void 0;
try {
const msg = JSON.parse(row.record);
Map.prototype.set.call(this.messages, msg.id, msg);
return msg;
} catch {
return void 0;
}
}
getOpenMessages(project) {
if (!this.database) {
return [...Map.prototype.values.call(this.messages)].filter((m) => m.project === project && (m.status === "queued" || m.status === "delivered")).sort((a, b) => Date.parse(b.createdAt) - Date.parse(a.createdAt));
}
const rows = this.database.prepare(`
SELECT record FROM messages
WHERE json_extract(record, '$.project') = ?
AND json_extract(record, '$.status') IN ('queued', 'delivered')
ORDER BY json_extract(record, '$.createdAt') DESC
`).all(project);
const result = [];
for (const row of rows) {
try {
const msg = JSON.parse(row.record);
Map.prototype.set.call(this.messages, msg.id, msg);
result.push(msg);
} catch {
}
}
return result;
}
getExpiringMessages(nowMs = Date.now()) {
const nowIso2 = new Date(nowMs).toISOString();
if (!this.database) {
return [...Map.prototype.values.call(this.messages)].filter((m) => (m.status === "queued" || m.status === "delivered") && Date.parse(m.expiresAt) <= nowMs);
}
const rows = this.database.prepare(`
SELECT record FROM messages
WHERE json_extract(record, '$.status') IN ('queued', 'delivered')
AND json_extract(record, '$.expiresAt') <= ?
`).all(nowIso2);
const result = [];
for (const row of rows) {
try {
const msg = JSON.parse(row.record);
Map.prototype.set.call(this.messages, msg.id, msg);
result.push(msg);
} catch {
}
}
return result;
}
/** Read the lease over one already project-scoped resource. */
getLease(resource) {
if (!this.database) return this.leases.get(resource);
const row = this.database.prepare("SELECT record FROM leases WHERE resource = ?").get(resource);
if (!row) {
this.leases.delete(resource);
return void 0;
}
const lease = parseLeaseRecord(row.record);
if (lease) this.leases.set(resource, lease);
return lease;
}
/**
* Take or extend the lease over `resource`, deciding the whole outcome inside
* one transaction so two writers cannot both read "free" and both insert.
*
* The token is the fence: a first acquisition starts at 1, the holder's own
* re-acquisition keeps its token, and only a takeover of an expired lease
* increments it. That is what lets a holder that wakes up after its deadline
* be refused at commit rather than silently writing behind the new holder.
*/
acquireLease(input) {
return this.inLeaseTransaction(() => {
const current = this.readLeaseForUpdate(input.resource);
const expired = current !== void 0 && leaseHasLapsed(current, input.nowMs);
if (current && !expired && current.holderAgentId !== input.holderAgentId) {
return { ok: false, reason: "held", lease: current };
}
const fencingToken = current === void 0 ? 1 : expired ? current.fencingToken + 1 : current.fencingToken;
const renewed = current !== void 0 && !expired;
const lease = {
resource: input.resource,
project: input.project,
name: input.name,
holderAgentId: input.holderAgentId,
holderAgentName: input.holderAgentName,
fencingToken,
acquiredAt: renewed && current ? current.acquiredAt : new Date(input.nowMs).toISOString(),
expiresAt: new Date(input.nowMs + input.ttlMs).toISOString()
};
this.writeLease(lease);
return { ok: true, lease, renewed };
});
}
/** Extend a lease the caller still holds under the token it was given. The
* token never changes on renewal — a renewal that would need a new token is
* a takeover, and takeovers go through `acquireLease`. */
renewLease(input) {
return this.inLeaseTransaction(() => {
const current = this.readLeaseForUpdate(input.resource);
if (!current) return { ok: false, reason: "missing" };
if (current.holderAgentId !== input.holderAgentId || current.fencingToken !== input.fencingToken) {
return { ok: false, reason: "superseded", lease: current };
}
if (leaseHasLapsed(current, input.nowMs)) {
return { ok: false, reason: "expired", lease: current };
}
const lease = { ...current, expiresAt: new Date(input.nowMs + input.ttlMs).toISOString() };
this.writeLease(lease);
return { ok: true, lease, renewed: true };
});
}
/** Drop a lease the caller holds. A clean release ends the fence: there is no
* stale writer left to keep a token for, so the next acquisition starts over. */
releaseLease(input) {
return this.inLeaseTransaction(() => {
const current = this.readLeaseForUpdate(input.resource);
if (!current) return { ok: false, reason: "missing" };
if (current.holderAgentId !== input.holderAgentId || current.fencingToken !== input.fencingToken) {
return { ok: false, reason: "superseded", lease: current };
}
this.deleteLease(input.resource);
return { ok: true, lease: current, renewed: false };
});
}
/** Every lease of one project, newest deadline last. Reader surface only. */
listLeases(project) {
if (this.database) {
const rows = this.database.prepare("SELECT record FROM leases").all();
this.leases.clear();
for (const row of rows) {
const lease = parseLeaseRecord(row.record);
if (lease) this.leases.set(lease.resource, lease);
}
}
return [...this.leases.values()].filter((lease) => lease.project === project).sort((left, right) => left.resource.localeCompare(right.resource));
}
inLeaseTransaction(work) {
if (!this.database) return work();
return withDatabaseTransaction(this.database, work);
}
readLeaseForUpdate(resource) {
if (!this.database) return this.leases.get(resource);
const row = this.database.prepare("SELECT record FROM leases WHERE resource = ?").get(resource);
return row ? parseLeaseRecord(row.record) : void 0;
}
writeLease(lease) {
this.leases.set(lease.resource, lease);
this.database?.prepare(`
INSERT INTO leases (resource, holder_agent_id, fencing_token, expires_at, record) VALUES (?, ?, ?, ?, ?)
ON CONFLICT(resource) DO UPDATE SET
holder_agent_id = excluded.holder_agent_id,
fencing_token = excluded.fencing_token,
expires_at = excluded.expires_at,
record = excluded.record
`).run(lease.resource, lease.holderAgentId, lease.fencingToken, lease.expiresAt, JSON.stringify(lease));
}
deleteLease(resource) {
this.leases.delete(resource);
this.database?.prepare("DELETE FROM leases WHERE resource = ?").run(resource);
}
// ----- Runtime → hub sync (P5) -----
/**
* Accept one sync event exactly once by `{projectId, runId, sequence}`,
* deciding inside one transaction. Identical bytes are an idempotent
* duplicate; different bytes under a used sequence are refused, and so is a
* run that already belongs to another hub project or home Runtime.
*/
ingestSyncEvent(event) {
const decide = () => {
const existing = this.readSyncEvent(event.projectId, event.runId, event.sequence);
if (existing) {
if (existing.contentHash === event.contentHash && existing.hubProject === event.hubProject) return { outcome: "duplicate" };
return { outcome: "conflict", reason: "sequence_reused", existingHash: existing.contentHash };
}
const owner = this.syncProjectOwner(event.projectId);
if (owner !== void 0 && owner !== event.hubProject) return { outcome: "conflict", reason: "project_mismatch" };
const home = this.syncRunHome(event.projectId, event.runId);
if (home !== void 0 && home !== event.homeRuntimeId) return { outcome: "conflict", reason: "home_runtime_mismatch" };
this.writeSyncEvent(event);
return { outcome: "accepted" };
};
return this.database ? withDatabaseTransaction(this.database, decide) : decide();
}
/** Every sync event one hub project holds, by run then sequence. */
listSyncEvents(hubProject) {
if (!this.database) {
return [...this.syncEvents.values()].filter((event) => event.hubProject === hubProject).sort((left, right) => left.runId.localeCompare(right.runId) || left.sequence - right.sequence);
}
const rows = this.database.prepare(`
SELECT project_id, run_id, sequence, hub_project, home_runtime_id, event_type, content_hash, received_at, record
FROM sync_events WHERE hub_project = ? ORDER BY run_id ASC, sequence ASC
`).all(hubProject);
return rows.map(syncEventFromRow);
}
/** Highest sequence of one run with no gap below it; 0 when sequence 1 is missing. */
syncCursor(projectId, runId) {
const sequences = this.database ? this.database.prepare("SELECT sequence FROM sync_events WHERE project_id = ? AND run_id = ? ORDER BY sequence ASC").all(projectId, runId).map((row) => row.sequence) : [...this.syncEvents.values()].filter((event) => event.projectId === projectId && event.runId === runId).map((event) => event.sequence).sort((left, right) => left - right);
let cursor = 0;
for (const sequence of sequences) {
if (sequence !== cursor + 1) break;
cursor = sequence;
}
return cursor;
}
saveRuntimePresence(record) {
this.runtimePresence.set(`${record.project}\0${record.runtimeId}`, record);
this.database?.prepare(`
INSERT INTO runtime_presence (runtime_id, hub_project, host, heartbeat, record) VALUES (?, ?, ?, ?, ?)
ON CONFLICT(hub_project, runtime_id) DO UPDATE SET
host = excluded.host,
heartbeat = excluded.heartbeat,
record = excluded.record
`).run(record.runtimeId, record.project, record.host ?? null, record.heartbeatAt, JSON.stringify(record));
}
getRuntimePresence(project, runtimeId) {
if (!this.database) return this.runtimePresence.get(`${project}\0${runtimeId}`);
const row = this.database.prepare("SELECT record FROM runtime_presence WHERE hub_project = ? AND runtime_id = ?").get(project, runtimeId);
return row ? JSON.parse(row.record) : void 0;
}
listRuntimePresence(project) {
if (!this.database) {
return [...this.runtimePresence.values()].filter((record) => record.project === project).sort((left, right) => left.runtimeId.localeCompare(right.runtimeId));
}
const rows = this.database.prepare("SELECT record FROM runtime_presence WHERE hub_project = ? ORDER BY runtime_id ASC").all(project);
return rows.map((row) => JSON.parse(row.record));
}
readSyncEvent(projectId, runId, sequence) {
if (!this.database) return this.syncEvents.get(syncKey(projectId, runId, sequence));
const row = this.database.prepare(`
SELECT project_id, run_id, sequence, hub_project, home_runtime_id, event_type, content_hash, received_at, record
FROM sync_events WHERE project_id = ? AND run_id = ? AND sequence = ?
`).get(projectId, runId, sequence);
return row ? syncEventFromRow(row) : void 0;
}
syncProjectOwner(projectId) {
if (!this.database) {
for (const event of this.syncEvents.values()) if (event.projectId === projectId) return event.hubProject;
return void 0;
}
const row = this.database.prepare("SELECT hub_project FROM sync_events WHERE project_id = ? LIMIT 1").get(projectId);
return row?.hub_project;
}
syncRunHome(projectId, runId) {
if (!this.database) {
for (const event of this.syncEvents.values()) {
if (event.projectId === projectId && event.runId === runId) return event.homeRuntimeId;
}
return void 0;
}
const row = this.database.prepare("SELECT home_runtime_id FROM sync_events WHERE project_id = ? AND run_id = ? LIMIT 1").get(projectId, runId);
return row?.home_runtime_id;
}
writeSyncEvent(event) {
if (!this.database) {
this.syncEvents.set(syncKey(event.projectId, event.runId, event.sequence), event);
return;
}
this.database.prepare(`
INSERT INTO sync_events (project_id, run_id, sequence, hub_project, home_runtime_id, event_type, content_hash, received_at, record)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`).run(
event.projectId,
event.runId,
event.sequence,
event.hubProject,
event.homeRuntimeId,
event.eventType,
event.contentHash,
event.receivedAt,
event.bytes
);
}
deleteWorkflowRun(runId) {
this.workflowRuns.delete(runId);
this.database?.prepare("DELETE FROM workflow_runs WHERE id = ?").run(runId);
}
deleteJournalEntry(id) {
this.journal.delete(id);
this.database?.prepare("DELETE FROM workflow_journal WHERE id = ?").run(id);
}
deleteContextItem(id) {
this.contextItems.delete(id);
this.database?.prepare("DELETE FROM context_items WHERE id = ?").run(id);
}
sweepRetention(messageRetentionMs2, runRetentionMs = 7 * 864e5, nowMs = Date.now()) {
const messageCutoffMs = nowMs - messageRetentionMs2;
const messageCutoffIso = new Date(messageCutoffMs).toISOString();
const runCutoffMs = nowMs - runRetentionMs;
const purgedMessages = [];
const purgedRuns = [];
const purgedJournal = [];
const purgedContextItems = [];
const purgedLeases = [];
if (!this.database) {
for (const m of [...Map.prototype.values.call(this.messages)]) {
const terminal = m.status === "replied" || m.status === "cancelled" || m.status === "expired" || m.status === "error";
if (!terminal) continue;
const terminalAt = m.repliedAt ?? m.cancelledAt ?? m.expiresAt ?? m.createdAt;
if (Date.parse(terminalAt) <= messageCutoffMs) {
Map.prototype.delete.call(this.messages, m.id);
purgedMessages.push(m);
}
}
} else {
const rows = this.database.prepare(`
SELECT record FROM messages
WHERE json_extract(record, '$.status') IN ('replied', 'cancelled', 'expired', 'error')
AND COALESCE(json_extract(record, '$.repliedAt'), json_extract(record, '$.cancelledAt'), json_extract(record, '$.expiresAt'), json_extract(record, '$.createdAt')) <= ?
`).all(messageCutoffIso);
for (const row of rows) {
try {
const msg = JSON.parse(row.record);
Map.prototype.delete.call(this.messages, msg.id);
this.database.prepare("DELETE FROM messages WHERE id = ?").run(msg.id);
purgedMessages.push(msg);
} catch {
}
}
}
const terminalRunsToPurge = [];
for (const run of this.workflowRuns.values()) {
const terminal = run.status === "completed" || run.status === "failed";
if (!terminal) continue;
const terminalAt = run.updatedAt ?? run.createdAt;
if (Date.parse(terminalAt) <= runCutoffMs) {
terminalRunsToPurge.push(run.id);
}
}
for (const runId of terminalRunsToPurge) {
this.deleteWorkflowRun(runId);
purgedRuns.push(runId);
const toDeleteJournal = [];
for (const entry of this.journal.values()) {
if (entry.runId === runId) toDeleteJournal.push(entry.id);
}
for (const jid of toDeleteJournal) {
this.deleteJournalEntry(jid);
purgedJournal.push(jid);
}
}
const orphanJournal = [];
for (const entry of this.journal.values()) {
if (Date.parse(entry.createdAt) <= runCutoffMs && !this.workflowRuns.has(entry.runId)) {
orphanJournal.push(entry.id);
}
}
for (const jid of orphanJournal) {
this.deleteJournalEntry(jid);
purgedJournal.push(jid);
}
const contextItemsToPurge = [];
for (const item of this.contextItems.values()) {
const terminal = item.status === "superseded" || item.status === "rejected" || item.validUntil !== void 0 && Date.parse(item.validUntil) <= runCutoffMs;
if (!terminal) continue;
const terminalAt = item.validUntil ?? item.observedAt;
if (terminalAt && Date.parse(terminalAt) <= runCutoffMs) {
contextItemsToPurge.push(item.id);
}
}
for (const id of contextItemsToPurge) {
this.deleteContextItem(id);
purgedContextItems.push(id);
}
const leaseCutoffMs = nowMs - runRetentionMs;
for (const lease of this.listAllLeases()) {
if (leaseHasLapsed(lease, leaseCutoffMs)) {
this.deleteLease(lease.resource);
purgedLeases.push(lease);
}
}
return { purgedMessages, purgedRuns, purgedJournal, purgedContextItems, purgedLeases };
}
listAllLeases() {
if (!this.database) return [...this.leases.values()];
const rows = this.database.prepare("SELECT record FROM leases").all();
const result = [];
for (const row of rows) {
const lease = parseLeaseRecord(row.record);
if (lease) result.push(lease);
}
return result;
}
saveWorkflowRun(run) {
this.workflowRuns.set(run.id, run);
this.database?.prepare(`
INSERT INTO workflow_runs (id, definition_id, delivery_id, record) VALUES (?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET record = excluded.record
`).run(run.id, run.definitionId, run.deliveryId, JSON.stringify(run));
}
saveJournalEntry(entry) {
this.journal.set(entry.id, entry);
this.database?.prepare(`
INSERT INTO workflow_journal (id, run_id, category, area, record) VALUES (?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET record = excluded.record
`).run(entry.id, entry.runId, entry.category, entry.area, JSON.stringify(entry));
}
saveContextItem(item) {
this.contextItems.set(item.id, item);
this.database?.prepare(`
INSERT INTO context_items (id, project, kind, record) VALUES (?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET record = excluded.record
`).run(item.id, item.project, item.kind, JSON.stringify(item));
}
getContextItem(id, project) {
const item = this.contextItems.get(id);
if (!item) return void 0;
if (project !== void 0 && item.project !== project) return void 0;
return item;
}
listContextItems(project, kinds) {
const wanted = kinds ? new Set(kinds) : void 0;
return [...this.contextItems.values()].filter((item) => item.project === project).filter((item) => wanted === void 0 || wanted.has(item.kind)).sort((left, right) => left.id.localeCompare(right.id));
}
saveWorkflowTransition(run, message, entry) {
if (this.database) {
withDatabaseTransaction(this.database, () => {
if (message) {
this.database.prepare(`
INSERT INTO messages (id, record) VALUES (?, ?)
ON CONFLICT(id) DO UPDATE SET record = excluded.record
`).run(message.id, JSON.stringify(message));
}
if (entry) {
this.database.prepare(`
INSERT INTO workflow_journal (id, run_id, category, area, record) VALUES (?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET record = excluded.record
`).run(entry.id, entry.runId, entry.category, entry.area, JSON.stringify(entry));
}
this.database.prepare(`
INSERT INTO workflow_runs (id, definition_id, delivery_id, record) VALUES (?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET record = excluded.record
`).run(run.id, run.definitionId, run.deliveryId, JSON.stringify(run));
});
}
if (message) Map.prototype.set.call(this.messages, message.id, message);
if (entry) this.journal.set(entry.id, entry);
this.workflowRuns.set(run.id, run);
}
healthy() {
if (!this.database) return true;
return this.database.prepare("SELECT 1 AS ok").get() !== void 0;
}
close() {
this.database?.close();
}
load() {
if (!this.database) return;
const agentRows = this.database.prepare("SELECT record FROM agents").all();
const workflowRows = this.database.prepare("SELECT record FROM workflow_runs").all();
const journalRows = this.database.prepare("SELECT record FROM workflow_journal").all();
const contextRows = this.database.prepare("SELECT record FROM context_items").all();
const leaseRows = this.database.prepare("SELECT record FROM leases").all();
for (const row of agentRows) {
const agent = JSON.parse(row.record);
this.agents.set(agent.id, agent);
}
for (const row of workflowRows) {
const run = JSON.parse(row.record);
this.workflowRuns.set(run.id, run);
}
for (const row of journalRows) {
const entry = JSON.parse(row.record);
this.journal.set(entry.id, entry);
}
for (const row of contextRows) {
const item = JSON.parse(row.record);
this.contextItems.set(item.id, item);
}
for (const row of leaseRows) {
const lease = parseLeaseRecord(row.record);
if (lease) this.leases.set(lease.resource, lease);
}
}
};
// plugins/kxm/src/hub.ts
var DEFAULT_WORKFLOW_WAIT_TIMEOUT_MS = 24 * 60 * 6e4;
var MIN_WORKFLOW_WAIT_TIMEOUT_MS = 1e3;
var MAX_WORKFLOW_WAIT_TIMEOUT_MS = 30 * 24 * 60 * 6e4;
function isLoopback(host2) {
if (host2 === "localhost" || host2 === "::1") return true;
return isIP(host2) === 4 && host2.startsWith("127.");
}
function publicAgent(agent, staleAfterMs, now = Date.now()) {
const { key: _key, ...identity } = agent;
return toAgentRecord(identity, staleAfterMs, now);
}
var RUNTIME_ID_PATTERN = /^[a-z][a-z0-9]{1,15}_[A-Za-z0-9][A-Za-z0-9_-]{5,127}$/;
function requireRuntimeId(value) {
const runtimeId = requireString(value, "runtimeId", { max: 144 });
if (!RUNTIME_ID_PATTERN.test(runtimeId)) {
throw new ProtocolError(400, "runtimeId must be an opaque runtime id", "invalid_runtime_id");
}
return runtimeId;
}
function runtimePresenceView(record, staleAfterMs, nowMs) {
const heartbeatMs = Date.parse(record.heartbeatAt);
const leaseExpiresMs = Number.isFinite(heartbeatMs) ? heartbeatMs + staleAfterMs : 0;
return {
runtimeId: record.runtimeId,
...record.host ? { host: record.host } : {},
registeredAt: record.registeredAt,
heartbeatAt: record.heartbeatAt,
leaseExpiresAt: new Date(leaseExpiresMs).toISOString(),
presence: leaseExpiresMs > nowMs ? "online" : "expired"
};
}
function safeTokenEqual(actual, expected) {
return timingSafeStringCompare(actual, expected);
}
function leaseRefusal(reason, name, lease) {
if (reason === "missing") {
return new ProtocolError(404, `no lease is held on ${name}`, "lease_not_found");
}
if (reason === "expired") {
return new ProtocolError(
409,
`lease on ${name} expired at ${lease?.expiresAt ?? "its deadline"}; re-acquire to take it over`,
"lease_expired",
{ lease }
);
}
if (reason === "held") {
return new ProtocolError(
409,
`lease on ${name} is held by ${lease?.holderAgentName ?? "another agent"} until ${lease?.expiresAt ?? "its deadline"}`,
"lease_held",
{ lease }
);
}
return new ProtocolError(
409,
`fencing token for ${name} was superseded; the hub is now at token ${lease?.fencingToken ?? "a newer value"}`,
"lease_superseded",
{ lease }
);
}
function bearerToken(request) {
const header = request.headers.authorization;
return header?.startsWith("Bearer ") ? header.slice(7) : void 0;
}
function json(response, statusCode, payload) {
const body = JSON.stringify(payload);
response.writeHead(statusCode, {
"content-type": "application/json; charset=utf-8",
"content-length": Buffer.byteLength(body),
"cache-control": "no-store",
"x-content-type-options": "nosniff"
});
response.end(body);
}
function text(response, statusCode, body, contentType) {
response.writeHead(statusCode, {
"content-type": contentType,
"content-length": Buffer.byteLength(body),
"cache-control": "no-store",
"x-content-type-options": "nosniff"
});
response.end(body);
}
async function readBody(request) {
const contentType = request.headers["content-type"] ?? "";
if (!contentType.toLowerCase().startsWith("application/json")) {
throw new ProtocolError(415, "content-type must be application/json", "unsupported_media_type");
}
const chunks = [];
let length = 0;
for await (const chunk of request) {
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
length += buffer.length;
if (length > MAX_BODY_BYTES) {
throw new ProtocolError(413, "request body is too large", "payload_too_large");
}
chunks.push(buffer);
}
return Buffer.concat(chunks);
}
function parseJsonBody(buffer) {
if (buffer.length === 0) return {};
try {
const value = JSON.parse(buffer.toString("utf8"));
if (value === null || Array.isArray(value) || typeof value !== "object") {
throw new Error("body must be an object");
}
return value;
} catch {
throw new ProtocolError(400, "request body must be valid JSON object", "invalid_json");
}
}
async function readJson(request) {
return parseJsonBody(await readBody(request));
}
function sameWorkflowMessageContext(left, right) {
if (!left || !right) return left === right;
return left.schema === right.schema && left.runId === right.runId && left.stageId === right.stageId && left.requirementKey === right.requirementKey && left.attempt === right.attempt;
}
function parseOptionalBoolean(value, field) {
if (value === void 0 || value === null) return false;
if (typeof value === "boolean") return value;
throw new ProtocolError(400, `${field} must be a boolean`);
}
function sameIdempotentRequest(message, target, content, delivery, correlationId, replyTo, hops, maxHops, ttlMs, workflowContext) {
return (message.to === target || message.toName.toLowerCase() === target.toLowerCase()) && message.content === content && message.delivery === delivery && message.correlationId === correlationId && message.replyTo === replyTo && message.hops === hops && message.maxHops === maxHops && sameWorkflowMessageContext(message.workflowContext, workflowContext) && Date.parse(message.expiresAt) - Date.parse(message.createdAt) === ttlMs;
}
function parseContextAuthority(value) {
if (typeof value !== "string" || !CONTEXT_AUTHORITIES.includes(value)) {
throw new ProtocolError(400, "authority must be one of policy, instruction, evidence, hypothesis", "invalid_context_request");
}
return value;
}
function parseContextConfidence(value) {
if (typeof value !== "string" || !CONTEXT_CONFIDENCES.includes(value)) {
throw new ProtocolError(400, "confidence must be one of verified, probable, uncertain", "invalid_context_request");
}
return value;
}
function boundedStringList(value, field, maxItems = 32) {
if (value === void 0) return [];
if (!Array.isArray(value) || value.length > maxItems) {
throw new ProtocolError(400, `${field} must be an array with at most ${maxItems} items`);
}
return value.map((item, index) => requireString(item, `${field}[${index}]`, { max: 1e3 }));
}
function boundedWorkflowEvidence(value, field = "evidence", maxItems = 64) {
if (value === void 0) return {};
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new ProtocolError(400, `${field} must be an object keyed by required evidence identity`, "invalid_workflow_evidence");
}
const entries = Object.entries(value);
if (entries.length > maxItems) {
throw new ProtocolError(400, `${field} must contain at most ${maxItems} keyed items`, "invalid_workflow_evidence");
}
const evidence = /* @__PURE__ */ new Map();
for (const [rawRequirement, rawEvidence] of entries) {
const requirement = canonicalWorkflowEvidenceKey(
requireString(rawRequirement, `${field} requirement`, { max: 128 })
);
if (evidence.has(requirement)) {
throw new ProtocolError(
400,
`${field} contains duplicate normalized requirement identity: ${requirement}`,
"invalid_workflow_evidence"
);
}
evidence.set(requirement, requireString(rawEvidence, `${field}.${requirement}`, { max: 1e3 }));
}
return Object.fromEntries(evidence);
}
function boundedWorkflowEvidenceReferences(value, field = "evidenceRefs", maxItems = 32) {
if (value === void 0) return {};
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new ProtocolError(400, `${field} must be an object keyed by required evidence identity`, "invalid_workflow_evidence_refs");
}
const entries = Object.entries(value);
if (entries.length > maxItems) {
throw new ProtocolError(400, `${field} must contain at most ${maxItems} requirements`, "invalid_workflow_evidence_refs");
}
const references = /* @__PURE__ */ new Map();
for (const [rawRequirement, rawReference] of entries) {
const requirement = canonicalWorkflowEvidenceKey(
requireString(rawRequirement, `${field} requirement`, { max: 128 })
);
if (references.has(requirement)) {
throw new ProtocolError(
400,
`${field} contains duplicate normalized requirement identity: ${requirement}`,
"invalid_workflow_evidence_refs"
);
}
if (!rawReference || typeof rawReference !== "object" || Array.isArray(rawReference)) {
throw new ProtocolError(400, `${field}.${requirement} must be an object`, "invalid_workflow_evidence_refs");
}
const referenceObject = rawReference;
if (Object.keys(referenceObject).some((key) => key !== "messageIds")) {
throw new ProtocolError(
400,
`${field}.${requirement} may contain only messageIds; provenance is hub-derived`,
"invalid_workflow_evidence_refs"
);
}
const rawIds = referenceObject.messageIds;
if (!Array.isArray(rawIds) || rawIds.length < 1 || rawIds.length > 16) {
throw new ProtocolError(
400,
`${field}.${requirement}.messageIds must contain between 1 and 16 IDs`,
"invalid_workflow_evidence_refs"
);
}
const messageIds = rawIds.map((candidate, index) => requireString(candidate, `${field}.${requirement}.messageIds[${index}]`, { max: 80 }));
if (new Set(messageIds).size !== messageIds.length) {
throw new ProtocolError(400, `${field}.${requirement}.messageIds must be unique`, "invalid_workflow_evidence_refs");
}
references.set(requirement, { messageIds });
}
return Object.fromEntries(references);
}
function requestedWorkflowMessageContext(value) {
if (value === void 0) return void 0;
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new ProtocolError(400, "workflowContext must be an object", "invalid_workflow_context");
}
const context = value;
if (Object.keys(context).some((key) => !["runId", "stageId", "requirementKey", "attempt"].includes(key))) {
throw new ProtocolError(400, "workflowContext contains unsupported fields", "invalid_workflow_context");
}
if (context.attempt === void 0) {
throw new ProtocolError(400, "workflowContext.attempt is required", "invalid_workflow_context");
}
return {
runId: requireString(context.runId, "workflowContext.runId", { max: 80 }),
stageId: requireString(context.stageId, "workflowContext.stageId", { max: 64 }),
requirementKey: canonicalWorkflowEvidenceKey(
requireString(context.requirementKey, "workflowContext.requirementKey", { max: 128 })
),
attempt: parseBoundedInteger(context.attempt, "workflowContext.attempt", 1, 1, 20)
};
}
function validateWorkflowSignalContext(evidence, runId, stageId, signalKey) {
const expectedContext = {
"workflow.run": runId,
"workflow.stage": stageId,
"workflow.signal": signalKey
};
for (const [contextKey, expectedValue] of Object.entries(expectedContext)) {
const suppliedValue = evidence[contextKey];
if (suppliedValue === void 0 || suppliedValue === expectedValue) continue;
throw new ProtocolError(
409,
`evidence ${contextKey} does not match the workflow signal route and active wait`,
"workflow_signal_context_mismatch",
{ contextKey }
);
}
}
function workflowSignalKey(value) {
const key = requireString(value, "signalKey", { max: 128 });
if (!/^[A-Za-z0-9][A-Za-z0-9._:-]*$/.test(key)) {
throw new ProtocolError(400, "signalKey may contain letters, numbers, dot, underscore, colon, and hyphen", "invalid_signal_key");
}
return key;
}
function createMeshHub(options = {}) {
const host2 = options.host ?? "127.0.0.1";
const port2 = options.port ?? 7331;
const authToken2 = options.authToken?.trim();
const projectTokens2 = Object.fromEntries(
Object.entries(options.projectTokens ?? {}).map(([project, token]) => [project, token.trim()])
);
const staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_AFTER_MS;
const defaultMessageTtlMs = options.messageTtlMs ?? DEFAULT_MESSAGE_TTL_MS;
const messageRetentionMs2 = options.messageRetentionMs ?? DEFAULT_MESSAGE_RETENTION_MS;
const cleanupIntervalMs = options.cleanupIntervalMs ?? Math.max(250, Math.floor(staleAfterMs / 3));
const shutdownGraceMs = options.shutdownGraceMs ?? 5e3;
const rateLimit = options.rateLimit === false ? void 0 : {
windowMs: options.rateLimit?.windowMs ?? DEFAULT_RATE_LIMIT_WINDOW_MS,
maxRequests: options.rateLimit?.maxRequests ?? DEFAULT_RATE_LIMIT_MAX
};
const webhookWorkflows2 = new Map((options.webhookWorkflows ?? []).map((workflow) => [workflow.id, workflow]));
const logger = options.logger ?? (() => void 0);
const hubNow = options.now ?? (() => Date.now());
const assetsDir2 = options.assetsDir;
const hubRepoRoot = options.repoRoot ?? (options.dataPath && options.dataPath !== ":memory:" ? resolve6(dirname6(dirname6(options.dataPath))) : process.cwd());
const store = new MeshStore(options.dataPath);
const agents = store.agents;
const messages = store.messages;
function agentLogSide(id, fallbackName, side) {
const agent = agents.get(id);
return {
[side]: id,
[`${side}Name`]: agent?.name ?? fallbackName,
[`${side}Online`]: Boolean(agent?.online),
...agent?.model ? { [`${side}Model`]: agent.model } : {}
};
}
function messageLog(message, fromId, fromName, toId, toName) {
return {
project: message.project,
status: message.status,
delivery: message.delivery,
...agentLogSide(fromId, fromName, "from"),
...agentLogSide(toId, toName, "to")
};
}
const workflowRuns = store.workflowRuns;
const journal = store.journal;
const stateProvider = new NativeStateProvider(store);
const skillLifecycle = options.skillLifecycle ?? (options.skillsDir || existsSync6(join6(process.cwd(), ".kxm", "skills")) ? new SkillLifecycle(options.skillsDir ?? join6(process.cwd(), ".kxm", "skills")) : void 0);
const streams = /* @__PURE__ */ new Map();
const opsStreams = /* @__PURE__ */ new Set();
const rateBuckets = /* @__PURE__ */ new Map();
const counters = {
requests: 0,
errors: 0,
registrations: 0,
messagesSent: 0,
messagesReplied: 0,
messagesCancelled: 0,
messagesExpired: 0,
messagesPurged: 0,
webhooksAccepted: 0,
workflowCheckpoints: 0,
workflowWaits: 0,
workflowSignals: 0,
workflowWaitTimeouts: 0,
workflowDegradations: 0,
journalEntries: 0,
contextRequests: 0,
attemptLatencySecondsTotal: 0,
meteredCostUsdTotal: 0,
leasesGranted: 0,
leasesRefused: 0,
leasesReleased: 0,
syncEventsAccepted: 0,
syncEventsDuplicate: 0,
syncEventsRefused: 0,
syncConflicts: 0,
runtimeHeartbeats: 0
};
let cleanupTimer;
let closed = false;
function exportTerminalRetrospective(run) {
if (!assetsDir2 || run.status !== "completed" && run.status !== "failed") return;
try {
const entries = [...journal.values()].filter((entry) => entry.runId === run.id);
const files = writeRetrospective(`${assetsDir2}${process.platform === "win32" ? "\\" : "/"}retrospectives`, buildRetrospective(run, entries, run.updatedAt));
logger({ event: "workflow_retrospective_exported", workflowRunId: run.id, jsonPath: files.jsonPath, markdownPath: files.mdPath });
} catch (error) {
logger({ event: "workflow_retrospective_export_failed", workflowRunId: run.id, error: error instanceof Error ? error.message : "retrospective_export_failed" });
}
}
if (!isLoopback(host2) && !authToken2) {
store.close();
throw new Error("KXM_AUTH_TOKEN is required when binding beyond localhost");
}
if (staleAfterMs < 100 || defaultMessageTtlMs < MIN_MESSAGE_TTL_MS || messageRetentionMs2 < MIN_MESSAGE_RETENTION_MS || shutdownGraceMs < 0) {
store.close();
throw new Error("stale and message TTL settings are below supported minimums");
}
if (rateLimit && (rateLimit.windowMs < 100 || rateLimit.maxRequests < 1)) {
store.close();
throw new Error("rate limit settings are invalid");
}
if (webhookWorkflows2.size !== (options.webhookWorkflows ?? []).length) {
store.close();
throw new Error("webhook workflow IDs must be unique");
}
for (const agent of agents.values()) {
agent.online = false;
store.saveAgent(agent);
}
function expectedProjectToken(project) {
return projectTokens2[project] || authToken2;
}
function requireProjectAuth(request, project) {
const expected = expectedProjectToken(project);
if (!expected) return;
if (!safeTokenEqual(bearerToken(request), expected)) {
throw new ProtocolError(401, "invalid project authentication token", "invalid_auth", {
operation: "other",
nextAction: "check_project_token"
});
}
}
function contextCallerProject(request, requested) {
const project = requireString(requested, "project", { max: 200 });
const agentHeader = request.headers["x-kxm-agent-id"];
if (typeof agentHeader === "string" && agentHeader.trim()) {
const agent = requireAgent(request);
requireProjectAuth(request, agent.project);
if (agent.project !== project) {
throw new ProtocolError(403, "context requests are limited to the agent's project", "context_isolation_violation");
}
return { project, caller: agent.id, credential: "agent" };
}
requireAdminAuth(request);
const callerHeader = request.headers["x-kxm-caller-id"];
const caller = typeof callerHeader === "string" && callerHeader.trim() ? callerHeader.trim() : "kxm-admin";
return { project, caller, credential: "admin" };
}
function requireAdminAuth(request) {
if (!authToken2 && isLoopback(host2)) return;
if (!authToken2 || !safeTokenEqual(bearerToken(request), authToken2)) {
throw new ProtocolError(401, "invalid administrative authentication token", "invalid_auth", {
operation: "other",
nextAction: "check_project_token"
});
}
}
function requireConfiguredAdminAuth(request, purpose = "workflow degradation approval") {
if (!authToken2) {
throw new ProtocolError(
503,
`KXM_AUTH_TOKEN must be configured for ${purpose}`,
"admin_auth_not_configured"
);
}
requireAdminAuth(request);
}
function requireAgent(request, expectedId) {
const agentId = expectedId ?? String(request.headers["x-kxm-agent-id"] ?? "");
const agentKey = String(request.headers["x-kxm-agent-key"] ?? "");
const agent = agents.get(agentId);
if (!agent || !agentKey || !safeTokenEqual(agentKey, agent.key)) {
throw new ProtocolError(401, "invalid agent identity", "invalid_agent_identity", {
operation: "other",
nextAction: "reconnect_with_current_agent_key"
});
}
const wasOffline = !agent.online;
agent.lastSeenAt = nowIso();
agent.online = true;
store.saveAgent(agent);
if (wasOffline) {
broadcastPresence(agent);
if ((streams.get(agent.id)?.size ?? 0) > 0) flushPending(agent.id);
}
return agent;
}
function checkRateLimit(request, response) {
if (!rateLimit) return;
const key = String(request.headers["x-kxm-agent-id"] ?? request.socket.remoteAddress ?? "unknown");
const now = Date.now();
const current = rateBuckets.get(key);
const bucket = !current || now - current.startedAt >= rateLimit.windowMs ? { startedAt: now, count: 0 } : current;
bucket.count += 1;
rateBuckets.set(key, bucket);
const remaining = Math.max(0, rateLimit.maxRequests - bucket.count);
response.setHeader("x-ratelimit-limit", String(rateLimit.maxRequests));
response.setHeader("x-ratelimit-remaining", String(remaining));
if (bucket.count > rateLimit.maxRequests) {
const retryAfterSeconds = Math.max(1, Math.ceil((bucket.startedAt + rateLimit.windowMs - now) / 1e3));
response.setHeader("retry-after", String(retryAfterSeconds));
throw new ProtocolError(429, "request rate limit exceeded", "rate_limited");
}
}
function publish(agentId, event) {
const clients = streams.get(agentId);
if (!clients || clients.size === 0) return false;
let frame;
let published = false;
for (const client of clients) {
if (client.presenceOnly && event.type !== "presence") continue;
frame ??= `event: ${event.type}
data: ${JSON.stringify(event)}
`;
client.response.write(frame);
published = true;
}
return published;
}
function publishOps(project, topic) {
const frame = `event: ops
data: ${JSON.stringify({ type: "ops", project, topic, at: nowIso() })}
`;
for (const client of opsStreams) {
if (client.project === project) client.response.write(frame);
}
}
function homeRuntimesView(project, nowMs) {
const presence = new Map(store.listRuntimePresence(project).map((record) => [record.runtimeId, record]));
const runs = /* @__PURE__ */ new Map();
for (const event of store.listSyncEvents(project)) {
const key = `${event.projectId}\0${event.runId}`;
const bucket = runs.get(key);
if (bucket) bucket.push(event);
else runs.set(key, [event]);
}
const homes = /* @__PURE__ */ new Map();
for (const events of runs.values()) {
const first = events[0];
let cursor = 0;
let status;
let workflowId;
let displayTitle;
let updatedAt;
for (const event of events) {
if (event.sequence !== cursor + 1) break;
cursor = event.sequence;
const parsed = JSON.parse(event.bytes);
const payload = parsed.payload ?? {};
if (event.eventType.startsWith("run.") && typeof payload.status === "string") status = payload.status;
if (typeof payload.workflowId === "string") workflowId = payload.workflowId;
if (typeof payload.displayTitle === "string") displayTitle = payload.displayTitle;
if (typeof parsed.occurredAt === "string") updatedAt = parsed.occurredAt;
}
const home = presence.get(first.homeRuntimeId);
const orphaned = !home || runtimePresenceView(home, staleAfterMs, nowMs).presence === "expired";
const list = homes.get(first.homeRuntimeId) ?? [];
list.push({
projectId: first.projectId,
runId: first.runId,
...workflowId ? { workflowId } : {},
...displayTitle ? { displayTitle } : {},
...status ? { status } : {},
lastSequence: cursor,
pendingGap: events.length > cursor,
...updatedAt ? { updatedAt } : {},
orphaned
});
homes.set(first.homeRuntimeId, list);
}
for (const runtimeId of presence.keys()) if (!homes.has(runtimeId)) homes.set(runtimeId, []);
return [...homes.entries()].sort(([left], [right]) => left.localeCompare(right)).map(([runtimeId, homeRuns]) => {
const record = presence.get(runtimeId);
const view = record ? runtimePresenceView(record, staleAfterMs, nowMs) : void 0;
return {
runtimeId,
...view ? { host: view.host, heartbeatAt: view.heartbeatAt, leaseExpiresAt: view.leaseExpiresAt } : {},
presence: view?.presence ?? "unknown",
orphaned: !view || view.presence === "expired",
runs: homeRuns.sort((left, right) => String(right.updatedAt ?? "").localeCompare(String(left.updatedAt ?? ""))).slice(0, 16),
runTotal: homeRuns.length
};
});
}
function opsSnapshot(project) {
const snapshotAt = Date.now();
const projectAgents = [...agents.values()].filter((agent) => agent.project === project).map((agent) => publicAgent(agent, staleAfterMs, snapshotAt)).sort((left, right) => Number(right.online) - Number(left.online) || left.name.localeCompare(right.name));
const open = store.getOpenMessages(project);
const projectRuns = [...workflowRuns.values()].filter((run) => run.project === project).sort((left, right) => Date.parse(right.updatedAt) - Date.parse(left.updatedAt));
return {
project,
fetchedAt: nowIso(),
agents: projectAgents,
openMessages: open.slice(0, 16).map((message) => ({
id: message.id,
status: message.status,
fromName: message.fromName,
toName: message.toName,
delivery: message.delivery,
createdAt: message.createdAt,
...message.correlationId ? { correlationId: message.correlationId } : {}
})),
openMessageTotal: open.length,
runs: projectRuns.slice(0, 8).map((run) => {
const stages = (run.stages ?? []).slice(0, 16).map((stage) => ({
id: stage.id,
label: stage.label,
status: stage.status,
...stage.attempts ? { attempts: stage.attempts } : {}
}));
const done = stages.filter((stage) => stage.status === "passed" || stage.status === "failed" || stage.status === "warning").length;
return {
id: run.id,
status: run.status,
definitionId: run.definitionId,
project: run.project,
...run.currentStage ? { currentStage: run.currentStage } : {},
...run.targetAgentName ? { targetAgentName: run.targetAgentName } : {},
...run.updatedAt ? { updatedAt: run.updatedAt } : {},
...stages.length > 0 ? { progress: { done, total: stages.length }, stages } : {}
};
}),
runTotal: projectRuns.length,
homeRuntimes: homeRuntimesView(project, hubNow()),
plans: [...journal.values()].filter((entry) => entry.category === "plan" && projectRuns.some((run) => run.id === entry.runId)).sort((left, right) => Date.parse(right.createdAt) - Date.parse(left.createdAt)).slice(0, 16).map((entry) => ({
id: entry.id,
runId: entry.runId,
summary: entry.summary.replace(/\s+/g, " ").trim().slice(0, 120),
createdAt: entry.createdAt,
...entry.stageId ? { stageId: entry.stageId } : {},
...entry.severity ? { severity: entry.severity } : {}
}))
};
}
function broadcastPresence(agent) {
for (const candidate of agents.values()) {
if (candidate.project === agent.project && candidate.id !== agent.id && candidate.online) {
publish(candidate.id, { type: "presence", agent: publicAgent(agent, staleAfterMs) });
}
}
publishOps(agent.project, "agents");
}
function findTarget(project, target, allowOffline = false) {
const byId = agents.get(target);
if (byId?.project === project && (allowOffline || byId.online)) return byId;
const byName = [...agents.values()].find(
(agent) => agent.project === project && (allowOffline || agent.online) && agent.name.toLowerCase() === target.toLowerCase()
);
if (!byName) throw new ProtocolError(404, `online target not found: ${target}`, "target_not_found");
return byName;
}
function findKnownTarget(project, target) {
const byId = agents.get(target);
if (byId?.project === project) return byId;
const byName = [...agents.values()].find(
(agent) => agent.project === project && agent.name.toLowerCase() === target.toLowerCase()
);
if (!byName) {
throw new ProtocolError(409, `workflow target has not registered: ${target}`, "workflow_target_unavailable");
}
return byName;
}
function resolveStageEvidencePolicies(stage, project, coordinator) {
if (!stage.evidencePolicies) return void 0;
const resolved = /* @__PURE__ */ new Map();
for (const [requirementKey, policy] of Object.entries(stage.evidencePolicies)) {
const eligible = /* @__PURE__ */ new Map();
for (const selector of policy.eligibleAgents) {
const agent = findKnownTarget(project, selector);
if (agent.id === coordinator.id) {
throw new ProtocolError(
409,
`workflow evidence policy ${stage.id}/${requirementKey} cannot include the coordinator`,
"workflow_evidence_policy_invalid"
);
}
eligible.set(agent.id, { id: agent.id, name: agent.name });
}
if (eligible.size < policy.minProducers) {
throw new ProtocolError(
409,
`workflow evidence policy ${stage.id}/${requirementKey} resolves to ${eligible.size} unique producers but requires ${policy.minProducers}`,
"workflow_evidence_policy_unresolvable"
);
}
resolved.set(requirementKey, {
kind: "peer-reply",
minProducers: policy.minProducers,
eligibleProducers: [...eligible.values()],
acceptedStatuses: ["replied"],
...policy.degradation ? { degradation: { ...policy.degradation } } : {}
});
}
return Object.fromEntries(resolved);
}
function authorizeWorkflowMessageContext(sender, targetInput, requested) {
const run = workflowRuns.get(requested.runId);
if (!run || run.project !== sender.project || run.targetAgentId !== sender.id) {
throw new ProtocolError(403, "workflow context is not assigned to this coordinator", "workflow_context_forbidden");
}
const stage = run.stages.find((candidate) => candidate.id === requested.stageId);
if (!stage || run.currentStage !== stage.id || run.status !== "running" || stage.status !== "in_progress") {
throw new ProtocolError(409, "workflow context does not reference the active stage", "workflow_context_inactive");
}
const requirementKey = canonicalWorkflowEvidenceKey(requested.requirementKey);
const policy = stage.resolvedEvidencePolicies?.[requirementKey];
if (!policy) {
throw new ProtocolError(
400,
`workflow requirement ${requirementKey} does not accept peer evidence`,
"workflow_evidence_policy_missing"
);
}
if (requested.attempt !== stage.attempts + 1) {
throw new ProtocolError(
409,
`workflow context attempt ${requested.attempt} does not match active attempt ${stage.attempts + 1}`,
"workflow_context_attempt_mismatch"
);
}
const normalizedTarget = targetInput.toLowerCase();
const eligible = policy.eligibleProducers.find(
(producer) => producer.id === targetInput || producer.name.toLowerCase() === normalizedTarget
);
if (!eligible) {
throw new ProtocolError(
403,
`target ${targetInput} is not eligible for workflow evidence ${requirementKey}`,
"workflow_evidence_producer_forbidden"
);
}
return {
schema: "pi-mesh.workflow-message-context.v1",
runId: run.id,
stageId: stage.id,
requirementKey,
attempt: requested.attempt
};
}
function webhookEvent(request, payload) {
const header = request.headers["x-github-event"];
if (typeof header === "string" && header.trim()) return header.trim();
const candidate = payload.webhookEvent ?? payload.event;
return typeof candidate === "string" && candidate.trim() ? candidate.trim() : void 0;
}
function requireSha256Signature(signature) {
const separator = signature.indexOf("=");
const algorithm = separator > 0 ? signature.slice(0, separator).toLowerCase() : "";
if (algorithm !== "sha256") {
throw new ProtocolError(401, "webhook signature must use sha256", "webhook_signature_unsupported");
}
}
function verifyProviderWebhookSignature(request, body, definition) {
if (definition.source === "generic") {
throw new ProtocolError(
401,
"generic workflow webhooks require x-kxm-signature over the timestamp, delivery ID, definition, and body",
"webhook_signature_missing"
);
}
const signature = request.headers["x-hub-signature-256"] ?? request.headers["x-hub-signature"];
if (typeof signature !== "string") {
throw new ProtocolError(401, "webhook signature is required", "webhook_signature_missing");
}
requireSha256Signature(signature);
const expected = `sha256=${createHmac2("sha256", definition.secret).update(body).digest("hex")}`;
if (!safeTokenEqual(signature, expected)) {
throw new ProtocolError(401, "webhook signature is invalid", "webhook_signature_invalid");
}
const deliveryHeader = definition.source === "jira" ? request.headers["x-atlassian-webhook-identifier"] : request.headers["x-github-delivery"];
return requireString(deliveryHeader, "webhook delivery identifier", { max: 128 });
}
function verifyKxmWebhookSignature(request, body, secret, scope) {
const signature = request.headers["x-kxm-signature"];
if (typeof signature !== "string") {
throw new ProtocolError(
401,
"KXM webhooks require x-kxm-signature over the timestamp, delivery ID, route, and body",
"webhook_signature_missing"
);
}
requireSha256Signature(signature);
const timestamp = request.headers["x-kxm-timestamp"];
if (typeof timestamp !== "string" || !/^[0-9]{1,12}$/.test(timestamp)) {
throw new ProtocolError(401, "x-kxm-timestamp must be Unix seconds", "webhook_timestamp_invalid");
}
const deliveryId = requireString(request.headers["x-kxm-delivery-id"], "webhook delivery identifier", { max: 128 });
if (!safeTokenEqual(signature, workflowWebhookSignature(secret, scope, timestamp, deliveryId, body))) {
throw new ProtocolError(401, "webhook signature is invalid", "webhook_signature_invalid");
}
if (Math.abs(Date.now() / 1e3 - Number(timestamp)) > WORKFLOW_WEBHOOK_MAX_SKEW_SECONDS) {
throw new ProtocolError(
401,
`webhook timestamp is outside the ${WORKFLOW_WEBHOOK_MAX_SKEW_SECONDS}-second window; re-sign at send time`,
"webhook_timestamp_expired"
);
}
return deliveryId;
}
function workflowPrompt(definition, runId, payload) {
const rendered = renderWorkflowPrompt(definition.promptTemplate, payload);
const stageList = definition.stages.map((stage, index) => {
const peerPolicies = Object.entries(stage.evidencePolicies ?? {}).map(([requirement, policy]) => ` Peer evidence ${requirement}: ${policy.minProducers} unique replied producer(s) from ${policy.eligibleAgents.join(", ")}`);
return [
`${index + 1}. ${stage.label} (stageId: ${stage.id}, maxAttempts: ${stage.maxAttempts})`,
` ${stage.instructions}`,
` Required evidence keys: ${stage.requiredEvidence.join(", ") || "none"}`,
...peerPolicies
].join("\n");
}).join("\n");
return [
`Durable workflow run: ${runId}`,
`Workflow: ${definition.id}`,
"",
rendered,
"",
"Execute these stages in order:",
stageList,
"",
`At every stage, record material knowledge with kxm_workflow_record in one of these categories: ${JOURNAL_CATEGORIES.join(", ")}. Pass the stageId the entry belongs to; the hub binds the attempt and, when you omit area, uses the stage's declared area.`,
"Keep reviewed configuration as YAML directly under .kxm/ (such as .kxm/project.yaml and .kxm/workflows/), logs in .kxm/logs, and durable workflow artifacts in .kxm/assets. Never create .kxm/config, which KXM refuses, and never commit runtime logs, .kxm/state, or secrets.",
"Complete each stage with kxm_workflow_checkpoint. Supply evidence as an object whose keys exactly match the stage's required evidence keys. Unrelated keys never satisfy a requirement. A warning or failure must be corrected and checkpointed again until it passes or the attempt limit is reached.",
"For a peer-evidence requirement, send or fan out with workflowContext containing this run ID, the exact stage ID, requirement key, and current 1-based attempt. At checkpoint, cite only the returned message IDs under evidenceRefs; the hub derives producer and reply provenance.",
"When an external system must finish asynchronously, call kxm_workflow_wait with a stable signal key and any already-verified keyed evidence. That evidence is accumulated with the signed callback before the stage can pass; then settle the turn.",
"For multi-agent planning, delegate to the requested peers, compare their proposals, record contradictions, and synthesize the strongest evidence-backed plan.",
"Do not claim the workflow is complete until the checkpoint response reports completed=true."
].join("\n");
}
function createWorkflowResumeMessage(run, definition, deliveryId, signalKey, status, summary, evidence, retry) {
const createdAt = nowIso();
const ttlMs = parseBoundedInteger(
definition.ttlMs,
"workflow.ttlMs",
defaultMessageTtlMs,
MIN_MESSAGE_TTL_MS,
MAX_MESSAGE_TTL_MS
);
const nextInstruction = retry ? `Correct the ${status} result, rerun the external check, then wait for a new signal or checkpoint the stage.` : `Continue with stage ${run.currentStage}.`;
const content = requireString([
`Resume durable workflow run: ${run.id}`,
`Workflow: ${definition.id}`,
`External signal: ${signalKey}`,
`Result: ${status}`,
`Summary: ${summary}`,
`Evidence: ${workflowEvidenceStrings(evidence).join(", ") || "none supplied"}`,
"",
nextInstruction,
"Review the run with kxm_workflow_get and keep recording material learning with kxm_workflow_record (any of its ten categories; pass stageId for stage-bound entries).",
"Do not claim the workflow is complete until the checkpoint response reports completed=true."
].join("\n"), "workflow resume prompt", { max: MAX_CONTENT_CHARS });
const seq = store.nextAgentSequence(run.targetAgentId);
const message = {
id: newId("msg"),
project: run.project,
from: `workflow:${run.id}`,
fromName: `signal:${definition.id}`,
to: run.targetAgentId,
toName: run.targetAgentName,
content,
delivery: definition.delivery,
hops: 0,
maxHops: DEFAULT_MAX_HOPS,
seq,
correlationId: run.id,
workflowRunId: run.id,
idempotencyKey: `${definition.id}:signal:${deliveryId}`,
createdAt,
expiresAt: new Date(Date.parse(createdAt) + ttlMs).toISOString(),
status: "queued"
};
run.messageId = message.id;
run.updatedAt = createdAt;
return message;
}
function expireWorkflowWaits() {
const timestamp = nowIso();
const now = Date.parse(timestamp);
for (const run of workflowRuns.values()) {
if (run.status !== "waiting" || !run.waiting || Date.parse(run.waiting.expiresAt) > now) continue;
const transition = structuredClone(run);
const waiting = transition.waiting;
const stage = transition.stages.find((candidate) => candidate.id === waiting.stageId);
if (stage) {
stage.status = "failed";
stage.summary = `Timed out waiting for external signal ${waiting.signalKey}`;
stage.updatedAt = timestamp;
}
transition.status = "failed";
delete transition.currentStage;
delete transition.waiting;
transition.updatedAt = timestamp;
const entry = {
id: newId("journal"),
runId: transition.id,
agentId: transition.targetAgentId,
category: "error",
area: stage?.area ?? "harness",
severity: "error",
summary: `External workflow signal timed out: ${waiting.signalKey}`,
evidence: [`wait-created:${waiting.createdAt}`, `wait-expired:${waiting.expiresAt}`],
relatedEntryIds: [],
createdAt: timestamp,
...stage ? { stageId: stage.id, attempt: stage.attempts + 1 } : {}
};
const definition = webhookWorkflows2.get(transition.definitionId);
const ttlMs = parseBoundedInteger(
definition?.ttlMs,
"workflow.ttlMs",
defaultMessageTtlMs,
MIN_MESSAGE_TTL_MS,
MAX_MESSAGE_TTL_MS
);
const seq = store.nextAgentSequence(transition.targetAgentId);
const message = {
id: newId("msg"),
project: transition.project,
from: `workflow:${transition.id}`,
fromName: `timeout:${transition.definitionId}`,
to: transition.targetAgentId,
toName: transition.targetAgentName,
content: [
`Durable workflow run ${transition.id} failed while waiting for external signal ${waiting.signalKey}.`,
`Stage: ${waiting.stageId}`,
`Expected: ${waiting.summary}`,
`Deadline: ${waiting.expiresAt}`,
"Review whether the external action completed, record any follow-up outside this terminal run, and escalate or start a new retry-safe workflow only when appropriate."
].join("\n"),
delivery: definition?.delivery ?? "followUp",
hops: 0,
maxHops: DEFAULT_MAX_HOPS,
seq,
correlationId: transition.id,
workflowRunId: transition.id,
idempotencyKey: `${transition.definitionId}:timeout:${waiting.signalKey}:${waiting.expiresAt}`,
createdAt: timestamp,
expiresAt: new Date(Date.parse(timestamp) + ttlMs).toISOString(),
status: "queued"
};
transition.messageId = message.id;
store.saveWorkflowTransition(transition, message, entry);
publishOps(transition.project, "workflows");
publishOps(transition.project, "messages");
exportTerminalRetrospective(transition);
if (agents.get(transition.targetAgentId)?.online) {
publish(transition.targetAgentId, { type: "message", message });
}
counters.workflowWaitTimeouts += 1;
counters.journalEntries += 1;
logger({
event: "workflow_wait_timed_out",
workflowRunId: transition.id,
stageId: waiting.stageId,
signalKey: waiting.signalKey,
messageId: message.id
});
}
}
function flushPending(agentId) {
expireMessages();
const cursor = store.getConsumerCursor(agentId);
const pending = store.getPendingMessages(agentId, cursor);
for (const message of pending) {
publish(agentId, { type: "message", message });
}
}
function expireMessages() {
const now = Date.now();
for (const message of store.getExpiringMessages(now)) {
if ((message.status === "queued" || message.status === "delivered") && Date.parse(message.expiresAt) <= now) {
message.status = "expired";
message.error = "message expired before a reply was received";
store.saveMessage(message);
publishOps(message.project, "messages");
publish(message.from, { type: "expired", message });
publish(message.to, { type: "expired", message });
counters.messagesExpired += 1;
logger({ event: "message_expired", messageId: message.id, ...messageLog(message, message.from, message.fromName, message.to, message.toName) });
const run = [...workflowRuns.values()].find(
(candidate) => candidate.messageId === message.id && candidate.status === "running"
);
if (run) {
const expiredStage = run.stages.find((candidate) => candidate.id === run.currentStage);
run.status = "failed";
delete run.currentStage;
run.updatedAt = nowIso();
store.saveWorkflowRun(run);
publishOps(run.project, "workflows");
const entry = {
id: newId("journal"),
runId: run.id,
agentId: run.targetAgentId,
category: "error",
area: "harness",
severity: "error",
summary: "Workflow coordinator prompt expired before completion",
evidence: [`message:${message.id}`],
relatedEntryIds: [],
createdAt: run.updatedAt,
...expiredStage ? { stageId: expiredStage.id, attempt: expiredStage.attempts + 1 } : {}
};
store.saveJournalEntry(entry);
counters.journalEntries += 1;
exportTerminalRetrospective(run);
}
}
}
}
function purgeTerminalMessages() {
const swept = store.sweepRetention(messageRetentionMs2);
for (const message of swept.purgedMessages) {
publishOps(message.project, "messages");
counters.messagesPurged += 1;
logger({ event: "message_purged", messageId: message.id, ...messageLog(message, message.from, message.fromName, message.to, message.toName) });
}
for (const runId of swept.purgedRuns) {
logger({ event: "workflow_run_purged", runId });
}
for (const lease of swept.purgedLeases) {
logger({
event: "lease_purged",
resource: lease.resource,
project: lease.project,
agentId: lease.holderAgentId,
fencingToken: lease.fencingToken,
expiresAt: lease.expiresAt
});
}
}
function metricsBody() {
const onlineAgents = [...agents.values()].filter((agent) => agent.online).length;
return [
"# HELP kxm_online_agents Current online agent count.",
"# TYPE kxm_online_agents gauge",
`kxm_online_agents ${onlineAgents}`,
"# HELP kxm_messages Current retained message count.",
"# TYPE kxm_messages gauge",
`kxm_messages ${store.countMessages()}`,
"# TYPE kxm_requests_total counter",
`kxm_requests_total ${counters.requests}`,
"# TYPE kxm_errors_total counter",
`kxm_errors_total ${counters.errors}`,
"# TYPE kxm_registrations_total counter",
`kxm_registrations_total ${counters.registrations}`,
"# TYPE kxm_messages_sent_total counter",
`kxm_messages_sent_total ${counters.messagesSent}`,
"# TYPE kxm_messages_replied_total counter",
`kxm_messages_replied_total ${counters.messagesReplied}`,
"# TYPE kxm_messages_cancelled_total counter",
`kxm_messages_cancelled_total ${counters.messagesCancelled}`,
"# TYPE kxm_messages_expired_total counter",
`kxm_messages_expired_total ${counters.messagesExpired}`,
"# TYPE kxm_messages_purged_total counter",
`kxm_messages_purged_total ${counters.messagesPurged}`,
"# TYPE kxm_webhooks_accepted_total counter",
`kxm_webhooks_accepted_total ${counters.webhooksAccepted}`,
"# TYPE kxm_workflow_checkpoints_total counter",
`kxm_workflow_checkpoints_total ${counters.workflowCheckpoints}`,
"# TYPE kxm_workflow_waits_total counter",
`kxm_workflow_waits_total ${counters.workflowWaits}`,
"# TYPE kxm_workflow_signals_total counter",
`kxm_workflow_signals_total ${counters.workflowSignals}`,
"# TYPE kxm_workflow_wait_timeouts_total counter",
`kxm_workflow_wait_timeouts_total ${counters.workflowWaitTimeouts}`,
"# TYPE kxm_workflow_degradations_total counter",
`kxm_workflow_degradations_total ${counters.workflowDegradations}`,
"# TYPE kxm_workflow_journal_entries_total counter",
`kxm_workflow_journal_entries_total ${counters.journalEntries}`,
"# TYPE kxm_context_requests_total counter",
`kxm_context_requests_total ${counters.contextRequests}`,
"# TYPE kxm_attempt_latency_seconds_total counter",
`kxm_attempt_latency_seconds_total ${counters.attemptLatencySecondsTotal}`,
"# TYPE kxm_metered_cost_usd_total counter",
`kxm_metered_cost_usd_total ${counters.meteredCostUsdTotal}`,
"# TYPE kxm_leases_granted_total counter",
`kxm_leases_granted_total ${counters.leasesGranted}`,
"# TYPE kxm_leases_refused_total counter",
`kxm_leases_refused_total ${counters.leasesRefused}`,
"# TYPE kxm_leases_released_total counter",
`kxm_leases_released_total ${counters.leasesReleased}`,
"# TYPE kxm_sync_events_accepted_total counter",
`kxm_sync_events_accepted_total ${counters.syncEventsAccepted}`,
"# TYPE kxm_sync_events_duplicate_total counter",
`kxm_sync_events_duplicate_total ${counters.syncEventsDuplicate}`,
"# TYPE kxm_sync_events_refused_total counter",
`kxm_sync_events_refused_total ${counters.syncEventsRefused}`,
"# TYPE kxm_sync_conflicts_total counter",
`kxm_sync_conflicts_total ${counters.syncConflicts}`,
"# TYPE kxm_runtime_heartbeats_total counter",
`kxm_runtime_heartbeats_total ${counters.runtimeHeartbeats}`,
""
].join("\n");
}
const server = createServer(async (request, response) => {
const requestIdHeader = request.headers["x-request-id"];
const requestId = typeof requestIdHeader === "string" && /^[A-Za-z0-9._-]{1,80}$/.test(requestIdHeader) ? requestIdHeader : newId("req");
response.setHeader("x-request-id", requestId);
response.setHeader("referrer-policy", "no-referrer");
counters.requests += 1;
try {
let projectContextPool2 = function(project, journalCategories) {
const pool = store.listContextItems(project);
try {
const authored = loadAuthoredMemory(hubRepoRoot);
for (const rec of authored) {
pool.push(memoryRecordToContextItem(rec, project));
}
} catch {
}
const categoryFilter = journalCategories ? new Set(journalCategories) : void 0;
const runIds = new Set(
[...workflowRuns.values()].filter((run) => run.project === project).map((run) => run.id)
);
const contradictionIds = [];
for (const entry of journal.values()) {
if (!runIds.has(entry.runId)) continue;
if (categoryFilter && !categoryFilter.has(entry.category)) continue;
pool.push(journalEntryToContextItem(entry, project));
if (entry.category === "contradiction") contradictionIds.push(`journal_${entry.id}`);
}
for (const contradiction of stateProvider.contradictions()) {
if (contradiction.project !== project) continue;
contradictionIds.push(...contradiction.competingCurrentIds, ...contradiction.competingProposalIds);
}
return { pool, contradictionIds };
}, contextWikiPool2 = function(project, compiledAt) {
const { pool, contradictionIds } = projectContextPool2(project);
const stateItems = store.listContextItems(project, ["state"]);
const contradictions = stateProvider.contradictions().filter((entry) => entry.project === project);
return {
project,
stateItems,
contextItems: pool,
contradictions,
openContradictionItemIds: contradictionIds,
compiledAt
};
};
var projectContextPool = projectContextPool2, contextWikiPool = contextWikiPool2;
const url = new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
const method = request.method ?? "GET";
if (method === "GET" && url.pathname === "/health") {
json(response, 200, { ok: true, agents: [...agents.values()].filter((agent) => agent.online).length });
return;
}
if (method === "GET" && url.pathname === "/ready") {
const ready = store.healthy();
json(response, ready ? 200 : 503, { ok: ready, storage: store.persistent ? "sqlite" : "memory" });
return;
}
checkRateLimit(request, response);
const signalMatch = url.pathname.match(/^\/v1\/webhooks\/([^/]+)\/runs\/([^/]+)\/signals\/([^/]+)$/);
if (method === "POST" && signalMatch) {
const definitionId = decodeURIComponent(signalMatch[1]);
const runId = decodeURIComponent(signalMatch[2]);
const signalKey = workflowSignalKey(decodeURIComponent(signalMatch[3]));
const definition = webhookWorkflows2.get(definitionId);
if (!definition) throw new ProtocolError(404, "webhook workflow not found", "webhook_not_found");
const rawBody = await readBody(request);
const deliveryId = verifyKxmWebhookSignature(
request,
rawBody,
definition.signalSecret ?? definition.secret,
{ definitionId: definition.id, runId, signalKey }
);
const body = parseJsonBody(rawBody);
const run = workflowRuns.get(runId);
if (!run || run.definitionId !== definition.id) {
throw new ProtocolError(404, "workflow run not found", "workflow_not_found");
}
const payloadHash = createHash5("sha256").update(rawBody).digest("hex");
const existingReceipt = run.signalReceipts?.find((receipt2) => receipt2.deliveryId === deliveryId);
if (existingReceipt) {
if (existingReceipt.signalKey !== signalKey || existingReceipt.payloadHash !== payloadHash) {
throw new ProtocolError(
409,
"webhook delivery identifier was already used for a different signal",
"workflow_signal_delivery_conflict"
);
}
json(response, 200, {
duplicate: true,
status: existingReceipt.status,
stageId: existingReceipt.stageId,
signalKey: existingReceipt.signalKey,
receivedAt: existingReceipt.receivedAt,
degraded: existingReceipt.degraded === true,
degradedRequirements: existingReceipt.degradedRequirements ?? [],
resumed: Boolean(existingReceipt.messageId)
});
return;
}
expireWorkflowWaits();
const status = requireString(body.status, "status", { max: 16 });
if (status !== "passed" && status !== "warning" && status !== "failed") {
throw new ProtocolError(400, "status must be passed, warning, or failed", "invalid_checkpoint_status");
}
const summary = requireString(body.summary, "summary", { max: 4e3 });
const evidence = boundedWorkflowEvidence(body.evidence);
const receivedAt = nowIso();
const transition = structuredClone(workflowRuns.get(runId));
if (transition.status === "waiting" && transition.waiting) {
validateWorkflowSignalContext(
evidence,
runId,
transition.waiting.stageId,
signalKey
);
}
const result = resumeWorkflowFromSignal(transition, signalKey, status, summary, evidence, receivedAt);
const receipt = {
deliveryId,
payloadHash,
signalKey,
stageId: result.stageId,
status,
receivedAt
};
if (result.degraded) {
const degradedStage = transition.stages.find((candidate) => candidate.id === result.stageId);
receipt.degraded = true;
receipt.degradedRequirements = [...degradedStage.degradedRequirements ?? []];
}
(transition.signalReceipts ??= []).push(receipt);
let message;
let entry;
if (status !== "passed") {
const stage = transition.stages.find((candidate) => candidate.id === result.stageId);
entry = {
id: newId("journal"),
runId: transition.id,
agentId: transition.targetAgentId,
category: "error",
area: stage.area ?? "gates",
severity: status === "failed" ? "error" : "warning",
summary: `${stage.label}: ${summary}`,
evidence: workflowEvidenceStrings(evidence),
relatedEntryIds: [],
createdAt: receivedAt,
stageId: stage.id,
attempt: stage.attempts
};
} else if (result.degraded) {
const stage = transition.stages.find((candidate) => candidate.id === result.stageId);
entry = {
id: newId("journal"),
runId: transition.id,
agentId: transition.targetAgentId,
category: "decision",
area: stage.area ?? "security",
severity: "warning",
summary: `${stage.label} passed from a signed callback using a previously approved degraded peer quorum`,
evidence: [
"class:workflow_quorum_degradation_used",
...(stage.degradedRequirements ?? []).map((requirement) => `requirement:${requirement}`)
],
relatedEntryIds: [],
createdAt: receivedAt,
stageId: stage.id,
attempt: stage.attempts
};
}
if (transition.status === "running") {
message = createWorkflowResumeMessage(
transition,
definition,
deliveryId,
signalKey,
status,
summary,
evidence,
result.retry
);
receipt.messageId = message.id;
}
store.saveWorkflowTransition(transition, message, entry);
publishOps(transition.project, "workflows");
if (message) publishOps(transition.project, "messages");
exportTerminalRetrospective(transition);
if (entry) counters.journalEntries += 1;
if (message && agents.get(transition.targetAgentId)?.online) {
publish(transition.targetAgentId, { type: "message", message });
}
counters.workflowSignals += 1;
counters.workflowCheckpoints += 1;
logger({
event: "workflow_signal_received",
workflowRunId: transition.id,
deliveryId,
signalKey,
stageId: result.stageId,
status,
retry: result.retry,
completed: result.completed,
...message ? { messageId: message.id } : {}
});
json(response, message ? 202 : 200, {
duplicate: false,
status,
stageId: result.stageId,
signalKey,
retry: result.retry,
completed: result.completed,
degraded: result.degraded === true,
degradedRequirements: receipt.degradedRequirements ?? [],
resumed: Boolean(message)
});
return;
}
const webhookMatch = url.pathname.match(/^\/v1\/webhooks\/([^/]+)$/);
if (method === "POST" && webhookMatch) {
const definitionId = decodeURIComponent(webhookMatch[1]);
const definition = webhookWorkflows2.get(definitionId);
if (!definition) throw new ProtocolError(404, "webhook workflow not found", "webhook_not_found");
const rawBody = await readBody(request);
const bodyOnlySignature = request.headers["x-kxm-signature"] === void 0;
const deliveryId = bodyOnlySignature ? verifyProviderWebhookSignature(request, rawBody, definition) : verifyKxmWebhookSignature(request, rawBody, definition.secret, { definitionId: definition.id });
const payload = parseJsonBody(rawBody);
const event = webhookEvent(request, payload);
if (definition.event && event !== definition.event) {
response.writeHead(204, { "cache-control": "no-store" }).end();
return;
}
if (definition.filter && String(valueAtPath(payload, definition.filter.path) ?? "") !== definition.filter.equals) {
response.writeHead(204, { "cache-control": "no-store" }).end();
return;
}
const payloadHash = createHash5("sha256").update(rawBody).digest("hex");
const existing = [...workflowRuns.values()].find(
(run2) => run2.definitionId === definition.id && run2.deliveryId === deliveryId
);
if (existing) {
if (existing.payloadHash !== payloadHash) {
throw new ProtocolError(
409,
"webhook delivery identifier was already used for a different body",
"webhook_delivery_conflict"
);
}
json(response, 200, { duplicate: true, runId: existing.id, status: existing.status });
return;
}
if (bodyOnlySignature && [...workflowRuns.values()].some(
(run2) => run2.definitionId === definition.id && run2.payloadHash === payloadHash
)) {
throw new ProtocolError(
409,
"this signed body already started a run under another delivery identifier",
"webhook_payload_replayed"
);
}
const target = findKnownTarget(definition.project, definition.target);
const createdAt = nowIso();
const runId = newId("run");
const ttlMs = parseBoundedInteger(
definition.ttlMs,
"workflow.ttlMs",
defaultMessageTtlMs,
MIN_MESSAGE_TTL_MS,
MAX_MESSAGE_TTL_MS
);
const content = requireString(workflowPrompt(definition, runId, payload), "workflow prompt", {
max: MAX_CONTENT_CHARS
});
const seq = store.nextAgentSequence(target.id);
const message = {
id: newId("msg"),
project: definition.project,
from: `workflow:${runId}`,
fromName: `webhook:${definition.id}`,
to: target.id,
toName: target.name,
content,
delivery: definition.delivery,
hops: 0,
maxHops: DEFAULT_MAX_HOPS,
seq,
correlationId: runId,
workflowRunId: runId,
idempotencyKey: `${definition.id}:${deliveryId}`,
createdAt,
expiresAt: new Date(Date.parse(createdAt) + ttlMs).toISOString(),
status: "queued"
};
const stages = definition.stages.map((stage, index) => {
const resolvedEvidencePolicies = resolveStageEvidencePolicies(stage, definition.project, target);
return {
...stage,
...resolvedEvidencePolicies ? { resolvedEvidencePolicies } : {},
status: index === 0 ? "in_progress" : "pending",
attempts: 0,
evidence: {},
...index === 0 ? { startedAt: createdAt, updatedAt: createdAt } : {}
};
});
const run = {
id: runId,
definitionId: definition.id,
source: definition.source,
deliveryId,
payloadHash,
definitionHash: workflowDefinitionHash(definition),
...event ? { event } : {},
project: definition.project,
targetAgentId: target.id,
targetAgentName: target.name,
messageId: message.id,
status: "running",
currentStage: stages[0].id,
stages,
...definition.maxTransitions !== void 0 ? { maxTransitions: definition.maxTransitions } : {},
...definition.reproOracle ? { reproOracle: definition.reproOracle } : {},
...definition.planHash ? { planHashConfig: definition.planHash } : {},
...definition.requirePlanHash ? { requirePlanHash: definition.requirePlanHash } : {},
createdAt,
updatedAt: createdAt
};
store.saveMessage(message);
store.saveWorkflowRun(run);
publishOps(run.project, "messages");
publishOps(run.project, "workflows");
if (target.online) publish(target.id, { type: "message", message });
counters.webhooksAccepted += 1;
logger({
event: "webhook_workflow_started",
workflowId: definition.id,
workflowRunId: run.id,
deliveryId,
project: definition.project,
target: target.id
});
json(response, 202, { run, runId: run.id, duplicate: false });
return;
}
if (method === "GET" && url.pathname === "/metrics") {
requireAdminAuth(request);
text(response, 200, metricsBody(), "text/plain; version=0.0.4; charset=utf-8");
return;
}
if (method === "GET" && url.pathname === "/v1/ops/snapshot") {
requireConfiguredAdminAuth(request, "operations metadata");
const project = requireString(url.searchParams.get("project"), "project", { max: 128 });
expireMessages();
expireWorkflowWaits();
purgeTerminalMessages();
json(response, 200, opsSnapshot(project));
return;
}
if (method === "GET" && url.pathname === "/v1/ops/events") {
requireConfiguredAdminAuth(request, "operations metadata");
const project = requireString(url.searchParams.get("project"), "project", { max: 128 });
response.writeHead(200, {
"content-type": "text/event-stream",
"cache-control": "no-cache, no-transform",
connection: "keep-alive",
"x-accel-buffering": "no",
"x-content-type-options": "nosniff"
});
response.write(`event: ready
data: ${JSON.stringify({ type: "ops", project, topic: "agents", at: nowIso() })}
`);
const client = {
project,
response,
heartbeat: setInterval(() => response.write(": heartbeat\n\n"), 15e3)
};
client.heartbeat.unref();
opsStreams.add(client);
request.on("close", () => {
clearInterval(client.heartbeat);
opsStreams.delete(client);
});
return;
}
if (method === "GET" && url.pathname === "/v1/workflows") {
expireWorkflowWaits();
const agent = requireAgent(request);
requireProjectAuth(request, agent.project);
const runs = [...workflowRuns.values()].filter(
(run) => run.project === agent.project && run.targetAgentId === agent.id
);
json(response, 200, { runs });
return;
}
const workflowMatch = url.pathname.match(/^\/v1\/workflows\/([^/]+)$/);
if (method === "GET" && workflowMatch) {
expireWorkflowWaits();
const agent = requireAgent(request);
requireProjectAuth(request, agent.project);
const run = workflowRuns.get(decodeURIComponent(workflowMatch[1]));
if (!run) throw new ProtocolError(404, "workflow run not found", "workflow_not_found");
if (run.project !== agent.project || run.targetAgentId !== agent.id) {
throw new ProtocolError(
403,
"workflow run is not visible to this agent",
"workflow_forbidden",
workflowScopeExtras("get", run.targetAgentName)
);
}
const entries = [...journal.values()].filter((entry) => entry.runId === run.id);
json(response, 200, { run, journal: entries });
return;
}
const degradationMatch = url.pathname.match(/^\/v1\/workflows\/([^/]+)\/degradations$/);
if (method === "POST" && degradationMatch) {
requireConfiguredAdminAuth(request);
const body = await readJson(request);
const run = workflowRuns.get(decodeURIComponent(degradationMatch[1]));
if (!run) throw new ProtocolError(404, "workflow run not found", "workflow_not_found");
const stageId = requireString(body.stageId, "stageId", { max: 64 });
const requirementKey = canonicalWorkflowEvidenceKey(
requireString(body.requirementKey, "requirementKey", { max: 128 })
);
const reason = requireString(body.reason, "reason", { max: 1e3 });
const timestamp = nowIso();
const transition = structuredClone(run);
const result = approveWorkflowDegradation(
transition,
stageId,
requirementKey,
reason,
newId("approval"),
timestamp
);
if (result.created) {
const stage = transition.stages.find((candidate) => candidate.id === stageId);
const entry = {
id: newId("journal"),
runId: transition.id,
agentId: "kxm-admin",
category: "decision",
area: stage.area ?? "security",
severity: "warning",
summary: `Approved degraded peer quorum for ${stageId}/${requirementKey} attempt ${result.approval.attempt}`,
details: reason,
evidence: [
"class:workflow_quorum_degradation_approved",
`approval:${result.approval.id}`,
`policy-min:${result.approval.policyMinProducers}`,
`approved-min:${result.approval.approvedMinProducers}`
],
relatedEntryIds: [],
createdAt: timestamp,
stageId,
attempt: result.approval.attempt
};
store.saveWorkflowTransition(transition, void 0, entry);
publishOps(transition.project, "workflows");
counters.workflowDegradations += 1;
counters.journalEntries += 1;
logger({
event: "workflow_degradation_approved",
workflowRunId: transition.id,
stageId,
requirementKey,
attempt: result.approval.attempt,
approvalId: result.approval.id
});
}
json(response, result.created ? 201 : 200, {
run: result.created ? transition : run,
approval: result.approval,
duplicate: !result.created
});
return;
}
const contextGetMatch = url.pathname.match(/^\/v1\/context\/get$/);
if (method === "POST" && contextGetMatch) {
const body = await readJson(request);
const { project: callerProject, caller: callerId } = contextCallerProject(request, body.project);
const policy = rolePolicy(typeof body.role === "string" ? body.role : "");
const { pool, contradictionIds } = projectContextPool2(callerProject, policy.journalCategories);
const outcome = arbitrate(body, pool, {
contradictionIds,
...skillLifecycle ? { skillLifecycle } : {}
});
counters.contextRequests += 1;
const assembledRequest = outcome.audit.request;
logger({
event: "context_packet_assembled",
project: assembledRequest.project,
role: assembledRequest.role,
...assembledRequest.workflowRunId !== void 0 ? { workflowRunId: assembledRequest.workflowRunId } : {},
...assembledRequest.stageId !== void 0 ? { stageId: assembledRequest.stageId } : {},
taskChars: assembledRequest.task.length,
taskTokens: outcome.audit.relevance.taskTokens,
matchedCandidates: outcome.audit.relevance.matchedCandidates,
selectedIds: outcome.audit.selectedIds,
provenanceSummary: outcome.audit.provenanceSummary,
estimatedTokens: outcome.audit.estimatedTokens,
budgetTokens: outcome.audit.budgetTokens,
candidateCount: outcome.audit.candidateCount,
excludedSuperseded: outcome.audit.excludedSuperseded
});
json(response, 200, { packet: outcome.packet, audit: outcome.audit });
return;
}
const contextRecallMatch = url.pathname.match(/^\/v1\/context\/recall$/);
if (method === "POST" && contextRecallMatch) {
const body = await readJson(request);
const { project: callerProject, caller: callerId } = contextCallerProject(request, body.project);
const query = requireString(body.query ?? "", "query", { max: 500, allowEmpty: true });
const kinds = Array.isArray(body.kinds) ? body.kinds.filter((kind) => typeof kind === "string") : void 0;
const limit = parseBoundedInteger(body.limit, "limit", 25, 1, 100);
const { pool } = projectContextPool2(callerProject);
const live = pool.filter((item) => item.status !== "superseded" && item.status !== "rejected").filter((item) => kinds === void 0 || kinds.includes(item.kind));
const recalled = rankRecall(query, live, limit);
counters.contextRequests += 1;
logger({
event: "context_recall",
project: callerProject,
queryChars: query.length,
queryTokens: new Set(relevanceTokens(query)).size,
limit,
results: recalled.length
});
json(response, 200, {
items: recalled.map(({ item, relevance }) => ({ ...contextItemAuditMetadata(item), relevance })),
unresolvedGaps: recalled.length === 0 ? ["no matching context records"] : []
});
return;
}
const contextStateMatch = url.pathname.match(/^\/v1\/context\/state$/);
if (method === "POST" && contextStateMatch) {
const body = await readJson(request);
const { project: callerProject, caller: callerId } = contextCallerProject(request, body.project);
const key = requireString(body.key, "key", { max: 200 });
const asOf = body.asOf === void 0 || body.asOf === null ? void 0 : requireString(body.asOf, "asOf", { max: 64 });
const current = await stateProvider.get(callerProject, key, asOf);
counters.contextRequests += 1;
json(response, 200, { state: current, key });
return;
}
const contextStateProposeMatch = url.pathname.match(/^\/v1\/context\/state\/propose$/);
if (method === "POST" && contextStateProposeMatch) {
const body = await readJson(request);
const { project: callerProject, caller: callerId, credential } = contextCallerProject(request, body.project);
if (credential === "admin") requireConfiguredAdminAuth(request, "human-origin state proposals");
if (body.proposedBy !== void 0 && body.proposedBy !== callerId) {
logger({ event: "security_alert", alert: "state_proposer_mismatch", project: callerProject, callerId, credential });
throw new ProtocolError(
403,
"proposedBy must name the authenticated caller",
"state_proposer_mismatch"
);
}
const origin = credential === "agent" ? "peer" : "human";
const proposalId = await stateProvider.propose({
schema: "kxm.state-change-proposal.v1",
project: callerProject,
key: requireString(body.key, "key", { max: 200 }),
summary: requireString(body.summary, "summary", { max: 4e3 }),
authority: parseContextAuthority(body.authority),
confidence: parseContextConfidence(body.confidence),
evidenceRefs: boundedStringList(body.evidenceRefs, "evidenceRefs", 32),
proposedBy: callerId,
origin
});
counters.contextRequests += 1;
publishOps(callerProject, "workflows");
logger({ event: "context_state_proposed", project: callerProject, proposalId, proposedBy: callerId, origin });
json(response, 201, { proposalId });
return;
}
const contextStatePromoteMatch = url.pathname.match(/^\/v1\/context\/state\/promote$/);
if (method === "POST" && contextStatePromoteMatch) {
requireConfiguredAdminAuth(request, "state promotion");
const body = await readJson(request);
const proposalId = requireString(body.proposalId, "proposalId", { max: 128 });
const project = requireString(body.project, "project", { max: 200 });
const evidence = boundedStringList(body.evidence, "evidence", 32);
const promoter = typeof body.promotedBy === "string" && body.promotedBy.trim() ? body.promotedBy.trim() : typeof body.caller === "string" && body.caller.trim() ? body.caller.trim() : typeof request.headers["x-kxm-caller-id"] === "string" && request.headers["x-kxm-caller-id"].trim() ? request.headers["x-kxm-caller-id"].trim() : "kxm-admin";
const promoted = await stateProvider.promote(proposalId, evidence, promoter);
counters.contextRequests += 1;
publishOps(project, "workflows");
logger({ event: "context_state_promoted", project, proposalId, promotedId: promoted.id, stateKey: promoted.stateKey, promotedBy: promoter });
json(response, 200, { state: promoted });
return;
}
const contextEpisodeMatch = url.pathname.match(/^\/v1\/context\/episode$/);
if (method === "POST" && contextEpisodeMatch) {
const body = await readJson(request);
const { project: callerProject, caller: callerId } = contextCallerProject(request, body.project);
const runId = body.workflowRunId === void 0 || body.workflowRunId === null ? void 0 : requireString(body.workflowRunId, "workflowRunId", { max: 128 });
const runIds = new Set(
[...workflowRuns.values()].filter((run) => run.project === callerProject && (runId === void 0 || run.id === runId)).map((run) => run.id)
);
const episodes = [...journal.values()].filter((entry) => runIds.has(entry.runId)).filter((entry) => entry.category === "error" || entry.category === "lesson" || entry.category === "observation" || entry.category === "experiment").sort((left, right) => left.createdAt.localeCompare(right.createdAt) || left.id.localeCompare(right.id)).map((entry) => journalEntryToContextItem(entry, callerProject)).slice(0, 50);
counters.contextRequests += 1;
json(response, 200, { episodes });
return;
}
const contextExplainMatch = url.pathname.match(/^\/v1\/context\/explain$/);
if (method === "POST" && contextExplainMatch) {
const body = await readJson(request);
const { project: callerProject, caller: callerId } = contextCallerProject(request, body.project);
const id = requireString(body.id, "id", { max: 128 });
const { pool } = projectContextPool2(callerProject);
const explanation = explainContextItem(id, pool);
counters.contextRequests += 1;
json(response, 200, {
found: explanation.item !== void 0,
lineage: explanation.lineage,
evidenceRefs: explanation.evidenceRefs,
sources: explanation.sources
});
return;
}
const contextWikiCompileMatch = url.pathname.match(/^\/v1\/context\/wiki\/compile$/);
if (method === "POST" && contextWikiCompileMatch) {
const body = await readJson(request);
const { project: callerProject } = contextCallerProject(request, body.project);
const wikiPool = contextWikiPool2(callerProject, nowIso());
const wiki = compileKnowledgeWiki(wikiPool);
counters.contextRequests += 1;
logger({
event: "context_wiki_compiled",
project: callerProject,
pages: wiki.audit.pages.length,
contradictions: wiki.audit.contradictions
});
json(response, 200, {
audit: wiki.audit,
lint: lintKnowledgeWiki(wiki.pages, wikiPool),
pages: [...wiki.pages].sort(([left], [right]) => left.localeCompare(right)).map(([path, content]) => ({ path, content }))
});
return;
}
const journalPromotionMatch = url.pathname.match(/^\/v1\/journal\/([^/]+)\/promotion$/);
if (method === "POST" && journalPromotionMatch) {
requireAdminAuth(request);
const body = await readJson(request);
const entryId = decodeURIComponent(journalPromotionMatch[1]);
const entry = journal.get(entryId);
if (!entry) throw new ProtocolError(404, "journal entry not found", "journal_not_found");
const to = requireString(body.to, "to", { max: 24 });
if (to !== "approved" && to !== "rejected" && to !== "quarantined") {
throw new ProtocolError(
400,
"journal promotion target must be approved, rejected, or quarantined",
"invalid_journal_promotion"
);
}
const evidenceRefs = boundedStringList(body.evidenceRefs, "evidenceRefs", 32);
const updated = applyJournalPromotion(
entry,
{
to,
evidenceRefs,
decidedBy: "kxm-admin",
reason: requireString(body.reason, "reason", { max: 1e3 })
},
nowIso()
);
store.saveJournalEntry(updated);
const promotedRun = workflowRuns.get(entry.runId);
if (promotedRun) {
publishOps(promotedRun.project, "workflows");
exportTerminalRetrospective(promotedRun);
}
logger({
event: "journal_promotion_recorded",
journalEntryId: entry.id,
workflowRunId: entry.runId,
category: entry.category,
to
});
json(response, 200, { entry: updated });
return;
}
const waitMatch = url.pathname.match(/^\/v1\/workflows\/([^/]+)\/waits$/);
if (method === "POST" && waitMatch) {
expireWorkflowWaits();
const agent = requireAgent(request);
requireProjectAuth(request, agent.project);
const body = await readJson(request);
const run = workflowRuns.get(decodeURIComponent(waitMatch[1]));
if (!run) throw new ProtocolError(404, "workflow run not found", "workflow_not_found");
if (run.project !== agent.project || run.targetAgentId !== agent.id) {
throw new ProtocolError(
403,
"only the assigned coordinator can wait this workflow",
"workflow_forbidden",
workflowScopeExtras("wait", run.targetAgentName)
);
}
const stageId = requireString(body.stageId, "stageId", { max: 64 });
const signalKey = workflowSignalKey(body.signalKey);
const summary = requireString(body.summary, "summary", { max: 4e3 });
const evidence = boundedWorkflowEvidence(body.evidence);
const evidenceRefs = boundedWorkflowEvidenceReferences(body.evidenceRefs);
const timeoutMs = parseBoundedInteger(
body.timeoutMs,
"timeoutMs",
DEFAULT_WORKFLOW_WAIT_TIMEOUT_MS,
MIN_WORKFLOW_WAIT_TIMEOUT_MS,
MAX_WORKFLOW_WAIT_TIMEOUT_MS
);
const createdAt = nowIso();
const transition = structuredClone(run);
const stage = transition.stages.find((candidate) => candidate.id === stageId);
const verifiedEvidence = stage && Object.keys(evidenceRefs).length ? verifyWorkflowEvidenceReferences(
transition,
stage,
evidenceRefs,
{ getMessage: (messageId) => messages.get(messageId) },
createdAt
) : {};
waitForWorkflowSignal(
transition,
stageId,
signalKey,
summary,
createdAt,
new Date(Date.parse(createdAt) + timeoutMs).toISOString(),
evidence,
verifiedEvidence
);
store.saveWorkflowTransition(transition);
publishOps(transition.project, "workflows");
counters.workflowWaits += 1;
logger({
event: "workflow_wait_started",
workflowRunId: transition.id,
stageId,
signalKey,
expiresAt: transition.waiting?.expiresAt
});
json(response, 202, {
run: transition,
instruction: "The agent may now settle this turn. A signed external signal will checkpoint the stage and resume the coordinator when more work is required."
});
return;
}
const checkpointMatch = url.pathname.match(/^\/v1\/workflows\/([^/]+)\/checkpoints$/);
if (method === "POST" && checkpointMatch) {
const agent = requireAgent(request);
requireProjectAuth(request, agent.project);
const body = await readJson(request);
const run = workflowRuns.get(decodeURIComponent(checkpointMatch[1]));
if (!run) throw new ProtocolError(404, "workflow run not found", "workflow_not_found");
if (run.project !== agent.project || run.targetAgentId !== agent.id) {
throw new ProtocolError(
403,
"only the assigned coordinator can checkpoint this workflow",
"workflow_forbidden",
workflowScopeExtras("checkpoint", run.targetAgentName)
);
}
const stageId = requireString(body.stageId, "stageId", { max: 64 });
const status = requireString(body.status, "status", { max: 16 });
if (status !== "passed" && status !== "warning" && status !== "failed") {
throw new ProtocolError(400, "status must be passed, warning, or failed", "invalid_checkpoint_status");
}
const summary = requireString(body.summary, "summary", { max: 4e3 });
const evidence = boundedWorkflowEvidence(body.evidence);
const evidenceRefs = boundedWorkflowEvidenceReferences(body.evidenceRefs);
if (status !== "passed" && Object.keys(evidenceRefs).length) {
throw new ProtocolError(
400,
"evidenceRefs are accepted only for a passing checkpoint or workflow wait",
"invalid_workflow_evidence_refs"
);
}
const timestamp = nowIso();
const transition = structuredClone(run);
const stage = transition.stages.find((candidate) => candidate.id === stageId);
const verifiedEvidence = stage && Object.keys(evidenceRefs).length ? verifyWorkflowEvidenceReferences(
transition,
stage,
evidenceRefs,
{ getMessage: (messageId) => messages.get(messageId) },
timestamp
) : {};
const result = checkpointRun(
transition,
stageId,
status,
summary,
evidence,
timestamp,
verifiedEvidence,
typeof body.outcome === "string" && body.outcome.trim() ? requireString(body.outcome, "outcome", { max: 64 }) : void 0
);
const checkpointStage = transition.stages.find((candidate) => candidate.id === stageId);
const checkpointAttempt = result.transition?.attempt ?? checkpointStage.attempts;
if (result.transition) {
const transitionEntry = {
id: newId("journal"),
runId: transition.id,
agentId: agent.id,
category: "state-change",
area: checkpointStage?.area ?? "workflow",
severity: "info",
summary: `typed transition ${result.transition.fromStage} -> ${result.transition.toStage} (${result.transition.outcome})`,
evidence: result.transition.evidenceKeys.map((key) => `requirement:${key}`),
relatedEntryIds: [],
createdAt: timestamp,
stageId,
attempt: checkpointAttempt
};
store.saveWorkflowTransition(transition, void 0, transitionEntry);
counters.journalEntries += 1;
}
if (result.exhausted) {
const exhaustEntry = {
id: newId("journal"),
runId: transition.id,
agentId: agent.id,
category: "error",
area: checkpointStage?.area ?? "workflow",
severity: "error",
summary: `transition budget exhausted at ${stageId} (outcome ${body.outcome ?? status}); run failed safely`,
evidence: [`class:transition_budget_exhausted`, `stage:${stageId}`],
relatedEntryIds: [],
createdAt: timestamp,
stageId,
attempt: checkpointAttempt
};
store.saveWorkflowTransition(transition, void 0, exhaustEntry);
counters.journalEntries += 1;
}
let entry;
if (status !== "passed") {
entry = {
id: newId("journal"),
runId: transition.id,
agentId: agent.id,
category: "error",
area: checkpointStage.area ?? "workflow",
severity: status === "failed" ? "error" : "warning",
summary: `${checkpointStage.label}: ${summary}`,
evidence: workflowEvidenceStrings(evidence),
relatedEntryIds: [],
createdAt: transition.updatedAt,
stageId,
attempt: checkpointAttempt
};
} else if (result.degraded) {
entry = {
id: newId("journal"),
runId: transition.id,
agentId: agent.id,
category: "decision",
area: checkpointStage.area ?? "security",
severity: "warning",
summary: `${checkpointStage.label} passed using an explicitly approved degraded peer quorum`,
evidence: [
"class:workflow_quorum_degradation_used",
...(checkpointStage.degradedRequirements ?? []).map((requirement) => `requirement:${requirement}`)
],
relatedEntryIds: [],
createdAt: transition.updatedAt,
stageId,
attempt: checkpointAttempt
};
}
store.saveWorkflowTransition(transition, void 0, entry);
publishOps(transition.project, "workflows");
counters.workflowCheckpoints += 1;
if (entry) counters.journalEntries += 1;
exportTerminalRetrospective(transition);
logger({
event: "workflow_checkpoint",
workflowRunId: transition.id,
stageId,
status,
attempt: transition.stages.find((candidate) => candidate.id === stageId)?.attempts,
retry: result.retry,
completed: result.completed
});
json(response, 200, {
run: transition,
retry: result.retry,
completed: result.completed,
instruction: result.retry ? "Correct the warning or failure, record what changed, rerun the relevant checks, and checkpoint this stage again." : result.completed ? "Workflow checkpoints are complete. Return the final outcome with links and evidence." : `Continue with stage ${transition.currentStage}.`
});
return;
}
const journalMatch = url.pathname.match(/^\/v1\/workflows\/([^/]+)\/journal$/);
if (method === "POST" && journalMatch) {
const agent = requireAgent(request);
requireProjectAuth(request, agent.project);
const body = await readJson(request);
const run = workflowRuns.get(decodeURIComponent(journalMatch[1]));
if (!run) throw new ProtocolError(404, "workflow run not found", "workflow_not_found");
if (run.project !== agent.project || run.targetAgentId !== agent.id) {
throw new ProtocolError(
403,
"only the assigned coordinator can journal this workflow",
"workflow_forbidden",
workflowScopeExtras("journal", run.targetAgentName)
);
}
const category = parseJournalCategory(body.category);
let stage;
if (body.stageId !== void 0 && body.stageId !== null) {
const requestedStageId = requireString(body.stageId, "stageId", { max: 128 });
stage = run.stages.find((candidate) => candidate.id === requestedStageId);
if (!stage) {
throw new ProtocolError(400, `stageId ${requestedStageId} is not part of this workflow run`, "invalid_journal_relation");
}
}
const area = body.area == null ? stage?.area : requireString(body.area, "area", { max: 24 });
if (area === void 0 || !IMPROVEMENT_AREAS.includes(area)) {
throw new ProtocolError(
400,
"area is required unless stageId names a stage that declares an area",
"invalid_improvement_area"
);
}
const attempt = stage ? journalAttemptFor(stage) : void 0;
const severity = requireString(body.severity ?? "info", "severity", { max: 16 });
if (severity !== "info" && severity !== "warning" && severity !== "error") {
throw new ProtocolError(400, "severity must be info, warning, or error", "invalid_journal_severity");
}
const relatedEntryIds = boundedStringList(body.relatedEntryIds, "relatedEntryIds", 16);
if (relatedEntryIds.some((id) => journal.get(id)?.runId !== run.id)) {
throw new ProtocolError(
400,
"relatedEntryIds must reference journal entries in the same workflow run",
"invalid_journal_relation"
);
}
const evidence = boundedStringList(body.evidence, "evidence");
if (journalEvidenceRequired(category) && evidence.length < 1) {
throw new ProtocolError(
400,
`journal category ${category} requires at least one durable evidence reference`,
"journal_evidence_required"
);
}
const entry = {
id: newId("journal"),
runId: run.id,
agentId: agent.id,
category,
area,
severity,
summary: requireString(body.summary, "summary", { max: 1e3 }),
...body.details ? { details: requireString(body.details, "details", { max: 8e3 }) } : {},
evidence,
relatedEntryIds,
createdAt: nowIso(),
...stage !== void 0 ? { stageId: stage.id } : {},
...attempt !== void 0 ? { attempt } : {}
};
store.saveJournalEntry(entry);
counters.journalEntries += 1;
exportTerminalRetrospective(run);
logger({
event: "workflow_journal_recorded",
workflowRunId: run.id,
journalEntryId: entry.id,
category,
area,
severity
});
json(response, 201, { entry });
return;
}
if (method === "GET" && url.pathname === "/v1/improvements") {
const agent = requireAgent(request);
requireProjectAuth(request, agent.project);
const projectRuns = new Map(
[...workflowRuns.values()].filter((run) => run.project === agent.project).map((run) => [run.id, run])
);
const visibleRuns = new Set(projectRuns.keys());
const entries = [...journal.values()].filter((entry) => visibleRuns.has(entry.runId));
json(response, 200, {
reports: improvementReport(entries),
signals: rankImprovementSignals(entries, projectRuns),
entries: entries.length
});
return;
}
if (method === "POST" && url.pathname === "/v1/agents/register") {
const body = await readJson(request);
const name = requireString(body.name, "name", { max: 64 });
const purpose = requireString(body.purpose ?? "General-purpose Pi agent", "purpose", { max: 256 });
const project = requireString(body.project, "project", { max: 128 });
requireProjectAuth(request, project);
const model = optionalString(body.model, "model", 128);
const hostLabel = optionalString(body.host, "host", MAX_AGENT_HOST_CHARS);
const existing = [...agents.values()].find(
(agent2) => agent2.project === project && agent2.name.toLowerCase() === name.toLowerCase()
);
if (existing?.online) {
throw new ProtocolError(409, `agent name already active in project: ${name}`, "duplicate_agent_name");
}
const timestamp = nowIso();
const agent = existing ?? {
id: newId("agt"),
key: newId("key"),
name,
purpose,
project,
connectedAt: timestamp,
lastSeenAt: timestamp,
online: true
};
agent.key = newId("key");
agent.name = name;
agent.purpose = purpose;
agent.project = project;
agent.connectedAt = timestamp;
agent.lastSeenAt = timestamp;
agent.online = true;
if (model) agent.model = model;
else delete agent.model;
if (hostLabel) agent.host = hostLabel;
else delete agent.host;
store.saveAgent(agent);
counters.registrations += 1;
logger({
event: existing ? "agent_resumed" : "agent_registered",
agentId: agent.id,
name,
project,
...hostLabel ? { host: hostLabel } : {}
});
broadcastPresence(agent);
json(response, existing ? 200 : 201, { agent: publicAgent(agent, staleAfterMs), agentKey: agent.key, resumed: Boolean(existing) });
return;
}
if (method === "GET" && url.pathname === "/v1/agents") {
const current = requireAgent(request);
requireProjectAuth(request, current.project);
const includeOffline = url.searchParams.get("includeOffline") === "true";
const listedAt = Date.now();
const result = [...agents.values()].filter((agent) => agent.project === current.project && (agent.online || includeOffline)).map((agent) => publicAgent(agent, staleAfterMs, listedAt));
json(response, 200, { agents: result });
return;
}
const heartbeatMatch = url.pathname.match(/^\/v1\/agents\/([^/]+)\/heartbeat$/);
if (method === "POST" && heartbeatMatch) {
const current = requireAgent(request, decodeURIComponent(heartbeatMatch[1]));
requireProjectAuth(request, current.project);
await readJson(request);
json(response, 200, { agent: publicAgent(current, staleAfterMs) });
return;
}
const inboxMatch = url.pathname.match(/^\/v1\/agents\/([^/]+)\/inbox$/);
if (method === "GET" && inboxMatch) {
const current = requireAgent(request, decodeURIComponent(inboxMatch[1]));
requireProjectAuth(request, current.project);
expireMessages();
json(response, 200, { messages: store.getPendingMessages(current.id) });
return;
}
const agentMatch = url.pathname.match(/^\/v1\/agents\/([^/]+)$/);
if (method === "DELETE" && agentMatch) {
const current = requireAgent(request, decodeURIComponent(agentMatch[1]));
requireProjectAuth(request, current.project);
current.online = false;
current.lastSeenAt = nowIso();
store.saveAgent(current);
broadcastPresence(current);
logger({ event: "agent_unregistered", agentId: current.id, project: current.project });
response.writeHead(204, { "cache-control": "no-store" }).end();
return;
}
if (method === "POST" && url.pathname === "/v1/runtime/presence") {
const body = await readJson(request);
const project = requireString(body.project, "project", { max: 128 });
requireProjectAuth(request, project);
const runtimeId = requireRuntimeId(body.runtimeId);
const hostLabel = optionalString(body.host, "host", MAX_AGENT_HOST_CHARS);
const heartbeatAt = new Date(hubNow()).toISOString();
const existing = store.getRuntimePresence(project, runtimeId);
const record = {
runtimeId,
project,
...hostLabel ? { host: hostLabel } : {},
registeredAt: existing?.registeredAt ?? heartbeatAt,
heartbeatAt
};
store.saveRuntimePresence(record);
counters.runtimeHeartbeats += 1;
if (!existing) logger({ event: "runtime_registered", project, runtimeId, ...hostLabel ? { host: hostLabel } : {} });
json(response, existing ? 200 : 201, { presence: runtimePresenceView(record, staleAfterMs, hubNow()) });
return;
}
if (method === "POST" && url.pathname === "/v1/sync/events") {
const body = await readJson(request);
const project = requireString(body.project, "project", { max: 128 });
requireProjectAuth(request, project);
const runtimeId = requireRuntimeId(body.runtimeId);
if (!Array.isArray(body.events)) {
throw new ProtocolError(400, "events must be an array", "invalid_sync_batch");
}
if (body.events.length > MAX_SYNC_BATCH_EVENTS) {
throw new ProtocolError(413, `a sync batch holds at most ${MAX_SYNC_BATCH_EVENTS} events`, "sync_batch_too_large");
}
const receivedAt = new Date(hubNow()).toISOString();
const results = [];
const touched = /* @__PURE__ */ new Map();
for (const candidate of body.events) {
const identity = candidate && typeof candidate === "object" && !Array.isArray(candidate) ? candidate : {};
const echo = {
...typeof identity.projectId === "string" ? { projectId: identity.projectId.slice(0, 144) } : {},
...typeof identity.runId === "string" ? { runId: identity.runId.slice(0, 144) } : {},
...Number.isInteger(identity.sequence) ? { sequence: identity.sequence } : {}
};
if (syncEventSchemaErrors(candidate) !== void 0) {
counters.syncEventsRefused += 1;
results.push({ ...echo, outcome: "rejected", code: "sync_event_invalid" });
continue;
}
const event = identity;
if (event.homeRuntimeId !== runtimeId) {
counters.syncEventsRefused += 1;
logger({ event: "security_alert", alert: "sync_runtime_mismatch", project, runtimeId, ...echo, homeRuntimeId: event.homeRuntimeId });
results.push({ ...echo, outcome: "rejected", code: "sync_runtime_mismatch" });
continue;
}
const bytes = kxmCanonicalJson(candidate);
const contentHash = kxmSyncEventHash(bytes);
const outcome = store.ingestSyncEvent({
projectId: event.projectId,
runId: event.runId,
sequence: event.sequence,
hubProject: project,
homeRuntimeId: event.homeRuntimeId,
eventType: event.eventType,
contentHash,
receivedAt,
bytes
});
if (outcome.outcome === "conflict") {
counters.syncConflicts += 1;
counters.syncEventsRefused += 1;
logger({
event: "security_alert",
alert: "sync_sequence_conflict",
reason: outcome.reason,
project,
runtimeId,
...echo,
presentedHash: contentHash,
...outcome.existingHash ? { existingHash: outcome.existingHash } : {}
});
results.push({ ...echo, outcome: "conflict", code: `sync_${outcome.reason}` });
continue;
}
if (outcome.outcome === "accepted") counters.syncEventsAccepted += 1;
else counters.syncEventsDuplicate += 1;
touched.set(`${event.projectId}\0${event.runId}`, { projectId: event.projectId, runId: event.runId });
results.push({ ...echo, outcome: outcome.outcome });
}
const cursors = [...touched.values()].map((run) => ({ ...run, cursor: store.syncCursor(run.projectId, run.runId) }));
if (results.some((result) => result.outcome === "accepted")) publishOps(project, "workflows");
json(response, 200, { results, cursors });
return;
}
const leaseMatch = url.pathname.match(/^\/v1\/leases\/([^/]+)\/(acquire|renew|release)$/);
if (method === "POST" && leaseMatch) {
const holder = requireAgent(request);
requireProjectAuth(request, holder.project);
const name = requireString(decodeURIComponent(leaseMatch[1]), "resource", { max: MAX_LEASE_RESOURCE_CHARS });
const action = leaseMatch[2];
const body = await readJson(request);
const resource = `${holder.project}/${name}`;
const nowMs = hubNow();
const leaseLog = { resource, project: holder.project, agentId: holder.id, agentName: holder.name };
if (action === "acquire") {
const ttlMs = parseBoundedInteger(body.ttlMs, "ttlMs", DEFAULT_LEASE_TTL_MS, MIN_LEASE_TTL_MS, MAX_LEASE_TTL_MS);
const outcome2 = store.acquireLease({
resource,
project: holder.project,
name,
holderAgentId: holder.id,
holderAgentName: holder.name,
ttlMs,
nowMs
});
if (!outcome2.ok) {
counters.leasesRefused += 1;
logger({ event: "lease_denied", ...leaseLog, reason: outcome2.reason, heldBy: outcome2.lease?.holderAgentId });
throw leaseRefusal(outcome2.reason, name, outcome2.lease);
}
counters.leasesGranted += 1;
logger({
event: outcome2.renewed ? "lease_renewed" : "lease_acquired",
...leaseLog,
fencingToken: outcome2.lease.fencingToken,
expiresAt: outcome2.lease.expiresAt
});
json(response, 200, { lease: outcome2.lease, renewed: outcome2.renewed });
return;
}
if (body.fencingToken === void 0) {
throw new ProtocolError(400, "fencingToken is required", "lease_token_required");
}
const fencingToken = parseBoundedInteger(body.fencingToken, "fencingToken", 1, 1, Number.MAX_SAFE_INTEGER);
if (action === "renew") {
const ttlMs = parseBoundedInteger(body.ttlMs, "ttlMs", DEFAULT_LEASE_TTL_MS, MIN_LEASE_TTL_MS, MAX_LEASE_TTL_MS);
const outcome2 = store.renewLease({ resource, holderAgentId: holder.id, fencingToken, ttlMs, nowMs });
if (!outcome2.ok) {
counters.leasesRefused += 1;
logger({ event: "lease_denied", ...leaseLog, reason: outcome2.reason, fencingToken });
throw leaseRefusal(outcome2.reason, name, outcome2.lease);
}
counters.leasesGranted += 1;
logger({ event: "lease_renewed", ...leaseLog, fencingToken, expiresAt: outcome2.lease.expiresAt });
json(response, 200, { lease: outcome2.lease, renewed: true });
return;
}
const outcome = store.releaseLease({ resource, holderAgentId: holder.id, fencingToken });
if (!outcome.ok) {
counters.leasesRefused += 1;
logger({ event: "lease_denied", ...leaseLog, reason: outcome.reason, fencingToken });
throw leaseRefusal(outcome.reason, name, outcome.lease);
}
counters.leasesReleased += 1;
logger({ event: "lease_released", ...leaseLog, fencingToken });
json(response, 200, { released: true, lease: outcome.lease });
return;
}
if (method === "GET" && url.pathname === "/v1/events") {
const agentId = requireString(url.searchParams.get("agentId"), "agentId", { max: 80 });
const current = requireAgent(request, agentId);
requireProjectAuth(request, current.project);
const presenceOnly = url.searchParams.get("presenceOnly") === "true";
if (presenceOnly && current.model !== "tui") {
throw new ProtocolError(403, "presence-only streams are reserved for metadata observers", "presence_stream_forbidden");
}
response.writeHead(200, {
"content-type": "text/event-stream",
"cache-control": "no-cache, no-transform",
connection: "keep-alive",
"x-accel-buffering": "no",
"x-content-type-options": "nosniff",
...presenceOnly ? { "x-kxm-events-mode": "presence" } : {}
});
response.write(`event: ready
data: ${JSON.stringify({ agent: publicAgent(current, staleAfterMs) })}
`);
const client = {
response,
heartbeat: setInterval(() => response.write(": heartbeat\n\n"), 15e3),
...presenceOnly ? { presenceOnly: true } : {}
};
client.heartbeat.unref();
const clients = streams.get(agentId) ?? /* @__PURE__ */ new Set();
clients.add(client);
streams.set(agentId, clients);
if (!presenceOnly) flushPending(agentId);
request.on("close", () => {
clearInterval(client.heartbeat);
clients.delete(client);
if (clients.size === 0) streams.delete(agentId);
});
return;
}
if (method === "POST" && url.pathname === "/v1/messages") {
const sender = requireAgent(request);
requireProjectAuth(request, sender.project);
const body = await readJson(request);
const targetInput = requireString(body.target, "target", { max: 80 });
const content = requireString(body.content, "content", { max: MAX_CONTENT_CHARS });
const delivery = parseDeliveryMode(body.delivery);
const requestedContext = requestedWorkflowMessageContext(body.workflowContext);
const workflowContext = requestedContext ? authorizeWorkflowMessageContext(sender, targetInput, requestedContext) : void 0;
const callerCorrelationId = optionalString(body.correlationId, "correlationId", 128);
if (workflowContext && callerCorrelationId && callerCorrelationId !== workflowContext.runId) {
throw new ProtocolError(
409,
"correlationId must match workflowContext.runId",
"workflow_context_correlation_mismatch"
);
}
const correlationId = workflowContext?.runId ?? callerCorrelationId;
const replyTo = optionalString(body.replyTo, "replyTo", 80);
const hops = parseBoundedInteger(body.hops, "hops", 0, 0, 100);
const maxHops = parseBoundedInteger(body.maxHops, "maxHops", DEFAULT_MAX_HOPS, 1, 20);
if (hops >= maxHops) {
throw new ProtocolError(
400,
`hop limit reached (${hops}/${maxHops}): this request would extend a chain of forwarded requests past its limit; answer the inbound request directly`,
"hop_limit_reached"
);
}
const ttlMs = parseBoundedInteger(
body.ttlMs,
"ttlMs",
defaultMessageTtlMs,
MIN_MESSAGE_TTL_MS,
MAX_MESSAGE_TTL_MS
);
const allowOffline = parseOptionalBoolean(body.allowOffline, "allowOffline");
const idempotencyKey = optionalString(body.idempotencyKey, "idempotencyKey", 128);
if (idempotencyKey) {
const existing = store.findMessageByIdempotency(sender.id, idempotencyKey);
if (existing) {
if (!sameIdempotentRequest(
existing,
targetInput,
content,
delivery,
correlationId,
replyTo,
hops,
maxHops,
ttlMs,
workflowContext
)) {
throw new ProtocolError(409, "idempotency key was already used for another request", "idempotency_conflict");
}
json(response, 200, { message: existing, idempotent: true });
return;
}
}
const target = findTarget(sender.project, targetInput, allowOffline);
if (target.id === sender.id) {
throw new ProtocolError(400, "cannot send a request to yourself", "self_target");
}
const createdAt = nowIso();
const seq = store.nextAgentSequence(target.id);
const message = {
id: newId("msg"),
project: sender.project,
from: sender.id,
fromName: sender.name,
to: target.id,
toName: target.name,
content,
delivery,
hops,
maxHops,
seq,
...correlationId ? { correlationId } : {},
...replyTo ? { replyTo } : {},
...idempotencyKey ? { idempotencyKey } : {},
...workflowContext ? { workflowRunId: workflowContext.runId, workflowContext } : {},
createdAt,
expiresAt: new Date(Date.parse(createdAt) + ttlMs).toISOString(),
status: "queued"
};
store.saveMessage(message);
publishOps(message.project, "messages");
if (target.online) publish(target.id, { type: "message", message });
counters.messagesSent += 1;
logger({ event: "message_sent", messageId: message.id, hops, ...messageLog(message, sender.id, sender.name, target.id, target.name) });
json(response, 202, { message, idempotent: false });
return;
}
const ackMatch = url.pathname.match(/^\/v1\/messages\/([^/]+)\/ack$/);
if (method === "POST" && ackMatch) {
const receiver = requireAgent(request);
requireProjectAuth(request, receiver.project);
await readJson(request);
expireMessages();
expireWorkflowWaits();
purgeTerminalMessages();
const message = messages.get(decodeURIComponent(ackMatch[1]));
if (!message) throw new ProtocolError(404, "message not found", "message_not_found");
if (message.to !== receiver.id) {
throw new ProtocolError(403, "only the recipient can acknowledge this message", "message_forbidden");
}
if (message.status !== "queued" && message.status !== "delivered") {
throw new ProtocolError(409, `cannot acknowledge a ${message.status} message`, "invalid_message_state");
}
if (message.status === "queued") {
message.status = "delivered";
message.deliveredAt = nowIso();
store.saveMessage(message);
publishOps(message.project, "messages");
}
if (typeof message.seq === "number") {
store.advanceCursor(receiver.id, message.seq);
}
json(response, 200, { message });
return;
}
const replyMatch = url.pathname.match(/^\/v1\/messages\/([^/]+)\/reply$/);
if (method === "POST" && replyMatch) {
const receiver = requireAgent(request);
requireProjectAuth(request, receiver.project);
const body = await readJson(request);
expireMessages();
const message = messages.get(decodeURIComponent(replyMatch[1]));
if (!message) throw new ProtocolError(404, "message not found", "message_not_found");
if (message.to !== receiver.id) {
throw new ProtocolError(403, "only the recipient can reply to this message", "message_forbidden");
}
if (message.status === "replied") {
throw new ProtocolError(409, "message already has a reply", "duplicate_reply");
}
if (message.status === "cancelled" || message.status === "expired" || message.status === "error") {
throw new ProtocolError(409, `cannot reply to a ${message.status} message`, "invalid_message_state");
}
message.reply = {
content: requireString(body.content, "content", { max: MAX_CONTENT_CHARS }),
createdAt: nowIso()
};
message.repliedAt = message.reply.createdAt;
message.status = "replied";
store.saveMessage(message);
publishOps(message.project, "messages");
const workflowRun = [...workflowRuns.values()].find((run) => run.messageId === message.id);
if (workflowRun?.status === "running") {
const settledStage = workflowRun.stages.find((candidate) => candidate.id === workflowRun.currentStage);
workflowRun.status = "failed";
delete workflowRun.currentStage;
workflowRun.updatedAt = message.repliedAt;
store.saveWorkflowRun(workflowRun);
publishOps(workflowRun.project, "workflows");
const entry = {
id: newId("journal"),
runId: workflowRun.id,
agentId: receiver.id,
category: "error",
area: "workflow",
severity: "error",
summary: "Coordinator settled before all required workflow checkpoints passed",
evidence: [`message:${message.id}`],
relatedEntryIds: [],
createdAt: message.repliedAt,
...settledStage ? { stageId: settledStage.id, attempt: settledStage.attempts + 1 } : {}
};
store.saveJournalEntry(entry);
counters.journalEntries += 1;
exportTerminalRetrospective(workflowRun);
}
publish(message.from, { type: "reply", message });
counters.messagesReplied += 1;
logger({ event: "message_replied", messageId: message.id, ...messageLog(message, receiver.id, receiver.name, message.from, message.fromName) });
json(response, 200, { message });
return;
}
const messageMatch = url.pathname.match(/^\/v1\/messages\/([^/]+)$/);
if (method === "DELETE" && messageMatch) {
const current = requireAgent(request);
requireProjectAuth(request, current.project);
expireMessages();
const message = messages.get(decodeURIComponent(messageMatch[1]));
if (!message) throw new ProtocolError(404, "message not found", "message_not_found");
if (message.from !== current.id) {
throw new ProtocolError(403, "only the sender can cancel this message", "message_forbidden");
}
if (message.status === "cancelled") {
json(response, 200, { message });
return;
}
if (message.status !== "queued" && message.status !== "delivered") {
throw new ProtocolError(409, `cannot cancel a ${message.status} message`, "invalid_message_state");
}
message.status = "cancelled";
message.cancelledAt = nowIso();
message.error = "message cancelled by sender";
store.saveMessage(message);
publishOps(message.project, "messages");
publish(message.to, { type: "cancelled", message });
counters.messagesCancelled += 1;
logger({ event: "message_cancelled", messageId: message.id, ...messageLog(message, current.id, current.name, message.to, message.toName) });
json(response, 200, { message });
return;
}
if (method === "GET" && messageMatch) {
const current = requireAgent(request);
requireProjectAuth(request, current.project);
expireMessages();
const message = messages.get(decodeURIComponent(messageMatch[1]));
if (!message) throw new ProtocolError(404, "message not found", "message_not_found");
if (message.from !== current.id && message.to !== current.id) {
throw new ProtocolError(403, "message is not visible to this agent", "message_forbidden");
}
json(response, 200, { message });
return;
}
throw new ProtocolError(404, "route not found", "route_not_found");
} catch (error) {
const statusCode = error instanceof ProtocolError ? error.statusCode : 500;
const code = error instanceof ProtocolError ? error.code : "internal_error";
const internalMessage = error instanceof Error ? error.message : "unknown error";
const publicMessage = statusCode >= 500 ? "internal server error" : internalMessage;
counters.errors += 1;
logger({ event: "request_error", requestId, statusCode, code, ...statusCode >= 500 ? { message: internalMessage } : {} });
if (!response.headersSent) {
json(response, statusCode, {
error: publicMessage,
code,
requestId,
...error instanceof ProtocolError && error.extras ? error.extras : {}
});
} else response.end();
}
});
return {
server,
state: { agents, messages, workflowRuns, journal, persistent: store.persistent },
async start() {
if (closed) throw new Error("hub is closed");
await new Promise((resolve9, reject) => {
server.once("error", reject);
server.listen(port2, host2, () => {
server.off("error", reject);
resolve9();
});
});
cleanupTimer = setInterval(() => {
const cutoff = Date.now() - staleAfterMs;
for (const agent of agents.values()) {
if (agent.online && Date.parse(agent.lastSeenAt) < cutoff) {
agent.online = false;
store.saveAgent(agent);
broadcastPresence(agent);
logger({ event: "agent_stale", agentId: agent.id, project: agent.project });
}
}
expireMessages();
expireWorkflowWaits();
purgeTerminalMessages();
const rateCutoff = Date.now() - (rateLimit?.windowMs ?? 0);
for (const [key, bucket] of rateBuckets) {
if (bucket.startedAt < rateCutoff) rateBuckets.delete(key);
}
}, cleanupIntervalMs);
cleanupTimer.unref();
const address2 = server.address();
if (!address2 || typeof address2 === "string") throw new Error("hub did not expose a TCP address");
return { host: host2, port: address2.port, url: `http://${host2}:${address2.port}` };
},
async close() {
if (closed) return;
closed = true;
if (cleanupTimer) clearInterval(cleanupTimer);
const serverClosed = server.listening ? new Promise((resolve9, reject) => server.close((error) => error ? reject(error) : resolve9())) : Promise.resolve();
const forceClose = setTimeout(() => server.closeAllConnections(), shutdownGraceMs);
forceClose.unref();
for (const clients of streams.values()) {
for (const client of clients) {
clearInterval(client.heartbeat);
client.response.end();
}
}
streams.clear();
for (const client of opsStreams) {
clearInterval(client.heartbeat);
client.response.end();
}
opsStreams.clear();
server.closeIdleConnections();
try {
await serverClosed;
} finally {
clearTimeout(forceClose);
}
store.close();
}
};
}
// plugins/kxm/src/server.ts
import { mkdirSync as mkdirSync7, readFileSync as readFileSync6 } from "node:fs";
import { dirname as dirname9, join as join8, resolve as resolve8 } from "node:path";
// plugins/kxm/src/hub-identity.ts
import { spawnSync } from "node:child_process";
var import_yaml7 = __toESM(require_dist(), 1);
// plugins/kxm/src/config.ts
var import_yaml6 = __toESM(require_dist(), 1);
import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
import { tmpdir, homedir } from "node:os";
import { dirname as dirname7, join as join7, resolve as resolve7 } from "node:path";
var KXM_CONFIG_SCHEMA = "kxm.config.v1";
var KxmHubConfigError = class extends Error {
code = "hub_config_invalid";
constructor(message) {
super(message);
this.name = "KxmHubConfigError";
}
};
var HUB_ENV_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
var HUB_OP_REF = /^op:\/\/\S+\/\S+\/\S+$/;
var LITERAL_SECRET_KEY = /^(token|secret|password|authToken|auth_token|apiKey|api_key|api_token|bearer|credential|access_token)$/i;
function isHubKeyEnvName(value) {
return HUB_ENV_NAME.test(value);
}
function isHubOpReference(value) {
return HUB_OP_REF.test(value);
}
var IMPROVEMENT_PROMOTION_POLICIES = ["manual_pr", "critic_quorum", "auto_threshold"];
var DEFAULT_KXM_CONFIG = {
schema: KXM_CONFIG_SCHEMA,
user: {
theme: "dark",
preferredCritics: ["reviewer-arch", "reviewer-cli"],
tokenBudget: 16e3
},
defaults: {
workflow: "software-engineering/feature-implementation",
harness: "pi"
},
dash: {
defaultScreen: "agents",
refreshIntervalMs: 1e3,
autoOpen: false
},
sync: {
defaultTracker: "none"
},
hub: {
autoStart: "background"
},
improvement: {
promotionPolicy: "manual_pr",
telemetryHalfLifeDays: 14,
autoThreshold: {
minRuns: 10,
minPassRate: 0.95,
minCostSavings: 0.5
}
},
routing: {
shadowExecution: {
enabled: false,
sampleRate: 0.05,
candidateModels: []
},
circuitBreaker: {
mode: "soft_demotion",
failureThreshold: 3,
windowSeconds: 3600,
cooldownSeconds: 1800,
penaltyMultiplier: 5
}
},
telemetry: {
federated: true,
anonymize: true
}
};
function userConfigDirectory(overrideDir) {
if (overrideDir) return resolve7(overrideDir);
return resolve7(process.env.KXM_USER_CONFIG_DIR?.trim() || join7(homedir(), ".config", "kxm"));
}
function repoConfigDirectory(repoRoot) {
return resolve7(repoRoot, ".kxm");
}
function deepMerge(target, source) {
const result = { ...target };
for (const [key, val] of Object.entries(source)) {
if (val && typeof val === "object" && !Array.isArray(val)) {
const existing = result[key] && typeof result[key] === "object" && !Array.isArray(result[key]) ? result[key] : {};
result[key] = deepMerge(existing, val);
} else if (val !== void 0) {
result[key] = val;
}
}
return result;
}
function literalSecretMessage(path) {
return `refusing literal hub token at ${path}: store an op:// reference (key.op) or an environment variable name (key.env), never the token`;
}
function rejectLiteralHubSecrets(value, path) {
if (Array.isArray(value)) {
value.forEach((item, index) => rejectLiteralHubSecrets(item, `${path}[${index}]`));
return;
}
if (!value || typeof value !== "object") return;
for (const [key, child] of Object.entries(value)) {
const childPath = `${path}.${key}`;
if (typeof child === "string" && (key === "key" || LITERAL_SECRET_KEY.test(key))) {
throw new KxmHubConfigError(literalSecretMessage(childPath));
}
if (child && typeof child === "object") rejectLiteralHubSecrets(child, childPath);
}
}
function parseKeyRef(raw, path) {
if (raw === void 0) return void 0;
if (typeof raw === "string") throw new KxmHubConfigError(literalSecretMessage(path));
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
throw new KxmHubConfigError(`${path} must be a key reference with op and/or env, never a token`);
}
const row = raw;
for (const key of Object.keys(row)) {
if (key !== "op" && key !== "env") {
throw new KxmHubConfigError(literalSecretMessage(`${path}.${key}`));
}
}
const ref = {};
if (row.op !== void 0) {
if (typeof row.op !== "string" || !isHubOpReference(row.op)) {
throw new KxmHubConfigError(`${path}.op must be an op://vault/item/field reference, not a token`);
}
ref.op = row.op;
}
if (row.env !== void 0) {
if (typeof row.env !== "string" || !isHubKeyEnvName(row.env)) {
throw new KxmHubConfigError(`${path}.env must be an environment variable name, not a token`);
}
ref.env = row.env;
}
if (!ref.op && !ref.env) throw new KxmHubConfigError(`${path} needs key.op, key.env, or both`);
return ref;
}
function parseEndpoint(raw, path) {
if (raw === void 0) return void 0;
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
throw new KxmHubConfigError(`${path} must be an object with url, project, and key`);
}
const row = raw;
const endpoint = {};
if (row.url !== void 0) {
if (typeof row.url !== "string" || !isHubUrl(row.url)) {
throw new KxmHubConfigError(`${path}.url must be an http or https URL without credentials, query, or fragment`);
}
endpoint.url = row.url.replace(/\/$/, "");
}
if (row.project !== void 0) {
if (typeof row.project !== "string" || !isHubProjectId(row.project)) {
throw new KxmHubConfigError(`${path}.project must be a single-line project id, not a token`);
}
endpoint.project = row.project.trim();
}
const key = parseKeyRef(row.key, `${path}.key`);
if (key) endpoint.key = key;
for (const name of Object.keys(row)) {
if (name !== "url" && name !== "project" && name !== "key") {
if (typeof row[name] === "string") throw new KxmHubConfigError(literalSecretMessage(`${path}.${name}`));
throw new KxmHubConfigError(`${path}.${name} is not a hub endpoint field`);
}
}
return endpoint;
}
function isHubUrl(raw) {
try {
const parsed = new URL(raw);
return (parsed.protocol === "http:" || parsed.protocol === "https:") && parsed.username === "" && parsed.password === "" && parsed.search === "" && parsed.hash === "" && !raw.includes("?") && !raw.includes("#");
} catch {
return false;
}
}
function isHubProjectId(raw) {
const value = raw.trim();
return value.length > 0 && value.length <= 200 && !/[\s\r\n]/.test(value);
}
function parseProjectMap(raw) {
if (raw === void 0) return void 0;
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
throw new KxmHubConfigError("hub.projects must be a map of project id to key reference, never a token");
}
const projects = {};
for (const [project, value] of Object.entries(raw)) {
if (!isHubProjectId(project)) {
throw new KxmHubConfigError(`hub.projects key ${JSON.stringify(project)} must be a project id, not a token`);
}
const ref = parseKeyRef(value, `hub.projects.${project}`);
if (!ref) throw new KxmHubConfigError(`hub.projects.${project} needs an op:// reference or an environment variable name`);
projects[project.trim()] = ref;
}
return projects;
}
function normalizeHubConfig(raw) {
const autoStart = raw?.autoStart;
const hub2 = {
autoStart: autoStart === "off" || autoStart === "background" ? autoStart : DEFAULT_KXM_CONFIG.hub.autoStart
};
if (raw === void 0) return hub2;
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
throw new KxmHubConfigError("hub must be an object");
}
rejectLiteralHubSecrets(raw, "hub");
const row = raw;
if (row.mode !== void 0) {
if (row.mode !== "local" && row.mode !== "cloud") {
throw new KxmHubConfigError("hub.mode must be local or cloud");
}
hub2.mode = row.mode;
}
const local = parseEndpoint(row.local, "hub.local");
const cloud = parseEndpoint(row.cloud, "hub.cloud");
const projects = parseProjectMap(row.projects);
if (local) hub2.local = local;
if (cloud) hub2.cloud = cloud;
if (projects && Object.keys(projects).length > 0) hub2.projects = projects;
return hub2;
}
function findConfigRoot(start) {
let dir = resolve7(start);
for (; ; ) {
if (existsSync7(join7(dir, ".kxm", "project.yaml")) || existsSync7(join7(dir, ".kxm", "config.yaml"))) return dir;
const parent = dirname7(dir);
if (parent === dir) return resolve7(start);
dir = parent;
}
}
function userConfigDirForEnv(env) {
const explicit = env.KXM_USER_CONFIG_DIR?.trim();
if (explicit) return explicit;
if (env === process.env) return void 0;
return join7(tmpdir(), "kxm-no-user-config");
}
function loadHubSettings(start, env = process.env) {
const userConfigDir = userConfigDirForEnv(env);
return loadKxmConfig(findConfigRoot(start), userConfigDir === void 0 ? {} : { userConfigDir }).hub;
}
function recordOf(raw) {
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
}
function finiteNumber(value) {
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
}
function normalizeImprovementConfig(raw) {
const value = recordOf(raw);
const threshold = recordOf(value.autoThreshold);
const policy = value.promotionPolicy;
const halfLife = finiteNumber(value.telemetryHalfLifeDays);
const minRuns = finiteNumber(threshold.minRuns);
const minPassRate = finiteNumber(threshold.minPassRate);
const minCostSavings = finiteNumber(threshold.minCostSavings);
return {
promotionPolicy: IMPROVEMENT_PROMOTION_POLICIES.includes(policy) ? policy : "manual_pr",
telemetryHalfLifeDays: halfLife !== void 0 && halfLife > 0 && halfLife <= 3650 ? halfLife : 14,
autoThreshold: {
minRuns: minRuns !== void 0 && Number.isInteger(minRuns) && minRuns >= 1 && minRuns <= 1e6 ? minRuns : 10,
minPassRate: minPassRate !== void 0 && minPassRate >= 0 && minPassRate <= 1 ? minPassRate : 0.95,
minCostSavings: minCostSavings !== void 0 && minCostSavings >= 0 ? minCostSavings : 0.5
}
};
}
function loadKxmConfig(repoRoot = process.cwd(), options = {}) {
const userDir = userConfigDirectory(options.userConfigDir);
const userConfigFile = join7(userDir, "config.yaml");
const repoDir = repoConfigDirectory(repoRoot);
const repoConfigFile = join7(repoDir, "config.yaml");
let userRaw = {};
let userLoadedPath;
if (existsSync7(userConfigFile)) {
try {
const text2 = readFileSync5(userConfigFile, "utf8");
userRaw = (0, import_yaml6.parse)(text2) ?? {};
userLoadedPath = userConfigFile;
} catch (error) {
throw new Error(`invalid user config YAML at ${userConfigFile}`, { cause: error });
}
}
let repoRaw = {};
let repoLoadedPath;
if (existsSync7(repoConfigFile)) {
try {
const text2 = readFileSync5(repoConfigFile, "utf8");
repoRaw = (0, import_yaml6.parse)(text2) ?? {};
repoLoadedPath = repoConfigFile;
} catch (error) {
throw new Error(`invalid project config YAML at ${repoConfigFile}`, { cause: error });
}
}
const baseCopy = JSON.parse(JSON.stringify(DEFAULT_KXM_CONFIG));
const mergedUser = deepMerge(baseCopy, userRaw);
const mergedAll = deepMerge(mergedUser, repoRaw);
return {
schema: KXM_CONFIG_SCHEMA,
user: mergedAll.user ?? {},
defaults: mergedAll.defaults ?? {},
dash: mergedAll.dash ?? {},
sync: mergedAll.sync ?? {},
hub: normalizeHubConfig(mergedAll.hub),
improvement: normalizeImprovementConfig(mergedAll.improvement),
routing: mergedAll.routing ?? DEFAULT_KXM_CONFIG.routing,
telemetry: mergedAll.telemetry ?? DEFAULT_KXM_CONFIG.telemetry,
loadedFrom: {
userConfigPath: userLoadedPath,
repoConfigPath: repoLoadedPath
}
};
}
// plugins/kxm/src/hub-binding.ts
var CloudTokenError = class extends Error {
code;
constructor(code, message) {
super(message);
this.name = "CloudTokenError";
this.code = code;
}
};
var LEGACY_BINDING_KEYS = ["schema", "url", "boundAt"];
var BINDING_KEYS = /* @__PURE__ */ new Set([...LEGACY_BINDING_KEYS, "cloud", "tokenEnv", "tokenCommand"]);
// plugins/kxm/src/hub-identity.ts
var OP_TIMEOUT_MS = 15e3;
var OP_MAX_BUFFER = 4096;
function defaultOpRead(reference, env) {
if (!isHubOpReference(reference)) {
throw new CloudTokenError("cloud_token_command_invalid", `refusing to resolve ${reference}; an op:// reference is required`);
}
const result = spawnSync("op", ["read", reference], {
encoding: "utf8",
shell: false,
timeout: OP_TIMEOUT_MS,
maxBuffer: OP_MAX_BUFFER,
env,
windowsHide: true
});
if (result.error || result.status !== 0) {
throw new CloudTokenError(
"cloud_token_command_failed",
`op read failed for ${reference}; the token was not saved`
);
}
const line = (result.stdout ?? "").trim();
if (!line || line.split(/\r?\n/).length !== 1) {
throw new CloudTokenError(
"cloud_token_command_failed",
`op read did not print a single token for ${reference}; the token was not saved`
);
}
return line;
}
function resolveKeyReference(ref, env, opRead = defaultOpRead) {
if (!ref) return void 0;
if (ref.env) {
const value = env[ref.env]?.trim();
if (value) return { value, source: `env:${ref.env}` };
}
if (ref.op) {
const value = opRead(ref.op, env).trim();
if (!value || value.split(/\r?\n/).length !== 1) {
throw new CloudTokenError("cloud_token_command_failed", `op read did not print a single token for ${ref.op}`);
}
return { value, source: `op:${ref.op}` };
}
return void 0;
}
function selectHubProjectTokenMap(input) {
if (input.explicit) return { tokens: input.explicit, source: "env" };
if (input.configured && Object.keys(input.configured).length > 0) return { tokens: input.configured, source: "config" };
if (input.file && Object.keys(input.file).length > 0) return { tokens: input.file, source: "file" };
return { tokens: void 0, source: "none" };
}
function resolveConfiguredHubProjectTokens(cwd, env = process.env, opRead = defaultOpRead) {
const projects = loadHubSettings(cwd, env).projects;
if (!projects || Object.keys(projects).length === 0) return void 0;
const tokens = {};
for (const [project, ref] of Object.entries(projects)) {
const resolved = resolveKeyReference(ref, env, opRead);
if (!resolved?.value) {
throw new CloudTokenError(
"cloud_token_missing",
`hub.projects.${project} did not resolve; set ${ref.env ?? "the named variable"} or fix the op:// reference. The token was not saved`
);
}
tokens[project] = resolved.value;
}
return tokens;
}
// plugins/kxm/src/logger.ts
import { appendFileSync, existsSync as existsSync8, mkdirSync as mkdirSync6, renameSync as renameSync3, statSync as statSync2, unlinkSync as unlinkSync2 } from "node:fs";
import { dirname as dirname8 } from "node:path";
var LOG_LEVEL_PRIORITY = {
debug: 10,
info: 20,
warn: 30,
error: 40
};
var DEFAULT_LOG_MAX_BYTES = 10 * 1024 * 1024;
var DEFAULT_LOG_MAX_FILES = 3;
var SENSITIVE_KEY_PATTERN = /(?:^|_)(?:token|secret|password|apiKey|api_key|authorization|bearer)(?:$|_)/i;
var ALLOWED_EXACT_KEYS = /* @__PURE__ */ new Set(["auth", "authType", "authMethod", "authArgs", "canUpdate", "status"]);
function redactLogValue(val, key) {
if (val === null || val === void 0) return val;
if (typeof val === "string") {
if (key && SENSITIVE_KEY_PATTERN.test(key) && !ALLOWED_EXACT_KEYS.has(key)) {
return "[redacted]";
}
return redactSecrets(val);
}
if (typeof val === "number" || typeof val === "boolean") {
return val;
}
if (Array.isArray(val)) {
return val.map((item) => redactLogValue(item, key));
}
if (typeof val === "object") {
const out = {};
for (const [k, v] of Object.entries(val)) {
out[k] = redactLogValue(v, k);
}
return out;
}
return String(val);
}
function rotateLogFiles(filePath, maxFiles) {
for (let i = maxFiles; i >= 1; i--) {
const current = `${filePath}.${i}`;
if (existsSync8(current)) {
if (i >= maxFiles) {
try {
unlinkSync2(current);
} catch {
}
} else {
try {
renameSync3(current, `${filePath}.${i + 1}`);
} catch {
}
}
}
}
if (existsSync8(filePath)) {
try {
renameSync3(filePath, `${filePath}.1`);
} catch {
}
}
}
function createLogger(options) {
const component = options.component;
const filePath = options.path;
const maxBytes = Math.max(100, options.maxBytes ?? DEFAULT_LOG_MAX_BYTES);
const maxFiles = Math.max(1, options.maxFiles ?? DEFAULT_LOG_MAX_FILES);
const configuredLevel = options.level ?? "info";
const isDaemon = Boolean(options.daemon ?? (process.env.KXM_DAEMON === "1" || process.env.KXM_DAEMON === "true"));
const shouldStdout = options.stdout ?? !isDaemon;
const correlationDefaults = options.correlation ?? {};
let currentSize = 0;
if (filePath && existsSync8(filePath)) {
try {
currentSize = statSync2(filePath).size;
} catch {
currentSize = 0;
}
}
function emit(level, entryOrEvent, extra) {
const minPriority = LOG_LEVEL_PRIORITY[configuredLevel] ?? LOG_LEVEL_PRIORITY.info;
const currentPriority = LOG_LEVEL_PRIORITY[level] ?? LOG_LEVEL_PRIORITY.info;
if (currentPriority < minPriority) return;
let base;
if (typeof entryOrEvent === "string") {
base = { event: entryOrEvent, ...extra };
} else {
base = { ...entryOrEvent, ...extra };
}
const timestamp = typeof base.timestamp === "string" ? base.timestamp : (/* @__PURE__ */ new Date()).toISOString();
delete base.timestamp;
delete base.level;
delete base.component;
const payload = {
timestamp,
level,
component,
...correlationDefaults,
...base
};
const sanitized = redactLogValue(payload);
const line = `${JSON.stringify(sanitized)}
`;
if (filePath) {
const lineBytes = Buffer.byteLength(line, "utf8");
if (currentSize + lineBytes > maxBytes) {
rotateLogFiles(filePath, maxFiles);
currentSize = 0;
}
try {
mkdirSync6(dirname8(filePath), { recursive: true });
appendFileSync(filePath, line, { encoding: "utf8", mode: 384 });
currentSize += lineBytes;
} catch {
}
}
if (shouldStdout) {
process.stdout.write(line);
}
}
const logFn = ((entryOrEvent, extra) => {
let lvl = "info";
if (typeof entryOrEvent === "object" && entryOrEvent !== null && typeof entryOrEvent.level === "string") {
const candidate = entryOrEvent.level.toLowerCase();
if (candidate === "debug" || candidate === "info" || candidate === "warn" || candidate === "error") {
lvl = candidate;
}
}
emit(lvl, entryOrEvent, extra);
});
logFn.info = (entryOrEvent, extra) => emit("info", entryOrEvent, extra);
logFn.warn = (entryOrEvent, extra) => emit("warn", entryOrEvent, extra);
logFn.error = (entryOrEvent, extra) => emit("error", entryOrEvent, extra);
logFn.debug = (entryOrEvent, extra) => emit("debug", entryOrEvent, extra);
logFn.child = (sub) => {
return createLogger({
...options,
component: sub.component ? `${component}.${sub.component}` : component,
correlation: { ...correlationDefaults, ...sub.correlation }
});
};
logFn.close = () => {
};
Object.defineProperty(logFn, "options", {
value: Object.freeze({ ...options }),
writable: false,
enumerable: true
});
return logFn;
}
// plugins/kxm/src/server.ts
var host = process.env.KXM_HOST ?? "127.0.0.1";
var port = Number.parseInt(process.env.KXM_PORT ?? String(DEFAULT_PORT), 10);
var authToken = process.env.KXM_AUTH_TOKEN;
var workspaceDir = resolve8(process.env.KXM_WORKSPACE_DIR?.trim() || ".kxm");
var configDir = resolve8(process.env.KXM_CONFIG_DIR?.trim() || join8(workspaceDir, "config"));
var logsDir = resolve8(process.env.KXM_LOGS_DIR?.trim() || join8(workspaceDir, "logs"));
var assetsDir = resolve8(process.env.KXM_ASSETS_DIR?.trim() || join8(workspaceDir, "assets"));
var stateDir = resolve8(process.env.KXM_STATE_DIR?.trim() || join8(workspaceDir, "state"));
var dataPathValue = process.env.KXM_DATA_PATH?.trim();
var dataPath = dataPathValue === ":memory:" ? dataPathValue : resolve8(dataPathValue || join8(stateDir, "kxm.db"));
var logPath = resolve8(process.env.KXM_LOG_PATH?.trim() || join8(logsDir, "kxm-hub.jsonl"));
var messageTtlMs = Number.parseInt(process.env.KXM_MESSAGE_TTL_MS ?? String(DEFAULT_MESSAGE_TTL_MS), 10);
var messageRetentionMs = Number.parseInt(
process.env.KXM_MESSAGE_RETENTION_MS ?? String(DEFAULT_MESSAGE_RETENTION_MS),
10
);
var rateLimitMax = Number.parseInt(process.env.KXM_RATE_LIMIT_MAX ?? String(DEFAULT_RATE_LIMIT_MAX), 10);
var rateLimitWindowMs = Number.parseInt(
process.env.KXM_RATE_LIMIT_WINDOW_MS ?? String(DEFAULT_RATE_LIMIT_WINDOW_MS),
10
);
for (const directory of [configDir, logsDir, assetsDir, stateDir, dirname9(logPath)]) {
mkdirSync7(directory, { recursive: true });
}
var structuredLog = createLogger({
component: "hub",
path: logPath
});
function parseProjectTokenEnv(raw) {
const trimmed = raw?.trim();
if (!trimmed) return void 0;
const value = JSON.parse(trimmed);
if (!value || Array.isArray(value) || typeof value !== "object") {
throw new Error("KXM_PROJECT_TOKENS must be a JSON object of project names to tokens");
}
const entries = Object.entries(value);
if (entries.some(([project, token]) => !project.trim() || typeof token !== "string" || !token.trim())) {
throw new Error("KXM_PROJECT_TOKENS must contain non-empty project names and token strings");
}
return Object.fromEntries(entries);
}
function projectTokens() {
const explicit = process.env.KXM_PROJECT_TOKENS_EXPLICIT === "1";
const fromEnv = parseProjectTokenEnv(process.env.KXM_PROJECT_TOKENS);
const workdir = resolve8(process.env.KXM_WORKDIR?.trim() || process.cwd());
const configured = explicit ? void 0 : resolveConfiguredHubProjectTokens(workdir, process.env);
const selected = selectHubProjectTokenMap({
explicit: explicit ? fromEnv : void 0,
configured,
file: explicit ? void 0 : fromEnv
});
if (selected.source === "config") {
const count = Object.keys(selected.tokens ?? {}).length;
process.stderr.write(`kxm hub: project tokens from .kxm/config.yaml (${count} projects, key references resolved, values not saved)
`);
}
return selected.tokens;
}
if (!Number.isInteger(port) || port < 0 || port > 65535) {
throw new Error("KXM_PORT must be an integer between 0 and 65535");
}
if (![messageTtlMs, messageRetentionMs, rateLimitMax, rateLimitWindowMs].every(Number.isInteger)) {
throw new Error("message TTL and rate limit settings must be integers");
}
var configuredProjectTokens = projectTokens();
var inlineWorkflows = process.env.KXM_WEBHOOK_WORKFLOWS?.trim();
var workflowFile = process.env.KXM_WEBHOOK_WORKFLOWS_FILE?.trim();
if (inlineWorkflows && workflowFile) {
throw new Error("configure only one of KXM_WEBHOOK_WORKFLOWS or KXM_WEBHOOK_WORKFLOWS_FILE");
}
var webhookWorkflows = parseWorkflowDefinitions(
workflowFile ? readFileSync6(resolve8(workflowFile), "utf8") : inlineWorkflows
);
var hub = createMeshHub({
host,
port,
dataPath,
assetsDir,
messageTtlMs,
messageRetentionMs,
rateLimit: { maxRequests: rateLimitMax, windowMs: rateLimitWindowMs },
...authToken ? { authToken } : {},
...configuredProjectTokens ? { projectTokens: configuredProjectTokens } : {},
...webhookWorkflows.length ? { webhookWorkflows } : {},
logger: structuredLog
});
var address = await hub.start();
var auth = authToken ? "token" : "none";
if (auth === "none") {
process.stderr.write("kxm hub: auth=none; every loopback caller is trusted. Set KXM_AUTH_TOKEN before relying on this hub.\n");
}
structuredLog({ event: "hub_started", url: address.url, workspaceDir, configDir, logsDir, assetsDir, stateDir, dataPath, logPath, auth });
process.stdout.write(`kxm hub listening at ${address.url}; storage=${dataPath}; auth=${auth}
`);
var shutdownPromise;
function shutdown(signal) {
if (shutdownPromise) return shutdownPromise;
shutdownPromise = (async () => {
structuredLog({ event: "hub_stopping", signal });
await hub.close();
structuredLog.close();
process.exit(0);
})();
return shutdownPromise;
}
process.once("SIGINT", () => void shutdown("SIGINT"));
process.once("SIGTERM", () => void shutdown("SIGTERM"));
process.once("message", (message) => {
if (message && typeof message === "object" && message.type === "shutdown") {
const signal = message.signal;
void shutdown(typeof signal === "string" ? signal : "parent");
}
});