@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
package/dist/index.js CHANGED
@@ -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, parseDocument } from 'yaml';
@@ -10,6 +9,7 @@ import addFormats from 'ajv-formats';
10
9
  import { pipeline, 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
  import { existsSync, mkdirSync, statSync, createReadStream, createWriteStream, readdirSync, lstatSync } from 'fs';
15
15
  import { createGunzip, createGzip } from 'zlib';
@@ -42,68 +42,6 @@ var init_constants = __esm({
42
42
  MAX_ANCESTOR_SEARCH_DEPTH = 20;
43
43
  }
44
44
  });
45
- var init_correlation = __esm({
46
- "src/errors/correlation.ts"() {
47
- }
48
- });
49
-
50
- // src/errors/severity.ts
51
- function getDefaultSeverity() {
52
- return {
53
- name: Severity.MEDIUM,
54
- level: 2
55
- };
56
- }
57
- var Severity, SEVERITY_LEVELS;
58
- var init_severity = __esm({
59
- "src/errors/severity.ts"() {
60
- Severity = {
61
- INFO: "info",
62
- LOW: "low",
63
- MEDIUM: "medium",
64
- HIGH: "high",
65
- CRITICAL: "critical"
66
- };
67
- SEVERITY_LEVELS = {
68
- info: 0,
69
- low: 1,
70
- medium: 2,
71
- high: 3,
72
- critical: 4
73
- };
74
- }
75
- });
76
-
77
- // src/errors/serialization.ts
78
- function extractErrorMessage(error) {
79
- if (error instanceof Error) {
80
- return error.message;
81
- }
82
- if (isErrorLike(error)) {
83
- return error.message;
84
- }
85
- if (typeof error === "string") {
86
- return error;
87
- }
88
- return String(error);
89
- }
90
- function extractStackTrace(error) {
91
- if (error instanceof Error) {
92
- return error.stack;
93
- }
94
- if (isErrorLike(error) && typeof error.stack === "string") {
95
- return error.stack;
96
- }
97
- return void 0;
98
- }
99
- function isErrorLike(value) {
100
- return typeof value === "object" && value !== null && "message" in value && typeof value.message === "string";
101
- }
102
- var init_serialization = __esm({
103
- "src/errors/serialization.ts"() {
104
- init_severity();
105
- }
106
- });
107
45
 
108
46
  // src/schema/errors.ts
109
47
  var errors_exports = {};
