@fungi.computer/truffle 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +27 -4
  2. package/dist/internal/private-workerd-sandbox-worker.mjs +243 -273
  3. package/dist/internal/sandbox-metafile.json +35 -30
  4. package/dist/local-extensions.d.ts +2 -2
  5. package/dist/local-extensions.js +43 -19
  6. package/dist/private-fungi-mcp-connection.js +6 -1
  7. package/dist/private-invocation-computer.d.ts +6 -2
  8. package/dist/private-invocation-computer.js +20 -13
  9. package/dist/private-local-computer-processes.d.ts +7 -2
  10. package/dist/private-local-computer-processes.js +47 -23
  11. package/dist/private-local-delegation.js +15 -11
  12. package/dist/private-local-exec-environment.d.ts +5 -2
  13. package/dist/private-local-exec-environment.js +35 -1
  14. package/dist/private-local-exec-review.js +14 -7
  15. package/dist/private-local-exec-rules.d.ts +7 -0
  16. package/dist/private-local-exec-rules.js +23 -6
  17. package/dist/private-local-extension-records.d.ts +1 -1
  18. package/dist/private-local-runtime-host.js +2 -2
  19. package/dist/private-local-sandbox-policy.js +4 -0
  20. package/dist/private-local-sandbox.d.ts +3 -1
  21. package/dist/private-local-sandbox.js +2 -2
  22. package/dist/private-local-schedule-client.d.ts +12 -0
  23. package/dist/private-local-schedule-client.js +41 -0
  24. package/dist/private-local-schedules.d.ts +84 -0
  25. package/dist/private-local-schedules.js +65 -0
  26. package/dist/private-local-service-contract.d.ts +3 -0
  27. package/dist/private-local-service-discovery.d.ts +3 -3
  28. package/dist/private-local-service-discovery.js +1 -1
  29. package/dist/private-local-service-listener.js +9 -0
  30. package/dist/private-local-service-owner.d.ts +130 -0
  31. package/dist/private-local-service-owner.js +29 -0
  32. package/dist/private-local-service.d.ts +3 -0
  33. package/dist/private-local-service.js +2 -0
  34. package/package.json +17 -13
@@ -20658,6 +20658,94 @@ function date4(params) {
20658
20658
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
20659
20659
  config(en_default());
20660
20660
 
20661
+ // ../../packages/forage/dist/normalization.js
20662
+ var jsonValueSchema = external_exports.json();
20663
+ function isJsonObject(value) {
20664
+ return value !== null && !Array.isArray(value) && typeof value === "object";
20665
+ }
20666
+ function compareCodeUnits(left, right) {
20667
+ if (left === right)
20668
+ return 0;
20669
+ const length = Math.min(left.length, right.length);
20670
+ for (let index = 0; index < length; index += 1) {
20671
+ const difference = left.charCodeAt(index) - right.charCodeAt(index);
20672
+ if (difference !== 0)
20673
+ return difference;
20674
+ }
20675
+ return left.length - right.length;
20676
+ }
20677
+ function normalizeQuery(query) {
20678
+ return query.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/[_./:-]/g, " ").toLowerCase().trim();
20679
+ }
20680
+ function tokenize(text) {
20681
+ return text.split(/[^a-zA-Z0-9]+/).filter((token) => token.length > 0);
20682
+ }
20683
+ var stopwords = /* @__PURE__ */ new Set([
20684
+ "the",
20685
+ "a",
20686
+ "an",
20687
+ "for",
20688
+ "to",
20689
+ "of",
20690
+ "that",
20691
+ "this",
20692
+ "with",
20693
+ "in",
20694
+ "on"
20695
+ ]);
20696
+ function isStopword(token) {
20697
+ return stopwords.has(token);
20698
+ }
20699
+ function stemVariants(token) {
20700
+ const variants = [];
20701
+ const add2 = (variant) => {
20702
+ if (variant !== token && variant.length >= 3 && !variants.includes(variant)) {
20703
+ variants.push(variant);
20704
+ }
20705
+ };
20706
+ if (token.endsWith("ing") && token.length > 4)
20707
+ add2(token.slice(0, -3));
20708
+ if (token.endsWith("ed") && token.length > 3)
20709
+ add2(token.slice(0, -2));
20710
+ if (token.endsWith("ation") && token.length > 6) {
20711
+ add2(`${token.slice(0, -3)}e`);
20712
+ }
20713
+ if (token.endsWith("ies") && token.length > 4) {
20714
+ add2(token.slice(0, -3));
20715
+ add2(`${token.slice(0, -3)}y`);
20716
+ }
20717
+ if (token.endsWith("es") && token.length > 3)
20718
+ add2(token.slice(0, -2));
20719
+ if (token.endsWith("s") && !token.endsWith("ss") && token.length > 3) {
20720
+ add2(token.slice(0, -1));
20721
+ }
20722
+ return variants;
20723
+ }
20724
+ function hashString64(value) {
20725
+ let word0 = 8997;
20726
+ let word1 = 33826;
20727
+ let word2 = 40164;
20728
+ let word3 = 52210;
20729
+ for (let index = 0; index < value.length; index += 1) {
20730
+ const low = word0 ^ value.charCodeAt(index);
20731
+ const product0 = low * 435;
20732
+ const product1 = word1 * 435 + (product0 >>> 16);
20733
+ const product2 = word2 * 435 + (product1 >>> 16) + (low << 8);
20734
+ const product3 = word3 * 435 + (product2 >>> 16) + (word1 << 8);
20735
+ word0 = product0 & 65535;
20736
+ word1 = product1 & 65535;
20737
+ word2 = product2 & 65535;
20738
+ word3 = product3 & 65535;
20739
+ }
20740
+ return word3.toString(16).padStart(4, "0") + word2.toString(16).padStart(4, "0") + word1.toString(16).padStart(4, "0") + word0.toString(16).padStart(4, "0");
20741
+ }
20742
+ function operationMethod(path) {
20743
+ return path.slice(path.indexOf(".") + 1);
20744
+ }
20745
+ function operationNamespace(path) {
20746
+ return path.slice(0, path.indexOf("."));
20747
+ }
20748
+
20661
20749
  // ../../packages/forage/dist/schemas.js
