@shapeshift-labs/frontier-lang-compiler 0.2.33 → 0.2.34

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/README.md CHANGED
@@ -465,8 +465,8 @@ The published Frontier package family is generated from one shared package catal
465
465
  - [`@shapeshift-labs/frontier-workflow`](https://www.npmjs.com/package/@shapeshift-labs/frontier-workflow): Serializable durable workflow/process manifests for Frontier apps, including steps, waits, approvals, timers, retries, expected patches, compensation, records, timelines, and registry graph output.
466
466
  - [`@shapeshift-labs/frontier-worker`](https://www.npmjs.com/package/@shapeshift-labs/frontier-worker): Serializable worker and edge task descriptors for Frontier apps, including queues, idempotency keys, retry and timeout policy, declared reads/writes/effects, snapshots, patch outputs, produced assets, execution records, logs, trace links, proof hashes, dedupe indexes, and registry graph output.
467
467
  - [`@shapeshift-labs/frontier-queue`](https://www.npmjs.com/package/@shapeshift-labs/frontier-queue): Serializable durable queue state, leases, retries, dedupe keys, patch-carrying jobs, dead-letter records, replay evidence, and queue inspection for Frontier apps.
468
- - [`@shapeshift-labs/frontier-swarm`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm): Hierarchical swarm plans, lanes, compute profiles, ownership policy, semantic ownership regions, task queues, event streams, run records, merge bundles, merge indexes, queue overlays, merge admission, changed-path checks, and proof artifacts for Frontier agent work.
469
- - [`@shapeshift-labs/frontier-swarm-codex`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm-codex): Node Codex CLI adapter for Frontier swarm plans, including prompt rendering, worktree and snapshot workspaces, Codex argument compatibility, browser resource allocation, JSONL capture, verification commands, pid-backed stop, collect/apply workflows, merge indexes, queue overlays, merge bundles, and result artifacts.
468
+ - [`@shapeshift-labs/frontier-swarm`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm): Hierarchical swarm plans, lanes, compute profiles, ownership policy, semantic ownership regions, task queues, event streams, run records, merge bundles, merge indexes, queue overlays, merge admission, coordinator dashboards, changed-path checks, and proof artifacts for Frontier agent work.
469
+ - [`@shapeshift-labs/frontier-swarm-codex`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm-codex): Node Codex CLI adapter for Frontier swarm plans, including prompt rendering, worktree and snapshot workspaces, Codex argument compatibility, browser resource allocation, JSONL capture, verification commands, pid-backed stop, collect/apply workflows, merge indexes, queue overlays, merge bundles, normalized job evidence, coordinator query artifacts, and result artifacts.
470
470
  - [`@shapeshift-labs/frontier-lang-kernel`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-kernel): Runtime-neutral semantic source graph, type/lattice/extern declarations, patch bundles, replay, hashing, evidence records, and merge-admission kernel for Frontier Lang.
471
471
  - [`@shapeshift-labs/frontier-lang-parser`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-parser): Dependency-light Frontier Lang parser for modules, entities, state, actions, effects, types, externs, targets, and lattice declarations.
472
472
  - [`@shapeshift-labs/frontier-lang-checker`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-checker): Checker and diagnostics for Frontier Lang semantic documents, including type symbols, effects, regions, lattice laws, CRDT metadata, and patch evidence.
@@ -476,6 +476,7 @@ The published Frontier package family is generated from one shared package catal
476
476
  - [`@shapeshift-labs/frontier-lang-python`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-python): Python projection adapter for Frontier Lang semantic documents, including dataclasses, typed patch records, and action stubs.
477
477
  - [`@shapeshift-labs/frontier-lang-c`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-c): C header projection adapter for Frontier Lang semantic documents, including structs and action prototypes.
478
478
  - [`@shapeshift-labs/frontier-lang-swift`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-swift): Swift source-language importer package for Frontier Lang semantic documents, including package-level metadata, SwiftSyntax adapter helpers, native import results, and semantic sidecar generation for SwiftSyntax/SwiftParser-shaped syntax trees.
479
+ - [`@shapeshift-labs/frontier-lang-kotlin`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-kotlin): Kotlin PSI source-language importer package for Frontier Lang semantic documents, including package-level metadata, Kotlin PSI adapter helpers, native import results, and semantic sidecar generation for Kotlin PSI/KtFile-shaped syntax trees.
479
480
  - [`@shapeshift-labs/frontier-lang-java`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-java): Java source-language importer package for Frontier Lang semantic documents, including package-level metadata, Java AST adapter helpers, native import results, and semantic sidecar generation for javac/JDT/JavaParser-shaped ASTs.
480
481
  - [`@shapeshift-labs/frontier-lang-go`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-go): Go source-language importer package for Frontier Lang semantic documents, including package-level metadata, Go AST adapter helpers, native import results, and semantic sidecar generation for go/ast File or Package trees.
481
482
  - [`@shapeshift-labs/frontier-lang-csharp`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-csharp): C# Roslyn source-language importer package for Frontier Lang semantic documents, including package-level metadata, Roslyn adapter helpers, native import results, and semantic sidecar generation for SyntaxTree/SyntaxNode-shaped ASTs.
@@ -568,6 +569,7 @@ Package source repositories:
568
569
  - [`siliconjungle/-shapeshift-labs-frontier-lang-c`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-c)
569
570
  - [`siliconjungle/-shapeshift-labs-frontier-lang-compiler`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-compiler)
570
571
  - [`siliconjungle/-shapeshift-labs-frontier-lang-swift`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-swift)
572
+ - [`siliconjungle/-shapeshift-labs-frontier-lang-kotlin`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-kotlin)
571
573
  - [`siliconjungle/-shapeshift-labs-frontier-lang-java`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-java)
572
574
  - [`siliconjungle/-shapeshift-labs-frontier-lang-go`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-go)
573
575
  - [`siliconjungle/-shapeshift-labs-frontier-lang-csharp`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-csharp)
package/bench/smoke.mjs CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  createKotlinPsiNativeImporterAdapter,
11
11
  createNativeImportCoverageMatrix,
12
12
  createNativeParserAstFormatMatrix,
13
+ createNativeParserFeatureMatrix,
13
14
  createProjectionTargetLossMatrix,
14
15
  createNativeSourcePreservation,
15
16
  createPythonAstNativeImporterAdapter,
@@ -20,6 +21,7 @@ import {
20
21
  importExternalSemanticIndex,
21
22
  importNativeSource,
22
23
  projectNativeImportToSource,
24
+ queryNativeParserFeatureMatrix,
23
25
  runNativeImporterAdapter,
24
26
  summarizeNativeImportFeatureEvidence
25
27
  } from '../dist/index.js';
@@ -121,6 +123,19 @@ const parserFormatMatrix = createNativeParserAstFormatMatrix({
121
123
  });
122
124
  const parserFormatMatrixDurationMs = performance.now() - parserFormatMatrixStart;
123
125
 
126
+ const parserFeatureMatrixStart = performance.now();
127
+ const parserFeatureMatrix = createNativeParserFeatureMatrix({
128
+ imports: nativeImportResults,
129
+ adapters: [estreeAdapter, createPythonAstNativeImporterAdapter(), createRustSynNativeImporterAdapter(), createClangAstNativeImporterAdapter(), createGoAstNativeImporterAdapter(), createJavaAstNativeImporterAdapter(), kotlinPsiAdapter, createCSharpRoslynNativeImporterAdapter(), createSwiftSyntaxNativeImporterAdapter()],
130
+ requiredFeatures: ['syntax', 'semantic', 'sourcePreservation']
131
+ });
132
+ const parserFeatureQuery = queryNativeParserFeatureMatrix(parserFeatureMatrix, {
133
+ language: 'javascript',
134
+ parser: 'estree',
135
+ requiredFeatures: ['syntax', 'semantic', 'sourcePreservation']
136
+ });
137
+ const parserFeatureMatrixDurationMs = performance.now() - parserFeatureMatrixStart;
138
+
124
139
  const projectionMatrixStart = performance.now();
125
140
  const projectionLossMatrix = createProjectionTargetLossMatrix({ imports: nativeImportResults });
126
141
  const projectionMatrixDurationMs = performance.now() - projectionMatrixStart;
@@ -280,6 +295,11 @@ console.log(JSON.stringify({
280
295
  parserFormatMatrixImports: parserFormatMatrix.summary.imports,
281
296
  parserFormatMatrixNativeAstNodes: parserFormatMatrix.summary.nativeAstNodes,
282
297
  parserFormatMatrixDurationMs: Number(parserFormatMatrixDurationMs.toFixed(2)),
298
+ parserFeatureMatrixParsers: parserFeatureMatrix.summary.parsers,
299
+ parserFeatureMatrixMergeReady: parserFeatureMatrix.summary.mergeReady,
300
+ parserFeatureMatrixSyntaxFull: parserFeatureMatrix.summary.byFeatureStatus.syntax?.full ?? 0,
301
+ parserFeatureQueryMergeReady: parserFeatureQuery.merge.mergeReady,
302
+ parserFeatureMatrixDurationMs: Number(parserFeatureMatrixDurationMs.toFixed(2)),
283
303
  projectionMatrixLanguages: projectionLossMatrix.summary.languages,
284
304
  projectionMatrixMissingAdapters: projectionLossMatrix.summary.missingAdapters,
285
305
  projectionMatrixUnsupportedTargetFeatures: projectionLossMatrix.summary.unsupportedTargetFeatures,
package/dist/index.d.ts CHANGED
@@ -318,6 +318,161 @@ export interface NativeParserAstFormatMatrixOptions {
318
318
  readonly generatedAt?: number;
319
319
  }
320
320
 
321
+ export type NativeParserFeatureCategory =
322
+ | 'syntax'
323
+ | 'semantic'
324
+ | 'type'
325
+ | 'controlFlow'
326
+ | 'macroMetaprogramming'
327
+ | 'sourcePreservation'
328
+ | string;
329
+
330
+ export type NativeParserFeatureCoverageStatus =
331
+ | 'full'
332
+ | 'partial'
333
+ | 'evidence-required'
334
+ | 'missing'
335
+ | 'blocked'
336
+ | 'not-applicable'
337
+ | string;
338
+
339
+ export interface NativeParserFeatureCoverage {
340
+ readonly category: NativeParserFeatureCategory;
341
+ readonly status: NativeParserFeatureCoverageStatus;
342
+ readonly readiness: SemanticMergeReadiness;
343
+ readonly mergeReady: boolean;
344
+ readonly supported: boolean;
345
+ readonly capabilities: Readonly<Record<string, unknown>>;
346
+ readonly gaps: readonly string[];
347
+ readonly lossKinds: Readonly<Record<string, number>>;
348
+ readonly reasons: readonly string[];
349
+ readonly notes: readonly string[];
350
+ }
351
+
352
+ export interface NativeParserFeatureCoverageMap {
353
+ readonly syntax: NativeParserFeatureCoverage;
354
+ readonly semantic: NativeParserFeatureCoverage;
355
+ readonly type: NativeParserFeatureCoverage;
356
+ readonly controlFlow: NativeParserFeatureCoverage;
357
+ readonly macroMetaprogramming: NativeParserFeatureCoverage;
358
+ readonly sourcePreservation: NativeParserFeatureCoverage;
359
+ readonly [category: string]: NativeParserFeatureCoverage;
360
+ }
361
+
362
+ export interface NativeParserFeatureMergeAssessment {
363
+ readonly mergeReady: boolean;
364
+ readonly readiness: SemanticMergeReadiness;
365
+ readonly requiredFeatures: readonly NativeParserFeatureCategory[];
366
+ readonly minimumReadiness: SemanticMergeReadiness;
367
+ readonly blockingFeatures: readonly NativeParserFeatureCategory[];
368
+ readonly reviewFeatures: readonly NativeParserFeatureCategory[];
369
+ readonly reasons: readonly string[];
370
+ }
371
+
372
+ export interface NativeParserFeatureParserRow {
373
+ readonly language: FrontierSourceLanguage | string;
374
+ readonly aliases: readonly string[];
375
+ readonly parser: string;
376
+ readonly parserFormat: string;
377
+ readonly parserAliases: readonly string[];
378
+ readonly parserAdapters: readonly string[];
379
+ readonly extensions: readonly string[];
380
+ readonly supportsLightweightScan: boolean;
381
+ readonly projectionTargets: readonly (FrontierCompileTarget | string)[];
382
+ readonly knownLossKinds: readonly NativeImportKnownLossKind[];
383
+ readonly defaultReadiness: SemanticMergeReadiness;
384
+ readonly notes: readonly string[];
385
+ readonly adapters: {
386
+ readonly total: number;
387
+ readonly ids: readonly string[];
388
+ readonly versions: readonly string[];
389
+ readonly exactness: readonly NativeImporterAdapterExactness[];
390
+ readonly coverage: NativeImporterAdapterCoverageAggregate;
391
+ };
392
+ readonly imports: {
393
+ readonly total: number;
394
+ readonly sourcePaths: readonly string[];
395
+ readonly readiness: SemanticMergeReadiness;
396
+ readonly readinessReasons: readonly string[];
397
+ readonly nativeAstNodes: number;
398
+ readonly symbols: number;
399
+ readonly references: number;
400
+ readonly types: number;
401
+ readonly controlFlow: number;
402
+ readonly sourceMaps: number;
403
+ readonly sourceMapMappings: number;
404
+ readonly losses: number;
405
+ readonly lossKinds: Readonly<Record<string, number>>;
406
+ readonly lossCategories: readonly NativeImportTaxonomyKind[];
407
+ readonly sourcePreservation: NativeImportSourcePreservationContract;
408
+ };
409
+ readonly features: NativeParserFeatureCoverageMap;
410
+ readonly merge: NativeParserFeatureMergeAssessment;
411
+ }
412
+
413
+ export interface NativeParserFeatureLanguageSummary {
414
+ readonly language: FrontierSourceLanguage | string;
415
+ readonly aliases: readonly string[];
416
+ readonly parserRows: number;
417
+ readonly parsers: readonly string[];
418
+ readonly imports: number;
419
+ readonly adapters: number;
420
+ readonly mergeReadyParsers: readonly string[];
421
+ readonly readiness: SemanticMergeReadiness;
422
+ }
423
+
424
+ export interface NativeParserFeatureMatrix {
425
+ readonly kind: 'frontier.lang.nativeParserFeatureMatrix';
426
+ readonly version: 1;
427
+ readonly generatedAt: number;
428
+ readonly parsers: readonly NativeParserFeatureParserRow[];
429
+ readonly languages: readonly NativeParserFeatureLanguageSummary[];
430
+ readonly summary: {
431
+ readonly languages: number;
432
+ readonly parsers: number;
433
+ readonly imports: number;
434
+ readonly adapters: number;
435
+ readonly mergeReady: number;
436
+ readonly byReadiness: Readonly<Record<SemanticMergeReadiness, number>>;
437
+ readonly byFeatureStatus: Readonly<Record<NativeParserFeatureCategory, Readonly<Record<NativeParserFeatureCoverageStatus, number>>>>;
438
+ readonly byFeatureReadiness: Readonly<Record<NativeParserFeatureCategory, Readonly<Record<SemanticMergeReadiness, number>>>>;
439
+ };
440
+ readonly metadata: {
441
+ readonly categories: readonly NativeParserFeatureCategory[];
442
+ readonly statuses: readonly NativeParserFeatureCoverageStatus[];
443
+ readonly requiredFeatures: readonly NativeParserFeatureCategory[];
444
+ readonly minimumReadiness: SemanticMergeReadiness;
445
+ readonly note: string;
446
+ };
447
+ }
448
+
449
+ export interface NativeParserFeatureMatrixOptions {
450
+ readonly languages?: readonly NativeImportLanguageProfile[];
451
+ readonly imports?: readonly NativeSourceImportResult[];
452
+ readonly adapters?: readonly NativeImporterAdapter[];
453
+ readonly requiredFeatures?: readonly NativeParserFeatureCategory[];
454
+ readonly minimumReadiness?: SemanticMergeReadiness;
455
+ readonly includeEmptyParsers?: boolean;
456
+ readonly generatedAt?: number;
457
+ }
458
+
459
+ export interface NativeParserFeatureMatrixQuery {
460
+ readonly language?: FrontierSourceLanguage | string;
461
+ readonly parser?: string;
462
+ readonly requiredFeatures?: readonly NativeParserFeatureCategory[];
463
+ readonly minimumReadiness?: SemanticMergeReadiness;
464
+ }
465
+
466
+ export interface NativeParserFeatureMatrixQueryResult {
467
+ readonly kind: 'frontier.lang.nativeParserFeatureQuery';
468
+ readonly version: 1;
469
+ readonly found: boolean;
470
+ readonly language?: FrontierSourceLanguage | string;
471
+ readonly parser?: string;
472
+ readonly row?: NativeParserFeatureParserRow;
473
+ readonly merge: NativeParserFeatureMergeAssessment;
474
+ }
475
+
321
476
  export interface NativeImporterAdapterCoverageAggregate {
322
477
  readonly total: number;
323
478
  readonly declared: Readonly<Record<string, number>>;
@@ -1942,6 +2097,8 @@ export declare const NativeImportTaxonomyKinds: readonly NativeImportTaxonomyKin
1942
2097
  export declare const NativeImportLossKinds: readonly NativeImportKnownLossKind[];
1943
2098
  export declare const NativeImportRegionTaxonomyKinds: readonly NativeImportRegionTaxonomyKind[];
1944
2099
  export declare const ProjectionTargetLossClasses: readonly ProjectionTargetLossClass[];
2100
+ export declare const NativeParserFeatureCategories: readonly NativeParserFeatureCategory[];
2101
+ export declare const NativeParserFeatureCoverageStatuses: readonly NativeParserFeatureCoverageStatus[];
1945
2102
  export declare const NativeImportReadinessBySeverity: Readonly<Record<NativeImportLossSummary['highestSeverity'], SemanticMergeReadiness>>;
1946
2103
  export declare const NativeImportFeatureEvidencePolicies: Readonly<Record<string, NativeImportFeatureEvidencePolicy>>;
1947
2104
  export declare const NativeImportLanguageProfiles: readonly NativeImportLanguageProfile[];
@@ -1965,6 +2122,8 @@ export declare function classifyNativeImportRoundtripReadiness(importResult: Nat
1965
2122
  export declare function createNativeImportCoverageMatrix(options?: NativeImportCoverageMatrixOptions): NativeImportCoverageMatrix;
1966
2123
  export declare function getNativeParserAstFormatProfile(format?: string): NativeParserAstFormatProfile | undefined;
1967
2124
  export declare function createNativeParserAstFormatMatrix(options?: NativeParserAstFormatMatrixOptions): NativeParserAstFormatMatrix;
2125
+ export declare function createNativeParserFeatureMatrix(options?: NativeParserFeatureMatrixOptions): NativeParserFeatureMatrix;
2126
+ export declare function queryNativeParserFeatureMatrix(matrixOrOptions?: NativeParserFeatureMatrix | NativeParserFeatureMatrixOptions, query?: NativeParserFeatureMatrixQuery): NativeParserFeatureMatrixQueryResult;
1968
2127
  export declare function createProjectionTargetLossMatrix(options?: ProjectionTargetLossMatrixOptions): ProjectionTargetLossMatrix;
1969
2128
  export declare function createNativeSourcePreservation(options: CreateNativeSourcePreservationOptions): NativeSourcePreservation;
1970
2129
  export declare function createSemanticImportSidecar(importResult: NativeSourceImportResult | NativeProjectImportResult, options?: SemanticImportSidecarOptions): SemanticImportSidecar;
package/dist/index.js CHANGED
@@ -277,6 +277,24 @@ export const ProjectionTargetLossClasses = Object.freeze([
277
277
  'missingAdapter'
278
278
  ]);
279
279
 
280
+ export const NativeParserFeatureCategories = Object.freeze([
281
+ 'syntax',
282
+ 'semantic',
283
+ 'type',
284
+ 'controlFlow',
285
+ 'macroMetaprogramming',
286
+ 'sourcePreservation'
287
+ ]);
288
+
289
+ export const NativeParserFeatureCoverageStatuses = Object.freeze([
290
+ 'full',
291
+ 'partial',
292
+ 'evidence-required',
293
+ 'missing',
294
+ 'blocked',
295
+ 'not-applicable'
296
+ ]);
297
+
280
298
  export const NativeImportLanguageProfiles = Object.freeze([
281
299
  nativeImportLanguageProfile('javascript', {
282
300
  aliases: ['js', 'mjs', 'cjs', 'jsx'],
@@ -2369,6 +2387,78 @@ export function createNativeParserAstFormatMatrix(input = {}) {
2369
2387
  };
2370
2388
  }
2371
2389
 
2390
+ export function createNativeParserFeatureMatrix(input = {}) {
2391
+ const imports = input.imports ?? [];
2392
+ const adapters = input.adapters ?? [];
2393
+ const profiles = mergeNativeImportProfiles(input.languages ?? NativeImportLanguageProfiles, imports, adapters);
2394
+ const parsers = nativeParserFeatureRowsForProfiles(profiles, {
2395
+ imports,
2396
+ adapters,
2397
+ requiredFeatures: input.requiredFeatures,
2398
+ minimumReadiness: input.minimumReadiness,
2399
+ includeEmptyParsers: input.includeEmptyParsers
2400
+ });
2401
+ const summary = nativeParserFeatureMatrixSummary(parsers);
2402
+ return {
2403
+ kind: 'frontier.lang.nativeParserFeatureMatrix',
2404
+ version: 1,
2405
+ generatedAt: input.generatedAt ?? Date.now(),
2406
+ parsers,
2407
+ languages: summarizeNativeParserFeatureLanguages(profiles, parsers),
2408
+ summary,
2409
+ metadata: {
2410
+ categories: [...NativeParserFeatureCategories],
2411
+ statuses: [...NativeParserFeatureCoverageStatuses],
2412
+ requiredFeatures: normalizeNativeParserRequiredFeatures(input.requiredFeatures),
2413
+ minimumReadiness: normalizeSemanticMergeReadiness(input.minimumReadiness ?? 'ready'),
2414
+ note: 'Native parser feature coverage is admission evidence per language/parser. It does not promote lightweight scans or host adapters beyond their declared and observed capabilities.'
2415
+ }
2416
+ };
2417
+ }
2418
+
2419
+ export function queryNativeParserFeatureMatrix(matrixOrInput = {}, query = {}) {
2420
+ const matrix = matrixOrInput?.kind === 'frontier.lang.nativeParserFeatureMatrix'
2421
+ ? matrixOrInput
2422
+ : createNativeParserFeatureMatrix(matrixOrInput);
2423
+ const language = normalizeNativeLanguageId(query.language);
2424
+ const parser = query.parser === undefined ? undefined : parserAstFormatIdForParser(query.parser);
2425
+ const requiredFeatures = normalizeNativeParserRequiredFeatures(query.requiredFeatures ?? matrix.metadata?.requiredFeatures);
2426
+ const minimumReadiness = normalizeSemanticMergeReadiness(query.minimumReadiness ?? matrix.metadata?.minimumReadiness ?? 'ready');
2427
+ const row = matrix.parsers.find((entry) => {
2428
+ if (language && normalizeNativeLanguageId(entry.language) !== language && !(entry.aliases ?? []).map(normalizeNativeLanguageId).includes(language)) {
2429
+ return false;
2430
+ }
2431
+ if (!parser) return true;
2432
+ const parserIds = [
2433
+ entry.parser,
2434
+ entry.parserFormat,
2435
+ ...(entry.parserAliases ?? []),
2436
+ ...(entry.parserAdapters ?? [])
2437
+ ].map(parserAstFormatIdForParser);
2438
+ return parserIds.includes(parser);
2439
+ });
2440
+ const merge = row
2441
+ ? nativeParserFeatureMergeAssessment(row, { requiredFeatures, minimumReadiness })
2442
+ : {
2443
+ mergeReady: false,
2444
+ readiness: 'blocked',
2445
+ requiredFeatures,
2446
+ minimumReadiness,
2447
+ blockingFeatures: requiredFeatures,
2448
+ reviewFeatures: [],
2449
+ reasons: [`No native parser feature coverage row matched language=${query.language ?? '*'} parser=${query.parser ?? '*'}.`]
2450
+ };
2451
+ return {
2452
+ kind: 'frontier.lang.nativeParserFeatureQuery',
2453
+ version: 1,
2454
+ found: Boolean(row),
2455
+ language: row?.language ?? language,
2456
+ parser: row?.parser ?? parser,
2457
+ row,
2458
+ merge
2459
+ };
2460
+ }
2461
+
2372
2462
  export function createProjectionTargetLossMatrix(input = {}) {
2373
2463
  const imports = input.imports ?? [];
2374
2464
  const adapters = input.adapters ?? [];
@@ -7523,6 +7613,557 @@ function normalizeParserAstFormatId(format) {
7523
7613
  return String(format ?? '').trim().toLowerCase().replace(/[_\s]+/g, '-');
7524
7614
  }
7525
7615
 
7616
+ const nativeParserMacroMetaprogrammingLossKinds = new Set([
7617
+ 'macroExpansion',
7618
+ 'macroHygiene',
7619
+ 'preprocessor',
7620
+ 'conditionalCompilation',
7621
+ 'metaprogramming',
7622
+ 'reflection',
7623
+ 'generatedCode'
7624
+ ]);
7625
+
7626
+ const nativeParserTypeCoverageLossKinds = new Set([
7627
+ 'typeInference',
7628
+ 'overloadResolution',
7629
+ 'overloadTypeInference',
7630
+ 'unsupportedSemantic'
7631
+ ]);
7632
+
7633
+ function nativeParserFeatureRowsForProfiles(profiles, context) {
7634
+ const rows = [];
7635
+ for (const profile of profiles) {
7636
+ const matchingImports = nativeParserFeatureImportsForProfile(profile, context.imports);
7637
+ const matchingAdapters = nativeParserFeatureAdapterSummariesForProfile(profile, context.adapters);
7638
+ for (const parser of nativeParserFeatureParserSlots(profile, matchingImports, matchingAdapters)) {
7639
+ const row = nativeParserFeatureRowForParser(profile, parser, {
7640
+ ...context,
7641
+ imports: matchingImports.filter((imported) => nativeParserFeatureParserMatches(nativeParserParserForImport(imported), parser)),
7642
+ adapters: matchingAdapters.filter((adapter) => nativeParserFeatureParserMatches(adapter.parser, parser))
7643
+ });
7644
+ if (context.includeEmptyParsers === false && row.imports.total === 0 && row.adapters.total === 0) continue;
7645
+ rows.push(row);
7646
+ }
7647
+ }
7648
+ return rows.sort((left, right) => {
7649
+ const languageOrder = left.language.localeCompare(right.language);
7650
+ return languageOrder || left.parser.localeCompare(right.parser);
7651
+ });
7652
+ }
7653
+
7654
+ function nativeParserFeatureRowForParser(profile, parser, context) {
7655
+ const imports = context.imports ?? [];
7656
+ const adapters = context.adapters ?? [];
7657
+ const parserFormat = parserAstFormatIdForParser(parser);
7658
+ const parserProfile = getNativeParserAstFormatProfile(parserFormat);
7659
+ const adapterCoverage = summarizeNativeImporterAdapterCoverageEntries([
7660
+ ...imports.map((imported) => nativeImporterAdapterCoverageEntryFromImport(imported)).filter(Boolean),
7661
+ ...adapters.map((adapter) => ({
7662
+ adapterId: adapter.id,
7663
+ language: adapter.language,
7664
+ parser: adapter.parser,
7665
+ coverage: adapter.coverage
7666
+ }))
7667
+ ]);
7668
+ const losses = imports.flatMap((imported) => imported?.losses ?? imported?.nativeAst?.losses ?? []);
7669
+ const evidence = imports.flatMap((imported) => imported?.evidence ?? []);
7670
+ const lossSummary = summarizeNativeImportLosses(losses, { evidence, parser });
7671
+ const semanticEvidence = nativeParserFeatureSemanticEvidence(imports);
7672
+ const sourceMaps = imports.flatMap((imported) => imported?.sourceMaps ?? imported?.universalAst?.sourceMaps ?? []);
7673
+ const sourceMapMappings = sourceMaps.reduce((sum, sourceMap) => sum + (sourceMap?.mappings?.length ?? 0), 0);
7674
+ const sourcePreservation = summarizeImportSourcePreservation(undefined, imports);
7675
+ const nativeAstNodes = imports.reduce((sum, imported) => sum + Object.keys(imported?.nativeAst?.nodes ?? imported?.nativeSource?.ast?.nodes ?? {}).length, 0);
7676
+ const featureContext = {
7677
+ profile,
7678
+ parser,
7679
+ parserFormat,
7680
+ parserProfile,
7681
+ imports,
7682
+ adapters,
7683
+ adapterCoverage,
7684
+ losses,
7685
+ evidence,
7686
+ lossSummary,
7687
+ semanticEvidence,
7688
+ sourceMaps,
7689
+ sourceMapMappings,
7690
+ sourcePreservation,
7691
+ nativeAstNodes
7692
+ };
7693
+ const features = {
7694
+ syntax: nativeParserSyntaxFeature(featureContext),
7695
+ semantic: nativeParserSemanticFeature(featureContext),
7696
+ type: nativeParserTypeFeature(featureContext),
7697
+ controlFlow: nativeParserControlFlowFeature(featureContext),
7698
+ macroMetaprogramming: nativeParserMacroMetaprogrammingFeature(featureContext),
7699
+ sourcePreservation: nativeParserSourcePreservationFeature(featureContext)
7700
+ };
7701
+ const importReadiness = imports.length
7702
+ ? lossSummary.semanticMergeReadiness
7703
+ : adapters.length ? 'needs-review' : normalizeSemanticMergeReadiness(profile.defaultReadiness) ?? 'needs-review';
7704
+ const row = {
7705
+ language: profile.language,
7706
+ aliases: profile.aliases,
7707
+ parser,
7708
+ parserFormat,
7709
+ parserAliases: uniqueStrings([...(parserProfile?.aliases ?? []), ...(parserProfile?.parserAdapters ?? [])]),
7710
+ parserAdapters: uniqueStrings([parser, ...(parserProfile?.parserAdapters ?? [])]),
7711
+ extensions: profile.extensions,
7712
+ supportsLightweightScan: profile.supportsLightweightScan,
7713
+ projectionTargets: profile.projectionTargets,
7714
+ knownLossKinds: uniqueStrings([...(profile.knownLossKinds ?? []), ...Object.keys(lossSummary.byKind)]),
7715
+ defaultReadiness: profile.defaultReadiness,
7716
+ notes: uniqueStrings([...(profile.notes ?? []), ...(parserProfile?.notes ?? [])]),
7717
+ adapters: {
7718
+ total: adapters.length,
7719
+ ids: adapters.map((adapter) => adapter.id),
7720
+ versions: uniqueStrings(adapters.map((adapter) => adapter.version).filter(Boolean)),
7721
+ exactness: uniqueStrings(adapters.map((adapter) => adapter.coverage?.exactness).filter(Boolean)),
7722
+ coverage: adapterCoverage
7723
+ },
7724
+ imports: {
7725
+ total: imports.length,
7726
+ sourcePaths: uniqueStrings(imports.map((imported) => imported?.sourcePath ?? imported?.nativeSource?.sourcePath ?? imported?.nativeAst?.sourcePath).filter(Boolean)),
7727
+ readiness: importReadiness,
7728
+ readinessReasons: imports.length ? lossSummary.readinessReasons : nativeImportCoverageReasons(profile),
7729
+ nativeAstNodes,
7730
+ symbols: semanticEvidence.symbols,
7731
+ references: semanticEvidence.references,
7732
+ types: semanticEvidence.types,
7733
+ controlFlow: semanticEvidence.controlFlow,
7734
+ sourceMaps: sourceMaps.length,
7735
+ sourceMapMappings,
7736
+ losses: lossSummary.total,
7737
+ lossKinds: lossSummary.byKind,
7738
+ lossCategories: lossSummary.categories,
7739
+ sourcePreservation
7740
+ },
7741
+ features
7742
+ };
7743
+ return {
7744
+ ...row,
7745
+ merge: nativeParserFeatureMergeAssessment(row, {
7746
+ requiredFeatures: context.requiredFeatures,
7747
+ minimumReadiness: context.minimumReadiness
7748
+ })
7749
+ };
7750
+ }
7751
+
7752
+ function nativeParserSyntaxFeature(context) {
7753
+ const blockingSyntaxLosses = context.losses.filter((loss) => loss.severity === 'error' && (loss.kind === 'unsupportedSyntax' || loss.kind === 'parserDiagnostic'));
7754
+ const exactAst = context.adapterCoverage.effective.exactAst ?? 0;
7755
+ const sourceRanges = context.adapterCoverage.effective.sourceRanges ?? 0;
7756
+ const parserDiagnostics = context.adapterCoverage.effective.parserDiagnostics ?? 0;
7757
+ let status = 'missing';
7758
+ const reasons = [];
7759
+ if (blockingSyntaxLosses.length) {
7760
+ status = 'blocked';
7761
+ reasons.push('Parser diagnostics or unsupported syntax errors block syntax coverage.');
7762
+ } else if (exactAst > 0 && (sourceRanges > 0 || context.sourceMapMappings > 0)) {
7763
+ status = 'full';
7764
+ reasons.push('Exact parser AST and source-range evidence are available.');
7765
+ } else if (exactAst > 0 || sourceRanges > 0 || context.nativeAstNodes > 1 || context.sourceMapMappings > 0) {
7766
+ status = 'partial';
7767
+ reasons.push('Syntax evidence exists, but exact AST/source-range coverage is incomplete.');
7768
+ } else if (context.adapters.length || context.parserProfile) {
7769
+ status = 'evidence-required';
7770
+ reasons.push('Parser slot is declared, but no observed syntax import evidence is attached.');
7771
+ } else {
7772
+ reasons.push('No syntax parser coverage is declared or observed.');
7773
+ }
7774
+ return nativeParserFeatureCoverage('syntax', status, {
7775
+ capabilities: {
7776
+ exactAst,
7777
+ sourceRanges,
7778
+ parserDiagnostics,
7779
+ nativeAstNodes: context.nativeAstNodes,
7780
+ sourceMapMappings: context.sourceMapMappings
7781
+ },
7782
+ gaps: nativeParserFeatureCapabilityGaps(context.adapterCoverage, ['exactAst', 'sourceRanges', 'parserDiagnostics']),
7783
+ lossKinds: nativeParserFeatureLossKindCounts(context.losses, ['unsupportedSyntax', 'parserDiagnostic']),
7784
+ reasons,
7785
+ notes: ['Syntax coverage covers parser AST/CST structure, diagnostics, source ranges, and source-map anchors.']
7786
+ });
7787
+ }
7788
+
7789
+ function nativeParserSemanticFeature(context) {
7790
+ const declarations = (context.adapterCoverage.effective.semanticDeclarations ?? 0) + context.semanticEvidence.declarations;
7791
+ const symbols = (context.adapterCoverage.effective.semanticSymbols ?? 0) + context.semanticEvidence.symbols;
7792
+ let status = 'missing';
7793
+ const reasons = [];
7794
+ if (symbols > 0 && declarations > 0) {
7795
+ status = 'full';
7796
+ reasons.push('Declaration and symbol evidence are available.');
7797
+ } else if (symbols > 0 || declarations > 0 || context.nativeAstNodes > 1) {
7798
+ status = 'partial';
7799
+ reasons.push('Semantic evidence is present, but declaration/symbol coverage is incomplete.');
7800
+ } else if (context.adapters.length || context.imports.length) {
7801
+ status = 'evidence-required';
7802
+ reasons.push('Import evidence exists, but no semantic declarations or symbols were observed.');
7803
+ } else {
7804
+ reasons.push('No semantic index evidence is declared or observed.');
7805
+ }
7806
+ return nativeParserFeatureCoverage('semantic', status, {
7807
+ capabilities: {
7808
+ declarations,
7809
+ symbols,
7810
+ semanticIndexLevel: nativeParserFeatureSemanticLevel(context.adapterCoverage, context.semanticEvidence)
7811
+ },
7812
+ gaps: nativeParserFeatureCapabilityGaps(context.adapterCoverage, ['semanticDeclarations', 'semanticSymbols']),
7813
+ lossKinds: nativeParserFeatureLossKindCounts(context.losses, ['partialSemanticIndex', 'unsupportedSemantic']),
7814
+ reasons,
7815
+ notes: ['Semantic coverage covers declaration and symbol evidence. References, types, and control flow are reported separately.']
7816
+ });
7817
+ }
7818
+
7819
+ function nativeParserTypeFeature(context) {
7820
+ const types = (context.adapterCoverage.effective.types ?? 0) + context.semanticEvidence.types;
7821
+ const typeLossKinds = nativeParserFeaturePresentLossKinds(context, nativeParserTypeCoverageLossKinds);
7822
+ let status = 'missing';
7823
+ const reasons = [];
7824
+ if (types > 0) {
7825
+ status = 'full';
7826
+ reasons.push('Resolved or declared type evidence is available.');
7827
+ } else if (typeLossKinds.length > 0 || context.semanticEvidence.symbols > 0) {
7828
+ status = 'evidence-required';
7829
+ reasons.push('Type-sensitive coverage needs compiler or language-server evidence.');
7830
+ } else {
7831
+ reasons.push('No type evidence is declared or observed.');
7832
+ }
7833
+ return nativeParserFeatureCoverage('type', status, {
7834
+ capabilities: { types },
7835
+ gaps: nativeParserFeatureCapabilityGaps(context.adapterCoverage, ['types']),
7836
+ lossKinds: nativeParserFeatureLossKindCounts(context.losses, [...nativeParserTypeCoverageLossKinds]),
7837
+ reasons,
7838
+ notes: ['Type coverage covers declared/inferred type facts and overload or inference evidence.']
7839
+ });
7840
+ }
7841
+
7842
+ function nativeParserControlFlowFeature(context) {
7843
+ const controlFlow = (context.adapterCoverage.effective.controlFlow ?? 0) + context.semanticEvidence.controlFlow;
7844
+ let status = 'missing';
7845
+ const reasons = [];
7846
+ if (controlFlow > 0) {
7847
+ status = 'full';
7848
+ reasons.push('Control-flow or CFG evidence is available.');
7849
+ } else if (context.imports.length || context.adapters.length) {
7850
+ status = 'evidence-required';
7851
+ reasons.push('Control-flow evidence was not observed for this parser row.');
7852
+ } else {
7853
+ reasons.push('No control-flow evidence is declared or observed.');
7854
+ }
7855
+ return nativeParserFeatureCoverage('controlFlow', status, {
7856
+ capabilities: { controlFlow },
7857
+ gaps: nativeParserFeatureCapabilityGaps(context.adapterCoverage, ['controlFlow']),
7858
+ lossKinds: {},
7859
+ reasons,
7860
+ notes: ['Control-flow coverage covers call/branch/CFG facts supplied by host parsers or semantic indexers.']
7861
+ });
7862
+ }
7863
+
7864
+ function nativeParserMacroMetaprogrammingFeature(context) {
7865
+ const macroLossKinds = nativeParserFeaturePresentLossKinds(context, nativeParserMacroMetaprogrammingLossKinds);
7866
+ const macroLosses = context.losses.filter((loss) => nativeParserMacroMetaprogrammingLossKinds.has(loss.kind));
7867
+ const featureEvidence = summarizeNativeImportFeatureEvidence(macroLosses, { evidence: context.evidence });
7868
+ const generatedRanges = context.adapterCoverage.effective.generatedRanges ?? 0;
7869
+ let status = 'not-applicable';
7870
+ const reasons = [];
7871
+ if (!macroLossKinds.length) {
7872
+ reasons.push('No macro, preprocessor, generator, or metaprogramming coverage risk is declared for this parser row.');
7873
+ } else if (macroLosses.some((loss) => loss.severity === 'error')) {
7874
+ status = 'blocked';
7875
+ reasons.push('Macro or metaprogramming evidence includes blocking loss records.');
7876
+ } else if (featureEvidence.missingRequiredEvidence.length > 0 || generatedRanges === 0) {
7877
+ status = 'evidence-required';
7878
+ reasons.push('Macro/metaprogramming coverage requires generated-range and policy evidence before merge admission.');
7879
+ } else {
7880
+ status = 'partial';
7881
+ reasons.push('Macro/metaprogramming risk has attached evidence, but this facade still treats generated behavior as review-required.');
7882
+ }
7883
+ return nativeParserFeatureCoverage('macroMetaprogramming', status, {
7884
+ capabilities: {
7885
+ generatedRanges,
7886
+ policyKinds: featureEvidence.policyKinds,
7887
+ highestRisk: featureEvidence.highestRisk
7888
+ },
7889
+ gaps: nativeParserFeatureCapabilityGaps(context.adapterCoverage, ['generatedRanges']),
7890
+ lossKinds: nativeParserFeatureLossKindCounts(context.losses, [...nativeParserMacroMetaprogrammingLossKinds]),
7891
+ reasons: uniqueStrings([...reasons, ...featureEvidence.reasons]),
7892
+ notes: ['Macro/metaprogramming coverage covers macros, preprocessors, generated code, reflection, and conditional compilation evidence.']
7893
+ });
7894
+ }
7895
+
7896
+ function nativeParserSourcePreservationFeature(context) {
7897
+ const exactSource = context.sourcePreservation.exactSourceAvailable;
7898
+ const tokens = context.sourcePreservation.tokens + (context.adapterCoverage.effective.tokens ?? 0);
7899
+ const trivia = context.sourcePreservation.trivia + (context.adapterCoverage.effective.trivia ?? 0);
7900
+ const sourceRanges = context.adapterCoverage.effective.sourceRanges ?? 0;
7901
+ let status = 'missing';
7902
+ const reasons = [];
7903
+ if (exactSource > 0 && (tokens > 0 || trivia > 0 || sourceRanges > 0)) {
7904
+ status = 'full';
7905
+ reasons.push('Exact source text and token/trivia or source-range evidence are available.');
7906
+ } else if (exactSource > 0 || tokens > 0 || trivia > 0 || sourceRanges > 0) {
7907
+ status = 'partial';
7908
+ reasons.push('Source-preservation evidence exists, but exact source, tokens, trivia, or ranges are incomplete.');
7909
+ } else if (context.imports.length || context.adapters.length) {
7910
+ status = 'evidence-required';
7911
+ reasons.push('Import or adapter evidence exists, but no exact source-preservation record was observed.');
7912
+ } else {
7913
+ reasons.push('No source-preservation evidence is declared or observed.');
7914
+ }
7915
+ return nativeParserFeatureCoverage('sourcePreservation', status, {
7916
+ capabilities: {
7917
+ exactSourceAvailable: exactSource,
7918
+ tokens,
7919
+ trivia,
7920
+ comments: context.sourcePreservation.comments,
7921
+ whitespace: context.sourcePreservation.whitespace,
7922
+ directives: context.sourcePreservation.directives,
7923
+ sourceRanges
7924
+ },
7925
+ gaps: nativeParserFeatureCapabilityGaps(context.adapterCoverage, ['tokens', 'trivia', 'sourceRanges']),
7926
+ lossKinds: nativeParserFeatureLossKindCounts(context.losses, ['sourcePreservation', 'commentsTrivia', 'sourceMapApproximation']),
7927
+ reasons,
7928
+ notes: ['Source-preservation coverage covers exact source text, token/trivia retention, comments, whitespace, directives, and source ranges.']
7929
+ });
7930
+ }
7931
+
7932
+ function nativeParserFeatureCoverage(category, status, input = {}) {
7933
+ const normalizedStatus = NativeParserFeatureCoverageStatuses.includes(status) ? status : 'missing';
7934
+ return Object.freeze({
7935
+ category,
7936
+ status: normalizedStatus,
7937
+ readiness: nativeParserFeatureReadinessForStatus(normalizedStatus),
7938
+ mergeReady: nativeParserFeatureStatusMergeReady(normalizedStatus),
7939
+ supported: normalizedStatus === 'full' || normalizedStatus === 'partial' || normalizedStatus === 'not-applicable',
7940
+ capabilities: Object.freeze(input.capabilities ?? {}),
7941
+ gaps: Object.freeze(uniqueStrings(input.gaps ?? [])),
7942
+ lossKinds: Object.freeze(input.lossKinds ?? {}),
7943
+ reasons: Object.freeze(uniqueStrings(input.reasons ?? [])),
7944
+ notes: Object.freeze(uniqueStrings(input.notes ?? []))
7945
+ });
7946
+ }
7947
+
7948
+ function nativeParserFeatureReadinessForStatus(status) {
7949
+ if (status === 'full' || status === 'not-applicable') return 'ready';
7950
+ if (status === 'partial') return 'ready-with-losses';
7951
+ if (status === 'blocked') return 'blocked';
7952
+ return 'needs-review';
7953
+ }
7954
+
7955
+ function nativeParserFeatureStatusMergeReady(status) {
7956
+ return status === 'full' || status === 'not-applicable';
7957
+ }
7958
+
7959
+ function nativeParserFeatureMergeAssessment(row, input = {}) {
7960
+ const requiredFeatures = normalizeNativeParserRequiredFeatures(input.requiredFeatures);
7961
+ const minimumReadiness = normalizeSemanticMergeReadiness(input.minimumReadiness ?? 'ready') ?? 'ready';
7962
+ const featureReadiness = requiredFeatures.reduce(
7963
+ (current, category) => maxSemanticMergeReadiness(current, row.features?.[category]?.readiness ?? 'blocked'),
7964
+ 'ready'
7965
+ );
7966
+ const readiness = maxSemanticMergeReadiness(row.imports?.readiness ?? 'needs-review', featureReadiness);
7967
+ const blockingFeatures = requiredFeatures.filter((category) => !nativeParserFeatureStatusMergeReady(row.features?.[category]?.status));
7968
+ const reviewFeatures = requiredFeatures.filter((category) => {
7969
+ const featureReadiness = row.features?.[category]?.readiness ?? 'blocked';
7970
+ return semanticMergeReadinessRank[featureReadiness] > semanticMergeReadinessRank.ready
7971
+ && semanticMergeReadinessRank[featureReadiness] <= semanticMergeReadinessRank['needs-review'];
7972
+ });
7973
+ const reasons = [];
7974
+ if ((row.imports?.total ?? 0) === 0) reasons.push('No native import evidence matched this language/parser row.');
7975
+ for (const category of blockingFeatures) {
7976
+ const feature = row.features?.[category];
7977
+ reasons.push(`${category} coverage is ${feature?.status ?? 'missing'}: ${(feature?.reasons ?? []).join(' ')}`);
7978
+ }
7979
+ if (semanticMergeReadinessRank[readiness] > semanticMergeReadinessRank[minimumReadiness]) {
7980
+ reasons.push(`Readiness ${readiness} is weaker than required threshold ${minimumReadiness}.`);
7981
+ }
7982
+ const mergeReady = (row.imports?.total ?? 0) > 0
7983
+ && blockingFeatures.length === 0
7984
+ && semanticMergeReadinessRank[readiness] <= semanticMergeReadinessRank[minimumReadiness];
7985
+ if (mergeReady) reasons.push(`Native import is merge-ready for required features: ${requiredFeatures.join(', ')}.`);
7986
+ return Object.freeze({
7987
+ mergeReady,
7988
+ readiness,
7989
+ requiredFeatures,
7990
+ minimumReadiness,
7991
+ blockingFeatures,
7992
+ reviewFeatures,
7993
+ reasons: uniqueStrings(reasons)
7994
+ });
7995
+ }
7996
+
7997
+ function normalizeNativeParserRequiredFeatures(value) {
7998
+ const requested = normalizeStringList(value);
7999
+ const features = requested.length ? requested : ['syntax', 'semantic', 'sourcePreservation'];
8000
+ return uniqueStrings(features.map(normalizeNativeParserFeatureCategory).filter((feature) => NativeParserFeatureCategories.includes(feature)));
8001
+ }
8002
+
8003
+ function normalizeNativeParserFeatureCategory(value) {
8004
+ const normalized = String(value ?? '').trim().replace(/[-_\s]+([a-zA-Z])/g, (_, letter) => letter.toUpperCase());
8005
+ if (normalized.toLowerCase() === 'macrometaprogramming' || normalized.toLowerCase() === 'macro') return 'macroMetaprogramming';
8006
+ if (normalized.toLowerCase() === 'controlflow' || normalized.toLowerCase() === 'cfg') return 'controlFlow';
8007
+ if (normalized.toLowerCase() === 'sourcepreservation' || normalized.toLowerCase() === 'source') return 'sourcePreservation';
8008
+ if (normalized.toLowerCase() === 'types') return 'type';
8009
+ return normalized;
8010
+ }
8011
+
8012
+ function nativeParserFeatureMatrixSummary(rows) {
8013
+ const summary = {
8014
+ languages: new Set(),
8015
+ parsers: rows.length,
8016
+ imports: 0,
8017
+ adapters: 0,
8018
+ mergeReady: 0,
8019
+ byReadiness: {},
8020
+ byFeatureStatus: {},
8021
+ byFeatureReadiness: {}
8022
+ };
8023
+ for (const row of rows) {
8024
+ summary.languages.add(row.language);
8025
+ summary.imports += row.imports.total;
8026
+ summary.adapters += row.adapters.total;
8027
+ if (row.merge.mergeReady) summary.mergeReady += 1;
8028
+ summary.byReadiness[row.merge.readiness] = (summary.byReadiness[row.merge.readiness] ?? 0) + 1;
8029
+ for (const [category, feature] of Object.entries(row.features)) {
8030
+ summary.byFeatureStatus[category] ??= {};
8031
+ summary.byFeatureReadiness[category] ??= {};
8032
+ summary.byFeatureStatus[category][feature.status] = (summary.byFeatureStatus[category][feature.status] ?? 0) + 1;
8033
+ summary.byFeatureReadiness[category][feature.readiness] = (summary.byFeatureReadiness[category][feature.readiness] ?? 0) + 1;
8034
+ }
8035
+ }
8036
+ return {
8037
+ ...summary,
8038
+ languages: summary.languages.size
8039
+ };
8040
+ }
8041
+
8042
+ function summarizeNativeParserFeatureLanguages(profiles, rows) {
8043
+ return profiles.map((profile) => {
8044
+ const languageRows = rows.filter((row) => row.language === profile.language);
8045
+ return {
8046
+ language: profile.language,
8047
+ aliases: profile.aliases,
8048
+ parserRows: languageRows.length,
8049
+ parsers: languageRows.map((row) => row.parser),
8050
+ imports: languageRows.reduce((sum, row) => sum + row.imports.total, 0),
8051
+ adapters: languageRows.reduce((sum, row) => sum + row.adapters.total, 0),
8052
+ mergeReadyParsers: languageRows.filter((row) => row.merge.mergeReady).map((row) => row.parser),
8053
+ readiness: languageRows.reduce((current, row) => maxSemanticMergeReadiness(current, row.merge.readiness), 'ready')
8054
+ };
8055
+ });
8056
+ }
8057
+
8058
+ function nativeParserFeatureParserSlots(profile, imports, adapters) {
8059
+ const slots = [
8060
+ ...(profile.parserAdapters ?? []),
8061
+ ...adapters.map((adapter) => adapter.parser),
8062
+ ...imports.map(nativeParserParserForImport)
8063
+ ].filter(Boolean);
8064
+ if (!slots.length && profile.supportsLightweightScan) slots.push(`${profile.language}.lightweight-declaration-scan`);
8065
+ const seen = new Set();
8066
+ const result = [];
8067
+ for (const slot of slots) {
8068
+ const key = `${normalizeParserAstFormatId(slot)}#${parserAstFormatIdForParser(slot)}`;
8069
+ if (seen.has(key)) continue;
8070
+ seen.add(key);
8071
+ result.push(String(slot));
8072
+ }
8073
+ return result;
8074
+ }
8075
+
8076
+ function nativeParserFeatureImportsForProfile(profile, imports = []) {
8077
+ const languages = nativeParserFeatureLanguageSet(profile);
8078
+ return imports.filter((imported) => languages.has(normalizeNativeLanguageId(imported?.language ?? imported?.nativeAst?.language ?? imported?.nativeSource?.language)));
8079
+ }
8080
+
8081
+ function nativeParserFeatureAdapterSummariesForProfile(profile, adapters = []) {
8082
+ const languages = nativeParserFeatureLanguageSet(profile);
8083
+ return adapters
8084
+ .map((adapter) => safeNativeImporterAdapterSummary(adapter))
8085
+ .filter(Boolean)
8086
+ .filter((adapter) => languages.has(normalizeNativeLanguageId(adapter.language)));
8087
+ }
8088
+
8089
+ function nativeParserFeatureLanguageSet(profile) {
8090
+ return new Set([profile.language, ...(profile.aliases ?? [])].map(normalizeNativeLanguageId).filter(Boolean));
8091
+ }
8092
+
8093
+ function nativeParserParserForImport(imported) {
8094
+ return imported?.adapter?.parser
8095
+ ?? imported?.metadata?.adapterCoverage?.parser
8096
+ ?? imported?.nativeAst?.parser
8097
+ ?? imported?.nativeSource?.parser
8098
+ ?? imported?.parser
8099
+ ?? imported?.metadata?.parser;
8100
+ }
8101
+
8102
+ function nativeParserFeatureParserMatches(candidateParser, rowParser) {
8103
+ if (!candidateParser || !rowParser) return false;
8104
+ const candidate = normalizeParserAstFormatId(candidateParser);
8105
+ const row = normalizeParserAstFormatId(rowParser);
8106
+ return candidate === row || parserAstFormatIdForParser(candidateParser) === parserAstFormatIdForParser(rowParser);
8107
+ }
8108
+
8109
+ function nativeParserFeatureSemanticEvidence(imports) {
8110
+ const totals = {
8111
+ declarations: 0,
8112
+ symbols: 0,
8113
+ references: 0,
8114
+ types: 0,
8115
+ controlFlow: 0
8116
+ };
8117
+ for (const imported of imports) {
8118
+ const semanticIndex = imported?.semanticIndex ?? imported?.universalAst?.semanticIndex;
8119
+ const evidence = observeNativeImporterSemanticEvidence(semanticIndex);
8120
+ totals.declarations += evidence.declarations;
8121
+ totals.symbols += semanticIndex?.symbols?.length ?? 0;
8122
+ totals.references += evidence.references;
8123
+ totals.types += evidence.types;
8124
+ totals.controlFlow += evidence.controlFlow;
8125
+ }
8126
+ return totals;
8127
+ }
8128
+
8129
+ function nativeParserFeatureSemanticLevel(adapterCoverage, semanticEvidence) {
8130
+ if ((adapterCoverage.effective.types ?? 0) > 0 || (adapterCoverage.effective.controlFlow ?? 0) > 0 || semanticEvidence.types > 0 || semanticEvidence.controlFlow > 0 || semanticEvidence.references > 0) {
8131
+ return 'semantic-index';
8132
+ }
8133
+ if ((adapterCoverage.effective.semanticDeclarations ?? 0) > 0 || (adapterCoverage.effective.semanticSymbols ?? 0) > 0 || semanticEvidence.declarations > 0 || semanticEvidence.symbols > 0) {
8134
+ return 'declaration-index';
8135
+ }
8136
+ return 'native-ast';
8137
+ }
8138
+
8139
+ function nativeParserFeatureCapabilityGaps(adapterCoverage, capabilities) {
8140
+ const gaps = new Set();
8141
+ for (const capability of capabilities) {
8142
+ if ((adapterCoverage.effective?.[capability] ?? 0) === 0) gaps.add(capability);
8143
+ }
8144
+ for (const capability of Object.keys(adapterCoverage.gaps ?? {})) {
8145
+ if (capabilities.includes(capability)) gaps.add(capability);
8146
+ }
8147
+ return [...gaps];
8148
+ }
8149
+
8150
+ function nativeParserFeatureLossKindCounts(losses, kinds) {
8151
+ const wanted = new Set(kinds);
8152
+ const counts = {};
8153
+ for (const loss of losses) {
8154
+ if (!wanted.has(loss?.kind)) continue;
8155
+ counts[loss.kind] = (counts[loss.kind] ?? 0) + 1;
8156
+ }
8157
+ return counts;
8158
+ }
8159
+
8160
+ function nativeParserFeaturePresentLossKinds(context, kindSet) {
8161
+ return uniqueStrings([
8162
+ ...(context.profile.knownLossKinds ?? []),
8163
+ ...Object.keys(context.lossSummary.byKind ?? {})
8164
+ ].filter((kind) => kindSet.has(kind)));
8165
+ }
8166
+
7526
8167
  function mergeNativeParserAstFormatProfiles(profiles, imports, adapters) {
7527
8168
  const byId = new Map((profiles ?? []).map((profile) => [normalizeParserAstFormatId(profile.id ?? profile), nativeParserAstFormatProfile(normalizeParserAstFormatId(profile.id ?? profile), profile)]));
7528
8169
  for (const adapter of adapters ?? []) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-compiler",
3
- "version": "0.2.33",
3
+ "version": "0.2.34",
4
4
  "description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",