@fulmenhq/tsfulmen 0.2.0 → 0.2.3

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 (111) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +61 -7
  3. package/config/crucible-ts/agentic/roles/README.md +3 -3
  4. package/config/crucible-ts/library/fulencode/fixtures/README.md +18 -0
  5. package/config/crucible-ts/library/fulencode/fixtures/bom/bom.yaml +14 -0
  6. package/config/crucible-ts/library/fulencode/fixtures/detection/detection.yaml +12 -0
  7. package/config/crucible-ts/library/fulencode/fixtures/invalid-encodings/base64.yaml +10 -0
  8. package/config/crucible-ts/library/fulencode/fixtures/normalization/text-safe.yaml +10 -0
  9. package/config/crucible-ts/library/fulencode/fixtures/telemetry/telemetry-test-cases.yaml +24 -0
  10. package/config/crucible-ts/library/fulencode/fixtures/valid-encodings/base64.yaml +11 -0
  11. package/config/crucible-ts/taxonomy/library/platform-modules/v1.0.0/modules.yaml +2 -2
  12. package/config/crucible-ts/taxonomy/metrics.yaml +79 -1
  13. package/dist/appidentity/index.d.ts +31 -109
  14. package/dist/appidentity/index.js +369 -60
  15. package/dist/appidentity/index.js.map +1 -1
  16. package/dist/config/index.d.ts +46 -1
  17. package/dist/config/index.js +427 -62
  18. package/dist/config/index.js.map +1 -1
  19. package/dist/crucible/index.js +367 -59
  20. package/dist/crucible/index.js.map +1 -1
  21. package/dist/errors/index.d.ts +1 -1
  22. package/dist/errors/index.js +367 -59
  23. package/dist/errors/index.js.map +1 -1
  24. package/dist/foundry/index.d.ts +2 -1
  25. package/dist/foundry/index.js +368 -60
  26. package/dist/foundry/index.js.map +1 -1
  27. package/dist/fulencode/index.d.ts +102 -0
  28. package/dist/fulencode/index.js +806 -0
  29. package/dist/fulencode/index.js.map +1 -0
  30. package/dist/index.d.ts +4 -3
  31. package/dist/index.js +370 -61
  32. package/dist/index.js.map +1 -1
  33. package/dist/pathfinder/index.d.ts +1 -1
  34. package/dist/pathfinder/index.js +367 -59
  35. package/dist/pathfinder/index.js.map +1 -1
  36. package/dist/reports/license-inventory.csv +31 -24
  37. package/dist/schema/index.d.ts +16 -3
  38. package/dist/schema/index.js +368 -60
  39. package/dist/schema/index.js.map +1 -1
  40. package/dist/signals/index.d.ts +483 -395
  41. package/dist/signals/index.js +368 -60
  42. package/dist/signals/index.js.map +1 -1
  43. package/dist/telemetry/http/index.js +368 -59
  44. package/dist/telemetry/http/index.js.map +1 -1
  45. package/dist/telemetry/index.d.ts +1 -1
  46. package/dist/telemetry/index.js +367 -59
  47. package/dist/telemetry/index.js.map +1 -1
  48. package/dist/telemetry/prometheus/index.d.ts +1 -1
  49. package/dist/telemetry/prometheus/index.js +369 -59
  50. package/dist/telemetry/prometheus/index.js.map +1 -1
  51. package/dist/{types-BJswWpQC.d.ts → types-DdoeE7F5.d.ts} +1 -1
  52. package/dist/types-Dv5TERCM.d.ts +108 -0
  53. package/package.json +13 -8
  54. package/schemas/crucible-ts/library/fulencode/v1.0.0/README.md +37 -0
  55. package/schemas/crucible-ts/library/fulencode/v1.0.0/bom-result.schema.json +48 -0
  56. package/schemas/crucible-ts/library/fulencode/v1.0.0/decode-options.schema.json +60 -0
  57. package/schemas/crucible-ts/library/fulencode/v1.0.0/decoding-result.schema.json +70 -0
  58. package/schemas/crucible-ts/library/fulencode/v1.0.0/detect-options.schema.json +25 -0
  59. package/schemas/crucible-ts/library/fulencode/v1.0.0/detection-result.schema.json +57 -0
  60. package/schemas/crucible-ts/library/fulencode/v1.0.0/encode-options.schema.json +71 -0
  61. package/schemas/crucible-ts/library/fulencode/v1.0.0/encoding-result.schema.json +57 -0
  62. package/schemas/crucible-ts/library/fulencode/v1.0.0/fulencode-config.schema.json +8 -4
  63. package/schemas/crucible-ts/library/fulencode/v1.0.0/fulencode-error.schema.json +66 -0
  64. package/schemas/crucible-ts/library/fulencode/v1.0.0/normalization-result.schema.json +73 -0
  65. package/schemas/crucible-ts/library/fulencode/v1.0.0/normalize-options.schema.json +44 -0
  66. package/schemas/crucible-ts/meta/README.md +38 -2
  67. package/schemas/crucible-ts/meta/draft-04/schema.json +222 -0
  68. package/schemas/crucible-ts/meta/draft-06/schema.json +218 -0
  69. package/schemas/crucible-ts/meta/draft-2019-09/meta/applicator.json +93 -0
  70. package/schemas/crucible-ts/meta/draft-2019-09/meta/content.json +21 -0
  71. package/schemas/crucible-ts/meta/draft-2019-09/meta/core.json +58 -0
  72. package/schemas/crucible-ts/meta/draft-2019-09/meta/format.json +15 -0
  73. package/schemas/crucible-ts/meta/draft-2019-09/meta/meta-data.json +35 -0
  74. package/schemas/crucible-ts/meta/draft-2019-09/meta/validation.json +119 -0
  75. package/schemas/crucible-ts/meta/draft-2019-09/offline.schema.json +148 -0
  76. package/schemas/crucible-ts/meta/draft-2019-09/schema.json +62 -0
  77. package/schemas/crucible-ts/meta/fixtures/draft-04-sample.json +16 -0
  78. package/schemas/crucible-ts/meta/fixtures/draft-06-sample.json +16 -0
  79. package/schemas/crucible-ts/meta/fixtures/draft-07-sample.json +34 -0
  80. package/schemas/crucible-ts/meta/fixtures/draft-2019-09-sample.json +21 -0
  81. package/schemas/crucible-ts/meta/fixtures/draft-2020-12-sample.json +21 -0
  82. package/schemas/crucible-ts/taxonomy/library/fulencode/normalization-profiles/v1.0.0/profiles.yaml +16 -0
  83. package/schemas/crucible-ts/upstream/3leaps/crucible/PROVENANCE.md +64 -0
  84. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/access-tier.dimension.json +103 -0
  85. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/retention-lifecycle.dimension.json +103 -0
  86. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/schema-stability.dimension.json +100 -0
  87. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/sensitivity.dimension.json +130 -0
  88. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/velocity-mode.dimension.json +79 -0
  89. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/volatility.dimension.json +72 -0
  90. package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/volume-tier.dimension.json +66 -0
  91. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/catalog/classifiers/README.md +29 -0
  92. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/access-tier-classification.md +163 -0
  93. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/classifiers-framework.md +157 -0
  94. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/data-sensitivity-classification.md +259 -0
  95. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/retention-lifecycle-classification.md +200 -0
  96. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/schema-stability-classification.md +205 -0
  97. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/velocity-mode-classification.md +222 -0
  98. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/volatility-classification.md +209 -0
  99. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/volume-tier-classification.md +200 -0
  100. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/ailink/v0/README.md +48 -0
  101. package/schemas/crucible-ts/upstream/3leaps/{ailink → crucible/schemas/ailink}/v0/prompt.schema.json +4 -18
  102. package/schemas/crucible-ts/upstream/3leaps/{ailink → crucible/schemas/ailink}/v0/search-response.schema.json +7 -37
  103. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/classifiers/v0/dimension-definition.schema.json +247 -0
  104. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/classifiers/v0/sensitivity-level.schema.json +67 -0
  105. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/error-response.schema.json +59 -0
  106. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/lifecycle-phases.data.json +102 -0
  107. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/lifecycle-phases.schema.json +101 -0
  108. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/release-phase.schema.json +18 -0
  109. package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/types.schema.json +177 -0
  110. package/schemas/crucible-ts/upstream/3leaps/PROVENANCE.md +0 -43
  111. /package/schemas/crucible-ts/upstream/3leaps/{agentic → crucible/schemas/agentic}/v0/role-prompt.schema.json +0 -0