20662
20750
  var pathPattern = /^[A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z][A-Za-z0-9_]*)+$/;
20663
20751
  var maximumCatalogOperations = 1e3;
@@ -20676,13 +20764,10 @@ function jsonDepth(value, depth) {
20676
20764
  }
20677
20765
  return maximum2;
20678
20766
  }
20679
- if (value === null)
20680
- return depth;
20681
- const record3 = external_exports.record(external_exports.string(), external_exports.json()).safeParse(value);
20682
- if (!record3.success)
20767
+ if (!isJsonObject(value))
20683
20768
  return depth;
20684
20769
  let maximum = depth;
20685
- for (const item of Object.values(record3.data)) {
20770
+ for (const item of Object.values(value)) {
20686
20771
  maximum = Math.max(maximum, jsonDepth(item, depth + 1));
20687
20772
  }
20688
20773
  return maximum;
@@ -20801,150 +20886,66 @@ var ForageError = class extends Error {
20801
20886
  }
20802
20887
  };
20803
20888
 
20804
- // ../../packages/forage/dist/normalization.js
20805
- var jsonValueSchema = external_exports.json();
20806
- var jsonPrimitiveSchema = external_exports.lazy(() => external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()]));
20807
- function isJsonObject(value) {
20808
- return value !== null && !Array.isArray(value) && !jsonPrimitiveSchema.safeParse(value).success;
20809
- }
20810
- function compareCodeUnits(left, right) {
20811
- if (left === right)
20812
- return 0;
20813
- const length = Math.min(left.length, right.length);
20814
- for (let index = 0; index < length; index += 1) {
20815
- const difference = left.charCodeAt(index) - right.charCodeAt(index);
20816
- if (difference !== 0)
20817
- return difference;
20818
- }
20819
- return left.length - right.length;
20820
- }
20821
- function normalizeQuery(query) {
20822
- return query.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/[_./:-]/g, " ").toLowerCase().trim();
20823
- }
20824
- function tokenize(text) {
20825
- return text.split(/[^a-zA-Z0-9]+/).filter((token) => token.length > 0);
20826
- }
20827
- var stopwords = /* @__PURE__ */ new Set([
20828
- "the",
20829
- "a",
20830
- "an",
20831
- "for",
20832
- "to",
20833
- "of",
20834
- "that",
20835
- "this",
20836
- "with",
20837
- "in",
20838
- "on"
20839
- ]);
20840
- function isStopword(token) {
20841
- return stopwords.has(token);
20842
- }
20843
- function stemVariants(token) {
20844
- const variants = [];
20845
- const add2 = (variant) => {
20846
- if (variant !== token && variant.length >= 3 && !variants.includes(variant)) {
20847
- variants.push(variant);
20848
- }
20849
- };
20850
- if (token.endsWith("ing") && token.length > 4)
20851
- add2(token.slice(0, -3));
20852
- if (token.endsWith("ed") && token.length > 3)
20853
- add2(token.slice(0, -2));
20854
- if (token.endsWith("ies") && token.length > 4) {
20855
- add2(token.slice(0, -3));
20856
- add2(`${token.slice(0, -3)}y`);
20857
- }
20858
- if (token.endsWith("es") && token.length > 3)
20859
- add2(token.slice(0, -2));
20860
- if (token.endsWith("s") && !token.endsWith("ss") && token.length > 3) {
20861
- add2(token.slice(0, -1));
20862
- }
20863
- return variants;
20864
- }
20865
- function canonicalStringify(value) {
20866
- if (value === null)
20867
- return "null";
20868
- const primitive = jsonPrimitiveSchema.safeParse(value);
20869
- if (primitive.success) {
20870
- return JSON.stringify(primitive.data);
20871
- }
20872
- if (Array.isArray(value)) {
20873
- return `[${value.map((item) => canonicalStringify(item)).join(",")}]`;
20874
- }
20875
- if (!isJsonObject(value))
20876
- return "null";
20877
- const entries = Object.entries(value).sort(([left], [right]) => compareCodeUnits(left, right));
20878
- return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${canonicalStringify(entry)}`).join(",")}}`;
20879
- }
20880
- function hashString64(value) {
20881
- let hash3 = 0xcbf29ce484222325n;
20882
- const prime = 0x100000001b3n;
20883
- const mask = (1n << 64n) - 1n;
20884
- for (let index = 0; index < value.length; index += 1) {
20885
- hash3 ^= BigInt(value.charCodeAt(index));
20886
- hash3 = hash3 * prime & mask;
20887
- }
20888
- return hash3.toString(16).padStart(16, "0");
20889
- }
20890
- function operationMethod(path) {
20891
- return path.slice(path.indexOf(".") + 1);
20892
- }
20893
- function operationNamespace(path) {
20894
- return path.slice(0, path.indexOf("."));
20895
- }
20896
-
20897
20889
  // ../../packages/forage/dist/rendering.js
