@fulmenhq/tsfulmen 0.1.13 → 0.2.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 (165) hide show
  1. package/CHANGELOG.md +73 -512
  2. package/README.md +111 -28
  3. package/config/crucible-ts/agentic/roles/README.md +76 -0
  4. package/config/crucible-ts/agentic/roles/cicd.yaml +82 -0
  5. package/config/crucible-ts/agentic/roles/dataeng.yaml +104 -0
  6. package/config/crucible-ts/agentic/roles/devlead.yaml +84 -0
  7. package/config/crucible-ts/agentic/roles/devrev.yaml +105 -0
  8. package/config/crucible-ts/agentic/roles/entarch.yaml +101 -0
  9. package/config/crucible-ts/agentic/roles/infoarch.yaml +95 -0
  10. package/config/crucible-ts/agentic/roles/prodmktg.yaml +92 -0
  11. package/config/crucible-ts/agentic/roles/qa.yaml +148 -0
  12. package/config/crucible-ts/agentic/roles/secrev.yaml +101 -0
  13. package/config/crucible-ts/agentic/roles/uxdev.yaml +168 -0
  14. package/config/crucible-ts/branding/ecosystem.yaml +26 -0
  15. package/config/crucible-ts/library/foundry/exit-codes.snapshot.json +26 -0
  16. package/config/crucible-ts/library/foundry/exit-codes.yaml +28 -3
  17. package/config/crucible-ts/library/foundry/patterns.yaml +2 -2
  18. package/config/crucible-ts/library/foundry/signal-resolution-fixtures.yaml +207 -0
  19. package/config/crucible-ts/library/foundry/signals.yaml +21 -0
  20. package/config/crucible-ts/library/foundry/simplified-modes.snapshot.json +9 -1
  21. package/config/crucible-ts/library/{foundry/similarity-fixtures.yaml → similarity/fixtures.yaml} +1 -1
  22. package/config/crucible-ts/library/v1.0.0/module-manifest.yaml +1 -2
  23. package/config/crucible-ts/taxonomy/fixture-catalog.yaml +145 -0
  24. package/config/crucible-ts/taxonomy/languages.yaml +2 -2
  25. package/config/crucible-ts/taxonomy/library/foundry-catalogs/v1.1.0/catalogs.yaml +77 -0
  26. package/config/crucible-ts/taxonomy/library/platform-modules/v1.1.0/modules.yaml +722 -0
  27. package/config/crucible-ts/taxonomy/metrics.yaml +1 -1
  28. package/config/crucible-ts/taxonomy/repository-categories.yaml +134 -1
  29. package/dist/appidentity/index.d.ts +117 -35
  30. package/dist/appidentity/index.js +752 -592
  31. package/dist/appidentity/index.js.map +1 -1
  32. package/dist/config/index.js +118 -6
  33. package/dist/config/index.js.map +1 -1
  34. package/dist/crucible/index.js +118 -6
  35. package/dist/crucible/index.js.map +1 -1
  36. package/dist/errors/index.js +118 -6
  37. package/dist/errors/index.js.map +1 -1
  38. package/dist/foundry/index.d.ts +13 -676
  39. package/dist/foundry/index.js +118 -6
  40. package/dist/foundry/index.js.map +1 -1
  41. package/dist/foundry/similarity/index.d.ts +2 -2
  42. package/dist/fulhash/index.d.ts +64 -12
  43. package/dist/fulhash/index.js +292 -53
  44. package/dist/fulhash/index.js.map +1 -1
  45. package/dist/index.d.ts +2 -2
  46. package/dist/index.js +753 -593
  47. package/dist/index.js.map +1 -1
  48. package/dist/{manager-D27vrdaS.d.ts → manager-CH3fX7zO.d.ts} +1 -1
  49. package/dist/pathfinder/index.js +368 -59
  50. package/dist/pathfinder/index.js.map +1 -1
  51. package/dist/reports/license-inventory.csv +302 -0
  52. package/dist/schema/index.js +118 -6
  53. package/dist/schema/index.js.map +1 -1
  54. package/dist/signals/index.d.ts +675 -0
  55. package/dist/signals/index.js +5790 -0
  56. package/dist/signals/index.js.map +1 -0
  57. package/dist/similarity/index.d.ts +2 -0
  58. package/dist/similarity/index.js +136 -0
  59. package/dist/similarity/index.js.map +1 -0
  60. package/dist/{suggest-Cv7SVQRu.d.ts → suggest-D8LbwtPV.d.ts} +1 -1
  61. package/dist/telemetry/http/index.js +704 -591
  62. package/dist/telemetry/http/index.js.map +1 -1
  63. package/dist/telemetry/index.js +118 -6
  64. package/dist/telemetry/index.js.map +1 -1
  65. package/dist/telemetry/prometheus/index.d.ts +1 -1
  66. package/dist/telemetry/prometheus/index.js +175 -11
  67. package/dist/telemetry/prometheus/index.js.map +1 -1
  68. package/package.json +15 -6
  69. package/schemas/crucible-ts/assessment/v1.0.0/severity-definitions.schema.json +1 -1
  70. package/schemas/crucible-ts/config/fulmen-ecosystem/v1.0.0/fulmen-config-paths.schema.json +1 -1
  71. package/schemas/crucible-ts/config/repository/app-identity/v1.0.0/app-identity.schema.json +3 -3
  72. package/schemas/crucible-ts/config/repository/v1.0.0/lifecycle-phase.json +1 -1
  73. package/schemas/crucible-ts/config/repository-category/codex/v1.0.0/codex-config.schema.json +1 -1
  74. package/schemas/crucible-ts/config/standards/v1.0.0/adr-adoption-status.json +1 -1
  75. package/schemas/crucible-ts/config/standards/v1.0.0/adr-frontmatter.schema.json +3 -3
  76. package/schemas/crucible-ts/config/standards/v1.0.0/adr-lifecycle-status.json +1 -1
  77. package/schemas/crucible-ts/config/sync-keys.schema.yaml +14 -0
  78. package/schemas/crucible-ts/content/ssot-provenance/v1.0.0/ssot-provenance.schema.json +1 -1
  79. package/schemas/crucible-ts/design/README.md +159 -0
  80. package/schemas/crucible-ts/design/core/v1.0.0/component-states.schema.json +204 -0
  81. package/schemas/crucible-ts/design/core/v1.0.0/semantic-colors.schema.json +179 -0
  82. package/schemas/crucible-ts/design/core/v1.0.0/spacing-scale.schema.json +165 -0
  83. package/schemas/crucible-ts/design/core/v1.0.0/typography-roles.schema.json +195 -0
  84. package/schemas/crucible-ts/design/tui/v1.0.0/color-palette.schema.json +303 -0
  85. package/schemas/crucible-ts/design/tui/v1.0.0/component.schema.json +374 -0
  86. package/schemas/crucible-ts/design/tui/v1.0.0/layout.schema.json +272 -0
  87. package/schemas/crucible-ts/design/tui/v1.0.0/theme.schema.json +205 -0
  88. package/schemas/crucible-ts/design/tui/v1.0.0/typography.schema.json +316 -0
  89. package/schemas/crucible-ts/devsecops/lorage-central/activity/v1.0.0/activity.schema.json +1 -1
  90. package/schemas/crucible-ts/devsecops/lorage-central/credentials/v1.0.0/credentials.schema.json +1 -1
  91. package/schemas/crucible-ts/devsecops/lorage-central/policy/v1.0.0/policy.schema.json +1 -1
  92. package/schemas/crucible-ts/devsecops/lorage-central/recipe/v1.0.0/recipe.schema.json +1 -1
  93. package/schemas/crucible-ts/devsecops/lorage-central/runbooks/v1.0.0/runbook.schema.json +1 -1
  94. package/schemas/crucible-ts/devsecops/lorage-central/tenant/v1.0.0/tenant.schema.json +1 -1
  95. package/schemas/crucible-ts/devsecops/secrets/v1.0.0/secrets.schema.json +1 -1
  96. package/schemas/crucible-ts/error-handling/v1.0.0/error-response.schema.json +1 -1
  97. package/schemas/crucible-ts/library/foundry/v1.0.0/country-codes.schema.json +1 -1
  98. package/schemas/crucible-ts/library/foundry/v1.0.0/exit-codes.schema.json +1 -1
  99. package/schemas/crucible-ts/library/foundry/v1.0.0/http-status-groups.schema.json +1 -1
  100. package/schemas/crucible-ts/library/foundry/v1.0.0/mime-types.schema.json +1 -1
  101. package/schemas/crucible-ts/library/foundry/v1.0.0/patterns.schema.json +1 -1
  102. package/schemas/crucible-ts/library/foundry/v1.0.0/signal-resolution-fixtures.schema.json +140 -0
  103. package/schemas/crucible-ts/library/foundry/v1.0.0/signals.schema.json +6 -1
  104. package/schemas/crucible-ts/library/fulencode/v1.0.0/fulencode-config.schema.json +1 -1
  105. package/schemas/crucible-ts/library/fulhash/v1.0.0/checksum-string.schema.json +2 -2
  106. package/schemas/crucible-ts/library/fulhash/v1.0.0/digest.schema.json +61 -1
  107. package/schemas/crucible-ts/library/fulhash/v1.0.0/fixtures.schema.json +1 -1
  108. package/schemas/crucible-ts/library/fulpack/v1.0.0/archive-entry.schema.json +1 -1
  109. package/schemas/crucible-ts/library/fulpack/v1.0.0/archive-info.schema.json +1 -1
  110. package/schemas/crucible-ts/library/fulpack/v1.0.0/archive-manifest.schema.json +2 -2
  111. package/schemas/crucible-ts/library/fulpack/v1.0.0/create-options.schema.json +1 -1
  112. package/schemas/crucible-ts/library/fulpack/v1.0.0/extract-options.schema.json +1 -1
  113. package/schemas/crucible-ts/library/fulpack/v1.0.0/extract-result.schema.json +1 -1
  114. package/schemas/crucible-ts/library/fulpack/v1.0.0/scan-options.schema.json +1 -1
  115. package/schemas/crucible-ts/library/fulpack/v1.0.0/validation-result.schema.json +1 -1
  116. package/schemas/crucible-ts/library/module-manifest/v1.0.0/module-manifest.schema.json +1 -1
  117. package/schemas/crucible-ts/library/{foundry → similarity}/v1.0.0/similarity.schema.json +2 -2
  118. package/schemas/crucible-ts/library/{foundry → similarity}/v2.0.0/similarity.schema.json +2 -2
  119. package/schemas/crucible-ts/observability/metrics/v1.0.0/metrics-event.schema.json +1 -1
  120. package/schemas/crucible-ts/pathfinder/v1.0.0/find-query.schema.json +1 -1
  121. package/schemas/crucible-ts/pathfinder/v1.0.0/finder-config.schema.json +1 -1
  122. package/schemas/crucible-ts/pathfinder/v1.0.0/path-result.schema.json +1 -1
  123. package/schemas/crucible-ts/protocol/http/v1.0.0/error-response.schema.json +1 -1
  124. package/schemas/crucible-ts/protocol/http/v1.0.0/health-response.schema.json +1 -1
  125. package/schemas/crucible-ts/protocol/http/v1.0.0/success-response.schema.json +1 -1
  126. package/schemas/crucible-ts/protocol/http/v1.0.0/version-response.schema.json +1 -1
  127. package/schemas/crucible-ts/server/management/v1.0.0/server-management.schema.json +1 -1
  128. package/schemas/crucible-ts/standards/publishing/v1.0.0/spec-catalog.schema.json +134 -0
  129. package/schemas/crucible-ts/taxonomy/devsecops/auth-methods/v1.0.0/auth-methods-key.schema.json +1 -1
  130. package/schemas/crucible-ts/taxonomy/devsecops/auth-methods/v1.0.0/auth-methods-metadata.schema.json +1 -1
  131. package/schemas/crucible-ts/taxonomy/devsecops/geo/v1.0.0/geo-key.schema.json +1 -1
  132. package/schemas/crucible-ts/taxonomy/devsecops/geo/v1.0.0/geo-metadata.schema.json +1 -1
  133. package/schemas/crucible-ts/taxonomy/devsecops/infra-phases/v1.0.0/infra-phases-key.schema.json +1 -1
  134. package/schemas/crucible-ts/taxonomy/devsecops/infra-phases/v1.0.0/infra-phases-metadata.schema.json +1 -1
  135. package/schemas/crucible-ts/taxonomy/devsecops/infra-providers/v1.0.0/infra-providers-key.schema.json +1 -1
  136. package/schemas/crucible-ts/taxonomy/devsecops/infra-providers/v1.0.0/infra-providers-metadata.schema.json +1 -1
  137. package/schemas/crucible-ts/taxonomy/devsecops/modules/v1.0.0/devsecops-module-entry.schema.json +1 -1
  138. package/schemas/crucible-ts/taxonomy/fixture/v1.0.0/fixture-catalog.schema.json +166 -0
  139. package/schemas/crucible-ts/taxonomy/language/v1.0.0/language-key.schema.json +1 -1
  140. package/schemas/crucible-ts/taxonomy/language/v1.0.0/language-metadata.schema.json +1 -1
  141. package/schemas/crucible-ts/taxonomy/library/foundry-catalogs/v1.1.0/catalog-entry.schema.json +98 -0
  142. package/schemas/crucible-ts/taxonomy/library/fulencode/detection-confidence/v1.0.0/levels.schema.json +1 -1
  143. package/schemas/crucible-ts/taxonomy/library/fulencode/encoding-families/v1.0.0/families.schema.json +1 -1
  144. package/schemas/crucible-ts/taxonomy/library/fulencode/normalization-profiles/v1.0.0/profiles.schema.json +1 -1
  145. package/schemas/crucible-ts/taxonomy/library/fulhash/algorithms/v1.0.0/algorithms.yaml +16 -0
  146. package/schemas/crucible-ts/taxonomy/library/modules/v1.0.0/module-entry.schema.json +1 -1
  147. package/schemas/crucible-ts/taxonomy/library/modules/v1.1.0/module-entry.schema.json +436 -0
  148. package/schemas/crucible-ts/taxonomy/repository-category/v1.0.0/category-key.schema.json +16 -8
  149. package/schemas/crucible-ts/taxonomy/repository-category/v1.0.0/category-metadata.schema.json +1 -1
  150. package/schemas/crucible-ts/upstream/3leaps/PROVENANCE.md +43 -0
  151. package/schemas/crucible-ts/upstream/3leaps/agentic/v0/role-prompt.schema.json +183 -0
  152. package/schemas/crucible-ts/upstream/3leaps/ailink/v0/prompt.schema.json +204 -0
  153. package/schemas/crucible-ts/upstream/3leaps/ailink/v0/search-response.schema.json +152 -0
  154. package/schemas/crucible-ts/upstream/README.md +50 -0
  155. package/schemas/crucible-ts/web/branding/v1.0.0/site-branding.schema.json +1 -1
  156. package/schemas/crucible-ts/web/styling/v1.0.0/site-styling.schema.json +1 -1
  157. package/schemas/crucible-ts/config/goneat/README.md +0 -60
  158. package/schemas/crucible-ts/config/goneat/v1.0.0/dates.yaml +0 -234
  159. package/schemas/crucible-ts/config/goneat/v1.0.0/goneat-config.yaml +0 -344
  160. package/schemas/crucible-ts/config/goneat/v1.0.0/lifecycle-phase.json +0 -20
  161. package/schemas/crucible-ts/config/goneat/v1.0.0/release-phase.json +0 -17
  162. package/schemas/crucible-ts/config/goneat/v1.0.0/security-policy.yaml +0 -178
  163. package/schemas/crucible-ts/config/goneat/v1.0.0/version-policy.schema.yaml +0 -205
  164. package/schemas/crucible-ts/tooling/goneat-tools/v1.0.0/README.md +0 -177
  165. package/schemas/crucible-ts/tooling/goneat-tools/v1.0.0/goneat-tools-config.schema.yaml +0 -146