@@ -1,7 +1,8 @@
1
1
  export { F as FoundryCatalogError, N as NormalizeOptions, a as SuggestOptions, S as Suggestion, c as casefold, d as distance, e as equalsIgnoreCase, n as normalize, s as score, b as stripAccents, f as suggest } from '../suggest-D8LbwtPV.js';
2
2
  import { Readable } from 'node:stream';
3
- export { AuthHook, AuthResult, ConfigLoader, ConfigReloadOptions, ConfigReloadResult, ConfigReloadTracker, ConfigValidationResult, ConfigValidator, DoubleTapConfig, DoubleTapState, GuardOptions, Platform, RateLimitHook, RateLimitResult, SignalEndpointOptions, SignalErrorResponse, PlatformCapabilities as SignalPlatformCapabilities, SignalRequest, SignalResponse, createBearerTokenAuth, createConfigReloadHandler, createDoubleTapTracker, createSignalEndpoint, createSimpleRateLimiter, ensurePOSIX, ensureSignalExitCodesSupported, ensureSupported, ensureWindows, getBehavior, getSignal, getSignalCatalog, getSignalNumber, getPlatformCapabilities as getSignalPlatformCapabilities, getSignalsVersion, getWindowTimeRemaining, getWindowsEvent, handleDoubleTap, isPOSIX as isSignalPOSIX, isWindows as isSignalWindows, isWithinWindow, listBehaviors, listSignals, onAnyShutdown, onEmergencyQuit, onReload, onShutdown, onUSR1, onUSR2, resetDoubleTap, supportsSignal, supportsSignalExitCodes as supportsSignalBasedExitCodes } from '../signals/index.js';
3
+ export { AuthHook, AuthResult, ConfigLoader, ConfigReloadEndpointOptions, ConfigReloadErrorResponse, ConfigReloadOptions, ConfigReloadRequest, ConfigReloadResponse, ConfigReloadResult, ConfigReloadTracker, ConfigValidationResult, ConfigValidator, ControlDiscoveryEndpointOptions, ControlDiscoveryErrorResponse, ControlDiscoveryResponse, ControlEndpointDescriptor, DoubleTapConfig, DoubleTapState, GuardOptions, Platform, RateLimitHook, RateLimitResult, SignalEndpointOptions, SignalErrorResponse, PlatformCapabilities as SignalPlatformCapabilities, SignalRequest, SignalResponse, createBearerTokenAuth, createConfigReloadEndpoint, createConfigReloadHandler, createControlDiscoveryEndpoint, createDoubleTapTracker, createSignalEndpoint, createSimpleRateLimiter, ensurePOSIX, ensureSignalExitCodesSupported, ensureSupported, ensureWindows, getBehavior, getSignal, getSignalCatalog, getSignalNumber, getPlatformCapabilities as getSignalPlatformCapabilities, getSignalsVersion, getWindowTimeRemaining, getWindowsEvent, handleDoubleTap, isPOSIX as isSignalPOSIX, isWindows as isSignalWindows, isWithinWindow, listBehaviors, listSignals, onAnyShutdown, onEmergencyQuit, onReload, onShutdown, onUSR1, onUSR2, resetDoubleTap, supportsSignal, supportsSignalExitCodes as supportsSignalBasedExitCodes } from '../signals/index.js';
4
4
  export { B as Behavior, a as BehaviorInfo, b as BehaviorPhase, E as ExitCodes, F as FallbackLogger, H as HandlerOptions, L as LogLevel, O as OsMappings, P as PlatformOverrides, e as PlatformSupport, f as PlatformSupportLevel, i as Signal, j as SignalBehavior, k as SignalCatalog, l as SignalHandler, m as SignalInfo, S as SignalManager, n as SignalManagerOptions, T as TelemetryEmitter, o as TimeoutBehavior, W as WindowsFallback, p as WindowsFallbackBehavior, q as WindowsFallbackOptions, s as WindowsFallbackResult, c as createSignalManager, g as getFallbackMetadata, d as getHttpFallbackGuidance, h as handleWindowsFallback, r as requiresFallback } from '../manager-CH3fX7zO.js';