20898
- var schemaNode = external_exports.lazy(() => external_exports.union([
20899
- external_exports.boolean(),
20890
+ var schemaNode = external_exports.union([
20900
20891
  external_exports.looseObject({
20901
20892
  $ref: external_exports.string().optional(),
20902
- $defs: external_exports.record(external_exports.string(), schemaNode).optional(),
20903
- definitions: external_exports.record(external_exports.string(), schemaNode).optional(),
20893
+ $defs: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
20894
+ definitions: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
20904
20895
  const: external_exports.unknown().optional(),
20905
20896
  enum: external_exports.array(external_exports.unknown()).optional(),
20906
- oneOf: external_exports.array(schemaNode).optional(),
20907
- anyOf: external_exports.array(schemaNode).optional(),
20908
- allOf: external_exports.array(schemaNode).optional(),
20897
+ oneOf: external_exports.array(external_exports.unknown()).optional(),
20898
+ anyOf: external_exports.array(external_exports.unknown()).optional(),
20899
+ allOf: external_exports.array(external_exports.unknown()).optional(),
20909
20900
  type: external_exports.union([external_exports.string(), external_exports.array(external_exports.string())]).optional(),
20910
- properties: external_exports.record(external_exports.string(), schemaNode).optional(),
20911
- additionalProperties: schemaNode.optional(),
20901
+ properties: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
20902
+ additionalProperties: external_exports.unknown().optional(),
20912
20903
  required: external_exports.array(external_exports.string()).optional(),
20913
- prefixItems: external_exports.array(schemaNode).optional(),
20914
- items: external_exports.union([schemaNode, external_exports.array(schemaNode)]).optional(),
20904
+ prefixItems: external_exports.array(external_exports.unknown()).optional(),
20905
+ items: external_exports.unknown().optional(),
20915
20906
  examples: external_exports.array(external_exports.unknown()).optional(),
20916
20907
  default: external_exports.unknown().optional()
20917
- })
20918
- ]));
20919
- var schemaFacts = /* @__PURE__ */ new WeakMap();
20920
- function factsFor(schema, io) {
20921
- let entry = schemaFacts.get(schema);
20908
+ }),
20909
+ external_exports.boolean()
20910
+ ]);
20911
+ var projections = /* @__PURE__ */ new WeakMap();
20912
+ function projectionFor(schema, io) {
20913
+ let entry = projections.get(schema);
20922
20914
  const cached3 = entry?.[io];
20923
20915
  if (cached3 !== void 0)
20924
20916
  return cached3;
20925
- let node;
20917
+ let raw;
20926
20918
  try {
20927
- node = schemaNode.parse(schema["~standard"].jsonSchema[io]({ target: "draft-2020-12" }));
20919
+ raw = schema["~standard"].jsonSchema[io]({ target: "draft-2020-12" });
20928
20920
  } catch {
20929
20921
  throw new ForageError("invalid_input", "Schema cannot be projected to JSON Schema");
20930
20922
  }
20931
- const json2 = jsonValueSchema.safeParse(node);
20932
- const facts = {
20933
- node,
20934
- json: json2.success ? json2.data : void 0
20935
- };
20923
+ decodeNode(raw);
20924
+ const projection = { raw };
20936
20925
  if (entry === void 0) {
20937
20926
  entry = {};
20938
- schemaFacts.set(schema, entry);
20927
+ projections.set(schema, entry);
20939
20928
  }
20940
- entry[io] = facts;
20941
- return facts;
20929
+ entry[io] = projection;
20930
+ return projection;
20942
20931
  }
