agent-contracts 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3951,7 +3951,7 @@ var require_lodash = __commonJS({
3951
3951
  }
3952
3952
  return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
3953
3953
  });
3954
- function join2(array, separator) {
3954
+ function join3(array, separator) {
3955
3955
  return array == null ? "" : nativeJoin.call(array, separator);
3956
3956
  }
3957
3957
  function last(array) {
@@ -5875,7 +5875,7 @@ var require_lodash = __commonJS({
5875
5875
  lodash.isUndefined = isUndefined;
5876
5876
  lodash.isWeakMap = isWeakMap;
5877
5877
  lodash.isWeakSet = isWeakSet;
5878
- lodash.join = join2;
5878
+ lodash.join = join3;
5879
5879
  lodash.kebabCase = kebabCase;
5880
5880
  lodash.last = last;
5881
5881
  lodash.lastIndexOf = lastIndexOf;
@@ -7496,7 +7496,7 @@ var require_stable = __commonJS({
7496
7496
  return result;
7497
7497
  }
7498
7498
  function stringifyFullFn(key, parent, stack, replacer, indent) {
7499
- var i3, res, join2;
7499
+ var i3, res, join3;
7500
7500
  const originalIndentation = indentation;
7501
7501
  var value = parent[key];
7502
7502
  if (typeof value === "object" && value !== null && typeof value.toJSON === "function") {
@@ -7522,12 +7522,12 @@ var require_stable = __commonJS({
7522
7522
  indentation += indent;
7523
7523
  res += `
7524
7524
  ${indentation}`;
7525
- join2 = `,
7525
+ join3 = `,
7526
7526
  ${indentation}`;
7527
7527
  for (i3 = 0; i3 < value.length - 1; i3++) {
7528
7528
  const tmp2 = stringifyFullFn(i3, value, stack, replacer, indent);
7529
7529
  res += tmp2 !== void 0 ? tmp2 : "null";
7530
- res += join2;
7530
+ res += join3;
7531
7531
  }
7532
7532
  const tmp = stringifyFullFn(i3, value, stack, replacer, indent);
7533
7533
  res += tmp !== void 0 ? tmp : "null";
@@ -7549,7 +7549,7 @@ ${originalIndentation}`;
7549
7549
  indentation += indent;
7550
7550
  res += `
7551
7551
  ${indentation}`;
7552
- join2 = `,
7552
+ join3 = `,
7553
7553
  ${indentation}`;
7554
7554
  var separator = "";
7555
7555
  for (i3 = 0; i3 < keys.length; i3++) {
@@ -7557,7 +7557,7 @@ ${indentation}`;
7557
7557
  const tmp = stringifyFullFn(key, value, stack, replacer, indent);
7558
7558
  if (tmp !== void 0) {
7559
7559
  res += `${separator}"${strEscape(key)}": ${tmp}`;
7560
- separator = join2;
7560
+ separator = join3;
7561
7561
  }
7562
7562
  }
7563
7563
  if (separator !== "") {
@@ -7579,7 +7579,7 @@ ${originalIndentation}`;
7579
7579
  }
7580
7580
  }
7581
7581
  function stringifyFullArr(key, value, stack, replacer, indent) {
7582
- var i3, res, join2;
7582
+ var i3, res, join3;
7583
7583
  const originalIndentation = indentation;
7584
7584
  if (typeof value === "object" && value !== null && typeof value.toJSON === "function") {
7585
7585
  value = value.toJSON(key);
@@ -7603,12 +7603,12 @@ ${originalIndentation}`;
7603
7603
  indentation += indent;
7604
7604
  res += `
7605
7605
  ${indentation}`;
7606
- join2 = `,
7606
+ join3 = `,
7607
7607
  ${indentation}`;
7608
7608
  for (i3 = 0; i3 < value.length - 1; i3++) {
7609
7609
  const tmp2 = stringifyFullArr(i3, value[i3], stack, replacer, indent);
7610
7610
  res += tmp2 !== void 0 ? tmp2 : "null";
7611
- res += join2;
7611
+ res += join3;
7612
7612
  }
7613
7613
  const tmp = stringifyFullArr(i3, value[i3], stack, replacer, indent);
7614
7614
  res += tmp !== void 0 ? tmp : "null";
@@ -7629,7 +7629,7 @@ ${originalIndentation}`;
7629
7629
  indentation += indent;
7630
7630
  res += `
7631
7631
  ${indentation}`;
7632
- join2 = `,
7632
+ join3 = `,
7633
7633
  ${indentation}`;
7634
7634
  var separator = "";
7635
7635
  for (i3 = 0; i3 < replacer.length; i3++) {
@@ -7638,7 +7638,7 @@ ${indentation}`;
7638
7638
  const tmp = stringifyFullArr(key, value[key], stack, replacer, indent);
7639
7639
  if (tmp !== void 0) {
7640
7640
  res += `${separator}"${strEscape(key)}": ${tmp}`;
7641
- separator = join2;
7641
+ separator = join3;
7642
7642
  }
7643
7643
  }
7644
7644
  }
@@ -7661,7 +7661,7 @@ ${originalIndentation}`;
7661
7661
  }
7662
7662
  }
7663
7663
  function stringifyIndent(key, value, stack, indent) {
7664
- var i3, res, join2;
7664
+ var i3, res, join3;
7665
7665
  const originalIndentation = indentation;
7666
7666
  switch (typeof value) {
7667
7667
  case "object":
@@ -7691,12 +7691,12 @@ ${originalIndentation}`;
7691
7691
  indentation += indent;
7692
7692
  res += `
7693
7693
  ${indentation}`;
7694
- join2 = `,
7694
+ join3 = `,
7695
7695
  ${indentation}`;
7696
7696
  for (i3 = 0; i3 < value.length - 1; i3++) {
7697
7697
  const tmp2 = stringifyIndent(i3, value[i3], stack, indent);
7698
7698
  res += tmp2 !== void 0 ? tmp2 : "null";
7699
- res += join2;
7699
+ res += join3;
7700
7700
  }
7701
7701
  const tmp = stringifyIndent(i3, value[i3], stack, indent);
7702
7702
  res += tmp !== void 0 ? tmp : "null";
@@ -7718,7 +7718,7 @@ ${originalIndentation}`;
7718
7718
  indentation += indent;
7719
7719
  res += `
7720
7720
  ${indentation}`;
7721
- join2 = `,
7721
+ join3 = `,
7722
7722
  ${indentation}`;
7723
7723
  var separator = "";
7724
7724
  for (i3 = 0; i3 < keys.length; i3++) {
@@ -7726,7 +7726,7 @@ ${indentation}`;
7726
7726
  const tmp = stringifyIndent(key, value[key], stack, indent);
7727
7727
  if (tmp !== void 0) {
7728
7728
  res += `${separator}"${strEscape(key)}": ${tmp}`;
7729
- separator = join2;
7729
+ separator = join3;
7730
7730
  }
7731
7731
  }
7732
7732
  if (separator !== "") {
@@ -52697,7 +52697,7 @@ var require_lodash3 = __commonJS({
52697
52697
  }
52698
52698
  return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
52699
52699
  });
52700
- function join2(array, separator) {
52700
+ function join3(array, separator) {
52701
52701
  return array == null ? "" : nativeJoin.call(array, separator);
52702
52702
  }
52703
52703
  function last(array) {
@@ -54616,7 +54616,7 @@ var require_lodash3 = __commonJS({
54616
54616
  lodash.isUndefined = isUndefined;
54617
54617
  lodash.isWeakMap = isWeakMap;
54618
54618
  lodash.isWeakSet = isWeakSet;
54619
- lodash.join = join2;
54619
+ lodash.join = join3;
54620
54620
  lodash.kebabCase = kebabCase;
54621
54621
  lodash.last = last;
54622
54622
  lodash.lastIndexOf = lastIndexOf;
@@ -58503,8 +58503,8 @@ var RemoveOperatorSchema = z11.object({
58503
58503
  });
58504
58504
 
58505
58505
  // src/loader/loader.ts
58506
- import { readFile } from "fs/promises";
58507
- import { dirname, resolve } from "path";
58506
+ import { readFile, readdir, stat as fsStat } from "fs/promises";
58507
+ import { dirname, resolve, join, extname } from "path";
58508
58508
  import { parse as parseYaml } from "yaml";
58509
58509
  var DslLoadError = class extends Error {
58510
58510
  constructor(message, filePath) {
@@ -58514,18 +58514,16 @@ var DslLoadError = class extends Error {
58514
58514
  }
58515
58515
  filePath;
58516
58516
  };
58517
- var REF_ELIGIBLE_SECTIONS = [
58518
- "agents",
58519
- "tasks",
58520
- "artifacts",
58521
- "tools",
58522
- "validations",
58523
- "handoff_types",
58524
- "workflow",
58525
- "policies"
58526
- ];
58517
+ function isRecord(v2) {
58518
+ return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
58519
+ }
58527
58520
  function isRef(value) {
58528
- return typeof value === "object" && value !== null && "$ref" in value && typeof value["$ref"] === "string";
58521
+ return isRecord(value) && "$ref" in value && typeof value["$ref"] === "string";
58522
+ }
58523
+ function hasRefs(value) {
58524
+ if (!("$refs" in value)) return false;
58525
+ const refs = value["$refs"];
58526
+ return Array.isArray(refs) && refs.every((r3) => typeof r3 === "string");
58529
58527
  }
58530
58528
  async function readYaml(filePath) {
58531
58529
  let content;
@@ -58547,17 +58545,160 @@ async function readYaml(filePath) {
58547
58545
  );
58548
58546
  }
58549
58547
  }
58550
- async function resolveRefs(data, baseDir) {
58551
- const resolved = { ...data };
58552
- for (const section of REF_ELIGIBLE_SECTIONS) {
58553
- const value = resolved[section];
58554
- if (isRef(value)) {
58555
- const refPath = resolve(baseDir, value.$ref);
58556
- resolved[section] = await readYaml(refPath);
58548
+ function deepMergeRefs(a3, b3, sourcePath) {
58549
+ const result = { ...a3 };
58550
+ for (const [key, bVal] of Object.entries(b3)) {
58551
+ const aVal = result[key];
58552
+ if (aVal === void 0) {
58553
+ result[key] = bVal;
58554
+ } else if (isRecord(aVal) && isRecord(bVal)) {
58555
+ result[key] = deepMergeRefs(aVal, bVal, sourcePath);
58556
+ } else {
58557
+ throw new DslLoadError(
58558
+ `Conflicting value for key "${key}" while merging $refs from ${sourcePath}`,
58559
+ sourcePath
58560
+ );
58557
58561
  }
58558
58562
  }
58563
+ return result;
58564
+ }
58565
+ async function loadRefsSource(refPath, baseDir, resolving) {
58566
+ const target = resolve(baseDir, refPath);
58567
+ const s2 = await fsStat(target).catch(() => null);
58568
+ if (s2?.isDirectory()) {
58569
+ if (resolving.has(target)) {
58570
+ throw new DslLoadError(`Circular $refs detected: ${target}`, target);
58571
+ }
58572
+ resolving.add(target);
58573
+ const result = await loadDirectoryAsMap(target, resolving);
58574
+ resolving.delete(target);
58575
+ return result;
58576
+ }
58577
+ if (!s2?.isFile()) {
58578
+ throw new DslLoadError(`File not found: ${target}`, target);
58579
+ }
58580
+ if (resolving.has(target)) {
58581
+ throw new DslLoadError(`Circular $refs detected: ${target}`, target);
58582
+ }
58583
+ resolving.add(target);
58584
+ const content = await readYaml(target);
58585
+ if (!isRecord(content)) {
58586
+ throw new DslLoadError(
58587
+ `Expected YAML object in ${target}, got ${Array.isArray(content) ? "array" : typeof content}`,
58588
+ target
58589
+ );
58590
+ }
58591
+ const resolved = await resolveRefsDeep(
58592
+ content,
58593
+ dirname(target),
58594
+ resolving
58595
+ );
58596
+ resolving.delete(target);
58559
58597
  return resolved;
58560
58598
  }
58599
+ async function loadDirectoryAsMap(dirPath, resolving) {
58600
+ let entries;
58601
+ try {
58602
+ entries = await readdir(dirPath);
58603
+ } catch {
58604
+ throw new DslLoadError(
58605
+ `Cannot read directory: ${dirPath}`,
58606
+ dirPath
58607
+ );
58608
+ }
58609
+ const yamlFiles = entries.filter((f2) => [".yaml", ".yml"].includes(extname(f2))).sort();
58610
+ if (yamlFiles.length === 0) {
58611
+ throw new DslLoadError(
58612
+ `No YAML files found in directory: ${dirPath}`,
58613
+ dirPath
58614
+ );
58615
+ }
58616
+ let merged = {};
58617
+ for (const file of yamlFiles) {
58618
+ const filePath = join(dirPath, file);
58619
+ const content = await readYaml(filePath);
58620
+ if (!isRecord(content)) {
58621
+ throw new DslLoadError(
58622
+ `Expected YAML object in ${filePath}, got ${Array.isArray(content) ? "array" : typeof content}`,
58623
+ filePath
58624
+ );
58625
+ }
58626
+ const resolved = await resolveRefsDeep(
58627
+ content,
58628
+ dirPath,
58629
+ resolving
58630
+ );
58631
+ merged = deepMergeRefs(merged, resolved, filePath);
58632
+ }
58633
+ return merged;
58634
+ }
58635
+ async function processRefs(obj, baseDir, resolving) {
58636
+ const refPaths = obj["$refs"];
58637
+ const inline = {};
58638
+ for (const [key, value] of Object.entries(obj)) {
58639
+ if (key !== "$refs") {
58640
+ inline[key] = value;
58641
+ }
58642
+ }
58643
+ let merged = {};
58644
+ for (const refPath of refPaths) {
58645
+ const loaded = await loadRefsSource(refPath, baseDir, resolving);
58646
+ merged = deepMergeRefs(merged, loaded, refPath);
58647
+ }
58648
+ merged = deepMergeRefs(merged, inline, "(inline)");
58649
+ return merged;
58650
+ }
58651
+ async function resolveRefsDeep(data, baseDir, resolving) {
58652
+ if (typeof data !== "object" || data === null) return data;
58653
+ if (Array.isArray(data)) {
58654
+ return Promise.all(
58655
+ data.map((item) => resolveRefsDeep(item, baseDir, resolving))
58656
+ );
58657
+ }
58658
+ if (isRef(data)) {
58659
+ const refTarget = resolve(baseDir, data.$ref);
58660
+ const s2 = await fsStat(refTarget).catch(() => null);
58661
+ if (s2?.isDirectory()) {
58662
+ if (resolving.has(refTarget)) {
58663
+ throw new DslLoadError(
58664
+ `Circular $ref detected: ${refTarget}`,
58665
+ refTarget
58666
+ );
58667
+ }
58668
+ resolving.add(refTarget);
58669
+ const result2 = await loadDirectoryAsMap(refTarget, resolving);
58670
+ resolving.delete(refTarget);
58671
+ return result2;
58672
+ }
58673
+ if (!s2?.isFile()) {
58674
+ throw new DslLoadError(`File not found: ${refTarget}`, refTarget);
58675
+ }
58676
+ if (resolving.has(refTarget)) {
58677
+ throw new DslLoadError(
58678
+ `Circular $ref detected: ${refTarget}`,
58679
+ refTarget
58680
+ );
58681
+ }
58682
+ resolving.add(refTarget);
58683
+ const content = await readYaml(refTarget);
58684
+ const resolved = await resolveRefsDeep(
58685
+ content,
58686
+ dirname(refTarget),
58687
+ resolving
58688
+ );
58689
+ resolving.delete(refTarget);
58690
+ return resolved;
58691
+ }
58692
+ let obj = data;
58693
+ if (hasRefs(obj)) {
58694
+ obj = await processRefs(obj, baseDir, resolving);
58695
+ }
58696
+ const result = {};
58697
+ for (const [key, value] of Object.entries(obj)) {
58698
+ result[key] = await resolveRefsDeep(value, baseDir, resolving);
58699
+ }
58700
+ return result;
58701
+ }
58561
58702
  function checkVersion(data, filePath) {
58562
58703
  const version = data["version"];
58563
58704
  if (version === void 0) {
@@ -58585,12 +58726,17 @@ async function loadDsl(entryPath) {
58585
58726
  const data = raw;
58586
58727
  checkVersion(data, absPath);
58587
58728
  const baseDir = dirname(absPath);
58588
- const resolved = await resolveRefs(data, baseDir);
58729
+ const resolving = /* @__PURE__ */ new Set([absPath]);
58730
+ const resolved = await resolveRefsDeep(
58731
+ data,
58732
+ baseDir,
58733
+ resolving
58734
+ );
58589
58735
  return { data: resolved, filePath: absPath };
58590
58736
  }
58591
58737
 
58592
58738
  // src/resolver/base-resolver.ts
58593
- import { resolve as resolve2, join } from "path";
58739
+ import { resolve as resolve2, join as join2 } from "path";
58594
58740
  import { stat } from "fs/promises";
58595
58741
  var BaseResolveError = class extends Error {
58596
58742
  constructor(message) {
@@ -58601,7 +58747,7 @@ var BaseResolveError = class extends Error {
58601
58747
  async function findEntryFile(dir) {
58602
58748
  const candidates = ["agent-contracts.yaml", "agent-contracts.yml"];
58603
58749
  for (const name of candidates) {
58604
- const p2 = join(dir, name);
58750
+ const p2 = join2(dir, name);
58605
58751
  try {
58606
58752
  const s2 = await stat(p2);
58607
58753
  if (s2.isFile()) return p2;
@@ -58653,7 +58799,7 @@ var MergeError = class extends Error {
58653
58799
  this.name = "MergeError";
58654
58800
  }
58655
58801
  };
58656
- function isRecord(v2) {
58802
+ function isRecord2(v2) {
58657
58803
  return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
58658
58804
  }
58659
58805
  function hasOperator(obj) {
@@ -58665,7 +58811,7 @@ function hasOperator(obj) {
58665
58811
  }
58666
58812
  function findIndexById(arr, id) {
58667
58813
  return arr.findIndex(
58668
- (item) => isRecord(item) && item["id"] === id
58814
+ (item) => isRecord2(item) && item["id"] === id
58669
58815
  );
58670
58816
  }
58671
58817
  function applyArrayMergeOperator(baseArray, operatorObj, path) {
@@ -58701,7 +58847,7 @@ function applyArrayMergeOperator(baseArray, operatorObj, path) {
58701
58847
  const removeList = operatorObj["$remove"];
58702
58848
  const idsToRemove = new Set(removeList.map((r3) => r3["id"]));
58703
58849
  const result = baseArray.filter((item) => {
58704
- if (isRecord(item) && typeof item["id"] === "string") {
58850
+ if (isRecord2(item) && typeof item["id"] === "string") {
58705
58851
  const itemId = item["id"];
58706
58852
  if (idsToRemove.has(itemId)) {
58707
58853
  idsToRemove.delete(itemId);
@@ -58790,7 +58936,7 @@ function deepMergeEntities(base, project, path, hasExtends) {
58790
58936
  for (const key of Object.keys(project)) {
58791
58937
  const baseVal = result[key];
58792
58938
  const projVal = project[key];
58793
- if (isRecord(projVal) && hasOperator(projVal)) {
58939
+ if (isRecord2(projVal) && hasOperator(projVal)) {
58794
58940
  if (!hasExtends) {
58795
58941
  throw new MergeError(
58796
58942
  `Merge operator used without extends at ${path}.${key}`
@@ -58798,12 +58944,12 @@ function deepMergeEntities(base, project, path, hasExtends) {
58798
58944
  }
58799
58945
  if (Array.isArray(baseVal)) {
58800
58946
  result[key] = applyArrayMergeOperator(baseVal, projVal, `${path}.${key}`);
58801
- } else if (isRecord(baseVal)) {
58947
+ } else if (isRecord2(baseVal)) {
58802
58948
  result[key] = applyMapMergeOperator(baseVal, projVal, `${path}.${key}`);
58803
58949
  } else {
58804
58950
  result[key] = applyArrayMergeOperator([], projVal, `${path}.${key}`);
58805
58951
  }
58806
- } else if (isRecord(projVal) && isRecord(baseVal) && !Array.isArray(projVal) && !Array.isArray(baseVal)) {
58952
+ } else if (isRecord2(projVal) && isRecord2(baseVal) && !Array.isArray(projVal) && !Array.isArray(baseVal)) {
58807
58953
  result[key] = deepMergeEntities(
58808
58954
  baseVal,
58809
58955
  projVal,
@@ -58817,7 +58963,7 @@ function deepMergeEntities(base, project, path, hasExtends) {
58817
58963
  return result;
58818
58964
  }
58819
58965
  function mergeEntityMaps(baseMap, projectMap, path, hasExtends) {
58820
- if (isRecord(projectMap) && !Array.isArray(projectMap)) {
58966
+ if (isRecord2(projectMap) && !Array.isArray(projectMap)) {
58821
58967
  const op = hasOperator(projectMap);
58822
58968
  if (op) {
58823
58969
  if (!hasExtends) {
@@ -58831,7 +58977,7 @@ function mergeEntityMaps(baseMap, projectMap, path, hasExtends) {
58831
58977
  const result = { ...baseMap };
58832
58978
  for (const [key, projVal] of Object.entries(projectMap)) {
58833
58979
  const baseVal = result[key];
58834
- if (baseVal !== void 0 && isRecord(baseVal) && isRecord(projVal)) {
58980
+ if (baseVal !== void 0 && isRecord2(baseVal) && isRecord2(projVal)) {
58835
58981
  result[key] = deepMergeEntities(
58836
58982
  baseVal,
58837
58983
  projVal,
@@ -58871,7 +59017,7 @@ function mergeDsl(base, project) {
58871
59017
  if (projVal === void 0) {
58872
59018
  continue;
58873
59019
  }
58874
- const baseMap = isRecord(baseVal) ? baseVal : {};
59020
+ const baseMap = isRecord2(baseVal) ? baseVal : {};
58875
59021
  result[section] = mergeEntityMaps(
58876
59022
  baseMap,
58877
59023
  projVal,