5
+ import '../types-Dv5TERCM.js';
5
6
 
6
7
  /**
7
8
  * Foundry module - TypeScript type definitions
@@ -1,13 +1,16 @@
1
1
  import { access, readFile, mkdir, writeFile } from 'fs/promises';
2
2
  import { dirname, extname, join, relative } from 'path';
3
3
  import { parse, stringify } from 'yaml';
4
+ import addFormats from 'ajv-formats';
4
5
  import { spawn } from 'child_process';
5
6
  import { fileURLToPath } from 'url';
6
7
  import glob from 'fast-glob';
7
8
  import 'crypto';
8
9
  import { Command } from 'commander';
9
10
  import Ajv from 'ajv';
10
- import addFormats from 'ajv-formats';
11
+ import Ajv2019 from 'ajv/dist/2019';
12
+ import Ajv2020 from 'ajv/dist/2020';
13
+ import AjvDraft04 from 'ajv-draft-04';
11
14
  import { Readable } from 'stream';
12
15
  import picomatch from 'picomatch';
13
16
  import { substringSimilarity, jaro_winkler, damerau_levenshtein, osa_distance, levenshtein, normalize as normalize$1, score as score$1, suggest as suggest$1 } from '@3leaps/string-metrics-wasm';
@@ -726,6 +729,27 @@ var init_types = __esm({
726
729
  "src/telemetry/types.ts"() {
727
730
  }
728
731
  });
732
+ function applyFulmenAjvFormats(ajv, options = {}) {
733
+ const mode = options.mode ?? "fast";
734
+ const formats = options.formats ?? DEFAULT_FORMATS;
735
+ addFormats(ajv, { mode, formats });
736
+ return ajv;
737
+ }
738
+ var DEFAULT_FORMATS;
739
+ var init_ajv_formats = __esm({
740
+ "src/schema/ajv-formats.ts"() {
741
+ DEFAULT_FORMATS = [
742
+ "date-time",
743
+ "email",
744
+ "hostname",
745
+ "ipv4",
746
+ "ipv6",
747
+ "uri",
748
+ "uri-reference",
749
+ "uuid"
750
+ ];
751
+ }
752
+ });
729
753
 
730
754
  // src/schema/errors.ts
731
755
  var errors_exports = {};
@@ -2551,6 +2575,7 @@ var init_cli = __esm({
2551
2575
  // src/schema/index.ts
2552
2576
  var init_schema = __esm({
2553
2577
  "src/schema/index.ts"() {
2578
+ init_ajv_formats();
2554
2579
  init_cli();
2555
2580
  init_errors();
2556
2581
  init_export();
@@ -2614,20 +2639,14 @@ async function loadMetaSchema(draft) {
2614
2639
  const content = await readFile(metaSchemaPath, "utf-8");
2615
2640
  return JSON.parse(content);
2616
2641
  }
2617
- async function loadVocabularySchemas() {
2642
+ async function loadVocabularySchemas(draft) {
2643
+ if (draft !== "draft-2019-09" && draft !== "draft-2020-12") {
2644
+ return [];
2645
+ }
2618
2646
  const __filename3 = fileURLToPath(import.meta.url);
2619
2647
  const __dirname4 = dirname(__filename3);
2620
- const vocabDir = join(
2621
- __dirname4,
2622
- "..",
2623
- "..",
2624
- "schemas",
2625
- "crucible-ts",
2626
- "meta",
2627
- "draft-2020-12",
2628
- "meta"
2629
- );
2630
- const vocabFiles = [
2648
+ const vocabDir = join(__dirname4, "..", "..", "schemas", "crucible-ts", "meta", draft, "meta");
2649
+ const vocabFiles = draft === "draft-2020-12" ? [
2631
2650
  "core.json",
2632
2651
  "applicator.json",
2633
2652
  "unevaluated.json",
@@ -2635,6 +2654,13 @@ async function loadVocabularySchemas() {
2635
2654
  "meta-data.json",
2636
2655
  "format-annotation.json",
2637
2656
  "content.json"
2657
+ ] : [
2658
+ "core.json",
2659
+ "applicator.json",
2660
+ "validation.json",
2661
+ "meta-data.json",
2662
+ "format.json",
2663
+ "content.json"
2638
2664
  ];
2639
2665
  const schemas = [];
2640
2666
  for (const file of vocabFiles) {
@@ -2689,47 +2715,65 @@ async function loadReferencedSchema(uri) {
2689
2715
  }
2690
2716
  return JSON.parse(content);
2691
2717
  }
2692
- function getAjv() {
2693
- if (!ajvInstance) {
2694
- ajvInstance = new Ajv({
2695
- strict: false,
2696
- allErrors: true,
2697
- verbose: true,
2698
- // Allow schemas with $id to be added without replacing existing ones
2699
- addUsedSchema: false,
2700
- // Enable async schema loading for YAML references
2701
- loadSchema: loadReferencedSchema
2702
- });
2703
- addFormats(ajvInstance, {
2704
- mode: "fast",
2705
- formats: ["date-time", "email", "hostname", "ipv4", "ipv6", "uri", "uri-reference"]
2706
- });
2707
- metaschemaReady = Promise.all([loadVocabularySchemas(), loadMetaSchema("draft-2020-12")]).then(([vocabSchemas, metaSchema]) => {
2708
- if (ajvInstance) {
2709
- for (const vocabSchema of vocabSchemas) {
2710
- try {
2711
- ajvInstance.addMetaSchema(vocabSchema);
2712
- } catch {
2713
- }
2714
- }
2715
- ajvInstance.addMetaSchema(metaSchema);
2716
- }
2717
- }).catch((error) => {
2718
- throw new Error(`Failed to load metaschemas: ${error}`);
2719
- });
2718
+ function detectDialect(schema) {
2719
+ if (schema && typeof schema === "object" && !Array.isArray(schema)) {
2720
+ const maybeSchema = schema;
2721
+ const declared = maybeSchema.$schema;
2722
+ if (typeof declared === "string") {
2723
+ if (declared.includes("draft-04")) return "draft-04";
2724
+ if (declared.includes("draft-06")) return "draft-06";
2725
+ if (declared.includes("draft-07")) return "draft-07";
2726
+ if (declared.includes("draft/2019-09")) return "draft-2019-09";
2727
+ if (declared.includes("draft/2020-12")) return "draft-2020-12";
2728
+ }
2720
2729
  }
2721
- return ajvInstance;
2730
+ return "draft-2020-12";
2731
+ }
2732
+ function createAjv(dialect) {
2733
+ const AjvCtor = dialect === "draft-2020-12" ? Ajv2020 : dialect === "draft-2019-09" ? Ajv2019 : dialect === "draft-04" ? AjvDraft04 : Ajv;
2734
+ const ajv = new AjvCtor({
2735
+ strict: false,
2736
+ allErrors: true,
2737
+ verbose: true,
2738
+ // Allow schemas with $id to be added without replacing existing ones
2739
+ addUsedSchema: false,
2740
+ // draft-04 uses "id"; later drafts use "$id"
2741
+ schemaId: dialect === "draft-04" ? "id" : "$id",
2742
+ // Enable async schema loading for YAML references
2743
+ loadSchema: loadReferencedSchema
2744
+ });
2745
+ applyFulmenAjvFormats(ajv);
2746
+ return ajv;
2747
+ }
2748
+ async function getAjv(dialect) {
2749
+ const existing = ajvInstances.get(dialect);
2750
+ if (existing) {
2751
+ const ready = metaschemaReady.get(dialect);
2752
+ if (ready) await ready;
2753
+ return existing;
2754
+ }
2755
+ const ajv = createAjv(dialect);
2756
+ ajvInstances.set(dialect, ajv);
2757
+ const readyPromise = Promise.all([loadVocabularySchemas(dialect), loadMetaSchema(dialect)]).then(([vocabSchemas, metaSchema]) => {
2758
+ for (const vocabSchema of vocabSchemas) {
2759
+ try {
2760
+ ajv.addMetaSchema(vocabSchema);
2761
+ } catch {
2762
+ }
2763
+ }
2764
+ try {
2765
+ ajv.addMetaSchema(metaSchema);
2766
+ } catch {
2767
+ }
2768
+ }).catch((error) => {
2769
+ throw new Error(`Failed to load metaschemas (${dialect}): ${error}`);
2770
+ });
2771
+ metaschemaReady.set(dialect, readyPromise);
2772
+ await readyPromise;
2773
+ return ajv;
2722
2774
  }
2723
2775
  async function compileSchema(schema, options = {}) {
2724
- const ajv = getAjv();
2725
- if (metaschemaReady) {
2726
- await metaschemaReady;
2727
- }
2728
- const cacheKey = typeof schema === "string" ? schema : JSON.stringify(schema);
2729
- const cached = schemaCache.get(cacheKey);
2730
- if (cached !== void 0) {
2731
- return cached;
2732
- }
2776
+ const baseKey = typeof schema === "string" ? schema : JSON.stringify(schema);
2733
2777
  let parsedSchema;
2734
2778
  if (typeof schema === "string") {
2735
2779
  try {
@@ -2747,18 +2791,27 @@ async function compileSchema(schema, options = {}) {
2747
2791
  } else {
2748
2792
  parsedSchema = schema;
2749
2793
  }
2794
+ const dialect = detectDialect(parsedSchema);
2795
+ const ajv = await getAjv(dialect);
2796
+ const cacheKey = `${dialect}:${baseKey}`;
2797
+ const cached = schemaCache.get(cacheKey);
2798
+ if (cached !== void 0) {
2799
+ return cached;
2800
+ }
2750
2801
  try {
2751
2802
  if (options.aliases && options.aliases.length > 0) {
2752
2803
  for (const alias of options.aliases) {
2753
2804
  if (alias && ajv.getSchema(alias) === void 0) {
2754
2805
  try {
2755
- ajv.addSchema(parsedSchema, alias);
2806
+ if (typeof parsedSchema === "object" && parsedSchema !== null) {
2807
+ ajv.addSchema(parsedSchema, alias);
2808
+ }
2756
2809
  } catch {
2757
2810
  }
2758
2811
  }
2759
2812
  }
2760
2813
  }
2761
- const validator = await ajv.compileAsync(parsedSchema);
2814
+ const validator = typeof parsedSchema === "boolean" ? ajv.compile(parsedSchema) : await ajv.compileAsync(parsedSchema);
2762
2815
  schemaCache.set(cacheKey, validator);
2763
2816
  return validator;
2764
2817
  } catch (error) {
@@ -2828,8 +2881,39 @@ async function validateFile(filePath, validator) {
2828
2881
  }
2829
2882
  async function validateSchema(schema) {
2830
2883
  try {
2831
- const validator = await compileSchema(schema);
2832
- validateData({}, validator);
2884
+ let parsedSchema;
2885
+ if (typeof schema === "string") {
2886
+ try {
2887
+ parsedSchema = JSON.parse(schema);
2888
+ } catch {
2889
+ parsedSchema = parse(schema);
2890
+ }
2891
+ } else if (Buffer.isBuffer(schema)) {
2892
+ const content = schema.toString("utf-8");
2893
+ try {
2894
+ parsedSchema = JSON.parse(content);
2895
+ } catch {
2896
+ parsedSchema = parse(content);
2897
+ }
2898
+ } else {
2899
+ parsedSchema = schema;
2900
+ }
2901
+ const dialect = detectDialect(parsedSchema);
2902
+ const ajv = await getAjv(dialect);
2903
+ const metaValid = ajv.validateSchema(parsedSchema);
2904
+ if (!metaValid && ajv.errors) {
2905
+ const diagnostics = ajv.errors.map(
2906
+ (error) => createDiagnostic(
2907
+ error.instancePath || "",
2908
+ error.message || "Schema meta-validation failed",
2909
+ error.keyword || "unknown",
2910
+ "ERROR",
2911
+ "ajv"
2912
+ )
2913
+ );
2914
+ return { valid: false, diagnostics, source: "ajv" };
2915
+ }
2916
+ await compileSchema(parsedSchema);
2833
2917
  return {
2834
2918
  valid: true,
2835
2919
  diagnostics: [],
@@ -2900,14 +2984,16 @@ async function validateFileBySchemaId(filePath, schemaId, registryOptions) {
2900
2984
  throw error;
2901
2985
  }
2902
2986
  }
2903
- var ajvInstance, metaschemaReady, schemaCache;
2987
+ var ajvInstances, metaschemaReady, schemaCache;
2904
2988
  var init_validator = __esm({
2905
2989
  "src/schema/validator.ts"() {
2906
2990
  init_telemetry();
2991
+ init_ajv_formats();
2907
2992
  init_errors();
2908
2993
  init_registry2();
2909
2994
  init_utils();
2910
- metaschemaReady = null;
2995
+ ajvInstances = /* @__PURE__ */ new Map();
2996
+ metaschemaReady = /* @__PURE__ */ new Map();
2911
2997
  schemaCache = /* @__PURE__ */ new Map();