@@ -1594,7 +1532,10 @@ async function loadReferencedSchema(uri) {
1594
1532
  const repoRoot = join(__dirname4, "..", "..");
1595
1533
  let resolvedPath;
1596
1534
  if (uri.startsWith("https://schemas.fulmenhq.dev/")) {
1597
- const relativePath = uri.replace("https://schemas.fulmenhq.dev/", "");
1535
+ let relativePath = uri.replace("https://schemas.fulmenhq.dev/", "");
1536
+ if (relativePath.startsWith("crucible/")) {
1537
+ relativePath = relativePath.slice("crucible/".length);
1538
+ }
1598
1539
  if (relativePath.startsWith("config/taxonomy/")) {
1599
1540
  resolvedPath = join(
1600
1541
  repoRoot,
@@ -1811,7 +1752,9 @@ async function compileSchemaById(schemaId, registryOptions) {
1811
1752
  const aliases = [];
1812
1753
  const normalizedRelativePath = metadata.relativePath.replace(/\\/g, "/");
1813
1754
  if (normalizedRelativePath) {
1814
- aliases.push(new URL(normalizedRelativePath, "https://schemas.fulmenhq.dev/").toString());
1755
+ aliases.push(
1756
+ new URL(`crucible/${normalizedRelativePath}`, "https://schemas.fulmenhq.dev/").toString()
1757
+ );
1815
1758
  }
1816
1759
  return compileSchema(content, { aliases });
1817
1760
  } catch (error) {
@@ -2329,6 +2272,12 @@ var init_exitCodes = __esm({
2329
2272
  EXIT_TEST_USAGE_ERROR: 94,
2330
2273
  EXIT_TEST_NO_TESTS_COLLECTED: 95,
2331
2274
  EXIT_COVERAGE_THRESHOLD_NOT_MET: 96,
2275
+ // Shell & Process Control (124-127)
2276
+ // Exit codes from shell conventions and process control utilities (timeout, exec)
2277
+ EXIT_TIMEOUT: 124,
2278
+ EXIT_TIMEOUT_INTERNAL: 125,
2279
+ EXIT_CANNOT_EXECUTE: 126,
2280
+ EXIT_NOT_FOUND: 127,
2332
2281
  // Signal-Induced Exits (128-165)
2333
2282
  // 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.
2334
2283
  EXIT_SIGNAL_HUP: 129,
@@ -2666,6 +2615,36 @@ var init_exitCodes = __esm({
2666
2615
  context: "Code coverage validation, quality gate failure",
2667
2616
  category: "testing"
2668
2617
  },
2618
+ 124: {
2619
+ code: 124,
2620
+ name: "EXIT_TIMEOUT",
2621
+ description: "Command timed out before completion",
2622
+ context: "GNU timeout or similar utility terminated command after deadline",
2623
+ category: "shell"
2624
+ },
2625
+ 125: {
2626
+ code: 125,
2627
+ name: "EXIT_TIMEOUT_INTERNAL",
2628
+ description: "Timeout utility itself failed",
2629
+ context: "Error in timeout tool before or during command execution (not command failure)",
2630
+ category: "shell"
2631
+ },
2632
+ 126: {
2633
+ code: 126,
2634
+ name: "EXIT_CANNOT_EXECUTE",
2635
+ description: "Command found but could not be executed",
2636
+ context: "Permission denied, not executable, exec format error",
2637
+ category: "shell",
2638
+ bsdEquivalent: "EX_NOPERM (partial)"
2639
+ },
2640
+ 127: {
2641
+ code: 127,
2642
+ name: "EXIT_NOT_FOUND",
2643
+ description: "Command not found",
2644
+ context: "Executable not found in PATH or specified path does not exist",
2645
+ category: "shell",
2646
+ bsdEquivalent: "EX_UNAVAILABLE (partial)"
2647
+ },
2669
2648
  129: {
2670
2649
  code: 129,
2671
2650
  name: "EXIT_SIGNAL_HUP",
@@ -4874,554 +4853,179 @@ var init_cache = __esm({
4874
4853
  cachedIdentity = null;
4875
4854
  }
4876
4855
  });
4877
- async function discoverIdentityPath(options) {
4878
- if (options?.path) {
4879
- const exists = await fileExists(options.path);
4880
- if (!exists) {
4881
- throw AppIdentityError.notFound([options.path]);
4882
- }
4883
- return { path: options.path, source: "explicit" };
4884
- }
4885
- const envPath = process.env[APP_IDENTITY_ENV_VAR];
4886
- if (envPath) {
4887
- const exists = await fileExists(envPath);
4888
- if (!exists) {
4889
- throw AppIdentityError.envOverrideMissing(envPath);
4890
- }
4891
- return { path: envPath, source: "env" };
4892
- }
4893
- const startDir = options?.startDir || process.cwd();
4894
- const result = await searchAncestors(startDir);
4895
- if (result) {
4896
- return { path: result, source: "ancestor" };
4897
- }
4898
- return null;
4899
- }
4900
- async function searchAncestors(startDir) {
4901
- let currentDir = startDir;
4902
- const searchedPaths = [];
4903
- for (let i = 0; i < MAX_ANCESTOR_SEARCH_DEPTH; i++) {
4904
- const candidatePath = join(currentDir, APP_IDENTITY_DIR, APP_IDENTITY_FILENAME);
4905
- searchedPaths.push(candidatePath);
4906
- if (await fileExists(candidatePath)) {
4907
- return candidatePath;
4908
- }
4909
- const parentDir = dirname(currentDir);
4910
- if (parentDir === currentDir) {
4911
- throw AppIdentityError.notFound(searchedPaths);
4912
- }
4913
- currentDir = parentDir;
4914
- }
4915
- throw AppIdentityError.notFound(searchedPaths);
4916
- }
4917
- async function fileExists(path) {
4918
- try {
4919
- await access(path);
4920
- return true;
4921
- } catch {
4922
- return false;
4923
- }
4924
- }
4925
- var init_discovery = __esm({
4926
- "src/appidentity/discovery.ts"() {
4927
- init_constants();
4928
- init_errors5();
4856
+ var init_correlation = __esm({
4857
+ "src/errors/correlation.ts"() {
4929
4858
  }
4930
4859
  });
4931
4860
 
4932
- // src/appidentity/loader.ts
4933
- var loader_exports = {};
4934
- __export(loader_exports, {
4935
- clearIdentityCache: () => clearIdentityCache,
4936
- getCachedIdentity: () => getCachedIdentity,
4937
- loadIdentity: () => loadIdentity
4938
- });
4939
- function deepFreeze5(obj) {
4940
- Object.freeze(obj);
4941
- Object.getOwnPropertyNames(obj).forEach((prop) => {
4942
- const value = obj[prop];
4943
- if (value !== null && (typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) {
4944
- deepFreeze5(value);
4945
- }
4946
- });
4947
- return obj;
4861
+ // src/errors/severity.ts
4862
+ function getDefaultSeverity() {
4863
+ return {
4864
+ name: Severity.MEDIUM,
4865
+ level: 2
4866
+ };
4948
4867
  }
4949
- async function loadIdentity(options) {
4950
- if (options?.identity) {
4951
- return deepFreeze5(structuredClone(options.identity));
4868
+ var Severity, SEVERITY_LEVELS;
4869
+ var init_severity = __esm({
4870
+ "src/errors/severity.ts"() {
4871
+ Severity = {
4872
+ INFO: "info",
4873
+ LOW: "low",
4874
+ MEDIUM: "medium",
4875
+ HIGH: "high",
4876
+ CRITICAL: "critical"
4877
+ };
4878
+ SEVERITY_LEVELS = {
4879
+ info: 0,
4880
+ low: 1,
4881
+ medium: 2,
4882
+ high: 3,
4883
+ critical: 4
4884
+ };
4952
4885
  }
4953
- if (!options?.skipCache) {
4954
- const cached = getCachedIdentity();
4955
- if (cached) {
4956
- return cached;
4957
- }
4886
+ });
4887
+
4888
+ // src/errors/serialization.ts
4889
+ function extractErrorMessage(error) {
4890
+ if (error instanceof Error) {
4891
+ return error.message;
4958
4892
  }
4959
- const discovery = await discoverIdentityPath({
4960
- path: options?.path,
4961
- startDir: options?.startDir
4962
- });
4963
- if (!discovery) {
4964
- throw AppIdentityError.notFound([]);
4893
+ if (isErrorLike(error)) {
4894
+ return error.message;
4965
4895
  }
4966
- let content;
4967
- try {
4968
- content = await readFile(discovery.path, "utf-8");
4969
- } catch (error) {
4970
- throw AppIdentityError.readFailed(
4971
- discovery.path,
4972
- error instanceof Error ? error : new Error(String(error))
4973
- );
4896
+ if (typeof error === "string") {
4897
+ return error;
4974
4898
  }
4975
- let parsed;
4976
- try {
4977
- parsed = parse(content);
4978
- } catch (error) {
4979
- throw AppIdentityError.parseFailed(
4980
- discovery.path,
4981
- error instanceof Error ? error : new Error(String(error))
4982
- );
4899
+ return String(error);
4900
+ }
4901
+ function extractStackTrace(error) {
4902
+ if (error instanceof Error) {
4903
+ return error.stack;
4983
4904
  }
4984
- if (!options?.skipValidation) {
4985
- const result = await validateDataBySchemaId(parsed, APP_IDENTITY_SCHEMA_ID);
4986
- if (!result.valid) {
4987
- throw AppIdentityError.validationFailed(discovery.path, result.diagnostics);
4988
- }
4905
+ if (isErrorLike(error) && typeof error.stack === "string") {
4906
+ return error.stack;
4989
4907
  }
4990
- const identity = deepFreeze5(structuredClone(parsed));
4991
- setCachedIdentity(identity);
4992
- return identity;
4908
+ return void 0;
4993
4909
  }
4994
- var init_loader2 = __esm({
4995
- "src/appidentity/loader.ts"() {
4996
- init_schema();
4997
- init_cache();
4998
- init_constants();
4999
- init_discovery();
5000
- init_errors5();
4910
+ function isErrorLike(value) {
4911
+ return typeof value === "object" && value !== null && "message" in value && typeof value.message === "string";
4912
+ }
4913
+ var init_serialization = __esm({
4914
+ "src/errors/serialization.ts"() {
4915
+ init_severity();
5001
4916
  }
5002
4917
  });
5003
- function createCLI(options = {}) {
5004
- const program = new Command();
5005
- program.name("tsfulmen-schema").description("Schema validation and discovery CLI for Fulmen (developer tool)").version("0.1.0");
5006
- 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) => {
5007
- try {
5008
- const schemas = await listSchemas(prefix, {
5009
- baseDir: cmdOptions?.baseDir || options.baseDir
5010
- });
5011
- if (schemas.length === 0) {
5012
- console.log("No schemas found");
5013
- return;
4918
+
4919
+ // src/errors/validators.ts
4920
+ async function validateErrorData(data) {
4921
+ return ErrorValidator.getInstance().validate(data);
4922
+ }
4923
+ var ErrorValidator;
4924
+ var init_validators2 = __esm({
4925
+ "src/errors/validators.ts"() {
4926
+ init_schema();
4927
+ ErrorValidator = class _ErrorValidator {
4928
+ static instance;
4929
+ validateFn = null;
4930
+ initPromise = null;
4931
+ initError = null;
4932
+ constructor() {
5014
4933
  }
5015
- console.log(`Found ${schemas.length} schema(s):
5016
- `);
5017
- for (const schema of schemas) {
5018
- console.log(` ${schema.id}`);
5019
- console.log(` Format: ${schema.format}`);
5020
- console.log(` Path: ${schema.relativePath}`);
5021
- if (schema.description) {
5022
- console.log(` Description: ${schema.description}`);
4934
+ /**
4935
+ * Get singleton instance
4936
+ */
4937
+ static getInstance() {
4938
+ if (!_ErrorValidator.instance) {
4939
+ _ErrorValidator.instance = new _ErrorValidator();
5023
4940
  }
5024
- console.log();
5025
- }
5026
- } catch (error) {
5027
- console.error("Error listing schemas:", error.message);
5028
- process.exit(1);
5029
- }
5030
- });
5031
- 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) => {
5032
- try {
5033
- const registry = getSchemaRegistry({
5034
- baseDir: cmdOptions.baseDir || options.baseDir
5035
- });
5036
- const schema = await registry.getSchema(cmdOptions.schemaId);
5037
- console.log("Schema Details:\n");
5038
- console.log(` ID: ${schema.id}`);
5039
- console.log(` Format: ${schema.format}`);
5040
- console.log(` Path: ${schema.path}`);
5041
- console.log(` Relative Path: ${schema.relativePath}`);
5042
- if (schema.version) {
5043
- console.log(` Version: ${schema.version}`);
5044
- }
5045
- if (schema.description) {
5046
- console.log(` Description: ${schema.description}`);
5047
- }
5048
- if (schema.schemaDraft) {
5049
- console.log(` Schema Draft: ${schema.schemaDraft}`);
4941
+ return _ErrorValidator.instance;
5050
4942
  }
5051
- const content = await readFile(schema.path, "utf-8");
5052
- console.log("\nSchema Content:");
5053
- console.log(content);
5054
- } catch (error) {
5055
- console.error("Error showing schema:", error.message);
5056
- process.exit(1);
5057
- }
5058
- });
5059
- 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(
5060
- async (file, cmdOptions) => {
5061
- try {
5062
- let result;
5063
- if (cmdOptions.useGoneat) {
5064
- const available = await isGoneatAvailable(cmdOptions.goneatPath);
5065
- if (!available) {
5066
- console.error("\u274C goneat not available. Install goneat or remove --use-goneat flag.");
5067
- console.error(" AJV validation (default) works without external dependencies.");
5068
- process.exit(1);
4943
+ /**
4944
+ * Initialize validator (lazy load, async)
4945
+ */
4946
+ async init() {
4947
+ if (this.validateFn !== null || this.initError !== null) {
4948
+ return;
4949
+ }
4950
+ if (this.initPromise) {
4951
+ return this.initPromise;
4952
+ }
4953
+ this.initPromise = (async () => {
4954
+ try {
4955
+ await compileSchemaById("pathfinder/v1.0.0/error-response");
4956
+ await compileSchemaById("assessment/v1.0.0/severity-definitions");
4957
+ this.validateFn = await compileSchemaById("error-handling/v1.0.0/error-response");
4958
+ } catch (err) {
4959
+ this.initError = err instanceof Error ? err : new Error(String(err));
4960
+ throw new Error(`Failed to initialize error validator: ${this.initError.message}`);
5069
4961
  }
5070
- const registry = getSchemaRegistry({
5071
- baseDir: cmdOptions.baseDir || options.baseDir
5072
- });
5073
- const schema = await registry.getSchema(cmdOptions.schemaId);
5074
- console.log("Using goneat validation...");
5075
- result = await runGoneatValidation(schema.path, file, cmdOptions.goneatPath);
5076
- } else {
5077
- console.log("Using AJV validation...");
5078
- result = await validateFileBySchemaId(file, cmdOptions.schemaId, {
5079
- baseDir: cmdOptions.baseDir || options.baseDir
5080
- });
4962
+ })();
4963
+ return this.initPromise;
4964
+ }
4965
+ /**
4966
+ * Validate error data against schema
4967
+ *
4968
+ * @param data - Data to validate
4969
+ * @returns Promise resolving to true if valid, false otherwise
4970
+ * @throws {Error} If validator failed to initialize
4971
+ */
4972
+ async validate(data) {
4973
+ if (this.validateFn === null) {
4974
+ await this.init();
5081
4975
  }
5082
- if (result.valid) {
5083
- console.log(`\u2705 Validation passed (${result.source})`);
5084
- process.exit(0);
5085
- } else {
5086
- console.log(`\u274C Validation failed (${result.source})`);
5087
- console.log("\nDiagnostics:");
5088
- console.log(formatDiagnostics(result.diagnostics));
5089
- process.exit(1);
4976
+ if (this.initError) {
4977
+ throw this.initError;
5090
4978
  }
5091
- } catch (error) {
5092
- console.error("Error validating file:", error.message);
5093
- process.exit(1);
4979
+ if (!this.validateFn) {
4980
+ throw new Error("Validator not initialized");
4981
+ }
4982
+ return this.validateFn(data);
5094
4983
  }
5095
- }
5096
- );
5097
- program.command("validate-schema").description("Validate a schema file itself").argument("<file>", "Schema file to validate").action(async (file) => {
5098
- try {
5099
- const content = await readFile(file, "utf-8");
5100
- const { validateSchema: validateSchema2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
5101
- const result = await validateSchema2(content);
5102
- if (result.valid) {
5103
- console.log("\u2705 Schema is valid");
5104
- process.exit(0);
5105
- } else {
5106
- console.log("\u274C Schema is invalid");
5107
- console.log("\nDiagnostics:");
5108
- console.log(formatDiagnostics(result.diagnostics));
5109
- process.exit(1);
4984
+ /**
4985
+ * Get validation errors from last validation
4986
+ *
4987
+ * @returns Validation errors or null
4988
+ */
4989
+ getErrors() {
4990
+ if (!this.validateFn) {
4991
+ return null;
4992
+ }
4993
+ return this.validateFn.errors;
5110
4994
  }
5111
- } catch (error) {
5112
- console.error("Error validating schema:", error.message);
5113
- process.exit(1);
5114
- }
5115
- });
5116
- 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) => {
5117
- try {
5118
- const content = await readFile(file, "utf-8");
5119
- const normalized = normalizeSchema(content, {
5120
- compact: cmdOptions.compact
5121
- });
5122
- if (cmdOptions.output) {
5123
- await writeFile(cmdOptions.output, normalized, "utf-8");
5124
- console.log(`\u2705 Normalized schema written to ${cmdOptions.output}`);
5125
- } else {
5126
- console.log(normalized);
4995
+ /**
4996
+ * Reset validator state (for testing)
4997
+ * @internal
4998
+ */
4999
+ static _reset() {
5000
+ _ErrorValidator.instance = new _ErrorValidator();
5127
5001
  }
5128
- } catch (error) {
5129
- console.error("Error normalizing schema:", error.message);
5130
- process.exit(1);
5131
- }
5132
- });
5133
- 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) => {
5134
- try {
5135
- const content1 = await readFile(file1, "utf-8");
5136
- const content2 = await readFile(file2, "utf-8");
5137
- const result = compareSchemas(content1, content2);
5138
- if (result.equal) {
5139
- console.log("\u2705 Schemas are semantically equal");
5140
- } else {
5141
- console.log("\u274C Schemas differ");
5002
+ };
5003
+ }
5004
+ });
5005
+
5006
+ // src/errors/fulmen-error.ts
5007
+ function isFulmenErrorData(value) {
5008
+ return typeof value === "object" && value !== null && "code" in value && typeof value.code === "string" && "message" in value && typeof value.message === "string";
5009
+ }
5010
+ var FulmenError;
5011
+ var init_fulmen_error = __esm({
5012
+ "src/errors/fulmen-error.ts"() {
5013
+ init_serialization();
5014
+ init_severity();
5015
+ init_validators2();
5016
+ FulmenError = class _FulmenError extends Error {
5017
+ data;
5018
+ constructor(data) {
5019
+ super(data.message);
5020
+ this.name = "FulmenError";
5021
+ this.data = Object.freeze({ ...data });
5022
+ Error.captureStackTrace(this, _FulmenError);
5142
5023
  }
5143
- if (cmdOptions.showNormalized) {
5144
- console.log("\nNormalized Schema 1:");
5145
- console.log(result.normalizedA);
5146
- console.log("\nNormalized Schema 2:");
5147
- console.log(result.normalizedB);
5148
- }
5149
- process.exit(result.equal ? 0 : 1);
5150
- } catch (error) {
5151
- console.error("Error comparing schemas:", error.message);
5152
- process.exit(1);
5153
- }
5154
- });
5155
- 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(
5156
- async (cmdOptions) => {
5157
- try {
5158
- const { exportSchema: exportSchema2 } = await Promise.resolve().then(() => (init_export(), export_exports));
5159
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5160
- const result = await exportSchema2({
5161
- schemaId: cmdOptions.schemaId,
5162
- outPath: cmdOptions.out,
5163
- includeProvenance: cmdOptions.provenance ?? true,
5164
- validate: cmdOptions.validate ?? true,
5165
- overwrite: cmdOptions.force ?? false,
5166
- format: cmdOptions.format ?? "auto",
5167
- baseDir: cmdOptions.baseDir || options.baseDir
5168
- });
5169
- console.log("\u2705 Schema exported successfully");
5170
- console.log(` Schema ID: ${result.schemaId}`);
5171
- console.log(` Output: ${result.outPath}`);
5172
- console.log(` Format: ${result.format}`);
5173
- if (result.provenance) {
5174
- console.log("\nProvenance:");
5175
- console.log(` Crucible: ${result.provenance.crucible_version}`);
5176
- console.log(` Library: ${result.provenance.library_version}`);
5177
- if (result.provenance.revision) {
5178
- console.log(` Revision: ${result.provenance.revision}`);
5179
- }
5180
- console.log(` Exported: ${result.provenance.exported_at}`);
5181
- }
5182
- process.exit(exitCodes2.EXIT_SUCCESS);
5183
- } catch (error) {
5184
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5185
- const { SchemaExportError: SchemaExportError2, SchemaValidationError: SchemaValidationError2, ExportErrorReason: ExportErrorReason2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
5186
- console.error("\u274C Schema export failed:", error.message);
5187
- if (error instanceof SchemaExportError2) {
5188
- if (error.outPath) {
5189
- console.error(` Output path: ${error.outPath}`);
5190
- }
5191
- switch (error.reason) {
5192
- case ExportErrorReason2.FILE_EXISTS:
5193
- case ExportErrorReason2.WRITE_FAILED:
5194
- process.exit(exitCodes2.EXIT_FILE_WRITE_ERROR);
5195
- break;
5196
- case ExportErrorReason2.INVALID_FORMAT:
5197
- process.exit(exitCodes2.EXIT_INVALID_ARGUMENT);
5198
- break;
5199
- default:
5200
- process.exit(exitCodes2.EXIT_FAILURE);
5201
- }
5202
- }
5203
- if (error instanceof SchemaValidationError2) {
5204
- const errorMsg = error.message.toLowerCase();
5205
- if (errorMsg.includes("not found")) {
5206
- process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5207
- }
5208
- process.exit(exitCodes2.EXIT_DATA_INVALID);
5209
- }
5210
- process.exit(exitCodes2.EXIT_FAILURE);
5211
- }
5212
- }
5213
- );
5214
- 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) => {
5215
- try {
5216
- const { loadIdentity: loadIdentity2 } = await Promise.resolve().then(() => (init_loader2(), loader_exports));
5217
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5218
- const identity = await loadIdentity2({ path: cmdOptions.path });
5219
- if (cmdOptions.json) {
5220
- console.log(JSON.stringify(identity, null, 2));
5221
- } else {
5222
- console.log("Application Identity:\n");
5223
- console.log(` Binary Name: ${identity.app.binary_name}`);
5224
- console.log(` Vendor: ${identity.app.vendor}`);
5225
- console.log(` Env Prefix: ${identity.app.env_prefix}`);
5226
- console.log(` Config Name: ${identity.app.config_name}`);
5227
- console.log(` Description: ${identity.app.description}`);
5228
- if (identity.metadata) {
5229
- console.log("\nMetadata:");
5230
- if (identity.metadata.license) {
5231
- console.log(` License: ${identity.metadata.license}`);
5232
- }
5233
- if (identity.metadata.repository_category) {
5234
- console.log(` Category: ${identity.metadata.repository_category}`);
5235
- }
5236
- if (identity.metadata.telemetry_namespace) {
5237
- console.log(` Telemetry: ${identity.metadata.telemetry_namespace}`);
5238
- }
5239
- if (identity.metadata.project_url) {
5240
- console.log(` Project URL: ${identity.metadata.project_url}`);
5241
- }
5242
- }
5243
- }
5244
- process.exit(exitCodes2.EXIT_SUCCESS);
5245
- } catch (error) {
5246
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5247
- const { AppIdentityError: AppIdentityError2 } = await Promise.resolve().then(() => (init_errors5(), errors_exports2));
5248
- console.error("\u274C Failed to load identity:", error.message);
5249
- if (error instanceof AppIdentityError2) {
5250
- if (error.message.includes("not found")) {
5251
- process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5252
- }
5253
- if (error.message.includes("Invalid") || error.message.includes("validation")) {
5254
- process.exit(exitCodes2.EXIT_DATA_INVALID);
5255
- }
5256
- }
5257
- process.exit(exitCodes2.EXIT_FAILURE);
5258
- }
5259
- });
5260
- program.command("identity-validate").description("Validate application identity against schema").argument("[file]", "Path to app.yaml (defaults to discovery)").action(async (file) => {
5261
- try {
5262
- const { loadIdentity: loadIdentity2 } = await Promise.resolve().then(() => (init_loader2(), loader_exports));
5263
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5264
- console.log("Validating application identity...");
5265
- const identity = await loadIdentity2({ path: file });
5266
- console.log("\u2705 Identity is valid");
5267
- console.log(` Binary: ${identity.app.binary_name}`);
5268
- console.log(` Vendor: ${identity.app.vendor}`);
5269
- process.exit(exitCodes2.EXIT_SUCCESS);
5270
- } catch (error) {
5271
- const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5272
- const { AppIdentityError: AppIdentityError2 } = await Promise.resolve().then(() => (init_errors5(), errors_exports2));
5273
- console.error("\u274C Identity validation failed:", error.message);
5274
- if (error instanceof AppIdentityError2) {
5275
- if (error.message.includes("not found")) {
5276
- process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5277
- }
5278
- if (error.message.includes("Invalid") || error.message.includes("validation")) {
5279
- process.exit(exitCodes2.EXIT_DATA_INVALID);
5280
- }
5281
- }
5282
- process.exit(exitCodes2.EXIT_FAILURE);
5283
- }
5284
- });
5285
- return program;
5286
- }
5287
- var init_cli = __esm({
5288
- "src/schema/cli.ts"() {
5289
- init_goneat_bridge();
5290
- init_normalizer();
5291
- init_registry();
5292
- init_utils();
5293
- init_validator();
5294
- if (import.meta.url === `file://${process.argv[1]}`) {
5295
- const program = createCLI();
5296
- program.parse(process.argv);
5297
- }
5298
- }
5299
- });
5300
-
5301
- // src/schema/index.ts
5302
- var init_schema = __esm({
5303
- "src/schema/index.ts"() {
5304
- init_cli();
5305
- init_errors();
5306
- init_export();
5307
- init_goneat_bridge();
5308
- init_normalizer();
5309
- init_registry();
5310
- init_utils();
5311
- init_validator();
5312
- }
5313
- });
5314
-
5315
- // src/errors/validators.ts
5316
- async function validateErrorData(data) {
5317
- return ErrorValidator.getInstance().validate(data);
5318
- }
5319
- var ErrorValidator;
5320
- var init_validators2 = __esm({
5321
- "src/errors/validators.ts"() {
5322
- init_schema();
5323
- ErrorValidator = class _ErrorValidator {
5324
- static instance;
5325
- validateFn = null;
5326
- initPromise = null;
5327
- initError = null;
5328
- constructor() {
5329
- }
5330
- /**
5331
- * Get singleton instance
5332
- */
5333
- static getInstance() {
5334
- if (!_ErrorValidator.instance) {
5335
- _ErrorValidator.instance = new _ErrorValidator();
5336
- }
5337
- return _ErrorValidator.instance;
5338
- }
5339
- /**
5340
- * Initialize validator (lazy load, async)
5341
- */
5342
- async init() {
5343
- if (this.validateFn !== null || this.initError !== null) {
5344
- return;
5345
- }
5346
- if (this.initPromise) {
5347
- return this.initPromise;
5348
- }
5349
- this.initPromise = (async () => {
5350
- try {
5351
- await compileSchemaById("pathfinder/v1.0.0/error-response");
5352
- await compileSchemaById("assessment/v1.0.0/severity-definitions");
5353
- this.validateFn = await compileSchemaById("error-handling/v1.0.0/error-response");
5354
- } catch (err) {
5355
- this.initError = err instanceof Error ? err : new Error(String(err));
5356
- throw new Error(`Failed to initialize error validator: ${this.initError.message}`);
5357
- }
5358
- })();
5359
- return this.initPromise;
5360
- }
5361
- /**
5362
- * Validate error data against schema
5363
- *
5364
- * @param data - Data to validate
5365
- * @returns Promise resolving to true if valid, false otherwise
5366
- * @throws {Error} If validator failed to initialize
5367
- */
5368
- async validate(data) {
5369
- if (this.validateFn === null) {
5370
- await this.init();
5371
- }
5372
- if (this.initError) {
5373
- throw this.initError;
5374
- }
5375
- if (!this.validateFn) {
5376
- throw new Error("Validator not initialized");
5377
- }
5378
- return this.validateFn(data);
5379
- }
5380
- /**
5381
- * Get validation errors from last validation
5382
- *
5383
- * @returns Validation errors or null
5384
- */
5385
- getErrors() {
5386
- if (!this.validateFn) {
5387
- return null;
5388
- }
5389
- return this.validateFn.errors;
5390
- }
5391
- /**
5392
- * Reset validator state (for testing)
5393
- * @internal
5394
- */
5395
- static _reset() {
5396
- _ErrorValidator.instance = new _ErrorValidator();
5397
- }
5398
- };
5399
- }
5400
- });
5401
-
5402
- // src/errors/fulmen-error.ts
5403
- function isFulmenErrorData(value) {
5404
- return typeof value === "object" && value !== null && "code" in value && typeof value.code === "string" && "message" in value && typeof value.message === "string";
5405
- }
5406
- var FulmenError;
5407
- var init_fulmen_error = __esm({
5408
- "src/errors/fulmen-error.ts"() {
5409
- init_serialization();
5410
- init_severity();
5411
- init_validators2();
5412
- FulmenError = class _FulmenError extends Error {
5413
- data;
5414
- constructor(data) {
5415
- super(data.message);
5416
- this.name = "FulmenError";
5417
- this.data = Object.freeze({ ...data });
5418
- Error.captureStackTrace(this, _FulmenError);
5419
- }
5420
- /**
5421
- * Serialize to JSON (schema-compliant)
5422
- */
5423
- toJSON() {
5424
- return this.data;
5024
+ /**
5025
+ * Serialize to JSON (schema-compliant)
5026
+ */
5027
+ toJSON() {
5028
+ return this.data;
5425
5029
  }
5426
5030
  /**
5427
5031
  * Check equality with another FulmenError
@@ -5675,12 +5279,568 @@ ${cause.message}`;
5675
5279
  ${cause.message}`;
5676
5280
  return new _AppIdentityError(message, path, cause);
5677
5281
  }
5678
- };
5282
+ /**
5283
+ * Create error for embedded identity already registered
5284
+ *
5285
+ * Uses first-wins semantics - once registered, cannot be replaced
5286
+ */
5287
+ static alreadyRegistered() {
5288
+ const message = "Embedded identity already registered. Registration uses first-wins semantics and cannot be replaced.";
5289
+ return new _AppIdentityError(message);
5290
+ }
5291
+ /**
5292
+ * Create error for embedded identity YAML parsing failure
5293
+ */
5294
+ static embeddedParseFailed(cause) {
5295
+ const message = `Failed to parse embedded identity YAML: ${cause.message}`;
5296
+ return new _AppIdentityError(message, void 0, cause);
5297
+ }
5298
+ /**
5299
+ * Create error for embedded identity schema validation failure
5300
+ */
5301
+ static embeddedValidationFailed(diagnostics) {
5302
+ const errorCount = diagnostics.filter((d) => d.severity === "ERROR").length;
5303
+ const warningCount = diagnostics.filter((d) => d.severity === "WARN").length;
5304
+ let message = "Invalid embedded identity\n";
5305
+ message += `Validation errors: ${errorCount} error(s), ${warningCount} warning(s)
5306
+ `;
5307
+ const displayDiagnostics = diagnostics.slice(0, 3);
5308
+ for (const diag of displayDiagnostics) {
5309
+ message += ` - ${diag.message}`;
5310
+ if (diag.pointer) {
5311
+ message += ` at ${diag.pointer}`;
5312
+ }
5313
+ message += "\n";
5314
+ }
5315
+ if (diagnostics.length > 3) {
5316
+ message += ` ... and ${diagnostics.length - 3} more
5317
+ `;
5318
+ }
5319
+ return new _AppIdentityError(message);
5320
+ }
5321
+ };
5322
+ }
5323
+ });
5324
+ async function discoverIdentityPath(options) {
5325
+ if (options?.path) {
5326
+ const exists = await fileExists(options.path);
5327
+ if (!exists) {
5328
+ throw AppIdentityError.notFound([options.path]);
5329
+ }
5330
+ return { path: options.path, source: "explicit" };
5331
+ }
5332
+ const envPath = process.env[APP_IDENTITY_ENV_VAR];
5333
+ if (envPath) {
5334
+ const exists = await fileExists(envPath);
5335
+ if (!exists) {
5336
+ throw AppIdentityError.envOverrideMissing(envPath);
5337
+ }
5338
+ return { path: envPath, source: "env" };
5339
+ }
5340
+ const startDir = options?.startDir || process.cwd();
5341
+ const result = await searchAncestors(startDir);
5342
+ if (result) {
5343
+ return { path: result, source: "ancestor" };
5344
+ }
5345
+ return null;
5346
+ }
5347
+ async function searchAncestors(startDir) {
5348
+ let currentDir = startDir;
5349
+ const searchedPaths = [];
5350
+ for (let i = 0; i < MAX_ANCESTOR_SEARCH_DEPTH; i++) {
5351
+ const candidatePath = join(currentDir, APP_IDENTITY_DIR, APP_IDENTITY_FILENAME);
5352
+ searchedPaths.push(candidatePath);
5353
+ if (await fileExists(candidatePath)) {
5354
+ return candidatePath;
5355
+ }
5356
+ const parentDir = dirname(currentDir);
5357
+ if (parentDir === currentDir) {
5358
+ throw AppIdentityError.notFound(searchedPaths);
5359
+ }
5360
+ currentDir = parentDir;
5361
+ }
5362
+ throw AppIdentityError.notFound(searchedPaths);
5363
+ }
5364
+ async function fileExists(path) {
5365
+ try {
5366
+ await access(path);
5367
+ return true;
5368
+ } catch {
5369
+ return false;
5370
+ }
5371
+ }
5372
+ var init_discovery = __esm({
5373
+ "src/appidentity/discovery.ts"() {
5374
+ init_constants();
5375
+ init_errors5();
5376
+ }
5377
+ });
5378
+
5379
+ // src/appidentity/loader.ts
5380
+ var loader_exports = {};
5381
+ __export(loader_exports, {
5382
+ clearIdentityCache: () => clearIdentityCache,
5383
+ getCachedIdentity: () => getCachedIdentity,
5384
+ loadIdentity: () => loadIdentity
5385
+ });
5386
+ function deepFreeze5(obj) {
5387
+ Object.freeze(obj);
5388
+ Object.getOwnPropertyNames(obj).forEach((prop) => {
5389
+ const value = obj[prop];
5390
+ if (value !== null && (typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) {
5391
+ deepFreeze5(value);
5392
+ }
5393
+ });
5394
+ return obj;
5395
+ }
5396
+ async function loadIdentity(options) {
5397
+ if (options?.identity) {
5398
+ return deepFreeze5(structuredClone(options.identity));
5399
+ }
5400
+ if (!options?.skipCache) {
5401
+ const cached = getCachedIdentity();
5402
+ if (cached) {
5403
+ return cached;
5404
+ }
5405
+ }
5406
+ let discovery;
5407
+ try {
5408
+ discovery = await discoverIdentityPath({
5409
+ path: options?.path,
5410
+ startDir: options?.startDir
5411
+ });
5412
+ } catch (error) {
5413
+ const hasExplicitPath = Boolean(options?.path);
5414
+ const hasEnvOverride = Boolean(process.env[APP_IDENTITY_ENV_VAR]);
5415
+ if (!hasExplicitPath && !hasEnvOverride && error instanceof AppIdentityError) {
5416
+ const embedded = getEmbeddedIdentity();
5417
+ if (embedded) {
5418
+ setCachedIdentity(embedded);
5419
+ return embedded;
5420
+ }
5421
+ }
5422
+ throw error;
5423
+ }
5424
+ if (!discovery) {
5425
+ const embedded = getEmbeddedIdentity();
5426
+ if (embedded) {
5427
+ setCachedIdentity(embedded);
5428
+ return embedded;
5429
+ }
5430
+ throw AppIdentityError.notFound([]);
5431
+ }
5432
+ let content;
5433
+ try {
5434
+ content = await readFile(discovery.path, "utf-8");
5435
+ } catch (error) {
5436
+ throw AppIdentityError.readFailed(
5437
+ discovery.path,
5438
+ error instanceof Error ? error : new Error(String(error))
5439
+ );
5440
+ }
5441
+ let parsed;
5442
+ try {
5443
+ parsed = parse(content);
5444
+ } catch (error) {
5445
+ throw AppIdentityError.parseFailed(
5446
+ discovery.path,
5447
+ error instanceof Error ? error : new Error(String(error))
5448
+ );
5449
+ }
5450
+ if (!options?.skipValidation) {
5451
+ const result = await validateDataBySchemaId(parsed, APP_IDENTITY_SCHEMA_ID);
5452
+ if (!result.valid) {
5453
+ throw AppIdentityError.validationFailed(discovery.path, result.diagnostics);
5454
+ }
5455
+ }
5456
+ const identity = deepFreeze5(structuredClone(parsed));
5457
+ setCachedIdentity(identity);
5458
+ return identity;
5459
+ }
5460
+ var init_loader2 = __esm({
5461
+ "src/appidentity/loader.ts"() {
5462
+ init_schema();
5463
+ init_cache();
5464
+ init_constants();
5465
+ init_discovery();
5466
+ init_embedded();
5467
+ init_errors5();
5468
+ }
5469
+ });
5470
+ function createCLI(options = {}) {
5471
+ const program = new Command();
5472
+ program.name("tsfulmen-schema").description("Schema validation and discovery CLI for Fulmen (developer tool)").version("0.1.0");
5473
+ 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) => {
5474
+ try {
5475
+ const schemas = await listSchemas(prefix, {
5476
+ baseDir: cmdOptions?.baseDir || options.baseDir
5477
+ });
5478
+ if (schemas.length === 0) {
5479
+ console.log("No schemas found");
5480
+ return;
5481
+ }
5482
+ console.log(`Found ${schemas.length} schema(s):
5483
+ `);
5484
+ for (const schema of schemas) {
5485
+ console.log(` ${schema.id}`);
5486
+ console.log(` Format: ${schema.format}`);
5487
+ console.log(` Path: ${schema.relativePath}`);
5488
+ if (schema.description) {
5489
+ console.log(` Description: ${schema.description}`);
5490
+ }
5491
+ console.log();
5492
+ }
5493
+ } catch (error) {
5494
+ console.error("Error listing schemas:", error.message);
5495
+ process.exit(1);
5496
+ }
5497
+ });
5498
+ 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) => {
5499
+ try {
5500
+ const registry = getSchemaRegistry({
5501
+ baseDir: cmdOptions.baseDir || options.baseDir
5502
+ });
5503
+ const schema = await registry.getSchema(cmdOptions.schemaId);
5504
+ console.log("Schema Details:\n");
5505
+ console.log(` ID: ${schema.id}`);
5506
+ console.log(` Format: ${schema.format}`);
5507
+ console.log(` Path: ${schema.path}`);
5508
+ console.log(` Relative Path: ${schema.relativePath}`);
5509
+ if (schema.version) {
5510
+ console.log(` Version: ${schema.version}`);
5511
+ }
5512
+ if (schema.description) {
5513
+ console.log(` Description: ${schema.description}`);
5514
+ }
5515
+ if (schema.schemaDraft) {
5516
+ console.log(` Schema Draft: ${schema.schemaDraft}`);
5517
+ }
5518
+ const content = await readFile(schema.path, "utf-8");
5519
+ console.log("\nSchema Content:");
5520
+ console.log(content);
5521
+ } catch (error) {
5522
+ console.error("Error showing schema:", error.message);
5523
+ process.exit(1);
5524
+ }
5525
+ });
5526
+ 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(
5527
+ async (file, cmdOptions) => {
5528
+ try {
5529
+ let result;
5530
+ if (cmdOptions.useGoneat) {
5531
+ const available = await isGoneatAvailable(cmdOptions.goneatPath);
5532
+ if (!available) {
5533
+ console.error("\u274C goneat not available. Install goneat or remove --use-goneat flag.");
5534
+ console.error(" AJV validation (default) works without external dependencies.");
5535
+ process.exit(1);
5536
+ }
5537
+ const registry = getSchemaRegistry({
5538
+ baseDir: cmdOptions.baseDir || options.baseDir
5539
+ });
5540
+ const schema = await registry.getSchema(cmdOptions.schemaId);
5541
+ console.log("Using goneat validation...");
5542
+ result = await runGoneatValidation(schema.path, file, cmdOptions.goneatPath);
5543
+ } else {
5544
+ console.log("Using AJV validation...");
5545
+ result = await validateFileBySchemaId(file, cmdOptions.schemaId, {
5546
+ baseDir: cmdOptions.baseDir || options.baseDir
5547
+ });
5548
+ }
5549
+ if (result.valid) {
5550
+ console.log(`\u2705 Validation passed (${result.source})`);
5551
+ process.exit(0);
5552
+ } else {
5553
+ console.log(`\u274C Validation failed (${result.source})`);
5554
+ console.log("\nDiagnostics:");
5555
+ console.log(formatDiagnostics(result.diagnostics));
5556
+ process.exit(1);
5557
+ }
5558
+ } catch (error) {
5559
+ console.error("Error validating file:", error.message);
5560
+ process.exit(1);
5561
+ }
5562
+ }
5563
+ );
5564
+ program.command("validate-schema").description("Validate a schema file itself").argument("<file>", "Schema file to validate").action(async (file) => {
5565
+ try {
5566
+ const content = await readFile(file, "utf-8");
5567
+ const { validateSchema: validateSchema2 } = await Promise.resolve().then(() => (init_validator(), validator_exports));
5568
+ const result = await validateSchema2(content);
5569
+ if (result.valid) {
5570
+ console.log("\u2705 Schema is valid");
5571
+ process.exit(0);
5572
+ } else {
5573
+ console.log("\u274C Schema is invalid");
5574
+ console.log("\nDiagnostics:");
5575
+ console.log(formatDiagnostics(result.diagnostics));
5576
+ process.exit(1);
5577
+ }
5578
+ } catch (error) {
5579
+ console.error("Error validating schema:", error.message);
5580
+ process.exit(1);
5581
+ }
5582
+ });
5583
+ 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) => {
5584
+ try {
5585
+ const content = await readFile(file, "utf-8");
5586
+ const normalized = normalizeSchema(content, {
5587
+ compact: cmdOptions.compact
5588
+ });
5589
+ if (cmdOptions.output) {
5590
+ await writeFile(cmdOptions.output, normalized, "utf-8");
5591
+ console.log(`\u2705 Normalized schema written to ${cmdOptions.output}`);
5592
+ } else {
5593
+ console.log(normalized);
5594
+ }
5595
+ } catch (error) {
5596
+ console.error("Error normalizing schema:", error.message);
5597
+ process.exit(1);
5598
+ }
5599
+ });
5600
+ 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) => {
5601
+ try {
5602
+ const content1 = await readFile(file1, "utf-8");
5603
+ const content2 = await readFile(file2, "utf-8");
5604
+ const result = compareSchemas(content1, content2);
5605
+ if (result.equal) {
5606
+ console.log("\u2705 Schemas are semantically equal");
5607
+ } else {
5608
+ console.log("\u274C Schemas differ");
5609
+ }
5610
+ if (cmdOptions.showNormalized) {
5611
+ console.log("\nNormalized Schema 1:");
5612
+ console.log(result.normalizedA);
5613
+ console.log("\nNormalized Schema 2:");
5614
+ console.log(result.normalizedB);
5615
+ }
5616
+ process.exit(result.equal ? 0 : 1);
5617
+ } catch (error) {
5618
+ console.error("Error comparing schemas:", error.message);
5619
+ process.exit(1);
5620
+ }
5621
+ });
5622
+ 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(
5623
+ async (cmdOptions) => {
5624
+ try {
5625
+ const { exportSchema: exportSchema2 } = await Promise.resolve().then(() => (init_export(), export_exports));
5626
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5627
+ const result = await exportSchema2({
5628
+ schemaId: cmdOptions.schemaId,
5629
+ outPath: cmdOptions.out,
5630
+ includeProvenance: cmdOptions.provenance ?? true,
5631
+ validate: cmdOptions.validate ?? true,
5632
+ overwrite: cmdOptions.force ?? false,
5633
+ format: cmdOptions.format ?? "auto",
5634
+ baseDir: cmdOptions.baseDir || options.baseDir
5635
+ });
5636
+ console.log("\u2705 Schema exported successfully");
5637
+ console.log(` Schema ID: ${result.schemaId}`);
5638
+ console.log(` Output: ${result.outPath}`);
5639
+ console.log(` Format: ${result.format}`);
5640
+ if (result.provenance) {
5641
+ console.log("\nProvenance:");
5642
+ console.log(` Crucible: ${result.provenance.crucible_version}`);
5643
+ console.log(` Library: ${result.provenance.library_version}`);
5644
+ if (result.provenance.revision) {
5645
+ console.log(` Revision: ${result.provenance.revision}`);
5646
+ }
5647
+ console.log(` Exported: ${result.provenance.exported_at}`);
5648
+ }
5649
+ process.exit(exitCodes2.EXIT_SUCCESS);
5650
+ } catch (error) {
5651
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5652
+ const { SchemaExportError: SchemaExportError2, SchemaValidationError: SchemaValidationError2, ExportErrorReason: ExportErrorReason2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
5653
+ console.error("\u274C Schema export failed:", error.message);
5654
+ if (error instanceof SchemaExportError2) {
5655
+ if (error.outPath) {
5656
+ console.error(` Output path: ${error.outPath}`);
5657
+ }
5658
+ switch (error.reason) {
5659
+ case ExportErrorReason2.FILE_EXISTS:
5660
+ case ExportErrorReason2.WRITE_FAILED:
5661
+ process.exit(exitCodes2.EXIT_FILE_WRITE_ERROR);
5662
+ break;
5663
+ case ExportErrorReason2.INVALID_FORMAT:
5664
+ process.exit(exitCodes2.EXIT_INVALID_ARGUMENT);
5665
+ break;
5666
+ default:
5667
+ process.exit(exitCodes2.EXIT_FAILURE);
5668
+ }
5669
+ }
5670
+ if (error instanceof SchemaValidationError2) {
5671
+ const errorMsg = error.message.toLowerCase();
5672
+ if (errorMsg.includes("not found")) {
5673
+ process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5674
+ }
5675
+ process.exit(exitCodes2.EXIT_DATA_INVALID);
5676
+ }
5677
+ process.exit(exitCodes2.EXIT_FAILURE);
5678
+ }
5679
+ }
5680
+ );
5681
+ 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) => {
5682
+ try {
5683
+ const { loadIdentity: loadIdentity2 } = await Promise.resolve().then(() => (init_loader2(), loader_exports));
5684
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5685
+ const identity = await loadIdentity2({ path: cmdOptions.path });
5686
+ if (cmdOptions.json) {
5687
+ console.log(JSON.stringify(identity, null, 2));
5688
+ } else {
5689
+ console.log("Application Identity:\n");
5690
+ console.log(` Binary Name: ${identity.app.binary_name}`);
5691
+ console.log(` Vendor: ${identity.app.vendor}`);
5692
+ console.log(` Env Prefix: ${identity.app.env_prefix}`);
5693
+ console.log(` Config Name: ${identity.app.config_name}`);
5694
+ console.log(` Description: ${identity.app.description}`);
5695
+ if (identity.metadata) {
5696
+ console.log("\nMetadata:");
5697
+ if (identity.metadata.license) {
5698
+ console.log(` License: ${identity.metadata.license}`);
5699
+ }
5700
+ if (identity.metadata.repository_category) {
5701
+ console.log(` Category: ${identity.metadata.repository_category}`);
5702
+ }
5703
+ if (identity.metadata.telemetry_namespace) {
5704
+ console.log(` Telemetry: ${identity.metadata.telemetry_namespace}`);
5705
+ }
5706
+ if (identity.metadata.project_url) {
5707
+ console.log(` Project URL: ${identity.metadata.project_url}`);
5708
+ }
5709
+ }
5710
+ }
5711
+ process.exit(exitCodes2.EXIT_SUCCESS);
5712
+ } catch (error) {
5713
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5714
+ const { AppIdentityError: AppIdentityError2 } = await Promise.resolve().then(() => (init_errors5(), errors_exports2));
5715
+ console.error("\u274C Failed to load identity:", error.message);
5716
+ if (error instanceof AppIdentityError2) {
5717
+ if (error.message.includes("not found")) {
5718
+ process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5719
+ }
5720
+ if (error.message.includes("Invalid") || error.message.includes("validation")) {
5721
+ process.exit(exitCodes2.EXIT_DATA_INVALID);
5722
+ }
5723
+ }
5724
+ process.exit(exitCodes2.EXIT_FAILURE);
5725
+ }
5726
+ });
5727
+ program.command("identity-validate").description("Validate application identity against schema").argument("[file]", "Path to app.yaml (defaults to discovery)").action(async (file) => {
5728
+ try {
5729
+ const { loadIdentity: loadIdentity2 } = await Promise.resolve().then(() => (init_loader2(), loader_exports));
5730
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5731
+ console.log("Validating application identity...");
5732
+ const identity = await loadIdentity2({ path: file });
5733
+ console.log("\u2705 Identity is valid");
5734
+ console.log(` Binary: ${identity.app.binary_name}`);
5735
+ console.log(` Vendor: ${identity.app.vendor}`);
5736
+ process.exit(exitCodes2.EXIT_SUCCESS);
5737
+ } catch (error) {
5738
+ const { exitCodes: exitCodes2 } = await Promise.resolve().then(() => (init_foundry(), foundry_exports));
5739
+ const { AppIdentityError: AppIdentityError2 } = await Promise.resolve().then(() => (init_errors5(), errors_exports2));
5740
+ console.error("\u274C Identity validation failed:", error.message);
5741
+ if (error instanceof AppIdentityError2) {
5742
+ if (error.message.includes("not found")) {
5743
+ process.exit(exitCodes2.EXIT_FILE_NOT_FOUND);
5744
+ }
5745
+ if (error.message.includes("Invalid") || error.message.includes("validation")) {
5746
+ process.exit(exitCodes2.EXIT_DATA_INVALID);
5747
+ }
5748
+ }
5749
+ process.exit(exitCodes2.EXIT_FAILURE);
5750
+ }
5751
+ });
5752
+ return program;
5753
+ }
5754
+ var init_cli = __esm({
5755
+ "src/schema/cli.ts"() {
5756
+ init_goneat_bridge();
5757
+ init_normalizer();
5758
+ init_registry();
5759
+ init_utils();
5760
+ init_validator();
5761
+ if (import.meta.url === `file://${process.argv[1]}`) {
5762
+ const program = createCLI();
5763
+ program.parse(process.argv);
5764
+ }
5765
+ }
5766
+ });
5767
+
5768
+ // src/schema/index.ts
5769
+ var init_schema = __esm({
5770
+ "src/schema/index.ts"() {
5771
+ init_cli();
5772
+ init_errors();
5773
+ init_export();
5774
+ init_goneat_bridge();
5775
+ init_normalizer();
5776
+ init_registry();
5777
+ init_utils();
5778
+ init_validator();
5779
+ }
5780
+ });
5781
+ function deepFreeze6(obj) {
5782
+ Object.freeze(obj);
5783
+ Object.getOwnPropertyNames(obj).forEach((prop) => {
5784
+ const value = obj[prop];
5785
+ if (value !== null && (typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) {
5786
+ deepFreeze6(value);
5787
+ }
5788
+ });
5789
+ return obj;
5790
+ }
5791
+ async function registerEmbeddedIdentity(data) {
5792
+ if (isRegistered) {
5793
+ throw AppIdentityError.alreadyRegistered();
5794
+ }
5795
+ let identity;
5796
+ if (typeof data === "string") {
5797
+ let parsed;
5798
+ try {
5799
+ parsed = parse(data);
5800
+ } catch (error) {
5801
+ throw AppIdentityError.embeddedParseFailed(
5802
+ error instanceof Error ? error : new Error(String(error))
5803
+ );
5804
+ }
5805
+ const result = await validateDataBySchemaId(parsed, APP_IDENTITY_SCHEMA_ID);
5806
+ if (!result.valid) {
5807
+ throw AppIdentityError.embeddedValidationFailed(result.diagnostics);
5808
+ }
5809
+ identity = parsed;
5810
+ } else {
5811
+ const result = await validateDataBySchemaId(data, APP_IDENTITY_SCHEMA_ID);
5812
+ if (!result.valid) {
5813
+ throw AppIdentityError.embeddedValidationFailed(result.diagnostics);
5814
+ }
5815
+ identity = data;
5816
+ }
5817
+ embeddedIdentity = deepFreeze6(structuredClone(identity));
5818
+ isRegistered = true;
5819
+ }
5820
+ function hasEmbeddedIdentity() {
5821
+ return isRegistered;
5822
+ }
5823
+ function getEmbeddedIdentity() {
5824
+ return embeddedIdentity;
5825
+ }
5826
+ function clearEmbeddedIdentity() {
5827
+ embeddedIdentity = null;
5828
+ isRegistered = false;
5829
+ }
5830
+ var embeddedIdentity, isRegistered;
5831
+ var init_embedded = __esm({
5832
+ "src/appidentity/embedded.ts"() {
5833
+ init_schema();
5834
+ init_constants();
5835
+ init_errors5();
5836
+ embeddedIdentity = null;
5837
+ isRegistered = false;
5679
5838
  }
5680
5839
  });
5681
5840
 
5682
5841
  // src/appidentity/index.ts
5683
5842
  init_constants();
5843
+ init_embedded();
5684
5844
  init_errors5();
5685
5845
 
5686
5846
  // src/appidentity/helpers.ts
@@ -7890,8 +8050,8 @@ async function scanZip(archive, options) {
7890
8050
  var FULPACK_VERSION = "1.0.0";
7891
8051
 
7892
8052
  // src/index.ts
7893
- var VERSION2 = "0.1.13";
8053
+ var VERSION2 = "0.2.0";
7894
8054
 
7895
- export { APP_IDENTITY_DIR, APP_IDENTITY_ENV_VAR, APP_IDENTITY_FILENAME, APP_IDENTITY_SCHEMA_ID, AppIdentityError, ArchiveFormat, DocScribeError, DocScribeParseError, DocScribeUnsupportedFormatError, ERROR_CODES, EntryType, FULPACK_VERSION, FulpackOperationError, MAX_ANCESTOR_SEARCH_DEPTH, Operation, VERSION2 as VERSION, __internal, buildEnvVar, checkDecompressionBomb, clearIdentityCache, create, createFulpackError, detectFormat2 as detectFormat, extract, extractHeaders, extractMetadata, getBinaryName, getCachedIdentity, getConfigIdentifiers, getConfigName, getEnvPrefix, getEnvVar, getTelemetryNamespace, getVendor, hasPathTraversal, info, inspectDocument, isAbsolutePath, loadIdentity, normalizeInput, parseFrontmatter, scan, splitDocuments, stripFrontmatter, validatePath, verify };
8055
+ export { APP_IDENTITY_DIR, APP_IDENTITY_ENV_VAR, APP_IDENTITY_FILENAME, APP_IDENTITY_SCHEMA_ID, AppIdentityError, ArchiveFormat, DocScribeError, DocScribeParseError, DocScribeUnsupportedFormatError, ERROR_CODES, EntryType, FULPACK_VERSION, FulpackOperationError, MAX_ANCESTOR_SEARCH_DEPTH, Operation, VERSION2 as VERSION, __internal, buildEnvVar, checkDecompressionBomb, clearEmbeddedIdentity, clearIdentityCache, create, createFulpackError, detectFormat2 as detectFormat, extract, extractHeaders, extractMetadata, getBinaryName, getCachedIdentity, getConfigIdentifiers, getConfigName, getEmbeddedIdentity, getEnvPrefix, getEnvVar, getTelemetryNamespace, getVendor, hasEmbeddedIdentity, hasPathTraversal, info, inspectDocument, isAbsolutePath, loadIdentity, normalizeInput, parseFrontmatter, registerEmbeddedIdentity, scan, splitDocuments, stripFrontmatter, validatePath, verify };
7896
8056
  //# sourceMappingURL=index.js.map
7897
8057
  //# sourceMappingURL=index.js.map