@@ -1,4 +1,3 @@
1
- import 'crypto';
2
1
  import { spawn } from 'child_process';
3
2
  import { readFile, writeFile, access, mkdir } from 'fs/promises';
4
3
  import { parse, stringify } from 'yaml';
@@ -10,6 +9,7 @@ import addFormats from 'ajv-formats';
10
9
  import { Readable } from 'stream';
11
10
  import picomatch from 'picomatch';
12
11
  import { suggest as suggest$1, substringSimilarity, score as score$1, normalize as normalize$1, jaro_winkler, damerau_levenshtein, osa_distance, levenshtein } from '@3leaps/string-metrics-wasm';
12
+ import 'crypto';
13
13
  import { Command } from 'commander';
14
14
 
15
15
  var __defProp = Object.defineProperty;
@@ -33,68 +33,6 @@ var init_constants = __esm({
33
33
  MAX_ANCESTOR_SEARCH_DEPTH = 20;
34
34
  }
35
35
  });
36
- var init_correlation = __esm({
37
- "src/errors/correlation.ts"() {
38
- }
39
- });
40
-
41
- // src/errors/severity.ts
42
- function getDefaultSeverity() {
43
- return {
44
- name: Severity.MEDIUM,
45
- level: 2
46
- };
47
- }
48
- var Severity, SEVERITY_LEVELS;
49
- var init_severity = __esm({
50
- "src/errors/severity.ts"() {
51
- Severity = {
52
- INFO: "info",
53
- LOW: "low",
54
- MEDIUM: "medium",
55
- HIGH: "high",
56
- CRITICAL: "critical"
57
- };
58
- SEVERITY_LEVELS = {
59
- info: 0,
60
- low: 1,
61
- medium: 2,
62
- high: 3,
63
- critical: 4
64
- };
65
- }
66
- });
67
-
68
- // src/errors/serialization.ts
69
- function extractErrorMessage(error) {
70
- if (error instanceof Error) {
71
- return error.message;
72
- }
73
- if (isErrorLike(error)) {
74
- return error.message;
75
- }
76
- if (typeof error === "string") {
77
- return error;
78
- }
79
- return String(error);
80
- }
81
- function extractStackTrace(error) {
82
- if (error instanceof Error) {
83
- return error.stack;
84
- }
85
- if (isErrorLike(error) && typeof error.stack === "string") {
86
- return error.stack;
87
- }
88
- return void 0;
89
- }
90
- function isErrorLike(value) {
91
- return typeof value === "object" && value !== null && "message" in value && typeof value.message === "string";
92
- }
93
- var init_serialization = __esm({
94
- "src/errors/serialization.ts"() {
95
- init_severity();
96
- }
97
- });
98
36
 
99
37
  // src/schema/errors.ts
100
38
  var errors_exports = {};