2912
2998
  }
2913
2999
  });
@@ -4687,6 +4773,224 @@ var init_capabilities2 = __esm({
4687
4773
  }
4688
4774
  });
4689
4775
 
4776
+ // src/foundry/signals/config-reload-endpoint.ts
4777
+ function createConfigReloadEndpoint(options) {
4778
+ const { loader, validator, onReload: onReload2, auth, rateLimit, logger, telemetry } = options;
4779
+ return async (payload, req) => {
4780
+ const correlationId = payload.correlation_id ?? generateCorrelationId2();
4781
+ const authResult = await auth(req);
4782
+ if (!authResult.authenticated) {
4783
+ if (logger) {
4784
+ logger.warn("Config reload endpoint: authentication failed", {
4785
+ correlation_id: correlationId,
4786
+ reason: authResult.reason
4787
+ });
4788
+ }
4789
+ if (telemetry) {
4790
+ telemetry.emit("fulmen.config.http_endpoint.auth_failed", {
4791
+ correlation_id: correlationId
4792
+ });
4793
+ }
4794
+ return {
4795
+ status: "error",
4796
+ error: "authentication_failed",
4797
+ message: authResult.reason || "Authentication required",
4798
+ statusCode: 401
4799
+ };
4800
+ }
4801
+ const identity = authResult.identity || "unknown";
4802
+ if (rateLimit) {
4803
+ const rateLimitResult = await rateLimit(identity);
4804
+ if (!rateLimitResult.allowed) {
4805
+ if (logger) {
4806
+ logger.warn("Config reload endpoint: rate limit exceeded", {
4807
+ correlation_id: correlationId,
4808
+ identity
4809
+ });
4810
+ }
4811
+ if (telemetry) {
4812
+ telemetry.emit("fulmen.config.http_endpoint.rate_limited", {
4813
+ correlation_id: correlationId
4814
+ });
4815
+ }
4816
+ return {
4817
+ status: "error",
4818
+ error: "rate_limit_exceeded",
4819
+ message: "Rate limit exceeded. Please try again later.",
4820
+ statusCode: 429
4821
+ };
4822
+ }
4823
+ }
4824
+ if (telemetry) {
4825
+ telemetry.emit("fulmen.config.http_endpoint.reload_requested", {
4826
+ correlation_id: correlationId
4827
+ });
4828
+ }
4829
+ try {
4830
+ const config = await loader();
4831
+ if (validator) {
4832
+ const validation = await validator(config);
4833
+ if (!validation.valid) {
4834
+ if (logger) {
4835
+ logger.warn("Config reload endpoint: validation failed", {
4836
+ correlation_id: correlationId,
4837
+ error_count: validation.errors?.length ?? 0
4838
+ });
4839
+ }
4840
+ if (telemetry) {
4841
+ telemetry.emit("fulmen.config.http_endpoint.reload_rejected", {
4842
+ correlation_id: correlationId,
4843
+ reason: "validation_failed"
4844
+ });
4845
+ }
4846
+ return {
4847
+ status: "error",
4848
+ error: "validation_failed",
4849
+ message: "Configuration validation failed",
4850
+ validation_errors: validation.errors,
4851
+ statusCode: 422
4852
+ };
4853
+ }
4854
+ }
4855
+ if (onReload2) {
4856
+ await onReload2(config);
4857
+ }
4858
+ if (telemetry) {
4859
+ telemetry.emit("fulmen.config.http_endpoint.reload_accepted", {
4860
+ correlation_id: correlationId
4861
+ });
4862
+ }
4863
+ if (logger) {
4864
+ logger.info("Config reload endpoint: reload accepted", {
4865
+ correlation_id: correlationId,
4866
+ reason: payload.reason
4867
+ });
4868
+ }
4869
+ return {
4870
+ status: "reloaded",
4871
+ correlation_id: correlationId,
4872
+ message: "Configuration reloaded",
4873
+ statusCode: 200
4874
+ };
4875
+ } catch (error) {
4876
+ if (logger) {
4877
+ logger.warn("Config reload endpoint: reload failed", {
4878
+ correlation_id: correlationId,
4879
+ error: error instanceof Error ? error.message : String(error)
4880
+ });
4881
+ }
4882
+ if (telemetry) {
4883
+ telemetry.emit("fulmen.config.http_endpoint.reload_error", {
4884
+ correlation_id: correlationId,
4885
+ error_type: error instanceof Error ? error.constructor.name : "unknown"
4886
+ });
4887
+ }
4888
+ return {
4889
+ status: "error",
4890
+ error: "reload_failed",
4891
+ message: error instanceof Error ? error.message : String(error),
4892
+ statusCode: 500
4893
+ };
4894
+ }
4895
+ };
4896
+ }
4897
+ function generateCorrelationId2() {
4898
+ return `cfg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
4899
+ }
4900
+ var init_config_reload_endpoint = __esm({
4901
+ "src/foundry/signals/config-reload-endpoint.ts"() {
4902
+ }
4903
+ });
4904
+
4905
+ // src/appidentity/runtime.ts
4906
+ function detectRuntime() {
4907
+ const versions = process.versions;
4908
+ if (typeof versions.bun === "string" && versions.bun.length > 0) {
4909
+ return { name: "bun", version: versions.bun };
4910
+ }
4911
+ if (typeof versions.node === "string" && versions.node.length > 0) {
4912
+ return { name: "node", version: versions.node };
4913
+ }
4914
+ return { name: "unknown" };
4915
+ }
4916
+ function buildRuntimeInfo(options = {}) {
4917
+ const runtime = detectRuntime();
4918
+ const serviceName = options.serviceName ?? options.identity?.app.binary_name ?? "unknown-service";
4919
+ const vendor = options.vendor ?? options.identity?.app.vendor;
4920
+ return {
4921
+ service: {
4922
+ name: serviceName,
4923
+ vendor,
4924
+ version: options.version
4925
+ },
4926
+ runtime,
4927
+ platform: {
4928
+ os: process.platform,
4929
+ arch: process.arch
4930
+ }
4931
+ };
4932
+ }
4933
+ var init_runtime = __esm({
4934
+ "src/appidentity/runtime.ts"() {
4935
+ }
4936
+ });
4937
+
4938
+ // src/foundry/signals/control-discovery-endpoint.ts
4939
+ function createControlDiscoveryEndpoint(options) {
4940
+ const { identity, version, endpoints, auth, authSummary, logger, telemetry } = options;
4941
+ return async (req) => {
4942
+ if (auth) {
4943
+ const authResult = await auth(req);
4944
+ if (!authResult.authenticated) {
4945
+ if (logger) {
4946
+ logger.warn("Control discovery endpoint: authentication failed", {
4947
+ reason: authResult.reason
4948
+ });
4949
+ }
4950
+ if (telemetry) {
4951
+ telemetry.emit("fulmen.control.discovery.auth_failed", {
4952
+ service: identity.app.binary_name
4953
+ });
4954
+ }
4955
+ return {
4956
+ status: "error",
4957
+ error: "authentication_failed",
4958
+ message: authResult.reason || "Authentication required",
4959
+ statusCode: 401
4960
+ };
4961
+ }
4962
+ }
4963
+ if (telemetry) {
4964
+ telemetry.emit("fulmen.control.discovery.served", {
4965
+ service: identity.app.binary_name
4966
+ });
4967
+ }
4968
+ const runtime = buildRuntimeInfo({ identity, version });
4969
+ return {
4970
+ status: "ok",
4971
+ service: {
4972
+ name: identity.app.binary_name,
4973
+ vendor: identity.app.vendor,
4974
+ version
4975
+ },
4976
+ runtime: {
4977
+ name: runtime.runtime.name,
4978
+ version: runtime.runtime.version,
4979
+ platform: runtime.platform.os,
4980
+ arch: runtime.platform.arch
4981
+ },
4982
+ auth_summary: authSummary,
4983
+ endpoints,
4984
+ statusCode: 200
4985
+ };
4986
+ };
4987
+ }
4988
+ var init_control_discovery_endpoint = __esm({
4989
+ "src/foundry/signals/control-discovery-endpoint.ts"() {
4990
+ init_runtime();
4991
+ }
4992
+ });
4993
+
4690
4994
  // src/foundry/signals/convenience.ts
4691
4995
  async function onShutdown(manager, handler, options = {}) {
4692
4996
  await manager.register("SIGTERM", handler, options);
@@ -4946,7 +5250,7 @@ var init_guards = __esm({
4946
5250
  function createSignalEndpoint(options) {
4947
5251
  const { manager, auth, rateLimit, logger, telemetry, allowedSignals } = options;
4948
5252
  return async (payload, req) => {
4949
- const correlationId = payload.correlation_id ?? generateCorrelationId2();
5253
+ const correlationId = payload.correlation_id ?? generateCorrelationId3();
4950
5254
  const authResult = await auth(req);
4951
5255
  if (!authResult.authenticated) {
4952
5256
  if (logger) {
@@ -5069,7 +5373,7 @@ function normalizeSignalName(signal) {
5069
5373
  }
5070
5374
  return `SIG${upper}`;
5071
5375
  }
5072
- function generateCorrelationId2() {
5376
+ function generateCorrelationId3() {
5073
5377
  return `sig-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
5074
5378
  }