20943
- function schemaFor(schema, io) {
20944
- return factsFor(schema, io).node;
20932
+ function rawSchema(schema, io) {
20933
+ return projectionFor(schema, io).raw;
20945
20934
  }
20946
- function isNodeList(value) {
20947
- return Array.isArray(value);
20935
+ function schemaText(schema, io) {
20936
+ const projection = projectionFor(schema, io);
20937
+ try {
20938
+ projection.text ??= JSON.stringify(projection.raw);
20939
+ return projection.text;
20940
+ } catch {
20941
+ throw new ForageError("invalid_input", "Schema cannot be projected to JSON Schema");
20942
+ }
20943
+ }
20944
+ function decodeNode(value) {
20945
+ const parsed = schemaNode.safeParse(value);
20946
+ if (!parsed.success)
20947
+ throw new ForageError("invalid_input", "Schema cannot be projected to JSON Schema");
20948
+ return parsed.data;
20948
20949
  }
20949
20950
  var maximumReferenceExpansions = 256;
20950
20951
  var localReference = /^#\/(?:\$defs|definitions)\/([^/]+)$/u;
@@ -20958,7 +20959,7 @@ function renderReference(reference, depth, refs) {
20958
20959
  refs.budget.expansions += 1;
20959
20960
  if (refs.budget.expansions > maximumReferenceExpansions)
20960
20961
  throw new ForageError("invalid_input", `Schema references expand more than ${String(maximumReferenceExpansions)} times; flatten its shared definitions`);
20961
- return renderNode(target, depth, {
20962
+ return renderNode(decodeNode(target), depth, {
20962
20963
  definitions: refs.definitions,
20963
20964
  expanding: /* @__PURE__ */ new Set([...refs.expanding, name]),
20964
20965
  budget: refs.budget
@@ -20970,7 +20971,7 @@ function rendersUnion(node, refs) {
20970
20971
  if (node.$ref !== void 0) {
20971
20972
  const name = localReference.exec(node.$ref)?.[1];
20972
20973
  const target = name === void 0 || refs.expanding.has(name) ? void 0 : refs.definitions[name];
20973
- return name !== void 0 && target !== void 0 && rendersUnion(target, {
20974
+ return name !== void 0 && target !== void 0 && rendersUnion(decodeNode(target), {
20974
20975
  definitions: refs.definitions,
20975
20976
  expanding: /* @__PURE__ */ new Set([...refs.expanding, name]),
20976
20977
  budget: refs.budget
@@ -20980,10 +20981,17 @@ function rendersUnion(node, refs) {
20980
20981
  return false;
20981
20982
  return node.enum !== void 0 && node.enum.length > 1 || node.oneOf !== void 0 && node.oneOf.length > 1 || node.anyOf !== void 0 && node.anyOf.length > 1;
20982
20983
  }
20983
- function renderNode(node, depth, refs) {
20984
- if (node === void 0 || node === true || node === false || depth > 12) {
20984
+ function renderNode(node, depth, scope2) {
20985
+ if (depth > 12) {
20985
20986
  return "unknown";
20986
20987
  }
20988
+ if (node === true || node === false)
20989
+ return "unknown";
20990
+ const refs = scope2 ?? {
20991
+ definitions: { ...node.definitions, ...node.$defs },
20992
+ expanding: /* @__PURE__ */ new Set(),
20993
+ budget: { expansions: 0 }
20994
+ };
20987
20995
  if (node.$ref)
20988
20996
  return renderReference(node.$ref, depth, refs);
20989
20997
  if (node.const !== void 0)
@@ -20991,15 +20999,16 @@ function renderNode(node, depth, refs) {
20991
20999
  if (node.enum)
20992
21000
  return node.enum.map((value) => JSON.stringify(value)).join(" | ");
20993
21001
  if (node.oneOf) {
20994
- return node.oneOf.map((value) => renderNode(value, depth + 1, refs)).join(" | ");
21002
+ return node.oneOf.map((value) => renderNode(decodeNode(value), depth + 1, refs)).join(" | ");
20995
21003
  }
20996
21004
  if (node.anyOf) {
20997
- return node.anyOf.map((value) => renderNode(value, depth + 1, refs)).join(" | ");
21005
+ return node.anyOf.map((value) => renderNode(decodeNode(value), depth + 1, refs)).join(" | ");
20998
21006
  }
20999
21007
  if (node.allOf) {
21000
21008
  return node.allOf.map((value) => {
21001
- const member = renderNode(value, depth + 1, refs);
21002
- return rendersUnion(value, refs) ? `(${member})` : member;
21009
+ const child = decodeNode(value);
21010
+ const member = renderNode(child, depth + 1, refs);
21011
+ return rendersUnion(child, refs) ? `(${member})` : member;
21003
21012
  }).join(" & ");
21004
21013
  }
21005
21014
  if (node.type === "object" || node.properties) {
@@ -21009,13 +21018,13 @@ function renderNode(node, depth, refs) {
21009
21018
  if (additional === false)
21010
21019
  return "Record<string, never>";
21011
21020
  if (additional && additional !== true) {
21012
- return `Record<string, ${renderNode(additional, depth + 1, refs)}>`;
21021
+ return `Record<string, ${renderNode(decodeNode(additional), depth + 1, refs)}>`;
21013
21022
  }
21014
21023
  return "Record<string, unknown>";
21015
21024
  }
21016
21025
  const required2 = new Set(node.required ?? []);
21017
21026
  const lines = properties.map(([key, value]) => {
21018
- const child = renderNode(value, depth + 1, refs);
21027
+ const child = renderNode(decodeNode(value), depth + 1, refs);
21019
21028
  const optional3 = required2.has(key) ? "" : "?";
21020
21029
  const safeKey = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : JSON.stringify(key);
21021
21030
  return `${" ".repeat(depth + 1)}${safeKey}${optional3}: ${child};`;
@@ -21027,16 +21036,17 @@ ${" ".repeat(depth)}}`;
21027
21036
  if (node.type === "array") {
21028
21037
  const items = node.items;
21029
21038
  if (node.prefixItems && node.prefixItems.length > 0) {
21030
- const tuple3 = node.prefixItems.map((value) => renderNode(value, depth + 1, refs));
21031
- if (items !== void 0 && items !== true && !isNodeList(items)) {
21032
- tuple3.push(`...${renderNode(items, depth + 1, refs)}[]`);
21039
+ const tuple3 = node.prefixItems.map((value) => renderNode(decodeNode(value), depth + 1, refs));
21040
+ if (items !== void 0 && items !== true && !Array.isArray(items)) {
21041
+ tuple3.push(`...${renderNode(decodeNode(items), depth + 1, refs)}[]`);
21033
21042
  }
21034
21043
  return `[${tuple3.join(", ")}]`;
21035
21044
  }
21036
- if (items !== void 0 && isNodeList(items))
21037
- return `[${items.map((value) => renderNode(value, depth + 1, refs)).join(", ")}][]`;
21038
- const item = renderNode(items, depth + 1, refs);
21039
- const compoundItem = items !== void 0 && items !== true && items !== false && (items.oneOf !== void 0 || items.anyOf !== void 0 || items.allOf !== void 0);
21045
+ if (items !== void 0 && Array.isArray(items))
21046
+ return `[${items.map((value) => renderNode(decodeNode(value), depth + 1, refs)).join(", ")}][]`;
21047
+ const itemNode = items === void 0 ? true : decodeNode(items);
21048
+ const item = renderNode(itemNode, depth + 1, refs);
21049
+ const compoundItem = itemNode !== true && itemNode !== false && (itemNode.oneOf !== void 0 || itemNode.anyOf !== void 0 || itemNode.allOf !== void 0);
21040
21050
  return `${compoundItem ? `(${item})` : item}[]`;
21041
21051
  }
21042
21052
  switch (node.type) {
@@ -21054,13 +21064,7 @@ ${" ".repeat(depth)}}`;
21054
21064
  }
21055
21065
  }
21056
21066
  function renderSchemaType(schema, io = "input") {
21057
- const root = schemaFor(schema, io);
21058
- const definitions = root === true || root === false ? {} : { ...root.definitions, ...root.$defs };
21059
- return renderNode(root, 0, {
21060
- definitions,
21061
- expanding: /* @__PURE__ */ new Set(),
21062
- budget: { expansions: 0 }
21063
- });
21067
+ return renderNode(decodeNode(rawSchema(schema, io)), 0);
21064
21068
  }
21065
21069
  function safeTypeName(name) {
21066
21070
  return name.replace(/[^A-Za-z0-9_$]/g, "_");
@@ -21079,30 +21083,35 @@ function renderOperationTypes(operations) {
21079
21083
  return operations.length === 0 ? types2 : `${types2}
21080
21084
  export declare const env: ${operations.map((operation) => operation.environment).join(" & ")};`;
21081
21085
  }
21086
+ var renderedOperations = /* @__PURE__ */ new WeakMap();
21082
21087
  function renderOperation(operation) {
21088
+ const cached3 = renderedOperations.get(operation);
21089
+ if (cached3 !== void 0)
21090
+ return cached3;
21083
21091
  const name = safeTypeName(operation.path.replace(/\./g, "$"));
21084
21092
  const input = renderSchemaType(operation.input, "input");
21085
21093
  const output = operation.output ? renderSchemaType(operation.output, "output") : "unknown";
21086
- return Object.freeze({
21094
+ const rendered = Object.freeze({
21087
21095
  indexEnvironment: renderEnvironment(operation.path, input, output),
21088
21096
  environment: renderEnvironment(operation.path, `${name}_Input`, `${name}_Output`),
21089
21097
  types: `export type ${name}_Input = ${input};
21090
21098
  export type ${name}_Output = ${output};`
21091
21099
  });
21100
+ renderedOperations.set(operation, rendered);
21101
+ return rendered;
21092
21102
  }
21093
21103
  function deriveSample(schema) {
21094
- const node = schemaFor(schema, "input");
21104
+ const node = decodeNode(rawSchema(schema, "input"));
21095
21105
  if (node === true || node === false || !node.properties) {
21096
21106
  return void 0;
21097
21107
  }
21098
- const properties = node.properties;
21099
21108
  const sample = {};
21100
21109
  let found = false;
21101
- const entries = Object.entries(properties).sort(([left], [right]) => compareCodeUnits(left, right));
21110
+ const entries = Object.entries(node.properties).sort(([left], [right]) => compareCodeUnits(left, right));
21102
21111
  for (const [key, value] of entries) {
21103
- if (value === true || value === false)
21112
+ const property = decodeNode(value);
21113
+ if (property === true || property === false)
21104
21114
  continue;
21105
- const property = value;
21106
21115
  const examples = property.examples;
21107
21116
  if (examples && examples.length > 0) {
21108
21117
  const example = jsonValueSchema.safeParse(examples[0]);
@@ -21120,66 +21129,6 @@ function deriveSample(schema) {
21120
21129
  }
21121
21130
  return found ? sample : void 0;
21122
21131
  }
21123
- function inputSchemaProjection(schema) {
21124
- const projection = factsFor(schema, "input").json;
21125
- if (projection === void 0) {
21126
- throw new ForageError("invalid_input", "Schema cannot be projected to JSON Schema");
21127
- }
21128
- return projection;
21129
- }
21130
- function schemaFingerprint(schema, io = "input") {
21131
- const facts = factsFor(schema, io);
21132
- facts.fingerprint ??= canonicalStringify(facts.json ?? null);
21133
- return facts.fingerprint;
21134
- }
21135
- function schemaDepth(value, depth) {
21136
- if (depth > maximumSampleDepth)
21137
- return depth;
21138
- if (Array.isArray(value)) {
21139
- let maximum2 = depth;
21140
- for (const item of value) {
21141
- maximum2 = Math.max(maximum2, schemaDepth(item, depth + 1));
21142
- }
21143
- return maximum2;
21144
- }
21145
- if (!isJsonObject(value))
21146
- return depth;
21147
- let maximum = depth;
21148
- for (const entry of Object.values(value)) {
21149
- maximum = Math.max(maximum, schemaDepth(entry, depth + 1));
21150
- }
21151
- return maximum;
21152
- }
21153
- function schemaProjectionSize(schema, io) {
21154
- const facts = factsFor(schema, io);
21155
- facts.size ??= { bytes: measureProjection(schema, io, facts.json) };
21156
- return facts.size.bytes;
21157
- }
21158
- function measureProjection(schema, io, projection) {
21159
- if (!projection)
21160
- return void 0;
21161
- const encoded = JSON.stringify(projection);
21162
- if (encoded.length > 2e4 || schemaDepth(projection, 0) > maximumSampleDepth) {
21163
- return void 0;
21164
- }
21165
- if (io === "output")
21166
- return encoded.length;
21167
- const sample = deriveSample(schema);
21168
- if (!sample)
21169
- return encoded.length;
21170
- if (Object.keys(sample).length > maximumSampleEntries || schemaDepth(sample, 0) > maximumSampleDepth) {
21171
- return void 0;
21172
- }
21173
- let sampleText;
21174
- try {
21175
- sampleText = JSON.stringify(sample);
21176
- } catch {
21177
- throw new ForageError("invalid_input", "Derived schema sample cannot be serialized");
21178
- }
21179
- if (!sampleText || sampleText.length > maximumSampleBytes)
21180
- return void 0;
21181
- return encoded.length + sampleText.length;
21182
- }
21183
21132
 
21184
21133
  // ../../packages/forage/dist/describe.js
21185
21134
  function boundedDescription(value) {
@@ -21196,16 +21145,19 @@ function describeCatalog(operations, rawInput) {
21196
21145
  const operation = operations.find((candidate) => candidate.path === rawInput.path);
21197
21146
  if (operation) {
21198
21147
  const callPath = `env.${operation.path}`;
21148
+ const inputSchema = jsonValueSchema.safeParse(rawSchema(operation.input, "input"));
21149
+ if (!inputSchema.success)
21150
+ throw new ForageError("invalid_input", "Schema cannot be projected to JSON Schema");
21199
21151
  const output = {
21200
21152
  path: operation.path,
21201
21153
  description: boundedDescription(operation.description),
21202
- types: renderOperationTypes([operation.rendered]),
21154
+ types: renderOperationTypes([renderOperation(operation)]),
21203
21155
  kind: "operation",
21204
- inputSchema: operation.inputSchema,
21156
+ inputSchema: inputSchema.data,
21205
21157
  usage: `await ${callPath}({ ... })`
21206
21158
  };
21207
21159
  if (output.types.length > maximumDescriptionTypes) {
21208
- throw new ForageError("invalid_input", "Description types exceed the bounded output");
21160
+ throw new ForageError("invalid_input", "Operation description exceeds the bounded output");
21209
21161
  }
21210
21162
  return checkedDescription(output);
21211
21163
  }
@@ -21221,11 +21173,11 @@ function describeCatalog(operations, rawInput) {
21221
21173
  const selected = rawInput.methods?.length ? namespaceOperations.filter((candidate) => rawInput.methods?.includes(candidate.path.slice(prefix.length))) : namespaceOperations;
21222
21174
  let types2;
21223
21175
  if (rawInput.detail === "index") {
21224
- types2 = renderNamespaceIndex(namespaceOperations.map((operation2) => operation2.rendered));
21176
+ types2 = renderNamespaceIndex(namespaceOperations.map(renderOperation));
21225
21177
  } else if (rawInput.methods?.length && selected.length === 0) {
21226
- types2 = renderNamespaceIndex(namespaceOperations.map((operation2) => operation2.rendered));
21178
+ types2 = renderNamespaceIndex(namespaceOperations.map(renderOperation));
21227
21179
  } else {
21228
- types2 = renderOperationTypes((selected.length > 0 ? selected : namespaceOperations).map((operation2) => operation2.rendered));
21180
+ types2 = renderOperationTypes((selected.length > 0 ? selected : namespaceOperations).map(renderOperation));
21229
21181
  }
21230
21182
  if (types2.length > maximumDescriptionTypes) {
21231
21183
  throw new ForageError("invalid_input", "Description types exceed the bounded output");
@@ -21240,12 +21192,14 @@ function describeCatalog(operations, rawInput) {
21240
21192
 
21241
21193
  // ../../packages/forage/dist/search.js
21242
21194
  function prepareOperation(operation) {
21195
+ const input = schemaText(operation.input, "input");
21196
+ const output = operation.output ? schemaText(operation.output, "output") : "";
21243
21197
  return Object.freeze({
21244
21198
  ...operation,
21245
- fingerprint: schemaFingerprint(operation.input),
21246
- inputSchema: inputSchemaProjection(operation.input),
21247
- sample: deriveSample(operation.input),
21248
- rendered: renderOperation(operation)
21199
+ fingerprint: hashString64(input + "\n" + output),
21200
+ inputBytes: input.length,
21201
+ outputBytes: output.length,
21202
+ sample: deriveSample(operation.input)
21249
21203
  });
21250
21204
  }
21251
21205
  var matchWeight = {
@@ -21257,28 +21211,25 @@ var matchWeight = {
21257
21211
  substring: 2,
21258
21212
  includes: 1
21259
21213
  };
21260
- function fieldWeight(field) {
21261
- switch (field) {
21262
- case "path":
21263
- return 12;
21264
- case "namespace":
21265
- return 8;
21266
- case "method":
21267
- return 10;
21268
- case "description":
21269
- return 5;
21270
- default:
21271
- return 5;
21272
- }
21273
- }
21214
+ var fieldWeight = {
21215
+ path: 12,
21216
+ namespace: 8,
21217
+ method: 10,
21218
+ description: 5
21219
+ };
21220
+ var fullCoverageBonus = 25;
21221
+ var partialCoverageBonus = 10;
21222
+ var firstTokenBonus = 8;
21223
+ var exactMatchBonus = 20;
21224
+ var maxBonus = Math.max(fullCoverageBonus, partialCoverageBonus) + firstTokenBonus + exactMatchBonus;
21225
+ var dominanceDivisor = 1 + Math.max(...Object.values(matchWeight)) * Math.max(...Object.values(fieldWeight)) + maxBonus;
21274
21226
  function catalogStamp(operations) {
21275
- const lines = [...operations].sort((left, right) => compareCodeUnits(left.path, right.path)).map((operation) => canonicalStringify([
21227
+ const lines = [...operations].sort((left, right) => compareCodeUnits(left.path, right.path)).map((operation) => JSON.stringify([
21276
21228
  operation.path,
21277
21229
  operation.description ?? null,
21278
21230
  operation.capabilityNotes ?? null,
21279
21231
  operation.instructions ?? null,
21280
- operation.fingerprint,
21281
- operation.output === void 0 ? null : schemaFingerprint(operation.output, "output")
21232
+ operation.fingerprint
21282
21233
  ]));
21283
21234
  return hashString64(lines.join("\n"));
21284
21235
  }
@@ -21305,7 +21256,7 @@ function scoreField(rawValue, field, queryTokens) {
21305
21256
  const value = normalizeQuery(rawValue);
21306
21257
  let bestLevel = "none";
21307
21258
  let bestScore = 0;
21308
- let matchedTokens = [];
21259
+ const matchedTokens = [];
21309
21260
  for (const token of queryTokens) {
21310
21261
  const terms = [token, ...stemVariants(token)];
21311
21262
  let selected = "none";
@@ -21318,13 +21269,12 @@ function scoreField(rawValue, field, queryTokens) {
21318
21269
  }
21319
21270
  if (selected === "none")
21320
21271
  continue;
21321
- const score = matchWeight[selected] * fieldWeight(field);
21272
+ const score = matchWeight[selected] * fieldWeight[field];
21273
+ if (!matchedTokens.includes(token))
21274
+ matchedTokens.push(token);
21322
21275
  if (score > bestScore) {
21323
21276
  bestLevel = selected;
21324
21277
  bestScore = score;
21325
- matchedTokens = [token];
21326
- } else if (score === bestScore && !matchedTokens.includes(token)) {
21327
- matchedTokens.push(token);
21328
21278
  }
21329
21279
  }
21330
21280
  return { level: bestLevel, score: bestScore, matchedTokens };
@@ -21367,7 +21317,7 @@ function emptyResult(stamp) {
21367
21317
  catalogStamp: stamp
21368
21318
  });
21369
21319
  }
21370
- function scoreCandidate(operation, normalizedQuery, queryTokens, coverageTokens, threshold) {
21320
+ function scoreCandidate(operation, queryTokens, coverageTokens) {
21371
21321
  const namespace = operationNamespace(operation.path);
21372
21322
  const method = operationMethod(operation.path);
21373
21323
  const description = operation.description ?? "";
@@ -21377,23 +21327,25 @@ function scoreCandidate(operation, normalizedQuery, queryTokens, coverageTokens,
21377
21327
  const methodScore = scoreField(method, "method", queryTokens);
21378
21328
  const descriptionScore = scoreField(description, "description", queryTokens);
21379
21329
  const matched = coverageTokens.filter((token) => fields.some((field) => tokenMatches(field, token))).length;
21380
- const coverage = matched / coverageTokens.length;
21381
- const phraseMatch = normalizeQuery(`${operation.path} ${description}`).includes(normalizedQuery);
21382
- if (coverage < threshold && !phraseMatch)
21330
+ if (matched === 0)
21383
21331
  return void 0;
21332
+ const coverage = matched / coverageTokens.length;
21384
21333
  const baseScore = Math.max(pathScore.score, namespaceScore.score, methodScore.score, descriptionScore.score);
21385
21334
  if (baseScore === 0)
21386
21335
  return void 0;
21387
- let bonus = matched === coverageTokens.length ? 25 : coverage * 10;
21336
+ let bonus = matched === coverageTokens.length ? fullCoverageBonus : coverage * partialCoverageBonus;
21388
21337
  const firstToken = coverageTokens[0];
21389
21338
  if (firstToken && fields.some((field) => tokenMatches(field, firstToken))) {
21390
- bonus += 8;
21339
+ bonus += firstTokenBonus;
21340
+ }
21341
+ if (pathScore.level === "exact" || methodScore.level === "exact") {
21342
+ bonus += exactMatchBonus;
21391
21343
  }
21392
- if (pathScore.level === "exact" || methodScore.level === "exact")
21393
- bonus += 20;
21394
21344
  const result2 = {
21395
21345
  path: operation.path,
21396
- score: baseScore + bonus
21346
+ // A whole matched word outranks any field-quality difference; the
21347
+ // derived divisor keeps all field and bonus evidence below one word.
21348
+ score: matched + (baseScore + bonus) / dominanceDivisor
21397
21349
  };
21398
21350
  if (description)
21399
21351
  result2.description = description;
@@ -21469,10 +21421,9 @@ function searchCatalog(operations, query, maxResults = 50, stamp) {
21469
21421
  const coverageTokens = queryTokens.filter((token) => !isStopword(token));
21470
21422
  if (coverageTokens.length === 0)
21471
21423
  return emptyResult(stamp);
21472
- const threshold = coverageTokens.length <= 2 ? 1 : 0.6;
21473
21424
  const candidates = [];
21474
21425
  for (const operation of operations) {
21475
- const candidate = scoreCandidate(operation, normalizedQuery, queryTokens, coverageTokens, threshold);
21426
+ const candidate = scoreCandidate(operation, queryTokens, coverageTokens);
21476
21427
  if (candidate)
21477
21428
  candidates.push(candidate);
21478
21429
  }
@@ -21521,6 +21472,23 @@ function listOperations(operations, catalogStamp2, rawInput) {
21521
21472
 
21522
21473
  // ../../packages/forage/dist/catalog.js
21523
21474
  var maximumCatalogProjectionBytes = 1e6;
21475
+ function schemaDepth(children, depth = 0) {
21476
+ if (depth >= maximumSampleDepth)
21477
+ return children.length === 0 ? depth : depth + 1;
21478
+ let maximum = depth;
21479
+ for (let index = children.length - 1; index >= 0; index -= 1) {
21480
+ const child = children[index];
21481
+ let childDepth = depth + 1;
21482
+ if (Array.isArray(child))
21483
+ childDepth = schemaDepth(child, childDepth);
21484
+ else if (external_exports.util.isObject(child))
21485
+ childDepth = schemaDepth(Object.values(child), childDepth);
21486
+ maximum = Math.max(maximum, childDepth);
21487
+ if (maximum > maximumSampleDepth)
21488
+ return maximum;
21489
+ }
21490
+ return maximum;
21491
+ }
21524
21492
  function parseCatalog(input) {
21525
21493
  const parsed = catalogInputSchema.safeParse(input);
21526
21494
  if (!parsed.success) {
@@ -21531,21 +21499,28 @@ function parseCatalog(input) {
21531
21499
  }
21532
21500
  const operations = [...parsed.data.operations].sort((left, right) => compareCodeUnits(left.path, right.path));
21533
21501
  const paths = /* @__PURE__ */ new Set();
21502
+ const preparedOperations = [];
21534
21503
  let projectionBytes = 0;
21535
21504
  for (const operation of operations) {
21536
21505
  if (paths.has(operation.path)) {
21537
21506
  throw new ForageError("duplicate_operation", `Duplicate operation path: ${operation.path}`);
21538
21507
  }
21539
21508
  paths.add(operation.path);
21540
- const inputProjection = schemaProjectionSize(operation.input, "input");
21541
- if (inputProjection === void 0) {
21509
+ const inputProjection = schemaText(operation.input, "input").length;
21510
+ if (inputProjection > maximumDescriptionTypes || schemaDepth(Object.values(rawSchema(operation.input, "input"))) > maximumSampleDepth) {
21542
21511
  throw new ForageError("invalid_input", `Schema projection is too large: ${operation.path}`);
21543
21512
  }
21544
- const outputProjection = operation.output ? schemaProjectionSize(operation.output, "output") : 0;
21545
- if (outputProjection === void 0) {
21513
+ const outputProjection = operation.output ? schemaText(operation.output, "output").length : 0;
21514
+ if (outputProjection > maximumDescriptionTypes || operation.output !== void 0 && schemaDepth(Object.values(rawSchema(operation.output, "output"))) > maximumSampleDepth) {
21546
21515
  throw new ForageError("invalid_input", `Schema output projection is too large: ${operation.path}`);
21547
21516
  }
21548
- projectionBytes += inputProjection + outputProjection + operation.path.length;
21517
+ const prepared = prepareOperation(operation);
21518
+ const sample = prepared.sample;
21519
+ const sampleBytes = sample === void 0 ? 0 : JSON.stringify(sample).length;
21520
+ if (sample !== void 0 && (Object.keys(sample).length > maximumSampleEntries || sampleBytes > maximumSampleBytes || jsonDepth(sample, 0) > maximumSampleDepth))
21521
+ throw new ForageError("invalid_input", `Schema projection is too large: ${operation.path}`);
21522
+ preparedOperations.push(prepared);
21523
+ projectionBytes += prepared.inputBytes + prepared.outputBytes + sampleBytes + operation.path.length;
21549
21524
  projectionBytes += operation.description?.length ?? 0;
21550
21525
  projectionBytes += operation.capabilityNotes?.length ?? 0;
21551
21526
  projectionBytes += operation.instructions?.length ?? 0;
@@ -21553,12 +21528,6 @@ function parseCatalog(input) {
21553
21528
  throw new ForageError("invalid_input", "Catalog metadata exceeds the bounded projection");
21554
21529
  }
21555
21530
  }
21556
- const preparedOperations = operations.map((operation) => prepareOperation(operation));
21557
- for (const operation of preparedOperations) {
21558
- if (renderOperationTypes([operation.rendered]).length > maximumDescriptionTypes) {
21559
- throw new ForageError("invalid_input", `Operation description exceeds the bounded output: ${operation.path}`);
21560
- }
21561
- }
21562
21531
  return {
21563
21532
  revision: parsed.data.revision,
21564
21533
  operations: preparedOperations
@@ -21609,7 +21578,8 @@ function createCatalog(input) {
21609
21578
 
21610
21579
  // ../../packages/forage/dist/app-api.js
21611
21580
  var bindingName = external_exports.lazy(() => external_exports.string().min(1).max(75).regex(/^[A-Za-z][A-Za-z0-9_]*$/));
21612
- var jsonSchema = external_exports.lazy(() => external_exports.union([external_exports.record(external_exports.string(), external_exports.json()), external_exports.boolean()]));
21581
+ var jsonSchemaDocument = external_exports.lazy(() => external_exports.record(external_exports.string(), external_exports.json()));
21582
+ var jsonSchema = external_exports.lazy(() => external_exports.union([jsonSchemaDocument, external_exports.boolean()]));
21613
21583
  var familyRow = external_exports.lazy(() => external_exports.object({
21614
21584
  tool: bindingName,
21615
21585
  title: external_exports.string().max(120),