@fulmenhq/tsfulmen 0.3.3 → 0.4.1

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 (123) hide show
  1. package/CHANGELOG.md +76 -1
  2. package/README.md +30 -1
  3. package/config/crucible-ts/taxonomy/metrics.yaml +1 -1
  4. package/dist/appidentity/index.js +9 -2209
  5. package/dist/appidentity/index.js.map +1 -1
  6. package/dist/assets/index.d.ts +184 -0
  7. package/dist/assets/index.js +4 -0
  8. package/dist/assets/index.js.map +1 -0
  9. package/dist/bin/prometheus-cli.js +15 -9139
  10. package/dist/bin/prometheus-cli.js.map +1 -1
  11. package/dist/bin/schema-cli.js +4 -6098
  12. package/dist/bin/schema-cli.js.map +1 -1
  13. package/dist/bin/signals-cli.js +15 -1910
  14. package/dist/bin/signals-cli.js.map +1 -1
  15. package/dist/chunk-24BAF63H.js +194 -0
  16. package/dist/chunk-24BAF63H.js.map +1 -0
  17. package/dist/chunk-3HISR2XI.js +36 -0
  18. package/dist/chunk-3HISR2XI.js.map +1 -0
  19. package/dist/chunk-56F2EEAG.js +328 -0
  20. package/dist/chunk-56F2EEAG.js.map +1 -0
  21. package/dist/chunk-5HZEJGZ5.js +725 -0
  22. package/dist/chunk-5HZEJGZ5.js.map +1 -0
  23. package/dist/chunk-7YWACZEJ.js +837 -0
  24. package/dist/chunk-7YWACZEJ.js.map +1 -0
  25. package/dist/chunk-BCO3FUUO.js +682 -0
  26. package/dist/chunk-BCO3FUUO.js.map +1 -0
  27. package/dist/chunk-GOTEQYAD.js +410 -0
  28. package/dist/chunk-GOTEQYAD.js.map +1 -0
  29. package/dist/chunk-HY6JQOFN.js +32 -0
  30. package/dist/chunk-HY6JQOFN.js.map +1 -0
  31. package/dist/chunk-LMNAUTW7.js +43 -0
  32. package/dist/chunk-LMNAUTW7.js.map +1 -0
  33. package/dist/chunk-LWAH2UG7.js +103 -0
  34. package/dist/chunk-LWAH2UG7.js.map +1 -0
  35. package/dist/chunk-OHE2AOH4.js +273 -0
  36. package/dist/chunk-OHE2AOH4.js.map +1 -0
  37. package/dist/chunk-P3DNOZOG.js +1488 -0
  38. package/dist/chunk-P3DNOZOG.js.map +1 -0
  39. package/dist/chunk-PQ6TKPUN.js +27 -0
  40. package/dist/chunk-PQ6TKPUN.js.map +1 -0
  41. package/dist/chunk-QCCN6POA.js +211 -0
  42. package/dist/chunk-QCCN6POA.js.map +1 -0
  43. package/dist/chunk-QGTNV4U2.js +985 -0
  44. package/dist/chunk-QGTNV4U2.js.map +1 -0
  45. package/dist/chunk-RSLFR4TO.js +631 -0
  46. package/dist/chunk-RSLFR4TO.js.map +1 -0
  47. package/dist/chunk-SNV5WG5V.js +9412 -0
  48. package/dist/chunk-SNV5WG5V.js.map +1 -0
  49. package/dist/chunk-UP2VWCW5.js +33 -0
  50. package/dist/chunk-UP2VWCW5.js.map +1 -0
  51. package/dist/chunk-VJIGX7MH.js +208 -0
  52. package/dist/chunk-VJIGX7MH.js.map +1 -0
  53. package/dist/chunk-WCCMRVZF.js +130 -0
  54. package/dist/chunk-WCCMRVZF.js.map +1 -0
  55. package/dist/chunk-WSMVLWLB.js +269 -0
  56. package/dist/chunk-WSMVLWLB.js.map +1 -0
  57. package/dist/config/index.js +6 -1220
  58. package/dist/config/index.js.map +1 -1
  59. package/dist/crucible/fulpack/index.js +2 -25
  60. package/dist/crucible/fulpack/index.js.map +1 -1
  61. package/dist/crucible/index.js +13 -1129
  62. package/dist/crucible/index.js.map +1 -1
  63. package/dist/docscribe/index.js +2 -680
  64. package/dist/docscribe/index.js.map +1 -1
  65. package/dist/errors/index.js +5 -1831
  66. package/dist/errors/index.js.map +1 -1
  67. package/dist/errors-D7KXV3QW.js +4 -0
  68. package/dist/errors-D7KXV3QW.js.map +1 -0
  69. package/dist/errors-R7ZODJXS.js +8 -0
  70. package/dist/errors-R7ZODJXS.js.map +1 -0
  71. package/dist/export-EA3RNQNS.js +6 -0
  72. package/dist/export-EA3RNQNS.js.map +1 -0
  73. package/dist/foundry/index.js +340 -3949
  74. package/dist/foundry/index.js.map +1 -1
  75. package/dist/foundry/similarity/index.js +3 -134
  76. package/dist/foundry/similarity/index.js.map +1 -1
  77. package/dist/fulencode/index.js +3 -319
  78. package/dist/fulencode/index.js.map +1 -1
  79. package/dist/fulhash/index.js +3 -611
  80. package/dist/fulhash/index.js.map +1 -1
  81. package/dist/fulpack/index.js +3 -1515
  82. package/dist/fulpack/index.js.map +1 -1
  83. package/dist/hash-YOJYVOWH.js +4 -0
  84. package/dist/hash-YOJYVOWH.js.map +1 -0
  85. package/dist/index.d.ts +1 -1
  86. package/dist/index.js +14 -4395
  87. package/dist/index.js.map +1 -1
  88. package/dist/loader-VP2ZIC4O.js +9 -0
  89. package/dist/loader-VP2ZIC4O.js.map +1 -0
  90. package/dist/logging/index.js +2 -723
  91. package/dist/logging/index.js.map +1 -1
  92. package/dist/pathfinder/index.js +18 -2341
  93. package/dist/pathfinder/index.js.map +1 -1
  94. package/dist/prom-client-PNEBGD3G.js +4801 -0
  95. package/dist/prom-client-PNEBGD3G.js.map +1 -0
  96. package/dist/reports/license-inventory.csv +1 -1
  97. package/dist/schema/index.d.ts +19 -6
  98. package/dist/schema/index.js +4 -6148
  99. package/dist/schema/index.js.map +1 -1
  100. package/dist/signals/index.js +8 -2767
  101. package/dist/signals/index.js.map +1 -1
  102. package/dist/similarity/index.js +3 -134
  103. package/dist/similarity/index.js.map +1 -1
  104. package/dist/telemetry/http/index.js +9 -930
  105. package/dist/telemetry/http/index.js.map +1 -1
  106. package/dist/telemetry/index.js +4 -1561
  107. package/dist/telemetry/index.js.map +1 -1
  108. package/dist/telemetry/prometheus/index.js +7 -8422
  109. package/dist/telemetry/prometheus/index.js.map +1 -1
  110. package/dist/validator-I3ASDVDB.js +6 -0
  111. package/dist/validator-I3ASDVDB.js.map +1 -0
  112. package/package.json +5 -1
  113. package/schemas/crucible-ts/library/module-manifest/v1.0.0/module-manifest.schema.json +1 -1
  114. package/schemas/crucible-ts/observability/logging/v1.0.0/definitions.schema.json +1 -1
  115. package/schemas/crucible-ts/observability/logging/v1.0.0/log-event.schema.json +13 -13
  116. package/schemas/crucible-ts/observability/logging/v1.0.0/logger-config.schema.json +2 -2
  117. package/schemas/crucible-ts/observability/logging/v1.0.0/logging-policy.schema.json +1 -1
  118. package/schemas/crucible-ts/observability/logging/v1.0.0/middleware-config.schema.json +2 -2
  119. package/schemas/crucible-ts/observability/logging/v1.0.0/severity-filter.schema.json +3 -3
  120. package/schemas/crucible-ts/upstream/3leaps/crucible/PROVENANCE.md +3 -3
  121. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/catalog/classifiers/README.md +1 -1
  122. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/classifiers-framework.md +1 -1
  123. package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/data-sensitivity-classification.md +1 -1
