@fulmenhq/tsfulmen 0.2.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/README.md +61 -7
- package/config/crucible-ts/agentic/roles/README.md +3 -3
- package/config/crucible-ts/library/fulencode/fixtures/README.md +18 -0
- package/config/crucible-ts/library/fulencode/fixtures/bom/bom.yaml +14 -0
- package/config/crucible-ts/library/fulencode/fixtures/detection/detection.yaml +12 -0
- package/config/crucible-ts/library/fulencode/fixtures/invalid-encodings/base64.yaml +10 -0
- package/config/crucible-ts/library/fulencode/fixtures/normalization/text-safe.yaml +10 -0
- package/config/crucible-ts/library/fulencode/fixtures/telemetry/telemetry-test-cases.yaml +24 -0
- package/config/crucible-ts/library/fulencode/fixtures/valid-encodings/base64.yaml +11 -0
- package/config/crucible-ts/taxonomy/library/platform-modules/v1.0.0/modules.yaml +2 -2
- package/config/crucible-ts/taxonomy/metrics.yaml +79 -1
- package/dist/appidentity/index.d.ts +31 -109
- package/dist/appidentity/index.js +369 -60
- package/dist/appidentity/index.js.map +1 -1
- package/dist/config/index.d.ts +46 -1
- package/dist/config/index.js +427 -62
- package/dist/config/index.js.map +1 -1
- package/dist/crucible/index.js +367 -59
- package/dist/crucible/index.js.map +1 -1
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +367 -59
- package/dist/errors/index.js.map +1 -1
- package/dist/foundry/index.d.ts +2 -1
- package/dist/foundry/index.js +368 -60
- package/dist/foundry/index.js.map +1 -1
- package/dist/fulencode/index.d.ts +102 -0
- package/dist/fulencode/index.js +806 -0
- package/dist/fulencode/index.js.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +370 -61
- package/dist/index.js.map +1 -1
- package/dist/pathfinder/index.d.ts +1 -1
- package/dist/pathfinder/index.js +367 -59
- package/dist/pathfinder/index.js.map +1 -1
- package/dist/reports/license-inventory.csv +31 -24
- package/dist/schema/index.d.ts +16 -3
- package/dist/schema/index.js +368 -60
- package/dist/schema/index.js.map +1 -1
- package/dist/signals/index.d.ts +483 -395
- package/dist/signals/index.js +368 -60
- package/dist/signals/index.js.map +1 -1
- package/dist/telemetry/http/index.js +368 -59
- package/dist/telemetry/http/index.js.map +1 -1
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.js +367 -59
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/prometheus/index.d.ts +1 -1
- package/dist/telemetry/prometheus/index.js +369 -59
- package/dist/telemetry/prometheus/index.js.map +1 -1
- package/dist/{types-BJswWpQC.d.ts → types-DdoeE7F5.d.ts} +1 -1
- package/dist/types-Dv5TERCM.d.ts +108 -0
- package/package.json +13 -8
- package/schemas/crucible-ts/library/fulencode/v1.0.0/README.md +37 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/bom-result.schema.json +48 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/decode-options.schema.json +60 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/decoding-result.schema.json +70 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/detect-options.schema.json +25 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/detection-result.schema.json +57 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/encode-options.schema.json +71 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/encoding-result.schema.json +57 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/fulencode-config.schema.json +8 -4
- package/schemas/crucible-ts/library/fulencode/v1.0.0/fulencode-error.schema.json +66 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/normalization-result.schema.json +73 -0
- package/schemas/crucible-ts/library/fulencode/v1.0.0/normalize-options.schema.json +44 -0
- package/schemas/crucible-ts/meta/README.md +38 -2
- package/schemas/crucible-ts/meta/draft-04/schema.json +222 -0
- package/schemas/crucible-ts/meta/draft-06/schema.json +218 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/applicator.json +93 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/content.json +21 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/core.json +58 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/format.json +15 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/meta-data.json +35 -0
- package/schemas/crucible-ts/meta/draft-2019-09/meta/validation.json +119 -0
- package/schemas/crucible-ts/meta/draft-2019-09/offline.schema.json +148 -0
- package/schemas/crucible-ts/meta/draft-2019-09/schema.json +62 -0
- package/schemas/crucible-ts/meta/fixtures/draft-04-sample.json +16 -0
- package/schemas/crucible-ts/meta/fixtures/draft-06-sample.json +16 -0
- package/schemas/crucible-ts/meta/fixtures/draft-07-sample.json +34 -0
- package/schemas/crucible-ts/meta/fixtures/draft-2019-09-sample.json +21 -0
- package/schemas/crucible-ts/meta/fixtures/draft-2020-12-sample.json +21 -0
- package/schemas/crucible-ts/taxonomy/library/fulencode/normalization-profiles/v1.0.0/profiles.yaml +16 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/PROVENANCE.md +64 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/access-tier.dimension.json +103 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/retention-lifecycle.dimension.json +103 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/schema-stability.dimension.json +100 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/sensitivity.dimension.json +130 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/velocity-mode.dimension.json +79 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/volatility.dimension.json +72 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/config/classifiers/dimensions/volume-tier.dimension.json +66 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/catalog/classifiers/README.md +29 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/access-tier-classification.md +163 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/classifiers-framework.md +157 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/data-sensitivity-classification.md +259 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/retention-lifecycle-classification.md +200 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/schema-stability-classification.md +205 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/velocity-mode-classification.md +222 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/volatility-classification.md +209 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/docs/standards/volume-tier-classification.md +200 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/ailink/v0/README.md +48 -0
- package/schemas/crucible-ts/upstream/3leaps/{ailink → crucible/schemas/ailink}/v0/prompt.schema.json +4 -18
- package/schemas/crucible-ts/upstream/3leaps/{ailink → crucible/schemas/ailink}/v0/search-response.schema.json +7 -37
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/classifiers/v0/dimension-definition.schema.json +247 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/classifiers/v0/sensitivity-level.schema.json +67 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/error-response.schema.json +59 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/lifecycle-phases.data.json +102 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/lifecycle-phases.schema.json +101 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/release-phase.schema.json +18 -0
- package/schemas/crucible-ts/upstream/3leaps/crucible/schemas/foundation/v0/types.schema.json +177 -0
- package/schemas/crucible-ts/upstream/3leaps/PROVENANCE.md +0 -43
- /package/schemas/crucible-ts/upstream/3leaps/{agentic → crucible/schemas/agentic}/v0/role-prompt.schema.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as MetricName, a as MetricUnit, b as MetricsRegistry } from '../registry-_yEKhTTl.js';
|
|
2
2
|
export { C as Counter, F as FlushOptions, G as Gauge, H as Histogram, c as HistogramBucket, d as HistogramOptions, e as HistogramSummary, g as MetricValue, f as MetricsEvent, i as isHistogramSummary, h as isValidMetricName, j as isValidMetricUnit } from '../registry-_yEKhTTl.js';
|
|
3
|
-
import { A as AjvError } from '../types-
|
|
3
|
+
import { A as AjvError } from '../types-DdoeE7F5.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Taxonomy loader for metrics definitions
|
package/dist/telemetry/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { readFile, access, mkdir, writeFile } from 'fs/promises';
|
|
2
2
|
import { dirname, extname, join, relative } from 'path';
|
|
3
3
|
import { parse, stringify } from 'yaml';
|
|
4
|
+
import addFormats from 'ajv-formats';
|
|
4
5
|
import { spawn } from 'child_process';
|
|
5
6
|
import { fileURLToPath } from 'url';
|
|
6
7
|
import glob from 'fast-glob';
|
|
7
8
|
import Ajv from 'ajv';
|
|
8
|
-
import
|
|
9
|
+
import Ajv2019 from 'ajv/dist/2019';
|
|
10
|
+
import Ajv2020 from 'ajv/dist/2020';
|
|
11
|
+
import AjvDraft04 from 'ajv-draft-04';
|
|
9
12
|
import { Readable } from 'stream';
|
|
10
13
|
import picomatch from 'picomatch';
|
|
11
14
|
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';
|
|
@@ -798,6 +801,27 @@ var init_types = __esm({
|
|
|
798
801
|
"src/telemetry/types.ts"() {
|
|
799
802
|
}
|
|
800
803
|
});
|
|
804
|
+
function applyFulmenAjvFormats(ajv, options = {}) {
|
|
805
|
+
const mode = options.mode ?? "fast";
|
|
806
|
+
const formats = options.formats ?? DEFAULT_FORMATS;
|
|
807
|
+
addFormats(ajv, { mode, formats });
|
|
808
|
+
return ajv;
|
|
809
|
+
}
|
|
810
|
+
var DEFAULT_FORMATS;
|
|
811
|
+
var init_ajv_formats = __esm({
|
|
812
|
+
"src/schema/ajv-formats.ts"() {
|
|
813
|
+
DEFAULT_FORMATS = [
|
|
814
|
+
"date-time",
|
|
815
|
+
"email",
|
|
816
|
+
"hostname",
|
|
817
|
+
"ipv4",
|
|
818
|
+
"ipv6",
|
|
819
|
+
"uri",
|
|
820
|
+
"uri-reference",
|
|
821
|
+
"uuid"
|
|
822
|
+
];
|
|
823
|
+
}
|
|
824
|
+
});
|
|
801
825
|
|
|
802
826
|
// src/schema/errors.ts
|
|
803
827
|
var errors_exports = {};
|
|
@@ -1522,20 +1546,14 @@ async function loadMetaSchema(draft) {
|
|
|
1522
1546
|
const content = await readFile(metaSchemaPath, "utf-8");
|
|
1523
1547
|
return JSON.parse(content);
|
|
1524
1548
|
}
|
|
1525
|
-
async function loadVocabularySchemas() {
|
|
1549
|
+
async function loadVocabularySchemas(draft) {
|
|
1550
|
+
if (draft !== "draft-2019-09" && draft !== "draft-2020-12") {
|
|
1551
|
+
return [];
|
|
1552
|
+
}
|
|
1526
1553
|
const __filename3 = fileURLToPath(import.meta.url);
|
|
1527
1554
|
const __dirname4 = dirname(__filename3);
|
|
1528
|
-
const vocabDir = join(
|
|
1529
|
-
|
|
1530
|
-
"..",
|
|
1531
|
-
"..",
|
|
1532
|
-
"schemas",
|
|
1533
|
-
"crucible-ts",
|
|
1534
|
-
"meta",
|
|
1535
|
-
"draft-2020-12",
|
|
1536
|
-
"meta"
|
|
1537
|
-
);
|
|
1538
|
-
const vocabFiles = [
|
|
1555
|
+
const vocabDir = join(__dirname4, "..", "..", "schemas", "crucible-ts", "meta", draft, "meta");
|
|
1556
|
+
const vocabFiles = draft === "draft-2020-12" ? [
|
|
1539
1557
|
"core.json",
|
|
1540
1558
|
"applicator.json",
|
|
1541
1559
|
"unevaluated.json",
|
|
@@ -1543,6 +1561,13 @@ async function loadVocabularySchemas() {
|
|
|
1543
1561
|
"meta-data.json",
|
|
1544
1562
|
"format-annotation.json",
|
|
1545
1563
|
"content.json"
|
|
1564
|
+
] : [
|
|
1565
|
+
"core.json",
|
|
1566
|
+
"applicator.json",
|
|
1567
|
+
"validation.json",
|
|
1568
|
+
"meta-data.json",
|
|
1569
|
+
"format.json",
|
|
1570
|
+
"content.json"
|
|
1546
1571
|
];
|
|
1547
1572
|
const schemas = [];
|
|
1548
1573
|
for (const file of vocabFiles) {
|
|
@@ -1597,47 +1622,65 @@ async function loadReferencedSchema(uri) {
|
|
|
1597
1622
|
}
|
|
1598
1623
|
return JSON.parse(content);
|
|
1599
1624
|
}
|
|
1600
|
-
function
|
|
1601
|
-
if (!
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
}
|
|
1611
|
-
addFormats(ajvInstance, {
|
|
1612
|
-
mode: "fast",
|
|
1613
|
-
formats: ["date-time", "email", "hostname", "ipv4", "ipv6", "uri", "uri-reference"]
|
|
1614
|
-
});
|
|
1615
|
-
metaschemaReady = Promise.all([loadVocabularySchemas(), loadMetaSchema("draft-2020-12")]).then(([vocabSchemas, metaSchema]) => {
|
|
1616
|
-
if (ajvInstance) {
|
|
1617
|
-
for (const vocabSchema of vocabSchemas) {
|
|
1618
|
-
try {
|
|
1619
|
-
ajvInstance.addMetaSchema(vocabSchema);
|
|
1620
|
-
} catch {
|
|
1621
|
-
}
|
|
1622
|
-
}
|
|
1623
|
-
ajvInstance.addMetaSchema(metaSchema);
|
|
1624
|
-
}
|
|
1625
|
-
}).catch((error) => {
|
|
1626
|
-
throw new Error(`Failed to load metaschemas: ${error}`);
|
|
1627
|
-
});
|
|
1625
|
+
function detectDialect(schema) {
|
|
1626
|
+
if (schema && typeof schema === "object" && !Array.isArray(schema)) {
|
|
1627
|
+
const maybeSchema = schema;
|
|
1628
|
+
const declared = maybeSchema.$schema;
|
|
1629
|
+
if (typeof declared === "string") {
|
|
1630
|
+
if (declared.includes("draft-04")) return "draft-04";
|
|
1631
|
+
if (declared.includes("draft-06")) return "draft-06";
|
|
1632
|
+
if (declared.includes("draft-07")) return "draft-07";
|
|
1633
|
+
if (declared.includes("draft/2019-09")) return "draft-2019-09";
|
|
1634
|
+
if (declared.includes("draft/2020-12")) return "draft-2020-12";
|
|
1635
|
+
}
|
|
1628
1636
|
}
|
|
1629
|
-
return
|
|
1637
|
+
return "draft-2020-12";
|
|
1638
|
+
}
|
|
1639
|
+
function createAjv(dialect) {
|
|
1640
|
+
const AjvCtor = dialect === "draft-2020-12" ? Ajv2020 : dialect === "draft-2019-09" ? Ajv2019 : dialect === "draft-04" ? AjvDraft04 : Ajv;
|
|
1641
|
+
const ajv = new AjvCtor({
|
|
1642
|
+
strict: false,
|
|
1643
|
+
allErrors: true,
|
|
1644
|
+
verbose: true,
|
|
1645
|
+
// Allow schemas with $id to be added without replacing existing ones
|
|
1646
|
+
addUsedSchema: false,
|
|
1647
|
+
// draft-04 uses "id"; later drafts use "$id"
|
|
1648
|
+
schemaId: dialect === "draft-04" ? "id" : "$id",
|
|
1649
|
+
// Enable async schema loading for YAML references
|
|
1650
|
+
loadSchema: loadReferencedSchema
|
|
1651
|
+
});
|
|
1652
|
+
applyFulmenAjvFormats(ajv);
|
|
1653
|
+
return ajv;
|
|
1654
|
+
}
|
|
1655
|
+
async function getAjv(dialect) {
|
|
1656
|
+
const existing = ajvInstances.get(dialect);
|
|
1657
|
+
if (existing) {
|
|
1658
|
+
const ready = metaschemaReady.get(dialect);
|
|
1659
|
+
if (ready) await ready;
|
|
1660
|
+
return existing;
|
|
1661
|
+
}
|
|
1662
|
+
const ajv = createAjv(dialect);
|
|
1663
|
+
ajvInstances.set(dialect, ajv);
|
|
1664
|
+
const readyPromise = Promise.all([loadVocabularySchemas(dialect), loadMetaSchema(dialect)]).then(([vocabSchemas, metaSchema]) => {
|
|
1665
|
+
for (const vocabSchema of vocabSchemas) {
|
|
1666
|
+
try {
|
|
1667
|
+
ajv.addMetaSchema(vocabSchema);
|
|
1668
|
+
} catch {
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
try {
|
|
1672
|
+
ajv.addMetaSchema(metaSchema);
|
|
1673
|
+
} catch {
|
|
1674
|
+
}
|
|
1675
|
+
}).catch((error) => {
|
|
1676
|
+
throw new Error(`Failed to load metaschemas (${dialect}): ${error}`);
|
|
1677
|
+
});
|
|
1678
|
+
metaschemaReady.set(dialect, readyPromise);
|
|
1679
|
+
await readyPromise;
|
|
1680
|
+
return ajv;
|
|
1630
1681
|
}
|
|
1631
1682
|
async function compileSchema(schema, options = {}) {
|
|
1632
|
-
const
|
|
1633
|
-
if (metaschemaReady) {
|
|
1634
|
-
await metaschemaReady;
|
|
1635
|
-
}
|
|
1636
|
-
const cacheKey = typeof schema === "string" ? schema : JSON.stringify(schema);
|
|
1637
|
-
const cached = schemaCache.get(cacheKey);
|
|
1638
|
-
if (cached !== void 0) {
|
|
1639
|
-
return cached;
|
|
1640
|
-
}
|
|
1683
|
+
const baseKey = typeof schema === "string" ? schema : JSON.stringify(schema);
|
|
1641
1684
|
let parsedSchema;
|
|
1642
1685
|
if (typeof schema === "string") {
|
|
1643
1686
|
try {
|
|
@@ -1655,18 +1698,27 @@ async function compileSchema(schema, options = {}) {
|
|
|
1655
1698
|
} else {
|
|
1656
1699
|
parsedSchema = schema;
|
|
1657
1700
|
}
|
|
1701
|
+
const dialect = detectDialect(parsedSchema);
|
|
1702
|
+
const ajv = await getAjv(dialect);
|
|
1703
|
+
const cacheKey = `${dialect}:${baseKey}`;
|
|
1704
|
+
const cached = schemaCache.get(cacheKey);
|
|
1705
|
+
if (cached !== void 0) {
|
|
1706
|
+
return cached;
|
|
1707
|
+
}
|
|
1658
1708
|
try {
|
|
1659
1709
|
if (options.aliases && options.aliases.length > 0) {
|
|
1660
1710
|
for (const alias of options.aliases) {
|
|
1661
1711
|
if (alias && ajv.getSchema(alias) === void 0) {
|
|
1662
1712
|
try {
|
|
1663
|
-
|
|
1713
|
+
if (typeof parsedSchema === "object" && parsedSchema !== null) {
|
|
1714
|
+
ajv.addSchema(parsedSchema, alias);
|
|
1715
|
+
}
|
|
1664
1716
|
} catch {
|
|
1665
1717
|
}
|
|
1666
1718
|
}
|
|
1667
1719
|
}
|
|
1668
1720
|
}
|
|
1669
|
-
const validator = await ajv.compileAsync(parsedSchema);
|
|
1721
|
+
const validator = typeof parsedSchema === "boolean" ? ajv.compile(parsedSchema) : await ajv.compileAsync(parsedSchema);
|
|
1670
1722
|
schemaCache.set(cacheKey, validator);
|
|
1671
1723
|
return validator;
|
|
1672
1724
|
} catch (error) {
|
|
@@ -1736,8 +1788,39 @@ async function validateFile(filePath, validator) {
|
|
|
1736
1788
|
}
|
|
1737
1789
|
async function validateSchema(schema) {
|
|
1738
1790
|
try {
|
|
1739
|
-
|
|
1740
|
-
|
|
1791
|
+
let parsedSchema;
|
|
1792
|
+
if (typeof schema === "string") {
|
|
1793
|
+
try {
|
|
1794
|
+
parsedSchema = JSON.parse(schema);
|
|
1795
|
+
} catch {
|
|
1796
|
+
parsedSchema = parse(schema);
|
|
1797
|
+
}
|
|
1798
|
+
} else if (Buffer.isBuffer(schema)) {
|
|
1799
|
+
const content = schema.toString("utf-8");
|
|
1800
|
+
try {
|
|
1801
|
+
parsedSchema = JSON.parse(content);
|
|
1802
|
+
} catch {
|
|
1803
|
+
parsedSchema = parse(content);
|
|
1804
|
+
}
|
|
1805
|
+
} else {
|
|
1806
|
+
parsedSchema = schema;
|
|
1807
|
+
}
|
|
1808
|
+
const dialect = detectDialect(parsedSchema);
|
|
1809
|
+
const ajv = await getAjv(dialect);
|
|
1810
|
+
const metaValid = ajv.validateSchema(parsedSchema);
|
|
1811
|
+
if (!metaValid && ajv.errors) {
|
|
1812
|
+
const diagnostics = ajv.errors.map(
|
|
1813
|
+
(error) => createDiagnostic(
|
|
1814
|
+
error.instancePath || "",
|
|
1815
|
+
error.message || "Schema meta-validation failed",
|
|
1816
|
+
error.keyword || "unknown",
|
|
1817
|
+
"ERROR",
|
|
1818
|
+
"ajv"
|
|
1819
|
+
)
|
|
1820
|
+
);
|
|
1821
|
+
return { valid: false, diagnostics, source: "ajv" };
|
|
1822
|
+
}
|
|
1823
|
+
await compileSchema(parsedSchema);
|
|
1741
1824
|
return {
|
|
1742
1825
|
valid: true,
|
|
1743
1826
|
diagnostics: [],
|
|
@@ -1808,14 +1891,16 @@ async function validateFileBySchemaId(filePath, schemaId, registryOptions) {
|
|
|
1808
1891
|
throw error;
|
|
1809
1892
|
}
|
|
1810
1893
|
}
|
|
1811
|
-
var
|
|
1894
|
+
var ajvInstances, metaschemaReady, schemaCache;
|
|
1812
1895
|
var init_validator = __esm({
|
|
1813
1896
|
"src/schema/validator.ts"() {
|
|
1814
1897
|
init_telemetry();
|
|
1898
|
+
init_ajv_formats();
|
|
1815
1899
|
init_errors();
|
|
1816
1900
|
init_registry2();
|
|
1817
1901
|
init_utils();
|
|
1818
|
-
|
|
1902
|
+
ajvInstances = /* @__PURE__ */ new Map();
|
|
1903
|
+
metaschemaReady = /* @__PURE__ */ new Map();
|
|
1819
1904
|
schemaCache = /* @__PURE__ */ new Map();
|
|
1820
1905
|
}
|
|
1821
1906
|
});
|
|
@@ -3770,6 +3855,224 @@ var init_capabilities2 = __esm({
|
|
|
3770
3855
|
}
|
|
3771
3856
|
});
|
|
3772
3857
|
|
|
3858
|
+
// src/foundry/signals/config-reload-endpoint.ts
|
|
3859
|
+
function createConfigReloadEndpoint(options) {
|
|
3860
|
+
const { loader, validator, onReload: onReload2, auth, rateLimit, logger, telemetry } = options;
|
|
3861
|
+
return async (payload, req) => {
|
|
3862
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId();
|
|
3863
|
+
const authResult = await auth(req);
|
|
3864
|
+
if (!authResult.authenticated) {
|
|
3865
|
+
if (logger) {
|
|
3866
|
+
logger.warn("Config reload endpoint: authentication failed", {
|
|
3867
|
+
correlation_id: correlationId,
|
|
3868
|
+
reason: authResult.reason
|
|
3869
|
+
});
|
|
3870
|
+
}
|
|
3871
|
+
if (telemetry) {
|
|
3872
|
+
telemetry.emit("fulmen.config.http_endpoint.auth_failed", {
|
|
3873
|
+
correlation_id: correlationId
|
|
3874
|
+
});
|
|
3875
|
+
}
|
|
3876
|
+
return {
|
|
3877
|
+
status: "error",
|
|
3878
|
+
error: "authentication_failed",
|
|
3879
|
+
message: authResult.reason || "Authentication required",
|
|
3880
|
+
statusCode: 401
|
|
3881
|
+
};
|
|
3882
|
+
}
|
|
3883
|
+
const identity = authResult.identity || "unknown";
|
|
3884
|
+
if (rateLimit) {
|
|
3885
|
+
const rateLimitResult = await rateLimit(identity);
|
|
3886
|
+
if (!rateLimitResult.allowed) {
|
|
3887
|
+
if (logger) {
|
|
3888
|
+
logger.warn("Config reload endpoint: rate limit exceeded", {
|
|
3889
|
+
correlation_id: correlationId,
|
|
3890
|
+
identity
|
|
3891
|
+
});
|
|
3892
|
+
}
|
|
3893
|
+
if (telemetry) {
|
|
3894
|
+
telemetry.emit("fulmen.config.http_endpoint.rate_limited", {
|
|
3895
|
+
correlation_id: correlationId
|
|
3896
|
+
});
|
|
3897
|
+
}
|
|
3898
|
+
return {
|
|
3899
|
+
status: "error",
|
|
3900
|
+
error: "rate_limit_exceeded",
|
|
3901
|
+
message: "Rate limit exceeded. Please try again later.",
|
|
3902
|
+
statusCode: 429
|
|
3903
|
+
};
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
if (telemetry) {
|
|
3907
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_requested", {
|
|
3908
|
+
correlation_id: correlationId
|
|
3909
|
+
});
|
|
3910
|
+
}
|
|
3911
|
+
try {
|
|
3912
|
+
const config = await loader();
|
|
3913
|
+
if (validator) {
|
|
3914
|
+
const validation = await validator(config);
|
|
3915
|
+
if (!validation.valid) {
|
|
3916
|
+
if (logger) {
|
|
3917
|
+
logger.warn("Config reload endpoint: validation failed", {
|
|
3918
|
+
correlation_id: correlationId,
|
|
3919
|
+
error_count: validation.errors?.length ?? 0
|
|
3920
|
+
});
|
|
3921
|
+
}
|
|
3922
|
+
if (telemetry) {
|
|
3923
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_rejected", {
|
|
3924
|
+
correlation_id: correlationId,
|
|
3925
|
+
reason: "validation_failed"
|
|
3926
|
+
});
|
|
3927
|
+
}
|
|
3928
|
+
return {
|
|
3929
|
+
status: "error",
|
|
3930
|
+
error: "validation_failed",
|
|
3931
|
+
message: "Configuration validation failed",
|
|
3932
|
+
validation_errors: validation.errors,
|
|
3933
|
+
statusCode: 422
|
|
3934
|
+
};
|
|
3935
|
+
}
|
|
3936
|
+
}
|
|
3937
|
+
if (onReload2) {
|
|
3938
|
+
await onReload2(config);
|
|
3939
|
+
}
|
|
3940
|
+
if (telemetry) {
|
|
3941
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_accepted", {
|
|
3942
|
+
correlation_id: correlationId
|
|
3943
|
+
});
|
|
3944
|
+
}
|
|
3945
|
+
if (logger) {
|
|
3946
|
+
logger.info("Config reload endpoint: reload accepted", {
|
|
3947
|
+
correlation_id: correlationId,
|
|
3948
|
+
reason: payload.reason
|
|
3949
|
+
});
|
|
3950
|
+
}
|
|
3951
|
+
return {
|
|
3952
|
+
status: "reloaded",
|
|
3953
|
+
correlation_id: correlationId,
|
|
3954
|
+
message: "Configuration reloaded",
|
|
3955
|
+
statusCode: 200
|
|
3956
|
+
};
|
|
3957
|
+
} catch (error) {
|
|
3958
|
+
if (logger) {
|
|
3959
|
+
logger.warn("Config reload endpoint: reload failed", {
|
|
3960
|
+
correlation_id: correlationId,
|
|
3961
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3962
|
+
});
|
|
3963
|
+
}
|
|
3964
|
+
if (telemetry) {
|
|
3965
|
+
telemetry.emit("fulmen.config.http_endpoint.reload_error", {
|
|
3966
|
+
correlation_id: correlationId,
|
|
3967
|
+
error_type: error instanceof Error ? error.constructor.name : "unknown"
|
|
3968
|
+
});
|
|
3969
|
+
}
|
|
3970
|
+
return {
|
|
3971
|
+
status: "error",
|
|
3972
|
+
error: "reload_failed",
|
|
3973
|
+
message: error instanceof Error ? error.message : String(error),
|
|
3974
|
+
statusCode: 500
|
|
3975
|
+
};
|
|
3976
|
+
}
|
|
3977
|
+
};
|
|
3978
|
+
}
|
|
3979
|
+
function generateCorrelationId() {
|
|
3980
|
+
return `cfg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
3981
|
+
}
|
|
3982
|
+
var init_config_reload_endpoint = __esm({
|
|
3983
|
+
"src/foundry/signals/config-reload-endpoint.ts"() {
|
|
3984
|
+
}
|
|
3985
|
+
});
|
|
3986
|
+
|
|
3987
|
+
// src/appidentity/runtime.ts
|
|
3988
|
+
function detectRuntime() {
|
|
3989
|
+
const versions = process.versions;
|
|
3990
|
+
if (typeof versions.bun === "string" && versions.bun.length > 0) {
|
|
3991
|
+
return { name: "bun", version: versions.bun };
|
|
3992
|
+
}
|
|
3993
|
+
if (typeof versions.node === "string" && versions.node.length > 0) {
|
|
3994
|
+
return { name: "node", version: versions.node };
|
|
3995
|
+
}
|
|
3996
|
+
return { name: "unknown" };
|
|
3997
|
+
}
|
|
3998
|
+
function buildRuntimeInfo(options = {}) {
|
|
3999
|
+
const runtime = detectRuntime();
|
|
4000
|
+
const serviceName = options.serviceName ?? options.identity?.app.binary_name ?? "unknown-service";
|
|
4001
|
+
const vendor = options.vendor ?? options.identity?.app.vendor;
|
|
4002
|
+
return {
|
|
4003
|
+
service: {
|
|
4004
|
+
name: serviceName,
|
|
4005
|
+
vendor,
|
|
4006
|
+
version: options.version
|
|
4007
|
+
},
|
|
4008
|
+
runtime,
|
|
4009
|
+
platform: {
|
|
4010
|
+
os: process.platform,
|
|
4011
|
+
arch: process.arch
|
|
4012
|
+
}
|
|
4013
|
+
};
|
|
4014
|
+
}
|
|
4015
|
+
var init_runtime = __esm({
|
|
4016
|
+
"src/appidentity/runtime.ts"() {
|
|
4017
|
+
}
|
|
4018
|
+
});
|
|
4019
|
+
|
|
4020
|
+
// src/foundry/signals/control-discovery-endpoint.ts
|
|
4021
|
+
function createControlDiscoveryEndpoint(options) {
|
|
4022
|
+
const { identity, version, endpoints, auth, authSummary, logger, telemetry } = options;
|
|
4023
|
+
return async (req) => {
|
|
4024
|
+
if (auth) {
|
|
4025
|
+
const authResult = await auth(req);
|
|
4026
|
+
if (!authResult.authenticated) {
|
|
4027
|
+
if (logger) {
|
|
4028
|
+
logger.warn("Control discovery endpoint: authentication failed", {
|
|
4029
|
+
reason: authResult.reason
|
|
4030
|
+
});
|
|
4031
|
+
}
|
|
4032
|
+
if (telemetry) {
|
|
4033
|
+
telemetry.emit("fulmen.control.discovery.auth_failed", {
|
|
4034
|
+
service: identity.app.binary_name
|
|
4035
|
+
});
|
|
4036
|
+
}
|
|
4037
|
+
return {
|
|
4038
|
+
status: "error",
|
|
4039
|
+
error: "authentication_failed",
|
|
4040
|
+
message: authResult.reason || "Authentication required",
|
|
4041
|
+
statusCode: 401
|
|
4042
|
+
};
|
|
4043
|
+
}
|
|
4044
|
+
}
|
|
4045
|
+
if (telemetry) {
|
|
4046
|
+
telemetry.emit("fulmen.control.discovery.served", {
|
|
4047
|
+
service: identity.app.binary_name
|
|
4048
|
+
});
|
|
4049
|
+
}
|
|
4050
|
+
const runtime = buildRuntimeInfo({ identity, version });
|
|
4051
|
+
return {
|
|
4052
|
+
status: "ok",
|
|
4053
|
+
service: {
|
|
4054
|
+
name: identity.app.binary_name,
|
|
4055
|
+
vendor: identity.app.vendor,
|
|
4056
|
+
version
|
|
4057
|
+
},
|
|
4058
|
+
runtime: {
|
|
4059
|
+
name: runtime.runtime.name,
|
|
4060
|
+
version: runtime.runtime.version,
|
|
4061
|
+
platform: runtime.platform.os,
|
|
4062
|
+
arch: runtime.platform.arch
|
|
4063
|
+
},
|
|
4064
|
+
auth_summary: authSummary,
|
|
4065
|
+
endpoints,
|
|
4066
|
+
statusCode: 200
|
|
4067
|
+
};
|
|
4068
|
+
};
|
|
4069
|
+
}
|
|
4070
|
+
var init_control_discovery_endpoint = __esm({
|
|
4071
|
+
"src/foundry/signals/control-discovery-endpoint.ts"() {
|
|
4072
|
+
init_runtime();
|
|
4073
|
+
}
|
|
4074
|
+
});
|
|
4075
|
+
|
|
3773
4076
|
// src/foundry/signals/convenience.ts
|
|
3774
4077
|
async function onShutdown(manager, handler, options = {}) {
|
|
3775
4078
|
await manager.register("SIGTERM", handler, options);
|
|
@@ -4029,7 +4332,7 @@ var init_guards = __esm({
|
|
|
4029
4332
|
function createSignalEndpoint(options) {
|
|
4030
4333
|
const { manager, auth, rateLimit, logger, telemetry, allowedSignals } = options;
|
|
4031
4334
|
return async (payload, req) => {
|
|
4032
|
-
const correlationId = payload.correlation_id ??
|
|
4335
|
+
const correlationId = payload.correlation_id ?? generateCorrelationId2();
|
|
4033
4336
|
const authResult = await auth(req);
|
|
4034
4337
|
if (!authResult.authenticated) {
|
|
4035
4338
|
if (logger) {
|
|
@@ -4152,7 +4455,7 @@ function normalizeSignalName(signal) {
|
|
|
4152
4455
|
}
|
|
4153
4456
|
return `SIG${upper}`;
|
|
4154
4457
|
}
|
|
4155
|
-
function
|
|
4458
|
+
function generateCorrelationId2() {
|
|
4156
4459
|
return `sig-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
4157
4460
|
}
|
|
4158
4461
|
function createBearerTokenAuth(expectedToken) {
|
|
@@ -4619,6 +4922,8 @@ var init_signals = __esm({
|
|
|
4619
4922
|
"src/foundry/signals/index.ts"() {
|
|
4620
4923
|
init_capabilities2();
|
|
4621
4924
|
init_catalog();
|
|
4925
|
+
init_config_reload_endpoint();
|
|
4926
|
+
init_control_discovery_endpoint();
|
|
4622
4927
|
init_convenience();
|
|
4623
4928
|
init_double_tap();
|
|
4624
4929
|
init_guards();
|
|
@@ -4764,7 +5069,9 @@ __export(foundry_exports, {
|
|
|
4764
5069
|
clearMimeTypeCache: () => clearMimeTypeCache,
|
|
4765
5070
|
clearPatternCache: () => clearPatternCache,
|
|
4766
5071
|
createBearerTokenAuth: () => createBearerTokenAuth,
|
|
5072
|
+
createConfigReloadEndpoint: () => createConfigReloadEndpoint,
|
|
4767
5073
|
createConfigReloadHandler: () => createConfigReloadHandler,
|
|
5074
|
+
createControlDiscoveryEndpoint: () => createControlDiscoveryEndpoint,
|
|
4768
5075
|
createDoubleTapTracker: () => createDoubleTapTracker,
|
|
4769
5076
|
createSignalEndpoint: () => createSignalEndpoint,
|
|
4770
5077
|
createSignalManager: () => createSignalManager,
|
|
@@ -5820,6 +6127,7 @@ var init_cli = __esm({
|
|
|
5820
6127
|
// src/schema/index.ts
|
|
5821
6128
|
var init_schema = __esm({
|
|
5822
6129
|
"src/schema/index.ts"() {
|
|
6130
|
+
init_ajv_formats();
|
|
5823
6131
|
init_cli();
|
|
5824
6132
|
init_errors();
|
|
5825
6133
|
init_export();
|