@@ -1585,7 +1523,10 @@ async function loadReferencedSchema(uri) {
1585
1523
  const repoRoot = join(__dirname4, "..", "..");
1586
1524
  let resolvedPath;
1587
1525
  if (uri.startsWith("https://schemas.fulmenhq.dev/")) {
1588
- const relativePath = uri.replace("https://schemas.fulmenhq.dev/", "");
1526
+ let relativePath = uri.replace("https://schemas.fulmenhq.dev/", "");
1527
+ if (relativePath.startsWith("crucible/")) {
1528
+ relativePath = relativePath.slice("crucible/".length);
1529
+ }
1589
1530
  if (relativePath.startsWith("config/taxonomy/")) {
1590
1531
  resolvedPath = join(
1591
1532
  repoRoot,
@@ -1802,7 +1743,9 @@ async function compileSchemaById(schemaId, registryOptions) {
1802
1743
  const aliases = [];
1803
1744
  const normalizedRelativePath = metadata.relativePath.replace(/\\/g, "/");
1804
1745
  if (normalizedRelativePath) {
1805
- aliases.push(new URL(normalizedRelativePath, "https://schemas.fulmenhq.dev/").toString());
1746
+ aliases.push(
1747
+ new URL(`crucible/${normalizedRelativePath}`, "https://schemas.fulmenhq.dev/").toString()
1748
+ );
1806
1749
  }
1807
1750
  return compileSchema(content, { aliases });
1808
1751
  } catch (error) {
@@ -2320,6 +2263,12 @@ var init_exitCodes = __esm({
2320
2263
  EXIT_TEST_USAGE_ERROR: 94,
2321
2264
  EXIT_TEST_NO_TESTS_COLLECTED: 95,
2322
2265
  EXIT_COVERAGE_THRESHOLD_NOT_MET: 96,
2266
+ // Shell & Process Control (124-127)
2267
+ // Exit codes from shell conventions and process control utilities (timeout, exec)
2268
+ EXIT_TIMEOUT: 124,
2269
+ EXIT_TIMEOUT_INTERNAL: 125,
2270
+ EXIT_CANNOT_EXECUTE: 126,
2271
+ EXIT_NOT_FOUND: 127,
2323
2272
  // Signal-Induced Exits (128-165)
2324
2273
  // Process terminated by Unix signals (128+N pattern per POSIX). Signal codes follow Linux numbering; macOS/FreeBSD differ for SIGUSR1/SIGUSR2. For full signal semantics, see config/library/foundry/signals.yaml. For signal handling patterns, see docs/standards/library/modules/signal-handling.md.
2325
2274
  EXIT_SIGNAL_HUP: 129,
@@ -2657,6 +2606,36 @@ var init_exitCodes = __esm({
2657
2606
  context: "Code coverage validation, quality gate failure",
2658
2607
  category: "testing"
2659
2608
  },
2609
+ 124: {
2610
+ code: 124,
2611
+ name: "EXIT_TIMEOUT",
2612
+ description: "Command timed out before completion",
2613
+ context: "GNU timeout or similar utility terminated command after deadline",
2614
+ category: "shell"
2615
+ },
2616
+ 125: {
2617
+ code: 125,
2618
+ name: "EXIT_TIMEOUT_INTERNAL",
2619
+ description: "Timeout utility itself failed",
2620
+ context: "Error in timeout tool before or during command execution (not command failure)",
2621
+ category: "shell"
2622
+ },
2623
+ 126: {
2624
+ code: 126,
2625
+ name: "EXIT_CANNOT_EXECUTE",
2626
+ description: "Command found but could not be executed",
2627
+ context: "Permission denied, not executable, exec format error",
2628
+ category: "shell",
2629
+ bsdEquivalent: "EX_NOPERM (partial)"
2630
+ },
2631
+ 127: {
2632
+ code: 127,
2633
+ name: "EXIT_NOT_FOUND",
2634
+ description: "Command not found",
2635
+ context: "Executable not found in PATH or specified path does not exist",
2636
+ category: "shell",
2637
+ bsdEquivalent: "EX_UNAVAILABLE (partial)"
2638
+ },
2660
2639
  129: {
2661
2640
  code: 129,
2662
2641
  name: "EXIT_SIGNAL_HUP",
@@ -4865,554 +4844,179 @@ var init_cache = __esm({
4865
4844
  cachedIdentity = null;
4866
4845
  }
4867
4846
  });
4868
- async function discoverIdentityPath(options) {
4869
- if (options?.path) {
4870
- const exists = await fileExists(options.path);
4871
- if (!exists) {
4872
- throw AppIdentityError.notFound([options.path]);
4873
- }
4874
- return { path: options.path, source: "explicit" };
4875
- }
4876
- const envPath = process.env[APP_IDENTITY_ENV_VAR];
4877
- if (envPath) {
4878
- const exists = await fileExists(envPath);
4879
- if (!exists) {
4880
- throw AppIdentityError.envOverrideMissing(envPath);
4881
- }
4882
- return { path: envPath, source: "env" };
4883
- }
4884
- const startDir = options?.startDir || process.cwd();
4885
- const result = await searchAncestors(startDir);
4886
- if (result) {
4887
- return { path: result, source: "ancestor" };
4888
- }
4889
- return null;
4890
- }
4891
- async function searchAncestors(startDir) {
4892
- let currentDir = startDir;
4893
- const searchedPaths = [];
4894
- for (let i = 0; i < MAX_ANCESTOR_SEARCH_DEPTH; i++) {
4895
- const candidatePath = join(currentDir, APP_IDENTITY_DIR, APP_IDENTITY_FILENAME);
4896
- searchedPaths.push(candidatePath);
4897
- if (await fileExists(candidatePath)) {
4898
- return candidatePath;
4899
- }
4900
- const parentDir = dirname(currentDir);
4901
- if (parentDir === currentDir) {
4902
- throw AppIdentityError.notFound(searchedPaths);
4903
- }
4904
- currentDir = parentDir;
4905
- }
4906
- throw AppIdentityError.notFound(searchedPaths);
4907
- }
4908
- async function fileExists(path) {
4909
- try {
4910
- await access(path);
4911
- return true;
4912
- } catch {
4913
- return false;
4914
- }
4915
- }
4916
- var init_discovery = __esm({
4917
- "src/appidentity/discovery.ts"() {
4918
- init_constants();
4919
- init_errors5();
4847
+ var init_correlation = __esm({
4848
+ "src/errors/correlation.ts"() {
4920
4849
  }
4921
4850
  });
4922
4851
 
4923
- // src/appidentity/loader.ts
4924
- var loader_exports = {};
4925
- __export(loader_exports, {
4926
- clearIdentityCache: () => clearIdentityCache,
4927
- getCachedIdentity: () => getCachedIdentity,
4928
- loadIdentity: () => loadIdentity
4929
- });
4930
- function deepFreeze5(obj) {
4931
- Object.freeze(obj);
4932
- Object.getOwnPropertyNames(obj).forEach((prop) => {
4933
- const value = obj[prop];
4934
- if (value !== null && (typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) {
4935
- deepFreeze5(value);
4936
- }
4937
- });
4938
- return obj;
4852
+ // src/errors/severity.ts
4853
+ function getDefaultSeverity() {
4854
+ return {
4855
+ name: Severity.MEDIUM,
4856
+ level: 2
4857
+ };
4939
4858
  }
4940
- async function loadIdentity(options) {
4941
- if (options?.identity) {
4942
- return deepFreeze5(structuredClone(options.identity));
4859
+ var Severity, SEVERITY_LEVELS;
4860
+ var init_severity = __esm({
4861
+ "src/errors/severity.ts"() {
4862
+ Severity = {
4863
+ INFO: "info",
4864
+ LOW: "low",
4865
+ MEDIUM: "medium",
4866
+ HIGH: "high",
4867
+ CRITICAL: "critical"
4868
+ };
4869
+ SEVERITY_LEVELS = {
4870
+ info: 0,
4871
+ low: 1,
4872
+ medium: 2,
4873
+ high: 3,
4874
+ critical: 4
4875
+ };
4943
4876
  }
4944
- if (!options?.skipCache) {
4945
- const cached = getCachedIdentity();
4946
- if (cached) {
4947
- return cached;
4948
- }
4877
+ });
4878
+
4879
+ // src/errors/serialization.ts
4880
+ function extractErrorMessage(error) {
4881
+ if (error instanceof Error) {
4882
+ return error.message;
4949
4883
  }
4950
- const discovery = await discoverIdentityPath({
4951
- path: options?.path,
4952
- startDir: options?.startDir
4953
- });
4954
- if (!discovery) {
4955
- throw AppIdentityError.notFound([]);
4884
+ if (isErrorLike(error)) {
4885
+ return error.message;
4956
4886
  }
4957
- let content;
4958
- try {
4959
- content = await readFile(discovery.path, "utf-8");
4960
- } catch (error) {
4961
- throw AppIdentityError.readFailed(
4962
- discovery.path,
4963
- error instanceof Error ? error : new Error(String(error))
4964
- );
4887
+ if (typeof error === "string") {
4888
+ return error;
4965
4889
  }
4966
- let parsed;
4967
- try {
4968
- parsed = parse(content);
4969
- } catch (error) {
4970
- throw AppIdentityError.parseFailed(
4971
- discovery.path,
4972
- error instanceof Error ? error : new Error(String(error))
4973
- );
4890
+ return String(error);
4891
+ }
4892
+ function extractStackTrace(error) {
4893
+ if (error instanceof Error) {
4894
+ return error.stack;
4974
4895
  }
4975
- if (!options?.skipValidation) {
4976
- const result = await validateDataBySchemaId(parsed, APP_IDENTITY_SCHEMA_ID);
4977
- if (!result.valid) {
4978
- throw AppIdentityError.validationFailed(discovery.path, result.diagnostics);
4979
- }
4896
+ if (isErrorLike(error) && typeof error.stack === "string") {
4897
+ return error.stack;
4980
4898
  }
4981
- const identity = deepFreeze5(structuredClone(parsed));
4982
- setCachedIdentity(identity);
4983
- return identity;
4899
+ return void 0;
4984
4900
  }
4985
- var init_loader2 = __esm({
4986
- "src/appidentity/loader.ts"() {
4987
- init_schema();
4988
- init_cache();
4989
- init_constants();
4990
- init_discovery();
4991
- init_errors5();
4901
+ function isErrorLike(value) {
4902
+ return typeof value === "object" && value !== null && "message" in value && typeof value.message === "string";
4903
+ }
4904
+ var init_serialization = __esm({
4905
+ "src/errors/serialization.ts"() {
4906
+ init_severity();
4992
4907
  }
4993
4908
  });
4994
- function createCLI(options = {}) {
4995
- const program = new Command();
4996
- program.name("tsfulmen-schema").description("Schema validation and discovery CLI for Fulmen (developer tool)").version("0.1.0");
4997
- program.command("list").description("List available schemas from registry").argument("[prefix]", "Filter schemas by prefix").option("--base-dir <path>", "Override schema base directory").action(async (prefix, cmdOptions) => {
4998
- try {
4999
- const schemas = await listSchemas(prefix, {
5000
- baseDir: cmdOptions?.baseDir || options.baseDir
5001
- });
5002
- if (schemas.length === 0) {
5003
- console.log("No schemas found");
5004
- return;
4909
+
4910
+ // src/errors/validators.ts
4911
+ async function validateErrorData(data) {
4912
+ return ErrorValidator.getInstance().validate(data);
4913
+ }
4914
+ var ErrorValidator;
4915
+ var init_validators2 = __esm({
4916
+ "src/errors/validators.ts"() {
4917
+ init_schema();
4918
+ ErrorValidator = class _ErrorValidator {
4919
+ static instance;
4920
+ validateFn = null;
4921
+ initPromise = null;
4922
+ initError = null;
4923
+ constructor() {
5005
4924
  }
5006
- console.log(`Found ${schemas.length} schema(s):
5007
- `);
5008
- for (const schema of schemas) {
5009
- console.log(` ${schema.id}`);
5010
- console.log(` Format: ${schema.format}`);
5011
- console.log(` Path: ${schema.relativePath}`);
5012
- if (schema.description) {
5013
- console.log(` Description: ${schema.description}`);
4925
+ /**
4926
+ * Get singleton instance
4927
+ */
4928
+ static getInstance() {
4929
+ if (!_ErrorValidator.instance) {
4930
+ _ErrorValidator.instance = new _ErrorValidator();
5014
4931
  }
5015
- console.log();
5016
- }
5017
- } catch (error) {
5018
- console.error("Error listing schemas:", error.message);
5019
- process.exit(1);
5020
- }
5021
- });
5022
- program.command("show").description("Show schema details").requiredOption("--schema-id <id>", "Schema ID to show").option("--base-dir <path>", "Override schema base directory").action(async (cmdOptions) => {
5023
- try {
5024
- const registry = getSchemaRegistry({
5025
- baseDir: cmdOptions.baseDir || options.baseDir
5026
- });
5027
- const schema = await registry.getSchema(cmdOptions.schemaId);
5028
- console.log("Schema Details:\n");
5029
- console.log(` ID: ${schema.id}`);
5030
- console.log(` Format: ${schema.format}`);
5031
- console.log(` Path: ${schema.path}`);
5032
- console.log(` Relative Path: ${schema.relativePath}`);
5033
- if (schema.version) {
5034
- console.log(` Version: ${schema.version}`);
5035
- }
5036
- if (schema.description) {
5037
- console.log(` Description: ${schema.description}`);
5038
- }
5039
- if (schema.schemaDraft) {
5040
- console.log(` Schema Draft: ${schema.schemaDraft}`);
4932
+ return _ErrorValidator.instance;
5041
4933
  }
5042
- const content = await readFile(schema.path, "utf-8");
5043
- console.log("\nSchema Content:");
5044
- console.log(content);
5045
- } catch (error) {
5046
- console.error("Error showing schema:", error.message);
5047
- process.exit(1);
5048
- }
5049
- });
5050
- program.command("validate").description("Validate data file against schema").requiredOption("--schema-id <id>", "Schema ID to validate against").argument("<file>", "Data file to validate").option("--use-goneat", "Use goneat for validation (requires goneat binary)").option("--goneat-path <path>", "Path to goneat binary").option("--base-dir <path>", "Override schema base directory").action(
5051
- async (file, cmdOptions) => {
5052
- try {
5053
- let result;
5054
- if (cmdOptions.useGoneat) {
5055
- const available = await isGoneatAvailable(cmdOptions.goneatPath);
5056
- if (!available) {
5057
- console.error("\u274C goneat not available. Install goneat or remove --use-goneat flag.");
5058
- console.error(" AJV validation (default) works without external dependencies.");
5059
- process.exit(1);
4934
+ /**
4935
+ * Initialize validator (lazy load, async)
4936
+ */
4937
+ async init() {
4938
+ if (this.validateFn !== null || this.initError !== null) {
4939
+ return;
4940
+ }
4941
+ if (this.initPromise) {
4942
+ return this.initPromise;
4943
+ }
4944
+ this.initPromise = (async () => {
4945
+ try {
4946
+ await compileSchemaById("pathfinder/v1.0.0/error-response");
4947
+ await compileSchemaById("assessment/v1.0.0/severity-definitions");
4948
+ this.validateFn = await compileSchemaById("error-handling/v1.0.0/error-response");
4949
+ } catch (err) {
4950
+ this.initError = err instanceof Error ? err : new Error(String(err));
4951
+ throw new Error(`Failed to initialize error validator: ${this.initError.message}`);
5060
4952
  }
5061
- const registry = getSchemaRegistry({
5062
- baseDir: cmdOptions.baseDir || options.baseDir
5063
- });
5064
- const schema = await registry.getSchema(cmdOptions.schemaId);
5065
- console.log("Using goneat validation...");
5066
- result = await runGoneatValidation(schema.path, file, cmdOptions.goneatPath);
5067
- } else {
5068
- console.log("Using AJV validation...");
5069
- result = await validateFileBySchemaId(file, cmdOptions.schemaId, {
5070
- baseDir: cmdOptions.baseDir || options.baseDir
5071
- });
4953
+ })();
4954
+ return this.initPromise;
4955
+ }
4956
+ /**
4957
+ * Validate error data against schema
4958
+ *
4959
+ * @param data - Data to validate
4960
+ * @returns Promise resolving to true if valid, false otherwise
4961
+ * @throws {Error} If validator failed to initialize
4962
+ */
4963
+ async validate(data) {
4964
+ if (this.validateFn === null) {
4965
+ await this.init();
5072
4966
  }
5073
- if (result.valid) {
5074
- console.log(`\u2705 Validation passed (${result.source})`);
5075
- process.exit(0);
5076
- } else {
5077
- console.log(`\u274C Validation failed (${result.source})`);
5078
- console.log("\nDiagnostics:");
5079
- console.log(formatDiagnostics(result.diagnostics));
5080
- process.exit(1);
4967
+ if (this.initError) {
4968
+ throw this.initError;
5081
4969
  }
5082
- } catch (error) {
5083
- console.error("Error validating file:", error.message);
5084
- process.exit(1);
4970
+ if (!this.validateFn) {
4971
+ throw new Error("Validator not initialized");
4972
+ }
4973
+ return this.validateFn(data);
5085
4974
  }
5086
- }
5087
- );
5088
- program.command("validate-schema").description("Validate a schema file itself").argument("<file>", "Schema file to validate").action(async (file) => {
5089
- try {
5090
- const content = await readFile(file, "utf-8");
5091
- const { validateSchema: validateSchema2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
5092
- const result = await validateSchema2(content);
5093
- if (result.valid) {
5094
- console.log("\u2705 Schema is valid");
5095
- process.exit(0);
5096
- } else {
5097
- console.log("\u274C Schema is invalid");
5098
- console.log("\nDiagnostics:");
5099
- console.log(formatDiagnostics(result.diagnostics));
5100
- process.exit(1);
4975
+ /**
4976
+ * Get validation errors from last validation
4977
+ *
4978
+ * @returns Validation errors or null
4979
+ */
4980
+ getErrors() {
4981
+ if (!this.validateFn) {
4982
+ return null;
4983
+ }
4984
+ return this.validateFn.errors;
5101
4985
  }
5102
- } catch (error) {
5103
- console.error("Error validating schema:", error.message);
5104
- process.exit(1);
5105
- }
5106
- });
5107
- program.command("normalize").description("Normalize schema to canonical JSON format").argument("<file>", "Schema file to normalize").option("--compact", "Output compact JSON (no formatting)").option("-o, --output <file>", "Write to output file instead of stdout").action(async (file, cmdOptions) => {
5108
- try {
5109
- const content = await readFile(file, "utf-8");
5110
- const normalized = normalizeSchema(content, {
5111
- compact: cmdOptions.compact
5112
- });
5113
- if (cmdOptions.output) {
5114
- await writeFile(cmdOptions.output, normalized, "utf-8");
5115
- console.log(`\u2705 Normalized schema written to ${cmdOptions.output}`);
5116
- } else {
5117
- console.log(normalized);
4986
+ /**
4987
+ * Reset validator state (for testing)
4988
+ * @internal
4989
+ */
4990
+ static _reset() {
4991
+ _ErrorValidator.instance = new _ErrorValidator();
5118
4992
  }
5119
- } catch (error) {
5120
- console.error("Error normalizing schema:", error.message);
5121
- process.exit(1);
5122
- }
5123
- });
5124
- program.command("compare").description("Compare two schemas for semantic equality").argument("<file1>", "First schema file").argument("<file2>", "Second schema file").option("--show-normalized", "Show normalized outputs").action(async (file1, file2, cmdOptions) => {
5125
- try {
5126
- const content1 = await readFile(file1, "utf-8");
5127
- const content2 = await readFile(file2, "utf-8");
5128
- const result = compareSchemas(content1, content2);
5129
- if (result.equal) {
5130
- console.log("\u2705 Schemas are semantically equal");
5131
- } else {
5132
- console.log("\u274C Schemas differ");
4993
+ };
4994
+ }
4995
+ });
4996
+
4997
+ // src/errors/fulmen-error.ts
4998
+ function isFulmenErrorData(value) {
4999
+ return typeof value === "object" && value !== null && "code" in value && typeof value.code === "string" && "message" in value && typeof value.message === "string";
5000
+ }
5001
+ var FulmenError;
5002
+ var init_fulmen_error = __esm({
5003
+ "src/errors/fulmen-error.ts"() {
5004
+ init_serialization();
5005
+ init_severity();
5006
+ init_validators2();
5007
+ FulmenError = class _FulmenError extends Error {
5008
+ data;
5009
+ constructor(data) {
5010
+ super(data.message);
5011
+ this.name = "FulmenError";
5012
+ this.data = Object.freeze({ ...data });
5013
+ Error.captureStackTrace(this, _FulmenError);
5133
5014
  }
5134
- if (cmdOptions.showNormalized) {
5135
- console.log("\nNormalized Schema 1:");
5136
- console.log(result.normalizedA);
5137
- console.log("\nNormalized Schema 2:");
5138
- console.log(result.normalizedB);
5139
- }
5140
- process.exit(result.equal ? 0 : 1);
5141
- } catch (error) {
5142
- console.error("Error comparing schemas:", error.message);
5143
- process.exit(1);
5144
- }
5145
- });
5146
- program.command("export").description("Export schema from registry to file with provenance").requiredOption("--schema-id <id>", "Schema ID to export").requiredOption("--out <path>", "Output file path").option("--force", "Overwrite existing file", false).option("--no-provenance", "Exclude provenance metadata").option("--no-validate", "Skip schema validation before export").option("--format <format>", "Export format (json|yaml|auto)", "auto").option("--base-dir <path>", "Override schema base directory").action(
5147
- async (cmdOptions) => {
5148
- try {
5149
- const { exportSchema: exportSchema2 } = await Promise.resolve().then(() => (init_export(), export_exports));
5150
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5151
- const result = await exportSchema2({
5152
- schemaId: cmdOptions.schemaId,
5153
- outPath: cmdOptions.out,
5154
- includeProvenance: cmdOptions.provenance ?? true,
5155
- validate: cmdOptions.validate ?? true,
5156
- overwrite: cmdOptions.force ?? false,
5157
- format: cmdOptions.format ?? "auto",
5158
- baseDir: cmdOptions.baseDir || options.baseDir
5159
- });
5160
- console.log("\u2705 Schema exported successfully");
5161
- console.log(` Schema ID: ${result.schemaId}`);
5162
- console.log(` Output: ${result.outPath}`);
5163
- console.log(` Format: ${result.format}`);
5164
- if (result.provenance) {
5165
- console.log("\nProvenance:");
5166
- console.log(` Crucible: ${result.provenance.crucible_version}`);
5167
- console.log(` Library: ${result.provenance.library_version}`);
5168
- if (result.provenance.revision) {
5169
- console.log(` Revision: ${result.provenance.revision}`);
5170
- }
5171
- console.log(` Exported: ${result.provenance.exported_at}`);
5172
- }
5173
- process.exit(exitCodes2.EXIT_SUCCESS);
5174
- } catch (error) {
5175
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5176
- const { SchemaExportError: SchemaExportError2, SchemaValidationError: SchemaValidationError2, ExportErrorReason: ExportErrorReason2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
5177
- console.error("\u274C Schema export failed:", error.message);
5178
- if (error instanceof SchemaExportError2) {
5179
- if (error.outPath) {
5180
- console.error(` Output path: ${error.outPath}`);
5181
- }
5182
- switch (error.reason) {
5183
- case ExportErrorReason2.FILE_EXISTS:
5184
- case ExportErrorReason2.WRITE_FAILED:
5185
- process.exit(exitCodes2.EXIT_FILE_WRITE_ERROR);
5186
- break;
5187
- case ExportErrorReason2.INVALID_FORMAT:
5188
- process.exit(exitCodes2.EXIT_INVALID_ARGUMENT);
5189
- break;
5190
- default:
5191
- process.exit(exitCodes2.EXIT_FAILURE);
5192
- }
5193
- }
5194
- if (error instanceof SchemaValidationError2) {
5195
- const errorMsg = error.message.toLowerCase();
5196
- if (errorMsg.includes("not found")) {
5197
- process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5198
- }
5199
- process.exit(exitCodes2.EXIT_DATA_INVALID);
5200
- }
5201
- process.exit(exitCodes2.EXIT_FAILURE);
5202
- }
5203
- }
5204
- );
5205
- program.command("identity-show").description("Show application identity from .fulmen/app.yaml").option("--path <path>", "Explicit path to app.yaml").option("--json", "Output as JSON").action(async (cmdOptions) => {
5206
- try {
5207
- const { loadIdentity: loadIdentity2 } = await Promise.resolve().then(() => (init_loader2(), loader_exports));
5208
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5209
- const identity = await loadIdentity2({ path: cmdOptions.path });
5210
- if (cmdOptions.json) {
5211
- console.log(JSON.stringify(identity, null, 2));
5212
- } else {
5213
- console.log("Application Identity:\n");
5214
- console.log(` Binary Name: ${identity.app.binary_name}`);
5215
- console.log(` Vendor: ${identity.app.vendor}`);
5216
- console.log(` Env Prefix: ${identity.app.env_prefix}`);
5217
- console.log(` Config Name: ${identity.app.config_name}`);
5218
- console.log(` Description: ${identity.app.description}`);
5219
- if (identity.metadata) {
5220
- console.log("\nMetadata:");
5221
- if (identity.metadata.license) {
5222
- console.log(` License: ${identity.metadata.license}`);
5223
- }
5224
- if (identity.metadata.repository_category) {
5225
- console.log(` Category: ${identity.metadata.repository_category}`);
5226
- }
5227
- if (identity.metadata.telemetry_namespace) {
5228
- console.log(` Telemetry: ${identity.metadata.telemetry_namespace}`);
5229
- }
5230
- if (identity.metadata.project_url) {
5231
- console.log(` Project URL: ${identity.metadata.project_url}`);
5232
- }
5233
- }
5234
- }
5235
- process.exit(exitCodes2.EXIT_SUCCESS);
5236
- } catch (error) {
5237
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5238
- const { AppIdentityError: AppIdentityError2 } = await Promise.resolve().then(() => (init_errors5(), errors_exports2));
5239
- console.error("\u274C Failed to load identity:", error.message);
5240
- if (error instanceof AppIdentityError2) {
5241
- if (error.message.includes("not found")) {
5242
- process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5243
- }
5244
- if (error.message.includes("Invalid") || error.message.includes("validation")) {
5245
- process.exit(exitCodes2.EXIT_DATA_INVALID);
5246
- }
5247
- }
5248
- process.exit(exitCodes2.EXIT_FAILURE);
5249
- }
5250
- });
5251
- program.command("identity-validate").description("Validate application identity against schema").argument("[file]", "Path to app.yaml (defaults to discovery)").action(async (file) => {
5252
- try {
5253
- const { loadIdentity: loadIdentity2 } = await Promise.resolve().then(() => (init_loader2(), loader_exports));
5254
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5255
- console.log("Validating application identity...");
5256
- const identity = await loadIdentity2({ path: file });
5257
- console.log("\u2705 Identity is valid");
5258
- console.log(` Binary: ${identity.app.binary_name}`);
5259
- console.log(` Vendor: ${identity.app.vendor}`);
5260
- process.exit(exitCodes2.EXIT_SUCCESS);
5261
- } catch (error) {
5262
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5263
- const { AppIdentityError: AppIdentityError2 } = await Promise.resolve().then(() => (init_errors5(), errors_exports2));
5264
- console.error("\u274C Identity validation failed:", error.message);
5265
- if (error instanceof AppIdentityError2) {
5266
- if (error.message.includes("not found")) {
5267
- process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5268
- }
5269
- if (error.message.includes("Invalid") || error.message.includes("validation")) {
5270
- process.exit(exitCodes2.EXIT_DATA_INVALID);
5271
- }
5272
- }
5273
- process.exit(exitCodes2.EXIT_FAILURE);
5274
- }
5275
- });
5276
- return program;
5277
- }
5278
- var init_cli = __esm({
5279
- "src/schema/cli.ts"() {
5280
- init_goneat_bridge();
5281
- init_normalizer();
5282
- init_registry();
5283
- init_utils();
5284
- init_validator();
5285
- if (import.meta.url === `file://${process.argv[1]}`) {
5286
- const program = createCLI();
5287
- program.parse(process.argv);
5288
- }
5289
- }
5290
- });
5291
-
5292
- // src/schema/index.ts
5293
- var init_schema = __esm({
5294
- "src/schema/index.ts"() {
5295
- init_cli();
5296
- init_errors();
5297
- init_export();
5298
- init_goneat_bridge();
5299
- init_normalizer();
5300
- init_registry();
5301
- init_utils();
5302
- init_validator();
5303
- }
5304
- });
5305
-
5306
- // src/errors/validators.ts
5307
- async function validateErrorData(data) {
5308
- return ErrorValidator.getInstance().validate(data);
5309
- }
5310
- var ErrorValidator;
5311
- var init_validators2 = __esm({
5312
- "src/errors/validators.ts"() {
5313
- init_schema();
5314
- ErrorValidator = class _ErrorValidator {
5315
- static instance;
5316
- validateFn = null;
5317
- initPromise = null;
5318
- initError = null;
5319
- constructor() {
5320
- }
5321
- /**
5322
- * Get singleton instance
5323
- */
5324
- static getInstance() {
5325
- if (!_ErrorValidator.instance) {
5326
- _ErrorValidator.instance = new _ErrorValidator();
5327
- }
5328
- return _ErrorValidator.instance;
5329
- }
5330
- /**
5331
- * Initialize validator (lazy load, async)
5332
- */
5333
- async init() {
5334
- if (this.validateFn !== null || this.initError !== null) {
5335
- return;
5336
- }
5337
- if (this.initPromise) {
5338
- return this.initPromise;
5339
- }
5340
- this.initPromise = (async () => {
5341
- try {
5342
- await compileSchemaById("pathfinder/v1.0.0/error-response");
5343
- await compileSchemaById("assessment/v1.0.0/severity-definitions");
5344
- this.validateFn = await compileSchemaById("error-handling/v1.0.0/error-response");
5345
- } catch (err) {
5346
- this.initError = err instanceof Error ? err : new Error(String(err));
5347
- throw new Error(`Failed to initialize error validator: ${this.initError.message}`);
5348
- }
5349
- })();
5350
- return this.initPromise;
5351
- }
5352
- /**
5353
- * Validate error data against schema
5354
- *
5355
- * @param data - Data to validate
5356
- * @returns Promise resolving to true if valid, false otherwise
5357
- * @throws {Error} If validator failed to initialize
5358
- */
5359
- async validate(data) {
5360
- if (this.validateFn === null) {
5361
- await this.init();
5362
- }
5363
- if (this.initError) {
5364
- throw this.initError;
5365
- }
5366
- if (!this.validateFn) {
5367
- throw new Error("Validator not initialized");
5368
- }
5369
- return this.validateFn(data);
5370
- }
5371
- /**
5372
- * Get validation errors from last validation
5373
- *
5374
- * @returns Validation errors or null
5375
- */
5376
- getErrors() {
5377
- if (!this.validateFn) {
5378
- return null;
5379
- }
5380
- return this.validateFn.errors;
5381
- }
5382
- /**
5383
- * Reset validator state (for testing)
5384
- * @internal
5385
- */
5386
- static _reset() {
5387
- _ErrorValidator.instance = new _ErrorValidator();
5388
- }
5389
- };
5390
- }
5391
- });
5392
-
5393
- // src/errors/fulmen-error.ts
5394
- function isFulmenErrorData(value) {
5395
- return typeof value === "object" && value !== null && "code" in value && typeof value.code === "string" && "message" in value && typeof value.message === "string";
5396
- }
5397
- var FulmenError;
5398
- var init_fulmen_error = __esm({
5399
- "src/errors/fulmen-error.ts"() {
5400
- init_serialization();
5401
- init_severity();
5402
- init_validators2();
5403
- FulmenError = class _FulmenError extends Error {
5404
- data;
5405
- constructor(data) {
5406
- super(data.message);
5407
- this.name = "FulmenError";
5408
- this.data = Object.freeze({ ...data });
5409
- Error.captureStackTrace(this, _FulmenError);
5410
- }
5411
- /**
5412
- * Serialize to JSON (schema-compliant)
5413
- */
5414
- toJSON() {
5415
- return this.data;
5015
+ /**
5016
+ * Serialize to JSON (schema-compliant)
5017
+ */
5018
+ toJSON() {
5019
+ return this.data;
5416
5020
  }
5417
5021
  /**
5418
5022
  * Check equality with another FulmenError
@@ -5666,12 +5270,568 @@ ${cause.message}`;
5666
5270
  ${cause.message}`;
5667
5271
  return new _AppIdentityError(message, path, cause);
5668
5272
  }
5669
- };
5273
+ /**
5274
+ * Create error for embedded identity already registered
5275
+ *
5276
+ * Uses first-wins semantics - once registered, cannot be replaced
5277
+ */
5278
+ static alreadyRegistered() {
5279
+ const message = "Embedded identity already registered. Registration uses first-wins semantics and cannot be replaced.";
5280
+ return new _AppIdentityError(message);
5281
+ }
5282
+ /**
5283
+ * Create error for embedded identity YAML parsing failure
5284
+ */
5285
+ static embeddedParseFailed(cause) {
5286
+ const message = `Failed to parse embedded identity YAML: ${cause.message}`;
5287
+ return new _AppIdentityError(message, void 0, cause);
5288
+ }
5289
+ /**
5290
+ * Create error for embedded identity schema validation failure
5291
+ */
5292
+ static embeddedValidationFailed(diagnostics) {
5293
+ const errorCount = diagnostics.filter((d) => d.severity === "ERROR").length;
5294
+ const warningCount = diagnostics.filter((d) => d.severity === "WARN").length;
5295
+ let message = "Invalid embedded identity\n";
5296
+ message += `Validation errors: ${errorCount} error(s), ${warningCount} warning(s)
5297
+ `;
5298
+ const displayDiagnostics = diagnostics.slice(0, 3);
5299
+ for (const diag of displayDiagnostics) {
5300
+ message += ` - ${diag.message}`;
5301
+ if (diag.pointer) {
5302
+ message += ` at ${diag.pointer}`;
5303
+ }
5304
+ message += "\n";
5305
+ }
5306
+ if (diagnostics.length > 3) {
5307
+ message += ` ... and ${diagnostics.length - 3} more
5308
+ `;
5309
+ }
5310
+ return new _AppIdentityError(message);
5311
+ }
5312
+ };
5313
+ }
5314
+ });
5315
+ async function discoverIdentityPath(options) {
5316
+ if (options?.path) {
5317
+ const exists = await fileExists(options.path);
5318
+ if (!exists) {
5319
+ throw AppIdentityError.notFound([options.path]);
5320
+ }
5321
+ return { path: options.path, source: "explicit" };
5322
+ }
5323
+ const envPath = process.env[APP_IDENTITY_ENV_VAR];
5324
+ if (envPath) {
5325
+ const exists = await fileExists(envPath);
5326
+ if (!exists) {
5327
+ throw AppIdentityError.envOverrideMissing(envPath);
5328
+ }
5329
+ return { path: envPath, source: "env" };
5330
+ }
5331
+ const startDir = options?.startDir || process.cwd();
5332
+ const result = await searchAncestors(startDir);
5333
+ if (result) {
5334
+ return { path: result, source: "ancestor" };
5335
+ }
5336
+ return null;
5337
+ }
5338
+ async function searchAncestors(startDir) {
5339
+ let currentDir = startDir;
5340
+ const searchedPaths = [];
5341
+ for (let i = 0; i < MAX_ANCESTOR_SEARCH_DEPTH; i++) {
5342
+ const candidatePath = join(currentDir, APP_IDENTITY_DIR, APP_IDENTITY_FILENAME);
5343
+ searchedPaths.push(candidatePath);
5344
+ if (await fileExists(candidatePath)) {
5345
+ return candidatePath;
5346
+ }
5347
+ const parentDir = dirname(currentDir);
5348
+ if (parentDir === currentDir) {
5349
+ throw AppIdentityError.notFound(searchedPaths);
5350
+ }
5351
+ currentDir = parentDir;
5352
+ }
5353
+ throw AppIdentityError.notFound(searchedPaths);
5354
+ }
5355
+ async function fileExists(path) {
5356
+ try {
5357
+ await access(path);
5358
+ return true;
5359
+ } catch {
5360
+ return false;
5361
+ }
5362
+ }
5363
+ var init_discovery = __esm({
5364
+ "src/appidentity/discovery.ts"() {
5365
+ init_constants();
5366
+ init_errors5();
5367
+ }
5368
+ });
5369
+
5370
+ // src/appidentity/loader.ts
5371
+ var loader_exports = {};
5372
+ __export(loader_exports, {
5373
+ clearIdentityCache: () => clearIdentityCache,
5374
+ getCachedIdentity: () => getCachedIdentity,
5375
+ loadIdentity: () => loadIdentity
5376
+ });
5377
+ function deepFreeze5(obj) {
5378
+ Object.freeze(obj);
5379
+ Object.getOwnPropertyNames(obj).forEach((prop) => {
5380
+ const value = obj[prop];
5381
+ if (value !== null && (typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) {
5382
+ deepFreeze5(value);
5383
+ }
5384
+ });
5385
+ return obj;
5386
+ }
5387
+ async function loadIdentity(options) {
5388
+ if (options?.identity) {
5389
+ return deepFreeze5(structuredClone(options.identity));
5390
+ }
5391
+ if (!options?.skipCache) {
5392
+ const cached = getCachedIdentity();
5393
+ if (cached) {
5394
+ return cached;
5395
+ }
5396
+ }
5397
+ let discovery;
5398
+ try {
5399
+ discovery = await discoverIdentityPath({
5400
+ path: options?.path,
5401
+ startDir: options?.startDir
5402
+ });
5403
+ } catch (error) {
5404
+ const hasExplicitPath = Boolean(options?.path);
5405
+ const hasEnvOverride = Boolean(process.env[APP_IDENTITY_ENV_VAR]);
5406
+ if (!hasExplicitPath && !hasEnvOverride && error instanceof AppIdentityError) {
5407
+ const embedded = getEmbeddedIdentity();
5408
+ if (embedded) {
5409
+ setCachedIdentity(embedded);
5410
+ return embedded;
5411
+ }
5412
+ }
5413
+ throw error;
5414
+ }
5415
+ if (!discovery) {
5416
+ const embedded = getEmbeddedIdentity();
5417
+ if (embedded) {
5418
+ setCachedIdentity(embedded);
5419
+ return embedded;
5420
+ }
5421
+ throw AppIdentityError.notFound([]);
5422
+ }
5423
+ let content;
5424
+ try {
5425
+ content = await readFile(discovery.path, "utf-8");
5426
+ } catch (error) {
5427
+ throw AppIdentityError.readFailed(
5428
+ discovery.path,
5429
+ error instanceof Error ? error : new Error(String(error))
5430
+ );
5431
+ }
5432
+ let parsed;
5433
+ try {
5434
+ parsed = parse(content);
5435
+ } catch (error) {
5436
+ throw AppIdentityError.parseFailed(
5437
+ discovery.path,
5438
+ error instanceof Error ? error : new Error(String(error))
5439
+ );
5440
+ }
5441
+ if (!options?.skipValidation) {
5442
+ const result = await validateDataBySchemaId(parsed, APP_IDENTITY_SCHEMA_ID);
5443
+ if (!result.valid) {
5444
+ throw AppIdentityError.validationFailed(discovery.path, result.diagnostics);
5445
+ }
5446
+ }
5447
+ const identity = deepFreeze5(structuredClone(parsed));
5448
+ setCachedIdentity(identity);
5449
+ return identity;
5450
+ }
5451
+ var init_loader2 = __esm({
5452
+ "src/appidentity/loader.ts"() {
5453
+ init_schema();
5454
+ init_cache();
5455
+ init_constants();
5456
+ init_discovery();
5457
+ init_embedded();
5458
+ init_errors5();
5459
+ }
5460
+ });
5461
+ function createCLI(options = {}) {
5462
+ const program = new Command();
5463
+ program.name("tsfulmen-schema").description("Schema validation and discovery CLI for Fulmen (developer tool)").version("0.1.0");
5464
+ program.command("list").description("List available schemas from registry").argument("[prefix]", "Filter schemas by prefix").option("--base-dir <path>", "Override schema base directory").action(async (prefix, cmdOptions) => {
5465
+ try {
5466
+ const schemas = await listSchemas(prefix, {
5467
+ baseDir: cmdOptions?.baseDir || options.baseDir
5468
+ });
5469
+ if (schemas.length === 0) {
5470
+ console.log("No schemas found");
5471
+ return;
5472
+ }
5473
+ console.log(`Found ${schemas.length} schema(s):
5474
+ `);
5475
+ for (const schema of schemas) {
5476
+ console.log(` ${schema.id}`);
5477
+ console.log(` Format: ${schema.format}`);
5478
+ console.log(` Path: ${schema.relativePath}`);
5479
+ if (schema.description) {
5480
+ console.log(` Description: ${schema.description}`);
5481
+ }
5482
+ console.log();
5483
+ }
5484
+ } catch (error) {
5485
+ console.error("Error listing schemas:", error.message);
5486
+ process.exit(1);
5487
+ }
5488
+ });
5489
+ program.command("show").description("Show schema details").requiredOption("--schema-id <id>", "Schema ID to show").option("--base-dir <path>", "Override schema base directory").action(async (cmdOptions) => {
5490
+ try {
5491
+ const registry = getSchemaRegistry({
5492
+ baseDir: cmdOptions.baseDir || options.baseDir
5493
+ });
5494
+ const schema = await registry.getSchema(cmdOptions.schemaId);
5495
+ console.log("Schema Details:\n");
5496
+ console.log(` ID: ${schema.id}`);
5497
+ console.log(` Format: ${schema.format}`);
5498
+ console.log(` Path: ${schema.path}`);
5499
+ console.log(` Relative Path: ${schema.relativePath}`);
5500
+ if (schema.version) {
5501
+ console.log(` Version: ${schema.version}`);
5502
+ }
5503
+ if (schema.description) {
5504
+ console.log(` Description: ${schema.description}`);
5505
+ }
5506
+ if (schema.schemaDraft) {
5507
+ console.log(` Schema Draft: ${schema.schemaDraft}`);
5508
+ }
5509
+ const content = await readFile(schema.path, "utf-8");
5510
+ console.log("\nSchema Content:");
5511
+ console.log(content);
5512
+ } catch (error) {
5513
+ console.error("Error showing schema:", error.message);
5514
+ process.exit(1);
5515
+ }
5516
+ });
5517
+ program.command("validate").description("Validate data file against schema").requiredOption("--schema-id <id>", "Schema ID to validate against").argument("<file>", "Data file to validate").option("--use-goneat", "Use goneat for validation (requires goneat binary)").option("--goneat-path <path>", "Path to goneat binary").option("--base-dir <path>", "Override schema base directory").action(
5518
+ async (file, cmdOptions) => {
5519
+ try {
5520
+ let result;
5521
+ if (cmdOptions.useGoneat) {
5522
+ const available = await isGoneatAvailable(cmdOptions.goneatPath);
5523
+ if (!available) {
5524
+ console.error("\u274C goneat not available. Install goneat or remove --use-goneat flag.");
5525
+ console.error(" AJV validation (default) works without external dependencies.");
5526
+ process.exit(1);
5527
+ }
5528
+ const registry = getSchemaRegistry({
5529
+ baseDir: cmdOptions.baseDir || options.baseDir
5530
+ });
5531
+ const schema = await registry.getSchema(cmdOptions.schemaId);
5532
+ console.log("Using goneat validation...");
5533
+ result = await runGoneatValidation(schema.path, file, cmdOptions.goneatPath);
5534
+ } else {
5535
+ console.log("Using AJV validation...");
5536
+ result = await validateFileBySchemaId(file, cmdOptions.schemaId, {
5537
+ baseDir: cmdOptions.baseDir || options.baseDir
5538
+ });
5539
+ }
5540
+ if (result.valid) {
5541
+ console.log(`\u2705 Validation passed (${result.source})`);
5542
+ process.exit(0);
5543
+ } else {
5544
+ console.log(`\u274C Validation failed (${result.source})`);
5545
+ console.log("\nDiagnostics:");
5546
+ console.log(formatDiagnostics(result.diagnostics));
5547
+ process.exit(1);
5548
+ }
5549
+ } catch (error) {
5550
+ console.error("Error validating file:", error.message);
5551
+ process.exit(1);
5552
+ }
5553
+ }
5554
+ );
5555
+ program.command("validate-schema").description("Validate a schema file itself").argument("<file>", "Schema file to validate").action(async (file) => {
5556
+ try {
5557
+ const content = await readFile(file, "utf-8");
5558
+ const { validateSchema: validateSchema2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
5559
+ const result = await validateSchema2(content);
5560
+ if (result.valid) {
5561
+ console.log("\u2705 Schema is valid");
5562
+ process.exit(0);
5563
+ } else {
5564
+ console.log("\u274C Schema is invalid");
5565
+ console.log("\nDiagnostics:");
5566
+ console.log(formatDiagnostics(result.diagnostics));
5567
+ process.exit(1);
5568
+ }
5569
+ } catch (error) {
5570
+ console.error("Error validating schema:", error.message);
5571
+ process.exit(1);
5572
+ }
5573
+ });
5574
+ program.command("normalize").description("Normalize schema to canonical JSON format").argument("<file>", "Schema file to normalize").option("--compact", "Output compact JSON (no formatting)").option("-o, --output <file>", "Write to output file instead of stdout").action(async (file, cmdOptions) => {
5575
+ try {
5576
+ const content = await readFile(file, "utf-8");
5577
+ const normalized = normalizeSchema(content, {
5578
+ compact: cmdOptions.compact
5579
+ });
5580
+ if (cmdOptions.output) {
5581
+ await writeFile(cmdOptions.output, normalized, "utf-8");
5582
+ console.log(`\u2705 Normalized schema written to ${cmdOptions.output}`);
5583
+ } else {
5584
+ console.log(normalized);
5585
+ }
5586
+ } catch (error) {
5587
+ console.error("Error normalizing schema:", error.message);
5588
+ process.exit(1);
5589
+ }
5590
+ });
5591
+ program.command("compare").description("Compare two schemas for semantic equality").argument("<file1>", "First schema file").argument("<file2>", "Second schema file").option("--show-normalized", "Show normalized outputs").action(async (file1, file2, cmdOptions) => {
5592
+ try {
5593
+ const content1 = await readFile(file1, "utf-8");
5594
+ const content2 = await readFile(file2, "utf-8");
5595
+ const result = compareSchemas(content1, content2);
5596
+ if (result.equal) {
5597
+ console.log("\u2705 Schemas are semantically equal");
5598
+ } else {
5599
+ console.log("\u274C Schemas differ");
5600
+ }
5601
+ if (cmdOptions.showNormalized) {
5602
+ console.log("\nNormalized Schema 1:");
5603
+ console.log(result.normalizedA);
5604
+ console.log("\nNormalized Schema 2:");
5605
+ console.log(result.normalizedB);
5606
+ }
5607
+ process.exit(result.equal ? 0 : 1);
5608
+ } catch (error) {
5609
+ console.error("Error comparing schemas:", error.message);
5610
+ process.exit(1);
5611
+ }
5612
+ });
5613
+ program.command("export").description("Export schema from registry to file with provenance").requiredOption("--schema-id <id>", "Schema ID to export").requiredOption("--out <path>", "Output file path").option("--force", "Overwrite existing file", false).option("--no-provenance", "Exclude provenance metadata").option("--no-validate", "Skip schema validation before export").option("--format <format>", "Export format (json|yaml|auto)", "auto").option("--base-dir <path>", "Override schema base directory").action(
5614
+ async (cmdOptions) => {
5615
+ try {
5616
+ const { exportSchema: exportSchema2 } = await Promise.resolve().then(() => (init_export(), export_exports));
5617
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5618
+ const result = await exportSchema2({
5619
+ schemaId: cmdOptions.schemaId,
5620
+ outPath: cmdOptions.out,
5621
+ includeProvenance: cmdOptions.provenance ?? true,
5622
+ validate: cmdOptions.validate ?? true,
5623
+ overwrite: cmdOptions.force ?? false,
5624
+ format: cmdOptions.format ?? "auto",
5625
+ baseDir: cmdOptions.baseDir || options.baseDir
5626
+ });
5627
+ console.log("\u2705 Schema exported successfully");
5628
+ console.log(` Schema ID: ${result.schemaId}`);
5629
+ console.log(` Output: ${result.outPath}`);
5630
+ console.log(` Format: ${result.format}`);
5631
+ if (result.provenance) {
5632
+ console.log("\nProvenance:");
5633
+ console.log(` Crucible: ${result.provenance.crucible_version}`);
5634
+ console.log(` Library: ${result.provenance.library_version}`);
5635
+ if (result.provenance.revision) {
5636
+ console.log(` Revision: ${result.provenance.revision}`);
5637
+ }
5638
+ console.log(` Exported: ${result.provenance.exported_at}`);
5639
+ }
5640
+ process.exit(exitCodes2.EXIT_SUCCESS);
5641
+ } catch (error) {
5642
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5643
+ const { SchemaExportError: SchemaExportError2, SchemaValidationError: SchemaValidationError2, ExportErrorReason: ExportErrorReason2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
5644
+ console.error("\u274C Schema export failed:", error.message);
5645
+ if (error instanceof SchemaExportError2) {
5646
+ if (error.outPath) {
5647
+ console.error(` Output path: ${error.outPath}`);
5648
+ }
5649
+ switch (error.reason) {
5650
+ case ExportErrorReason2.FILE_EXISTS:
5651
+ case ExportErrorReason2.WRITE_FAILED:
5652
+ process.exit(exitCodes2.EXIT_FILE_WRITE_ERROR);
5653
+ break;
5654
+ case ExportErrorReason2.INVALID_FORMAT:
5655
+ process.exit(exitCodes2.EXIT_INVALID_ARGUMENT);
5656
+ break;
5657
+ default:
5658
+ process.exit(exitCodes2.EXIT_FAILURE);
5659
+ }
5660
+ }
5661
+ if (error instanceof SchemaValidationError2) {
5662
+ const errorMsg = error.message.toLowerCase();
5663
+ if (errorMsg.includes("not found")) {
5664
+ process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5665
+ }
5666
+ process.exit(exitCodes2.EXIT_DATA_INVALID);
5667
+ }
5668
+ process.exit(exitCodes2.EXIT_FAILURE);
5669
+ }
5670
+ }
5671
+ );
5672
+ program.command("identity-show").description("Show application identity from .fulmen/app.yaml").option("--path <path>", "Explicit path to app.yaml").option("--json", "Output as JSON").action(async (cmdOptions) => {
5673
+ try {
5674
+ const { loadIdentity: loadIdentity2 } = await Promise.resolve().then(() => (init_loader2(), loader_exports));
5675
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5676
+ const identity = await loadIdentity2({ path: cmdOptions.path });
5677
+ if (cmdOptions.json) {
5678
+ console.log(JSON.stringify(identity, null, 2));
5679
+ } else {
5680
+ console.log("Application Identity:\n");
5681
+ console.log(` Binary Name: ${identity.app.binary_name}`);
5682
+ console.log(` Vendor: ${identity.app.vendor}`);
5683
+ console.log(` Env Prefix: ${identity.app.env_prefix}`);
5684
+ console.log(` Config Name: ${identity.app.config_name}`);
5685
+ console.log(` Description: ${identity.app.description}`);
5686
+ if (identity.metadata) {
5687
+ console.log("\nMetadata:");
5688
+ if (identity.metadata.license) {
5689
+ console.log(` License: ${identity.metadata.license}`);
5690
+ }
5691
+ if (identity.metadata.repository_category) {
5692
+ console.log(` Category: ${identity.metadata.repository_category}`);
5693
+ }
5694
+ if (identity.metadata.telemetry_namespace) {
5695
+ console.log(` Telemetry: ${identity.metadata.telemetry_namespace}`);
5696
+ }
5697
+ if (identity.metadata.project_url) {
5698
+ console.log(` Project URL: ${identity.metadata.project_url}`);
5699
+ }
5700
+ }
5701
+ }
5702
+ process.exit(exitCodes2.EXIT_SUCCESS);
5703
+ } catch (error) {
5704
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5705
+ const { AppIdentityError: AppIdentityError2 } = await Promise.resolve().then(() => (init_errors5(), errors_exports2));
5706
+ console.error("\u274C Failed to load identity:", error.message);
5707
+ if (error instanceof AppIdentityError2) {
5708
+ if (error.message.includes("not found")) {
5709
+ process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5710
+ }
5711
+ if (error.message.includes("Invalid") || error.message.includes("validation")) {
5712
+ process.exit(exitCodes2.EXIT_DATA_INVALID);
5713
+ }
5714
+ }
5715
+ process.exit(exitCodes2.EXIT_FAILURE);
5716
+ }
5717
+ });
5718
+ program.command("identity-validate").description("Validate application identity against schema").argument("[file]", "Path to app.yaml (defaults to discovery)").action(async (file) => {
5719
+ try {
5720
+ const { loadIdentity: loadIdentity2 } = await Promise.resolve().then(() => (init_loader2(), loader_exports));
5721
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5722
+ console.log("Validating application identity...");
5723
+ const identity = await loadIdentity2({ path: file });
5724
+ console.log("\u2705 Identity is valid");
5725
+ console.log(` Binary: ${identity.app.binary_name}`);
5726
+ console.log(` Vendor: ${identity.app.vendor}`);
5727
+ process.exit(exitCodes2.EXIT_SUCCESS);
5728
+ } catch (error) {
5729
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5730
+ const { AppIdentityError: AppIdentityError2 } = await Promise.resolve().then(() => (init_errors5(), errors_exports2));
5731
+ console.error("\u274C Identity validation failed:", error.message);
5732
+ if (error instanceof AppIdentityError2) {
5733
+ if (error.message.includes("not found")) {
5734
+ process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5735
+ }
5736
+ if (error.message.includes("Invalid") || error.message.includes("validation")) {
5737
+ process.exit(exitCodes2.EXIT_DATA_INVALID);
5738
+ }
5739
+ }
5740
+ process.exit(exitCodes2.EXIT_FAILURE);
5741
+ }
5742
+ });
5743
+ return program;
5744
+ }
5745
+ var init_cli = __esm({
5746
+ "src/schema/cli.ts"() {
5747
+ init_goneat_bridge();
5748
+ init_normalizer();
5749
+ init_registry();
5750
+ init_utils();
5751
+ init_validator();
5752
+ if (import.meta.url === `file://${process.argv[1]}`) {
5753
+ const program = createCLI();
5754
+ program.parse(process.argv);
5755
+ }
5756
+ }
5757
+ });
5758
+
5759
+ // src/schema/index.ts
5760
+ var init_schema = __esm({
5761
+ "src/schema/index.ts"() {
5762
+ init_cli();
5763
+ init_errors();
5764
+ init_export();
5765
+ init_goneat_bridge();
5766
+ init_normalizer();
5767
+ init_registry();
5768
+ init_utils();
5769
+ init_validator();
5770
+ }
5771
+ });
5772
+ function deepFreeze6(obj) {
5773
+ Object.freeze(obj);
5774
+ Object.getOwnPropertyNames(obj).forEach((prop) => {
5775
+ const value = obj[prop];
5776
+ if (value !== null && (typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) {
5777
+ deepFreeze6(value);
5778
+ }
5779
+ });
5780
+ return obj;
5781
+ }
5782
+ async function registerEmbeddedIdentity(data) {
5783
+ if (isRegistered) {
5784
+ throw AppIdentityError.alreadyRegistered();
5785
+ }
5786
+ let identity;
5787
+ if (typeof data === "string") {
5788
+ let parsed;
5789
+ try {
5790
+ parsed = parse(data);
5791
+ } catch (error) {
5792
+ throw AppIdentityError.embeddedParseFailed(
5793
+ error instanceof Error ? error : new Error(String(error))
5794
+ );
5795
+ }
5796
+ const result = await validateDataBySchemaId(parsed, APP_IDENTITY_SCHEMA_ID);
5797
+ if (!result.valid) {
5798
+ throw AppIdentityError.embeddedValidationFailed(result.diagnostics);
5799
+ }
5800
+ identity = parsed;
5801
+ } else {
5802
+ const result = await validateDataBySchemaId(data, APP_IDENTITY_SCHEMA_ID);
5803
+ if (!result.valid) {
5804
+ throw AppIdentityError.embeddedValidationFailed(result.diagnostics);
5805
+ }
5806
+ identity = data;
5807
+ }
5808
+ embeddedIdentity = deepFreeze6(structuredClone(identity));
5809
+ isRegistered = true;
5810
+ }
5811
+ function hasEmbeddedIdentity() {
5812
+ return isRegistered;
5813
+ }
5814
+ function getEmbeddedIdentity() {
5815
+ return embeddedIdentity;
5816
+ }
5817
+ function clearEmbeddedIdentity() {
5818
+ embeddedIdentity = null;
5819
+ isRegistered = false;
5820
+ }
5821
+ var embeddedIdentity, isRegistered;
5822
+ var init_embedded = __esm({
5823
+ "src/appidentity/embedded.ts"() {
5824
+ init_schema();
5825
+ init_constants();
5826
+ init_errors5();
5827
+ embeddedIdentity = null;
5828
+ isRegistered = false;
5670
5829
  }
5671
5830
  });
5672
5831
 
5673
5832
  // src/appidentity/index.ts
5674
5833
  init_constants();
5834
+ init_embedded();
5675
5835
  init_errors5();
5676
5836
 
5677
5837
  // src/appidentity/helpers.ts
@@ -5716,6 +5876,6 @@ async function getEnvVar(key, options) {
5716
5876
  // src/appidentity/index.ts
5717
5877
  init_loader2();
5718
5878
 
5719
- export { APP_IDENTITY_DIR, APP_IDENTITY_ENV_VAR, APP_IDENTITY_FILENAME, APP_IDENTITY_SCHEMA_ID, AppIdentityError, MAX_ANCESTOR_SEARCH_DEPTH, buildEnvVar, clearIdentityCache, getBinaryName, getCachedIdentity, getConfigIdentifiers, getConfigName, getEnvPrefix, getEnvVar, getTelemetryNamespace, getVendor, loadIdentity };
5879
+ export { APP_IDENTITY_DIR, APP_IDENTITY_ENV_VAR, APP_IDENTITY_FILENAME, APP_IDENTITY_SCHEMA_ID, AppIdentityError, MAX_ANCESTOR_SEARCH_DEPTH, buildEnvVar, clearEmbeddedIdentity, clearIdentityCache, getBinaryName, getCachedIdentity, getConfigIdentifiers, getConfigName, getEmbeddedIdentity, getEnvPrefix, getEnvVar, getTelemetryNamespace, getVendor, hasEmbeddedIdentity, loadIdentity, registerEmbeddedIdentity };
5720
5880
  //# sourceMappingURL=index.js.map
5721
5881
  //# sourceMappingURL=index.js.map