@@ -1,895 +1,15 @@
1
+ import { suggest } from '../chunk-LWAH2UG7.js';
2
+ import '../chunk-3HISR2XI.js';
3
+ import { parseFrontmatter } from '../chunk-BCO3FUUO.js';
4
+ import { metrics } from '../chunk-SNV5WG5V.js';
5
+ import '../chunk-QCCN6POA.js';
6
+ import '../chunk-56F2EEAG.js';
7
+ import '../chunk-UP2VWCW5.js';
1
8
  import { readFile, readdir, stat } from 'fs/promises';
2
9
  import { join } from 'path';
3
- import { parse, parseDocument } from 'yaml';
4
- import 'ajv-formats';
5
- import 'child_process';
6
- import 'url';
7
- import 'fast-glob';
8
- import 'ajv';
9
- import 'ajv/dist/2019.js';
10
- import 'ajv/dist/2020.js';
11
- import 'ajv-draft-04';
12
- import 'commander';
13
- import { suggest as suggest$1 } from '@3leaps/string-metrics-wasm';
10
+ import { parse } from 'yaml';
14
11
  import { readFileSync } from 'fs';
15
12
 
16
- var __getOwnPropNames = Object.getOwnPropertyNames;
17
- var __esm = (fn, res) => function __init() {
18
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
19
- };
20
-
21
- // src/telemetry/counter.ts
22
- var Counter;
23
- var init_counter = __esm({
24
- "src/telemetry/counter.ts"() {
25
- Counter = class {
26
- constructor(name) {
27
- this.name = name;
28
- }
29
- value = 0;
30
- labeledValues = /* @__PURE__ */ new Map();
31
- /**
32
- * Increment counter by delta (default: 1)
33
- *
34
- * @param delta - Amount to increment (must be non-negative)
35
- * @param labels - Optional label dimensions for this observation
36
- * @throws {Error} If delta is negative
37
- *
38
- * @example
39
- * ```typescript
40
- * counter.inc(); // Increment unlabeled by 1
41
- * counter.inc(5); // Increment unlabeled by 5
42
- * counter.inc(1, { status: '200' }); // Increment labeled instance
43
- * counter.inc(1, { result: 'success' }); // Different label set
44
- * ```
45
- */
46
- inc(delta = 1, labels) {
47
- if (delta < 0) {
48
- throw new Error(`Counter delta must be non-negative, got: ${delta}`);
49
- }
50
- if (labels && Object.keys(labels).length > 0) {
51
- const labelKey = this.serializeLabels(labels);
52
- const current = this.labeledValues.get(labelKey) || 0;
53
- this.labeledValues.set(labelKey, current + delta);
54
- } else {
55
- this.value += delta;
56
- }
57
- }
58
- /**
59
- * Get current counter value (unlabeled)
60
- */
61
- getValue() {
62
- return this.value;
63
- }
64
- /**
65
- * Get all labeled values
66
- * @returns Map of serialized label keys to values
67
- */
68
- getLabeledValues() {
69
- return new Map(this.labeledValues);
70
- }
71
- /**
72
- * Get value for specific label combination
73
- */
74
- getValueForLabels(labels) {
75
- const labelKey = this.serializeLabels(labels);
76
- return this.labeledValues.get(labelKey) || 0;
77
- }
78
- /**
79
- * Reset counter to zero (all label combinations)
80
- */
81
- reset() {
82
- this.value = 0;
83
- this.labeledValues.clear();
84
- }
85
- /**
86
- * Serialize labels to deterministic string key
87
- * Format: key1=value1,key2=value2 (sorted by key)
88
- */
89
- serializeLabels(labels) {
90
- return Object.entries(labels).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}=${v}`).join(",");
91
- }
92
- };
93
- }
94
- });
95
-
96
- // src/telemetry/gauge.ts
97
- var Gauge;
98
- var init_gauge = __esm({
99
- "src/telemetry/gauge.ts"() {
100
- Gauge = class {
101
- constructor(name) {
102
- this.name = name;
103
- }
104
- value = 0;
105
- labeledValues = /* @__PURE__ */ new Map();
106
- /**
107
- * Set gauge to specific value
108
- *
109
- * @param value - New gauge value (can be any number, including negative)
110
- * @param labels - Optional label dimensions for this observation
111
- *
112
- * @example
113
- * ```typescript
114
- * gauge.set(42); // Set unlabeled to 42
115
- * gauge.set(-10); // Negative values allowed
116
- * gauge.set(1, { phase: 'collect' }); // Set labeled instance
117
- * ```
118
- */
119
- set(value, labels) {
120
- if (labels && Object.keys(labels).length > 0) {
121
- const labelKey = this.serializeLabels(labels);
122
- this.labeledValues.set(labelKey, value);
123
- } else {
124
- this.value = value;
125
- }
126
- }
127
- /**
128
- * Increment gauge by delta (default: 1)
129
- *
130
- * @param delta - Amount to increment (can be negative)
131
- * @param labels - Optional label dimensions for this observation
132
- */
133
- inc(delta = 1, labels) {
134
- if (labels && Object.keys(labels).length > 0) {
135
- const labelKey = this.serializeLabels(labels);
136
- const current = this.labeledValues.get(labelKey) || 0;
137
- this.labeledValues.set(labelKey, current + delta);
138
- } else {
139
- this.value += delta;
140
- }
141
- }
142
- /**
143
- * Decrement gauge by delta (default: 1)
144
- *
145
- * @param delta - Amount to decrement (can be negative)
146
- * @param labels - Optional label dimensions for this observation
147
- */
148
- dec(delta = 1, labels) {
149
- if (labels && Object.keys(labels).length > 0) {
150
- const labelKey = this.serializeLabels(labels);
151
- const current = this.labeledValues.get(labelKey) || 0;
152
- this.labeledValues.set(labelKey, current - delta);
153
- } else {
154
- this.value -= delta;
155
- }
156
- }
157
- /**
158
- * Get current gauge value (unlabeled)
159
- */
160
- getValue() {
161
- return this.value;
162
- }
163
- /**
164
- * Get all labeled values
165
- * @returns Map of serialized label keys to values
166
- */
167
- getLabeledValues() {
168
- return new Map(this.labeledValues);
169
- }
170
- /**
171
- * Get value for specific label combination
172
- */
173
- getValueForLabels(labels) {
174
- const labelKey = this.serializeLabels(labels);
175
- return this.labeledValues.get(labelKey) || 0;
176
- }
177
- /**
178
- * Reset gauge to zero (all label combinations)
179
- */
180
- reset() {
181
- this.value = 0;
182
- this.labeledValues.clear();
183
- }
184
- /**
185
- * Serialize labels to deterministic string key
186
- * Format: key1=value1,key2=value2 (sorted by key)
187
- */
188
- serializeLabels(labels) {
189
- return Object.entries(labels).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}=${v}`).join(",");
190
- }
191
- };
192
- }
193
- });
194
- async function getDefaultUnit(name) {
195
- return TaxonomyLoader.getInstance().getDefaultUnit(name);
196
- }
197
- var DEFAULT_MS_BUCKETS, TaxonomyLoader;
198
- var init_taxonomy = __esm({
199
- "src/telemetry/taxonomy.ts"() {
200
- DEFAULT_MS_BUCKETS = [1, 5, 10, 50, 100, 500, 1e3, 5e3, 1e4];
201
- TaxonomyLoader = class _TaxonomyLoader {
202
- static instance;
203
- taxonomy = null;
204
- loadPromise = null;
205
- loadError = null;
206
- constructor() {
207
- }
208
- /**
209
- * Get singleton instance
210
- */
211
- static getInstance() {
212
- if (!_TaxonomyLoader.instance) {
213
- _TaxonomyLoader.instance = new _TaxonomyLoader();
214
- }
215
- return _TaxonomyLoader.instance;
216
- }
217
- /**
218
- * Load taxonomy from YAML file
219
- */
220
- async load() {
221
- if (this.taxonomy !== null) {
222
- return this.taxonomy;
223
- }
224
- if (this.loadError !== null) {
225
- throw this.loadError;
226
- }
227
- if (this.loadPromise) {
228
- return this.loadPromise;
229
- }
230
- this.loadPromise = (async () => {
231
- try {
232
- const taxonomyPath = join(
233
- __dirname,
234
- "..",
235
- "..",
236
- "config",
237
- "crucible-ts",
238
- "taxonomy",
239
- "metrics.yaml"
240
- );
241
- const content = await readFile(taxonomyPath, "utf-8");
242
- this.taxonomy = parse(content);
243
- return this.taxonomy;
244
- } catch (err) {
245
- this.loadError = err instanceof Error ? err : new Error(String(err));
246
- throw new Error(`Failed to load metrics taxonomy: ${this.loadError.message}`);
247
- }
248
- })();
249
- return this.loadPromise;
250
- }
251
- /**
252
- * Get taxonomy (async)
253
- */
254
- async getTaxonomy() {
255
- return this.load();
256
- }
257
- /**
258
- * Get metric definition by name
259
- */
260
- async getMetric(name) {
261
- const taxonomy = await this.load();
262
- return taxonomy.metrics.find((m) => m.name === name);
263
- }
264
- /**
265
- * Get default unit for metric
266
- */
267
- async getDefaultUnit(name) {
268
- const metric = await this.getMetric(name);
269
- return metric?.unit;
270
- }
271
- /**
272
- * Get default histogram buckets for metric
273
- * Returns ADR-0007 buckets for _ms metrics, undefined for others
274
- */
275
- async getDefaultBuckets(name) {
276
- if (name.endsWith("_ms")) {
277
- const taxonomy = await this.load();
278
- return taxonomy.defaults.histogram_buckets.ms_metrics;
279
- }
280
- return void 0;
281
- }
282
- /**
283
- * Check if metric name is valid (exists in taxonomy)
284
- */
285
- async isValidMetricName(name) {
286
- try {
287
- const taxonomy = await this.load();
288
- return taxonomy.metrics.some((m) => m.name === name);
289
- } catch {
290
- return false;
291
- }
292
- }
293
- /**
294
- * Reset loader state (for testing)
295
- * @internal
296
- */
297
- static _reset() {
298
- _TaxonomyLoader.instance = new _TaxonomyLoader();
299
- }
300
- };
301
- }
302
- });
303
-
304
- // src/telemetry/histogram.ts
305
- var Histogram;
306
- var init_histogram = __esm({
307
- "src/telemetry/histogram.ts"() {
308
- init_taxonomy();
309
- Histogram = class {
310
- constructor(name, options) {
311
- this.name = name;
312
- if (options?.buckets) {
313
- this.buckets = [...options.buckets].sort((a, b) => a - b);
314
- } else if (name.endsWith("_ms") || name.endsWith("_seconds")) {
315
- this.buckets = [...DEFAULT_MS_BUCKETS];
316
- } else {
317
- this.buckets = [];
318
- }
319
- for (const bucket of this.buckets) {
320
- this.bucketCounts.set(bucket, 0);
321
- }
322
- }
323
- count = 0;
324
- sum = 0;
325
- bucketCounts = /* @__PURE__ */ new Map();
326
- labeledStates = /* @__PURE__ */ new Map();
327
- buckets;
328
- /**
329
- * Record an observation
330
- *
331
- * @param value - Value to observe (typically a duration in ms or seconds)
332
- * @param labels - Optional label dimensions for this observation
333
- *
334
- * @example
335
- * ```typescript
336
- * const start = performance.now();
337
- * // ... operation ...
338
- * histogram.observe(performance.now() - start);
339
- * histogram.observe(duration, { phase: 'collect', result: 'success' });
340
- * ```
341
- */
342
- observe(value, labels) {
343
- if (labels && Object.keys(labels).length > 0) {
344
- const labelKey = this.serializeLabels(labels);
345
- let state = this.labeledStates.get(labelKey);
346
- if (!state) {
347
- state = {
348
- count: 0,
349
- sum: 0,
350
- bucketCounts: /* @__PURE__ */ new Map()
351
- };
352
- for (const bucket of this.buckets) {
353
- state.bucketCounts.set(bucket, 0);
354
- }
355
- this.labeledStates.set(labelKey, state);
356
- }
357
- state.count++;
358
- state.sum += value;
359
- for (const bucket of this.buckets) {
360
- if (value <= bucket) {
361
- state.bucketCounts.set(bucket, (state.bucketCounts.get(bucket) || 0) + 1);
362
- }
363
- }
364
- } else {
365
- this.count++;
366
- this.sum += value;
367
- for (const bucket of this.buckets) {
368
- if (value <= bucket) {
369
- this.bucketCounts.set(bucket, (this.bucketCounts.get(bucket) || 0) + 1);
370
- }
371
- }
372
- }
373
- }
374
- /**
375
- * Get histogram summary
376
- *
377
- * Returns OTLP-compatible histogram summary with cumulative bucket counts.
378
- */
379
- getSummary() {
380
- const buckets = this.buckets.map((le) => ({
381
- le,
382
- count: this.bucketCounts.get(le) || 0
383
- }));
384
- return {
385
- count: this.count,
386
- sum: this.sum,
387
- buckets
388
- };
389
- }
390
- /**
391
- * Get current observation count
392
- */
393
- getCount() {
394
- return this.count;
395
- }
396
- /**
397
- * Get sum of all observed values
398
- */
399
- getSum() {
400
- return this.sum;
401
- }
402
- /**
403
- * Get average of observed values
404
- */
405
- getAverage() {
406
- return this.count > 0 ? this.sum / this.count : 0;
407
- }
408
- /**
409
- * Get all labeled summaries
410
- * @returns Map of serialized label keys to histogram summaries
411
- */
412
- getLabeledSummaries() {
413
- const summaries = /* @__PURE__ */ new Map();
414
- for (const [labelKey, state] of this.labeledStates) {
415
- const buckets = this.buckets.map((le) => ({
416
- le,
417
- count: state.bucketCounts.get(le) || 0
418
- }));
419
- summaries.set(labelKey, {
420
- count: state.count,
421
- sum: state.sum,
422
- buckets
423
- });
424
- }
425
- return summaries;
426
- }
427
- /**
428
- * Get summary for specific label combination
429
- */
430
- getSummaryForLabels(labels) {
431
- const labelKey = this.serializeLabels(labels);
432
- const state = this.labeledStates.get(labelKey);
433
- if (!state) {
434
- return null;
435
- }
436
- const buckets = this.buckets.map((le) => ({
437
- le,
438
- count: state.bucketCounts.get(le) || 0
439
- }));
440
- return {
441
- count: state.count,
442
- sum: state.sum,
443
- buckets
444
- };
445
- }
446
- /**
447
- * Reset histogram to initial state (all label combinations)
448
- */
449
- reset() {
450
- this.count = 0;
451
- this.sum = 0;
452
- for (const bucket of this.buckets) {
453
- this.bucketCounts.set(bucket, 0);
454
- }
455
- this.labeledStates.clear();
456
- }
457
- /**
458
- * Serialize labels to deterministic string key
459
- * Format: key1=value1,key2=value2 (sorted by key)
460
- */
461
- serializeLabels(labels) {
462
- return Object.entries(labels).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}=${v}`).join(",");
463
- }
464
- };
465
- }
466
- });
467
-
468
- // src/telemetry/registry.ts
469
- var MetricsRegistry;
470
- var init_registry = __esm({
471
- "src/telemetry/registry.ts"() {
472
- init_counter();
473
- init_gauge();
474
- init_histogram();
475
- init_taxonomy();
476
- MetricsRegistry = class {
477
- counters = /* @__PURE__ */ new Map();
478
- gauges = /* @__PURE__ */ new Map();
479
- histograms = /* @__PURE__ */ new Map();
480
- /**
481
- * Get or create a counter
482
- *
483
- * @param name - Metric name from taxonomy
484
- * @returns Counter instance
485
- *
486
- * @example
487
- * ```typescript
488
- * const counter = registry.counter('schema_validations');
489
- * counter.inc();
490
- * ```
491
- */
492
- counter(name) {
493
- let counter = this.counters.get(name);
494
- if (!counter) {
495
- counter = new Counter(name);
496
- this.counters.set(name, counter);
497
- }
498
- return counter;
499
- }
500
- /**
501
- * Get or create a gauge
502
- *
503
- * @param name - Metric name from taxonomy
504
- * @returns Gauge instance
505
- *
506
- * @example
507
- * ```typescript
508
- * const gauge = registry.gauge('foundry_lookup_count');
509
- * gauge.set(42);
510
- * ```
511
- */
512
- gauge(name) {
513
- let gauge = this.gauges.get(name);
514
- if (!gauge) {
515
- gauge = new Gauge(name);
516
- this.gauges.set(name, gauge);
517
- }
518
- return gauge;
519
- }
520
- /**
521
- * Get or create a histogram
522
- *
523
- * @param name - Metric name from taxonomy
524
- * @param options - Optional histogram options
525
- * @returns Histogram instance
526
- *
527
- * @example
528
- * ```typescript
529
- * // Auto-applies ADR-0007 buckets for _ms metrics
530
- * const histogram = registry.histogram('config_load_ms');
531
- * histogram.observe(42.5);
532
- *
533
- * // Custom buckets
534
- * const custom = registry.histogram('custom_metric', {
535
- * buckets: [10, 50, 100, 500, 1000]
536
- * });
537
- * ```
538
- */
539
- histogram(name, options) {
540
- let histogram = this.histograms.get(name);
541
- if (!histogram) {
542
- histogram = new Histogram(name, options);
543
- this.histograms.set(name, histogram);
544
- }
545
- return histogram;
546
- }
547
- /**
548
- * Export all metrics as events
549
- *
550
- * Returns array of schema-compliant MetricsEvent objects.
551
- * Does not clear metrics (use flush() to clear after export).
552
- *
553
- * @returns Promise resolving to array of metrics events
554
- *
555
- * @example
556
- * ```typescript
557
- * const events = await registry.export();
558
- * console.log(JSON.stringify(events, null, 2));
559
- * ```
560
- */
561
- async export() {
562
- const events = [];
563
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
564
- for (const [name, counter] of this.counters) {
565
- const unit = await getDefaultUnit(name);
566
- events.push({
567
- timestamp,
568
- name,
569
- value: counter.getValue(),
570
- unit
571
- });
572
- for (const [labelKey, value] of counter.getLabeledValues()) {
573
- if (value > 0) {
574
- const tags = this.deserializeLabels(labelKey);
575
- events.push({
576
- timestamp,
577
- name,
578
- value,
579
- tags,
580
- unit
581
- });
582
- }
583
- }
584
- }
585
- for (const [name, gauge] of this.gauges) {
586
- const unit = await getDefaultUnit(name);
587
- events.push({
588
- timestamp,
589
- name,
590
- value: gauge.getValue(),
591
- unit
592
- });
593
- for (const [labelKey, value] of gauge.getLabeledValues()) {
594
- const tags = this.deserializeLabels(labelKey);
595
- events.push({
596
- timestamp,
597
- name,
598
- value,
599
- tags,
600
- unit
601
- });
602
- }
603
- }
604
- for (const [name, histogram] of this.histograms) {
605
- const unit = await getDefaultUnit(name);
606
- events.push({
607
- timestamp,
608
- name,
609
- value: histogram.getSummary(),
610
- unit
611
- });
612
- for (const [labelKey, summary] of histogram.getLabeledSummaries()) {
613
- if (summary.count > 0) {
614
- const tags = this.deserializeLabels(labelKey);
615
- events.push({
616
- timestamp,
617
- name,
618
- value: summary,
619
- tags,
620
- unit
621
- });
622
- }
623
- }
624
- }
625
- return events;
626
- }
627
- /**
628
- * Deserialize label key back to tags object
629
- * Format: key1=value1,key2=value2 → {key1: "value1", key2: "value2"}
630
- */
631
- deserializeLabels(labelKey) {
632
- if (!labelKey) {
633
- return {};
634
- }
635
- const tags = {};
636
- for (const pair of labelKey.split(",")) {
637
- const [key, value] = pair.split("=");
638
- if (key && value) {
639
- tags[key] = value;
640
- }
641
- }
642
- return tags;
643
- }
644
- /**
645
- * Export and clear all metrics
646
- *
647
- * Exports metrics as events, optionally emits them via logger,
648
- * then resets all metrics to zero.
649
- *
650
- * @param options - Flush options
651
- * @returns Promise resolving to array of exported events
652
- *
653
- * @example
654
- * ```typescript
655
- * // Export and clear
656
- * const events = await registry.flush();
657
- *
658
- * // Export, emit to logger, and clear
659
- * const events = await registry.flush({
660
- * emit: (events) => console.log(JSON.stringify(events))
661
- * });
662
- * ```
663
- */
664
- async flush(options) {
665
- const events = await this.export();
666
- try {
667
- if (options?.emit) {
668
- options.emit(events);
669
- }
670
- } finally {
671
- this.clear();
672
- }
673
- return events;
674
- }
675
- /**
676
- * Clear all metrics (reset to zero)
677
- *
678
- * Resets all counters, gauges, and histograms to their initial state.
679
- */
680
- clear() {
681
- for (const counter of this.counters.values()) {
682
- counter.reset();
683
- }
684
- for (const gauge of this.gauges.values()) {
685
- gauge.reset();
686
- }
687
- for (const histogram of this.histograms.values()) {
688
- histogram.reset();
689
- }
690
- }
691
- /**
692
- * Get all registered metric names
693
- *
694
- * Returns array of all metric names that have been accessed
695
- * (counters, gauges, or histograms).
696
- */
697
- getMetricNames() {
698
- const names = /* @__PURE__ */ new Set();
699
- for (const name of this.counters.keys()) {
700
- names.add(name);
701
- }
702
- for (const name of this.gauges.keys()) {
703
- names.add(name);
704
- }
705
- for (const name of this.histograms.keys()) {
706
- names.add(name);
707
- }
708
- return Array.from(names);
709
- }
710
- /**
711
- * Get total count of registered metrics
712
- */
713
- getMetricCount() {
714
- return this.counters.size + this.gauges.size + this.histograms.size;
715
- }
716
- };
717
- }
718
- });
719
-
720
- // src/telemetry/types.ts
721
- var init_types = __esm({
722
- "src/telemetry/types.ts"() {
723
- }
724
- });
725
- var init_ajv_formats = __esm({
726
- "src/schema/ajv-formats.ts"() {
727
- }
728
- });
729
-
730
- // src/schema/errors.ts
731
- var init_errors = __esm({
732
- "src/schema/errors.ts"() {
733
- }
734
- });
735
-
736
- // src/schema/utils.ts
737
- var init_utils = __esm({
738
- "src/schema/utils.ts"() {
739
- init_errors();
740
- }
741
- });
742
- var init_goneat_bridge = __esm({
743
- "src/schema/goneat-bridge.ts"() {
744
- init_utils();
745
- }
746
- });
747
- var init_normalizer = __esm({
748
- "src/schema/normalizer.ts"() {
749
- init_errors();
750
- }
751
- });
752
- var init_registry2 = __esm({
753
- "src/schema/registry.ts"() {
754
- init_errors();
755
- }
756
- });
757
- var init_validator = __esm({
758
- "src/schema/validator.ts"() {
759
- init_telemetry();
760
- init_ajv_formats();
761
- init_errors();
762
- init_registry2();
763
- init_utils();
764
- }
765
- });
766
- var init_cli = __esm({
767
- "src/schema/cli.ts"() {
768
- init_goneat_bridge();
769
- init_normalizer();
770
- init_registry2();
771
- init_utils();
772
- init_validator();
773
- }
774
- });
775
- var init_export = __esm({
776
- "src/schema/export.ts"() {
777
- init_errors();
778
- init_registry2();
779
- init_validator();
780
- }
781
- });
782
-
783
- // src/schema/index.ts
784
- var init_schema = __esm({
785
- "src/schema/index.ts"() {
786
- init_ajv_formats();
787
- init_cli();
788
- init_errors();
789
- init_export();
790
- init_goneat_bridge();
791
- init_normalizer();
792
- init_registry2();
793
- init_utils();
794
- init_validator();
795
- }
796
- });
797
-
798
- // src/telemetry/validators.ts
799
- var init_validators = __esm({
800
- "src/telemetry/validators.ts"() {
801
- init_schema();
802
- }
803
- });
804
-
805
- // src/telemetry/index.ts
806
- var metrics;
807
- var init_telemetry = __esm({
808
- "src/telemetry/index.ts"() {
809
- init_registry();
810
- init_registry();
811
- init_counter();
812
- init_gauge();
813
- init_histogram();
814
- init_taxonomy();
815
- init_types();
816
- init_validators();
817
- metrics = new MetricsRegistry();
818
- }
819
- });
820
- var init_distance = __esm({
821
- "src/foundry/similarity/distance.ts"() {
822
- }
823
- });
824
-
825
- // src/foundry/errors.ts
826
- var init_errors2 = __esm({
827
- "src/foundry/errors.ts"() {
828
- }
829
- });
830
-
831
- // src/foundry/similarity/errors.ts
832
- var init_errors3 = __esm({
833
- "src/foundry/similarity/errors.ts"() {
834
- init_errors2();
835
- }
836
- });
837
- var init_normalization = __esm({
838
- "src/foundry/similarity/normalization.ts"() {
839
- }
840
- });
841
- var init_score = __esm({
842
- "src/foundry/similarity/score.ts"() {
843
- }
844
- });
845
- function suggest(input, candidates, options) {
846
- const metric = options?.metric ?? DEFAULT_METRIC;
847
- const minScore = options?.minScore;
848
- const maxSuggestions = options?.maxSuggestions;
849
- let normalizePreset = options?.normalizePreset ?? DEFAULT_NORMALIZE_PRESET;
850
- if (!options?.normalizePreset) {
851
- normalizePreset = "default";
852
- }
853
- const wasmOptions = {
854
- metric,
855
- normalizePreset,
856
- minScore,
857
- maxSuggestions,
858
- preferPrefix: options?.preferPrefix,
859
- jaroPrefixScale: options?.jaroPrefixScale,
860
- jaroMaxPrefix: options?.jaroMaxPrefix
861
- };
862
- const results = suggest$1(input, candidates, wasmOptions);
863
- return results.map((r) => ({
864
- value: r.value,
865
- score: r.score,
866
- matchedRange: r.matchedRange,
867
- reason: r.reason,
868
- normalizedValue: r.normalizedValue
869
- }));
870
- }
871
- var DEFAULT_METRIC, DEFAULT_NORMALIZE_PRESET;
872
- var init_suggest = __esm({
873
- "src/foundry/similarity/suggest.ts"() {
874
- DEFAULT_METRIC = "levenshtein";
875
- DEFAULT_NORMALIZE_PRESET = "default";
876
- }
877
- });
878
-
879
- // src/foundry/similarity/index.ts
880
- var init_similarity = __esm({
881
- "src/foundry/similarity/index.ts"() {
882
- init_distance();
883
- init_errors3();
884
- init_normalization();
885
- init_score();
886
- init_suggest();
887
- }
888
- });
889
-
890
- // src/crucible/configs.ts
891
- init_telemetry();
892
-
893
13
  // src/crucible/normalize.ts
894
14
  var CATEGORY_BASE_PATHS = {
895
15
  docs: "docs/crucible-ts/",
@@ -1018,7 +138,6 @@ async function listAssets(category, options) {
1018
138
  }
1019
139
 
1020
140
  // src/crucible/errors.ts
1021
- init_similarity();
1022
141
  var AssetNotFoundError = class extends Error {
1023
142
  assetId;
1024
143
  category;
@@ -1026,7 +145,9 @@ var AssetNotFoundError = class extends Error {
1026
145
  constructor(id, category, availableIds) {
1027
146
  const suggestions = suggest(id, availableIds, {
1028
147
  maxSuggestions: 3,
1029
- minScore: 0.6});
148
+ minScore: 0.6,
149
+ normalize: true
150
+ });
1030
151
  const suggestionText = suggestions.length > 0 ? `
1031
152
 
1032
153
  Did you mean:
@@ -1094,237 +215,6 @@ async function getConfigDefaults(category, version) {
1094
215
  throw new AssetNotFoundError(matchingAsset.id, "config", availableIds);
1095
216
  }
1096
217
  }
1097
-
1098
- // src/docscribe/normalize.ts
1099
- var decoder = new TextDecoder("utf-8", { fatal: false, ignoreBOM: true });
1100
- function stripBom(value) {
1101
- return value.charCodeAt(0) === 65279 ? value.slice(1) : value;
1102
- }
1103
- function normalizeNewlines(value) {
1104
- return value.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
1105
- }
1106
- function normalizeInput(input) {
1107
- let content;
1108
- if (typeof input === "string") {
1109
- content = input;
1110
- } else if (input instanceof Uint8Array) {
1111
- content = decoder.decode(input);
1112
- } else {
1113
- content = decoder.decode(new Uint8Array(input));
1114
- }
1115
- const normalized = normalizeNewlines(stripBom(content));
1116
- return { content: normalized, original: input };
1117
- }
1118
-
1119
- // src/docscribe/types.ts
1120
- var DocScribeError = class extends Error {
1121
- constructor(message, options) {
1122
- super(message, options);
1123
- Object.setPrototypeOf(this, new.target.prototype);
1124
- this.name = "DocScribeError";
1125
- }
1126
- };
1127
- var DocScribeParseError = class extends DocScribeError {
1128
- constructor(message, options) {
1129
- super(message, options);
1130
- Object.setPrototypeOf(this, new.target.prototype);
1131
- this.name = "DocScribeParseError";
1132
- }
1133
- };
1134
-
1135
- // src/docscribe/frontmatter.ts
1136
- var FRONTMATTER_DELIMITER = "---";
1137
- var STRING_KEYS = /* @__PURE__ */ new Set([
1138
- "title",
1139
- "description",
1140
- "author",
1141
- "date",
1142
- "lastUpdated",
1143
- "status",
1144
- "version"
1145
- ]);
1146
- function parseFrontmatter(input) {
1147
- const { content } = normalizeInput(input);
1148
- const bounds = locateFrontmatter(content);
1149
- if (!bounds) {
1150
- return { metadata: null, body: content, range: null, bodyStartLine: 1 };
1151
- }
1152
- const yamlBlock = content.slice(bounds.openEnd, bounds.closingStart);
1153
- const metadata = yamlBlock.trim().length === 0 ? {} : parseYamlMetadata(yamlBlock);
1154
- const bodyRaw = content.slice(bounds.closingEnd);
1155
- const leadingNewlinesMatch = bodyRaw.match(/^\n+/);
1156
- const leadingNewlinesLength = leadingNewlinesMatch ? leadingNewlinesMatch[0].length : 0;
1157
- const bodyStartIndex = bounds.closingEnd + leadingNewlinesLength;
1158
- const prefix = content.slice(0, bodyStartIndex);
1159
- const bodyStartLine = prefix.length === 0 ? 1 : prefix.split("\n").length;
1160
- const body = bodyRaw.slice(leadingNewlinesLength);
1161
- return {
1162
- metadata,
1163
- body,
1164
- range: { start: bounds.start, end: bounds.closingEnd },
1165
- bodyStartLine
1166
- };
1167
- }
1168
- function locateFrontmatter(content) {
1169
- let cursor = 0;
1170
- while (cursor < content.length) {
1171
- const newlineIndex = content.indexOf("\n", cursor);
1172
- const lineEnd = newlineIndex === -1 ? content.length : newlineIndex;
1173
- const line = content.slice(cursor, lineEnd);
1174
- if (line.trim().length === 0) {
1175
- if (newlineIndex === -1) {
1176
- return null;
1177
- }
1178
- cursor = newlineIndex + 1;
1179
- continue;
1180
- }
1181
- if (line.trim() !== FRONTMATTER_DELIMITER) {
1182
- return null;
1183
- }
1184
- const openStart = cursor;
1185
- const openEnd = newlineIndex === -1 ? content.length : newlineIndex + 1;
1186
- let search = openEnd;
1187
- while (search <= content.length) {
1188
- const nextNewline = content.indexOf("\n", search);
1189
- const segmentEnd = nextNewline === -1 ? content.length : nextNewline;
1190
- const candidate = content.slice(search, segmentEnd).trim();
1191
- if (candidate === FRONTMATTER_DELIMITER) {
1192
- const closingStart = search;
1193
- const closingEnd = nextNewline === -1 ? segmentEnd : nextNewline + 1;
1194
- return {
1195
- start: openStart,
1196
- openEnd,
1197
- closingStart,
1198
- closingEnd
1199
- };
1200
- }
1201
- if (nextNewline === -1) {
1202
- break;
1203
- }
1204
- search = nextNewline + 1;
1205
- }
1206
- return null;
1207
- }
1208
- return null;
1209
- }
1210
- function parseYamlMetadata(source) {
1211
- const document = parseDocument(source, { prettyErrors: true });
1212
- if (document.errors.length > 0) {
1213
- const error = document.errors[0];
1214
- const location = error.linePos && error.linePos.length > 0 ? error.linePos[0] : null;
1215
- const position = location ? ` (line ${location.line + 1}, column ${location.col + 1})` : "";
1216
- throw new DocScribeParseError(`Invalid YAML frontmatter${position}: ${error.message}`, {
1217
- cause: error
1218
- });
1219
- }
1220
- let raw;
1221
- try {
1222
- raw = document.toJS({ mapAsMap: false });
1223
- } catch (error) {
1224
- throw new DocScribeParseError("Failed to parse YAML frontmatter", {
1225
- cause: error instanceof Error ? error : void 0
1226
- });
1227
- }
1228
- if (raw == null) {
1229
- return {};
1230
- }
1231
- if (typeof raw !== "object" || Array.isArray(raw)) {
1232
- throw new DocScribeParseError("YAML frontmatter must be a mapping at the top level");
1233
- }
1234
- return normalizeMetadata(raw);
1235
- }
1236
- function normalizeMetadata(raw) {
1237
- const normalized = {};
1238
- for (const [key, value] of Object.entries(raw)) {
1239
- normalized[key] = normalizeMetadataValue(value);
1240
- }
1241
- const base = {};
1242
- for (const [key, value] of Object.entries(normalized)) {
1243
- if (STRING_KEYS.has(key) || key === "tags" || key === "relatedDocs") {
1244
- continue;
1245
- }
1246
- base[key] = value;
1247
- }
1248
- const metadata = {
1249
- ...base,
1250
- ...normalized.title !== void 0 ? { title: ensureStringValue(normalized.title) } : {},
1251
- ...normalized.description !== void 0 ? { description: ensureStringValue(normalized.description) } : {},
1252
- ...normalized.author !== void 0 ? { author: ensureStringValue(normalized.author) } : {},
1253
- ...normalized.date !== void 0 ? { date: ensureStringValue(normalized.date) } : {},
1254
- ...normalized.lastUpdated !== void 0 ? { lastUpdated: ensureStringValue(normalized.lastUpdated) } : {},
1255
- ...normalized.status !== void 0 ? { status: ensureStringValue(normalized.status) } : {},
1256
- ...normalized.version !== void 0 ? { version: ensureStringValue(normalized.version) } : {},
1257
- ...normalized.tags !== void 0 ? (() => {
1258
- const tags = ensureStringArray(normalized.tags);
1259
- return tags.length > 0 ? { tags } : {};
1260
- })() : {},
1261
- ...normalized.relatedDocs !== void 0 ? (() => {
1262
- const related = ensureStringArray(normalized.relatedDocs);
1263
- return related.length > 0 ? { relatedDocs: related } : {};
1264
- })() : {}
1265
- };
1266
- return metadata;
1267
- }
1268
- function normalizeMetadataValue(value) {
1269
- if (value === null) {
1270
- return null;
1271
- }
1272
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1273
- return value;
1274
- }
1275
- if (value instanceof Date) {
1276
- return value.toISOString();
1277
- }
1278
- if (Array.isArray(value)) {
1279
- return value.map(
1280
- (item) => normalizeMetadataValue(item)
1281
- );
1282
- }
1283
- if (typeof value === "object") {
1284
- const result = {};
1285
- for (const [key, nested] of Object.entries(value)) {
1286
- result[key] = normalizeMetadataValue(nested);
1287
- }
1288
- return result;
1289
- }
1290
- return String(value);
1291
- }
1292
- function ensureStringValue(value) {
1293
- if (value === null) {
1294
- return "";
1295
- }
1296
- if (typeof value === "string") {
1297
- return value;
1298
- }
1299
- if (typeof value === "number" || typeof value === "boolean") {
1300
- return String(value);
1301
- }
1302
- if (Array.isArray(value)) {
1303
- return value.flatMap((item) => ensureStringArrayItem(item)).join(", ");
1304
- }
1305
- return JSON.stringify(value);
1306
- }
1307
- function ensureStringArray(value) {
1308
- return ensureStringArrayItem(value);
1309
- }
1310
- function ensureStringArrayItem(value) {
1311
- if (value === null) {
1312
- return [];
1313
- }
1314
- if (typeof value === "string") {
1315
- return value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
1316
- }
1317
- if (typeof value === "number" || typeof value === "boolean") {
1318
- return [String(value)];
1319
- }
1320
- if (Array.isArray(value)) {
1321
- return value.flatMap((item) => ensureStringArrayItem(item));
1322
- }
1323
- return [JSON.stringify(value)];
1324
- }
1325
-
1326
- // src/crucible/docs.ts
1327
- init_telemetry();
1328
218
  async function listDocumentation(filters) {
1329
219
  const assets = await listAssets("docs", {
1330
220
  prefix: filters?.prefix,
@@ -1390,9 +280,6 @@ async function getDocumentationMetadata(id) {
1390
280
  return null;
1391
281
  }
1392
282
  }
1393
-
1394
- // src/crucible/roles.ts
1395
- init_telemetry();
1396
283
  var ROLE_PREFIX = "agentic/roles";
1397
284
  var SLUG_PATTERN = /^[a-z][a-z0-9]*$/;
1398
285
  async function listRoleSlugs() {
@@ -1436,10 +323,7 @@ async function loadRoleCatalog() {
1436
323
  }
1437
324
  return catalog;
1438
325
  }
1439
-
1440
- // src/crucible/schemas.ts
1441
- init_telemetry();
1442
- async function listSchemas2(kind) {
326
+ async function listSchemas(kind) {
1443
327
  const assets = await listAssets("schemas");
1444
328
  const summaries = assets.map((asset) => ({
1445
329
  ...asset,
@@ -1495,6 +379,6 @@ function getCrucibleVersion() {
1495
379
  }
1496
380
  }
1497
381
 
1498
- export { AssetNotFoundError, InvalidAssetIdError, getConfigDefaults, getCrucibleVersion, getDocumentation, getDocumentationMetadata, getDocumentationWithMetadata, listAssets, listCategories, listConfigDefaults, listDocumentation, listRoleSlugs, listSchemas2 as listSchemas, loadRole, loadRoleCatalog, loadSchemaById };
382
+ export { AssetNotFoundError, InvalidAssetIdError, getConfigDefaults, getCrucibleVersion, getDocumentation, getDocumentationMetadata, getDocumentationWithMetadata, listAssets, listCategories, listConfigDefaults, listDocumentation, listRoleSlugs, listSchemas, loadRole, loadRoleCatalog, loadSchemaById };
1499
383
  //# sourceMappingURL=index.js.map
1500
384
  //# sourceMappingURL=index.js.map