5075
5379
  function createBearerTokenAuth(expectedToken) {
@@ -5536,6 +5840,8 @@ var init_signals = __esm({
5536
5840
  "src/foundry/signals/index.ts"() {
5537
5841
  init_capabilities2();
5538
5842
  init_catalog();
5843
+ init_config_reload_endpoint();
5844
+ init_control_discovery_endpoint();
5539
5845
  init_convenience();
5540
5846
  init_double_tap();
5541
5847
  init_guards();
@@ -5681,7 +5987,9 @@ __export(foundry_exports, {
5681
5987
  clearMimeTypeCache: () => clearMimeTypeCache,
5682
5988
  clearPatternCache: () => clearPatternCache,
5683
5989
  createBearerTokenAuth: () => createBearerTokenAuth,
5990
+ createConfigReloadEndpoint: () => createConfigReloadEndpoint,
5684
5991
  createConfigReloadHandler: () => createConfigReloadHandler,
5992
+ createControlDiscoveryEndpoint: () => createControlDiscoveryEndpoint,
5685
5993
  createDoubleTapTracker: () => createDoubleTapTracker,
5686
5994
  createSignalEndpoint: () => createSignalEndpoint,
5687
5995
  createSignalManager: () => createSignalManager,
@@ -5783,6 +6091,6 @@ var init_foundry = __esm({
5783
6091
  });
5784
6092
  init_foundry();
5785
6093
 
5786
- export { ConfigReloadTracker, EXIT_CODES_VERSION, FoundryCatalogError, SignalManager, SimplifiedMode, VERSION, casefold, clearCountryCodeCache, clearHttpStatusCache, clearMimeTypeCache, clearPatternCache, createBearerTokenAuth, createConfigReloadHandler, createDoubleTapTracker, createSignalEndpoint, createSignalManager, createSimpleRateLimiter, describePattern, detectMimeType, detectMimeTypeFromBuffer, detectMimeTypeFromFile, detectMimeTypeFromStream, distance, ensurePOSIX, ensureSignalExitCodesSupported, ensureSupported, ensureWindows, equalsIgnoreCase, exitCodeMetadata, exitCodes, getBehavior, getCountryByAlpha2, getCountryByAlpha3, getCountryByNumeric, getExitCodeInfo, getFallbackMetadata, getHttpFallbackGuidance, getHttpStatus, getMimeType, getMimeTypeByExtension, getPattern, getPatternRegex, getPlatform, getPlatformCapabilities, getSignal, getSignalCatalog, getSignalNumber, getPlatformCapabilities2 as getSignalPlatformCapabilities, getSignalsVersion, getSimplifiedCodeDescription, getSimplifiedCodes, getStatusReason, getWindowTimeRemaining, getWindowsEvent, handleDoubleTap, handleWindowsFallback, isClientError, isInformational, isPOSIX, isRedirection, isServerError, isPOSIX2 as isSignalPOSIX, isWindows2 as isSignalWindows, isSuccess, isSupportedMimeType, isWindows, isWithinWindow, listBehaviors, listCountries, listHttpStatuses, listMimeTypes, listPatterns, listSignals, loadAllCatalogs, loadCountryCodeCatalog, loadHttpStatusCatalog, loadMimeTypeCatalog, loadPatternCatalog, mapExitCodeToSimplified, matchMagicNumber, matchPattern, normalize, onAnyShutdown, onEmergencyQuit, onReload, onShutdown, onUSR1, onUSR2, requiresFallback, resetDoubleTap, score, stripAccents, suggest, supportsSignal, supportsSignalExitCodes2 as supportsSignalBasedExitCodes, supportsSignalExitCodes };
6094
+ export { ConfigReloadTracker, EXIT_CODES_VERSION, FoundryCatalogError, SignalManager, SimplifiedMode, VERSION, casefold, clearCountryCodeCache, clearHttpStatusCache, clearMimeTypeCache, clearPatternCache, createBearerTokenAuth, createConfigReloadEndpoint, createConfigReloadHandler, createControlDiscoveryEndpoint, createDoubleTapTracker, createSignalEndpoint, createSignalManager, createSimpleRateLimiter, describePattern, detectMimeType, detectMimeTypeFromBuffer, detectMimeTypeFromFile, detectMimeTypeFromStream, distance, ensurePOSIX, ensureSignalExitCodesSupported, ensureSupported, ensureWindows, equalsIgnoreCase, exitCodeMetadata, exitCodes, getBehavior, getCountryByAlpha2, getCountryByAlpha3, getCountryByNumeric, getExitCodeInfo, getFallbackMetadata, getHttpFallbackGuidance, getHttpStatus, getMimeType, getMimeTypeByExtension, getPattern, getPatternRegex, getPlatform, getPlatformCapabilities, getSignal, getSignalCatalog, getSignalNumber, getPlatformCapabilities2 as getSignalPlatformCapabilities, getSignalsVersion, getSimplifiedCodeDescription, getSimplifiedCodes, getStatusReason, getWindowTimeRemaining, getWindowsEvent, handleDoubleTap, handleWindowsFallback, isClientError, isInformational, isPOSIX, isRedirection, isServerError, isPOSIX2 as isSignalPOSIX, isWindows2 as isSignalWindows, isSuccess, isSupportedMimeType, isWindows, isWithinWindow, listBehaviors, listCountries, listHttpStatuses, listMimeTypes, listPatterns, listSignals, loadAllCatalogs, loadCountryCodeCatalog, loadHttpStatusCatalog, loadMimeTypeCatalog, loadPatternCatalog, mapExitCodeToSimplified, matchMagicNumber, matchPattern, normalize, onAnyShutdown, onEmergencyQuit, onReload, onShutdown, onUSR1, onUSR2, requiresFallback, resetDoubleTap, score, stripAccents, suggest, supportsSignal, supportsSignalExitCodes2 as supportsSignalBasedExitCodes, supportsSignalExitCodes };
5787
6095
  //# sourceMappingURL=index.js.map
5788
6096
  //# sourceMappingURL=index.js.map