flex-md 4.7.2 → 4.7.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.
Files changed (104) hide show
  1. package/README.md +1 -1
  2. package/dist/__tests__/diagnostics.test.js +45 -47
  3. package/dist/__tests__/ofs.test.js +28 -30
  4. package/dist/__tests__/structural.test.js +19 -21
  5. package/dist/__tests__/validate.test.js +27 -29
  6. package/dist/cli/index.js +13 -15
  7. package/dist/detect/json/detectIntent.js +1 -4
  8. package/dist/detect/json/detectMarkdown.js +29 -35
  9. package/dist/detect/json/detectPresence.js +2 -6
  10. package/dist/detect/json/index.js +10 -31
  11. package/dist/detect/json/types.js +1 -2
  12. package/dist/extract/extract.js +11 -14
  13. package/dist/extract/types.js +1 -2
  14. package/dist/index.js +22 -69
  15. package/dist/logger.js +3 -6
  16. package/dist/md/match.js +1 -4
  17. package/dist/md/normalize.js +1 -4
  18. package/dist/md/outline.js +4 -8
  19. package/dist/md/parse.js +11 -20
  20. package/dist/ofs/adapter.js +45 -49
  21. package/dist/ofs/enricher.js +3 -8
  22. package/dist/ofs/infer.js +4 -7
  23. package/dist/ofs/issuesEnvelope.js +5 -10
  24. package/dist/ofs/memory.js +6 -10
  25. package/dist/ofs/parser.js +7 -13
  26. package/dist/ofs/stringify.js +1 -4
  27. package/dist/pipeline/enforce.js +12 -15
  28. package/dist/pipeline/kind.js +3 -6
  29. package/dist/pipeline/repair.js +8 -11
  30. package/dist/strictness/container.js +1 -4
  31. package/dist/strictness/processor.js +7 -10
  32. package/dist/strictness/types.js +1 -4
  33. package/dist/tokens/auto-fix.js +1 -4
  34. package/dist/tokens/cognitive-cost.js +6 -10
  35. package/dist/tokens/compliance.js +4 -8
  36. package/dist/tokens/confidence.js +6 -9
  37. package/dist/tokens/estimator.js +20 -26
  38. package/dist/tokens/improvements.js +12 -16
  39. package/dist/tokens/index.js +22 -40
  40. package/dist/tokens/parser.js +4 -7
  41. package/dist/tokens/patterns.js +2 -5
  42. package/dist/tokens/runtime-estimator.js +9 -12
  43. package/dist/tokens/smart-report.js +10 -14
  44. package/dist/tokens/spec-estimator.js +10 -15
  45. package/dist/tokens/types.js +1 -2
  46. package/dist/tokens/validator.js +3 -6
  47. package/dist/types.js +1 -2
  48. package/dist/validate/compliance.js +4 -8
  49. package/dist/validate/connection.js +5 -8
  50. package/dist/validate/types.js +1 -2
  51. package/dist/validate/validate.js +16 -19
  52. package/dist-cjs/__tests__/diagnostics.test.cjs +61 -0
  53. package/dist-cjs/__tests__/ofs.test.cjs +53 -0
  54. package/dist-cjs/__tests__/structural.test.cjs +30 -0
  55. package/dist-cjs/__tests__/validate.test.cjs +110 -0
  56. package/dist-cjs/cli/index.cjs +110 -0
  57. package/dist-cjs/detect/json/detectIntent.cjs +82 -0
  58. package/dist-cjs/detect/json/detectMarkdown.cjs +304 -0
  59. package/dist-cjs/detect/json/detectPresence.cjs +195 -0
  60. package/dist-cjs/detect/json/index.cjs +34 -0
  61. package/dist-cjs/detect/json/types.cjs +2 -0
  62. package/dist-cjs/extract/extract.cjs +72 -0
  63. package/dist-cjs/extract/types.cjs +2 -0
  64. package/dist-cjs/flex-md-loader.cjs +102 -0
  65. package/dist-cjs/index.cjs +79 -0
  66. package/dist-cjs/logger.cjs +22 -0
  67. package/dist-cjs/md/match.cjs +47 -0
  68. package/dist-cjs/md/normalize.cjs +13 -0
  69. package/dist-cjs/md/outline.cjs +49 -0
  70. package/dist-cjs/md/parse.cjs +199 -0
  71. package/dist-cjs/ofs/adapter.cjs +195 -0
  72. package/dist-cjs/ofs/enricher.cjs +151 -0
  73. package/dist-cjs/ofs/infer.cjs +63 -0
  74. package/dist-cjs/ofs/issuesEnvelope.cjs +76 -0
  75. package/dist-cjs/ofs/memory.cjs +26 -0
  76. package/dist-cjs/ofs/parser.cjs +373 -0
  77. package/dist-cjs/ofs/stringify.cjs +45 -0
  78. package/dist-cjs/pipeline/enforce.cjs +49 -0
  79. package/dist-cjs/pipeline/kind.cjs +30 -0
  80. package/dist-cjs/pipeline/repair.cjs +115 -0
  81. package/dist-cjs/strictness/container.cjs +49 -0
  82. package/dist-cjs/strictness/processor.cjs +32 -0
  83. package/dist-cjs/strictness/types.cjs +109 -0
  84. package/dist-cjs/tokens/auto-fix.cjs +59 -0
  85. package/dist-cjs/tokens/cognitive-cost.cjs +209 -0
  86. package/dist-cjs/tokens/compliance.cjs +74 -0
  87. package/dist-cjs/tokens/confidence.cjs +335 -0
  88. package/dist-cjs/tokens/estimator.cjs +157 -0
  89. package/dist-cjs/tokens/improvements.cjs +701 -0
  90. package/dist-cjs/tokens/index.cjs +74 -0
  91. package/dist-cjs/tokens/parser.cjs +100 -0
  92. package/dist-cjs/tokens/patterns.cjs +23 -0
  93. package/dist-cjs/tokens/runtime-estimator.cjs +74 -0
  94. package/dist-cjs/tokens/smart-report.cjs +191 -0
  95. package/dist-cjs/tokens/spec-estimator.cjs +125 -0
  96. package/dist-cjs/tokens/types.cjs +2 -0
  97. package/dist-cjs/tokens/validator.cjs +62 -0
  98. package/dist-cjs/types.cjs +2 -0
  99. package/dist-cjs/validate/compliance.cjs +103 -0
  100. package/dist-cjs/validate/connection.cjs +47 -0
  101. package/dist-cjs/validate/types.cjs +2 -0
  102. package/dist-cjs/validate/validate.cjs +319 -0
  103. package/docs/consumption.md +1 -1
  104. package/package.json +14 -8
@@ -1,13 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.detectImprovements = detectImprovements;
4
- exports.formatImprovementReport = formatImprovementReport;
5
- const parser_js_1 = require("./parser.js");
6
- const compliance_js_1 = require("./compliance.js");
1
+ import { parseSystemPart } from './parser.js';
2
+ import { detectSystemPartLevel } from './compliance.js';
7
3
  /**
8
4
  * Main improvement detector
9
5
  */
10
- function detectImprovements(spec, targetLevel = 2) {
6
+ export function detectImprovements(spec, targetLevel = 2) {
11
7
  const improvements = [];
12
8
  const antiPatterns = [];
13
9
  const optimizations = [];
@@ -36,8 +32,8 @@ function detectImprovements(spec, targetLevel = 2) {
36
32
  function detectSectionImprovements(section, targetLevel) {
37
33
  const improvements = [];
38
34
  const kind = (section.kind || 'text');
39
- const systemPart = (0, parser_js_1.parseSystemPart)(section.instruction, kind);
40
- const currentLevel = systemPart ? (0, compliance_js_1.detectSystemPartLevel)(systemPart, kind) : null;
35
+ const systemPart = parseSystemPart(section.instruction, kind);
36
+ const currentLevel = systemPart ? detectSystemPartLevel(systemPart, kind) : null;
41
37
  // 1. Missing system part
42
38
  if (!systemPart) {
43
39
  improvements.push({
@@ -319,7 +315,7 @@ function detectUnreasonableValues(systemPart, section) {
319
315
  function detectSectionAntiPatterns(section) {
320
316
  const patterns = [];
321
317
  const kind = (section.kind || 'text');
322
- const systemPart = (0, parser_js_1.parseSystemPart)(section.instruction, kind);
318
+ const systemPart = parseSystemPart(section.instruction, kind);
323
319
  const isRequired = section.required !== false;
324
320
  // Anti-pattern: Required section with no instruction at all
325
321
  if (isRequired && !section.instruction) {
@@ -348,7 +344,7 @@ function detectSectionAntiPatterns(section) {
348
344
  }
349
345
  // Anti-pattern: Optional section with higher compliance than required
350
346
  if (!isRequired && systemPart) {
351
- const level = (0, compliance_js_1.detectSystemPartLevel)(systemPart, kind);
347
+ const level = detectSystemPartLevel(systemPart, kind);
352
348
  if (level === 3) {
353
349
  patterns.push({
354
350
  sectionName: section.name,
@@ -398,9 +394,9 @@ function detectSpecOptimizations(spec) {
398
394
  const firstKind = (spec.sections[0].kind || 'text');
399
395
  // Optimization: All sections at L1, could upgrade key ones to L2
400
396
  const levels = spec.sections
401
- .map(s => (0, parser_js_1.parseSystemPart)(s.instruction, (s.kind || 'text')))
397
+ .map(s => parseSystemPart(s.instruction, (s.kind || 'text')))
402
398
  .filter(sp => sp !== null)
403
- .map(sp => (0, compliance_js_1.detectSystemPartLevel)(sp, firstKind));
399
+ .map(sp => detectSystemPartLevel(sp, firstKind));
404
400
  const allL1 = levels.length > 0 && levels.every(l => l === 1);
405
401
  if (allL1 && levels.length >= 3) {
406
402
  opts.push({
@@ -428,7 +424,7 @@ function detectSpecOptimizations(spec) {
428
424
  });
429
425
  }
430
426
  // Optimization: Too many sections without system parts
431
- const withoutSystemParts = spec.sections.filter(s => (0, parser_js_1.parseSystemPart)(s.instruction, (s.kind || 'text')) === null);
427
+ const withoutSystemParts = spec.sections.filter(s => parseSystemPart(s.instruction, (s.kind || 'text')) === null);
432
428
  if (withoutSystemParts.length > spec.sections.length * 0.3) {
433
429
  opts.push({
434
430
  type: 'simplify',
@@ -453,7 +449,7 @@ function detectSpecOptimizations(spec) {
453
449
  // Optimization: All text sections could benefit from more specific lengths
454
450
  const textSections = spec.sections.filter(s => (s.kind || 'text') === 'text');
455
451
  const vagueLengths = textSections.filter(s => {
456
- const sp = (0, parser_js_1.parseSystemPart)(s.instruction, 'text');
452
+ const sp = parseSystemPart(s.instruction, 'text');
457
453
  return sp?.parsed.type === 'length' &&
458
454
  ['brief', 'moderate', 'detailed', 'extensive'].includes(sp.parsed.value);
459
455
  });
@@ -609,7 +605,7 @@ function byImpact(a, b) {
609
605
  /**
610
606
  * Format improvement report
611
607
  */
612
- function formatImprovementReport(analysis) {
608
+ export function formatImprovementReport(analysis) {
613
609
  const lines = [];
614
610
  lines.push('\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2551');
615
611
  lines.push('\u2551 IMPROVEMENT DETECTION REPORT \u2551');
@@ -1,35 +1,17 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.getMaxTokens = getMaxTokens;
18
- exports.getMaxTokensFromInstructions = getMaxTokensFromInstructions;
19
- const parser_js_1 = require("../ofs/parser.js");
20
- const spec_estimator_js_1 = require("./spec-estimator.js");
21
- __exportStar(require("./types.js"), exports);
22
- __exportStar(require("./parser.js"), exports);
23
- __exportStar(require("./estimator.js"), exports);
24
- __exportStar(require("./spec-estimator.js"), exports);
25
- __exportStar(require("./runtime-estimator.js"), exports);
26
- __exportStar(require("./validator.js"), exports);
27
- __exportStar(require("./compliance.js"), exports);
28
- __exportStar(require("./cognitive-cost.js"), exports);
29
- __exportStar(require("./confidence.js"), exports);
30
- __exportStar(require("./smart-report.js"), exports);
31
- __exportStar(require("./improvements.js"), exports);
32
- __exportStar(require("./auto-fix.js"), exports);
1
+ import { parseOutputFormatSpec, parseFormatSpecs } from '../ofs/parser.js';
2
+ import { estimateSpecTokens, estimateFormatSpecsTokens } from './spec-estimator.js';
3
+ export * from './types.js';
4
+ export * from './parser.js';
5
+ export * from './estimator.js';
6
+ export * from './spec-estimator.js';
7
+ export * from './runtime-estimator.js';
8
+ export * from './validator.js';
9
+ export * from './compliance.js';
10
+ export * from './cognitive-cost.js';
11
+ export * from './confidence.js';
12
+ export * from './smart-report.js';
13
+ export * from './improvements.js';
14
+ export * from './auto-fix.js';
33
15
  /**
34
16
  * Convenience function: estimate max_tokens from spec
35
17
  *
@@ -37,26 +19,26 @@ __exportStar(require("./auto-fix.js"), exports);
37
19
  * @param options - Estimation options
38
20
  * @returns Estimated max_tokens value
39
21
  */
40
- function getMaxTokens(spec, options) {
22
+ export function getMaxTokens(spec, options) {
41
23
  if (!spec)
42
24
  return 0;
43
25
  const extractFromInstructions = options?.extractFromInstructions ?? false;
44
26
  // If extractFromInstructions is true and spec is a string, try to extract both formats
45
27
  if (extractFromInstructions && typeof spec === 'string') {
46
- const formatSpecs = (0, parser_js_1.parseFormatSpecs)(spec);
28
+ const formatSpecs = parseFormatSpecs(spec);
47
29
  if (formatSpecs.input || formatSpecs.output) {
48
- const estimate = (0, spec_estimator_js_1.estimateFormatSpecsTokens)(formatSpecs.input, formatSpecs.output, options);
30
+ const estimate = estimateFormatSpecsTokens(formatSpecs.input, formatSpecs.output, options);
49
31
  return estimate.total.estimated;
50
32
  }
51
33
  // Fall through to output-only parsing if no formats found
52
34
  }
53
35
  // Original behavior: parse as output format spec
54
36
  const parsedSpec = typeof spec === 'string'
55
- ? (0, parser_js_1.parseOutputFormatSpec)(spec)
37
+ ? parseOutputFormatSpec(spec)
56
38
  : spec;
57
39
  if (!parsedSpec)
58
40
  return 0;
59
- const estimate = (0, spec_estimator_js_1.estimateSpecTokens)(parsedSpec, options);
41
+ const estimate = estimateSpecTokens(parsedSpec, options);
60
42
  return estimate.total.estimated;
61
43
  }
62
44
  /**
@@ -67,8 +49,8 @@ function getMaxTokens(spec, options) {
67
49
  * @param options - Estimation options
68
50
  * @returns Estimated max_tokens value based on both input and output formats
69
51
  */
70
- function getMaxTokensFromInstructions(instructions, options) {
71
- const formatSpecs = (0, parser_js_1.parseFormatSpecs)(instructions);
72
- const estimate = (0, spec_estimator_js_1.estimateFormatSpecsTokens)(formatSpecs.input, formatSpecs.output, options);
52
+ export function getMaxTokensFromInstructions(instructions, options) {
53
+ const formatSpecs = parseFormatSpecs(instructions);
54
+ const estimate = estimateFormatSpecsTokens(formatSpecs.input, formatSpecs.output, options);
73
55
  return estimate.total.estimated;
74
56
  }
@@ -1,19 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseSystemPart = parseSystemPart;
4
- const patterns_js_1 = require("./patterns.js");
5
- function parseSystemPart(instruction, kind // Allow 'code' as a special case if needed
1
+ import { SYSTEM_PART_PATTERNS, INSTRUCTION_SPLIT } from './patterns.js';
2
+ export function parseSystemPart(instruction, kind // Allow 'code' as a special case if needed
6
3
  ) {
7
4
  if (!instruction)
8
5
  return null;
9
- const pattern = patterns_js_1.SYSTEM_PART_PATTERNS[kind];
6
+ const pattern = SYSTEM_PART_PATTERNS[kind];
10
7
  if (!pattern)
11
8
  return null;
12
9
  const match = instruction.match(pattern);
13
10
  if (!match)
14
11
  return null;
15
12
  // Split into system and guidance parts
16
- const parts = instruction.split(patterns_js_1.INSTRUCTION_SPLIT);
13
+ const parts = instruction.split(INSTRUCTION_SPLIT);
17
14
  const raw = parts[0];
18
15
  const guidance = parts.slice(1).join('. ') || null;
19
16
  const parsed = parseMatchByKind(kind, match);
@@ -1,8 +1,5 @@
1
- "use strict";
2
1
  // patterns.ts
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.INSTRUCTION_SPLIT = exports.SYSTEM_PART_PATTERNS = void 0;
5
- exports.SYSTEM_PART_PATTERNS = {
2
+ export const SYSTEM_PART_PATTERNS = {
6
3
  // TEXT: Enumerated literal strings only
7
4
  text: /^Length:\s*(1\s+sentence|1-2\s+sentences|1\s+paragraph|2-3\s+paragraphs|brief|moderate|detailed|extensive)/i,
8
5
  // LIST/ORDERED-LIST: [optional "at least"] + number + [optional range]
@@ -20,4 +17,4 @@ exports.SYSTEM_PART_PATTERNS = {
20
17
  code: /^Lines:\s*(~)?(\d+)(?:-(\d+))?/i
21
18
  };
22
19
  // Separator for splitting system part from guidance
23
- exports.INSTRUCTION_SPLIT = /\.\s+/;
20
+ export const INSTRUCTION_SPLIT = /\.\s+/;
@@ -1,9 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runtimeEstimateTokens = runtimeEstimateTokens;
4
- const parser_js_1 = require("../ofs/parser.js");
5
- const spec_estimator_js_1 = require("./spec-estimator.js");
6
- const estimator_js_1 = require("./estimator.js");
1
+ import { parseFormatSpecs } from '../ofs/parser.js';
2
+ import { estimateFormatSpecsTokens } from './spec-estimator.js';
3
+ import { estimateTextTokens } from './estimator.js';
7
4
  /**
8
5
  * Estimate max_tokens for an LLM API call at runtime.
9
6
  *
@@ -19,7 +16,7 @@ const estimator_js_1 = require("./estimator.js");
19
16
  * @param params - Runtime estimation parameters
20
17
  * @returns Token estimate with breakdown
21
18
  */
22
- function runtimeEstimateTokens(params) {
19
+ export function runtimeEstimateTokens(params) {
23
20
  const { prompt = '', context = '', instructions = '' } = params;
24
21
  const opts = {
25
22
  includeOptional: params.options?.includeOptional ?? true,
@@ -31,14 +28,14 @@ function runtimeEstimateTokens(params) {
31
28
  additionalOverhead: params.options?.additionalOverhead ?? 0
32
29
  };
33
30
  // Extract format specs from instructions (only output format is used at runtime)
34
- const formatSpecs = (0, parser_js_1.parseFormatSpecs)(instructions);
31
+ const formatSpecs = parseFormatSpecs(instructions);
35
32
  // Estimate tokens for each component
36
- const promptTokens = opts.estimatePrompt ? (0, estimator_js_1.estimateTextTokens)(prompt) : 0;
37
- const contextTokens = opts.estimateContext ? (0, estimator_js_1.estimateTextTokens)(context) : 0;
38
- const instructionsTokens = opts.estimateInstructions ? (0, estimator_js_1.estimateTextTokens)(instructions) : 0;
33
+ const promptTokens = opts.estimatePrompt ? estimateTextTokens(prompt) : 0;
34
+ const contextTokens = opts.estimateContext ? estimateTextTokens(context) : 0;
35
+ const instructionsTokens = opts.estimateInstructions ? estimateTextTokens(instructions) : 0;
39
36
  // Estimate output tokens from output format spec (input format is for planning only)
40
37
  const outputEstimate = formatSpecs.output
41
- ? (0, spec_estimator_js_1.estimateFormatSpecsTokens)(undefined, formatSpecs.output, {
38
+ ? estimateFormatSpecsTokens(undefined, formatSpecs.output, {
42
39
  includeOptional: opts.includeOptional,
43
40
  safetyMultiplier: 1.0, // Don't apply safety multiplier here, apply at the end
44
41
  strategy: opts.strategy
@@ -1,19 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.analyzeSpec = analyzeSpec;
4
- exports.formatSmartReport = formatSmartReport;
5
- const compliance_js_1 = require("./compliance.js");
6
- const cognitive_cost_js_1 = require("./cognitive-cost.js");
7
- const confidence_js_1 = require("./confidence.js");
8
- const spec_estimator_js_1 = require("./spec-estimator.js");
1
+ import { checkSpecCompliance } from './compliance.js';
2
+ import { calculateCognitiveCost } from './cognitive-cost.js';
3
+ import { calculateConfidence } from './confidence.js';
4
+ import { estimateSpecTokens } from './spec-estimator.js';
9
5
  /**
10
6
  * Comprehensive smart analysis of spec
11
7
  */
12
- function analyzeSpec(spec, targetLevel = 2) {
13
- const compliance = (0, compliance_js_1.checkSpecCompliance)(spec, targetLevel);
14
- const cognitiveCost = (0, cognitive_cost_js_1.calculateCognitiveCost)(spec);
15
- const confidence = (0, confidence_js_1.calculateConfidence)(spec);
16
- const tokenEstimate = (0, spec_estimator_js_1.estimateSpecTokens)(spec);
8
+ export function analyzeSpec(spec, targetLevel = 2) {
9
+ const compliance = checkSpecCompliance(spec, targetLevel);
10
+ const cognitiveCost = calculateCognitiveCost(spec);
11
+ const confidence = calculateConfidence(spec);
12
+ const tokenEstimate = estimateSpecTokens(spec);
17
13
  const recommendations = generateSmartRecommendations(compliance, cognitiveCost, confidence, tokenEstimate);
18
14
  return {
19
15
  spec,
@@ -85,7 +81,7 @@ function generateSmartRecommendations(compliance, cost, confidence, estimate) {
85
81
  /**
86
82
  * Format comprehensive smart report
87
83
  */
88
- function formatSmartReport(analysis) {
84
+ export function formatSmartReport(analysis) {
89
85
  const lines = [];
90
86
  lines.push('╔═══════════════════════════════════════════════════╗');
91
87
  lines.push('║ FLEX-MD SMART ANALYSIS REPORT ║');
@@ -1,11 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.estimateSpecTokens = estimateSpecTokens;
4
- exports.estimateInputSpecTokens = estimateInputSpecTokens;
5
- exports.estimateFormatSpecsTokens = estimateFormatSpecsTokens;
6
- const parser_js_1 = require("./parser.js");
7
- const estimator_js_1 = require("./estimator.js");
8
- function estimateSpecTokens(spec, options = {}) {
1
+ import { parseSystemPart } from './parser.js';
2
+ import { estimateTokens, getFallbackEstimate, TOKEN_CONSTANTS } from './estimator.js';
3
+ export function estimateSpecTokens(spec, options = {}) {
9
4
  const { includeOptional = true, safetyMultiplier = 1.2, strategy = 'average' } = options;
10
5
  const bySectionName = {};
11
6
  let totalEstimated = 0;
@@ -17,13 +12,13 @@ function estimateSpecTokens(spec, options = {}) {
17
12
  if (!includeOptional && !isRequired)
18
13
  continue;
19
14
  const kind = section.kind || 'text';
20
- const systemPart = (0, parser_js_1.parseSystemPart)(section.instruction, kind);
15
+ const systemPart = parseSystemPart(section.instruction, kind);
21
16
  let estimate;
22
17
  if (systemPart) {
23
- estimate = (0, estimator_js_1.estimateTokens)(systemPart);
18
+ estimate = estimateTokens(systemPart);
24
19
  }
25
20
  else {
26
- estimate = (0, estimator_js_1.getFallbackEstimate)(kind, isRequired);
21
+ estimate = getFallbackEstimate(kind, isRequired);
27
22
  }
28
23
  // Apply optional section discount
29
24
  if (!isRequired) {
@@ -40,8 +35,8 @@ function estimateSpecTokens(spec, options = {}) {
40
35
  totalMax += estimate.max;
41
36
  }
42
37
  // Add overhead
43
- const overhead = estimator_js_1.TOKEN_CONSTANTS.baseOverhead +
44
- (spec.sections.length * estimator_js_1.TOKEN_CONSTANTS.headingOverhead);
38
+ const overhead = TOKEN_CONSTANTS.baseOverhead +
39
+ (spec.sections.length * TOKEN_CONSTANTS.headingOverhead);
45
40
  totalEstimated += overhead;
46
41
  totalMin += overhead;
47
42
  totalMax += overhead;
@@ -75,7 +70,7 @@ function estimateSpecTokens(spec, options = {}) {
75
70
  * Estimate tokens for an Input Format Spec.
76
71
  * Uses the same logic as output format estimation.
77
72
  */
78
- function estimateInputSpecTokens(spec, options = {}) {
73
+ export function estimateInputSpecTokens(spec, options = {}) {
79
74
  // Input format uses the same structure as output format, so reuse the same logic
80
75
  const outputSpec = {
81
76
  ...spec,
@@ -87,7 +82,7 @@ function estimateInputSpecTokens(spec, options = {}) {
87
82
  * Estimate tokens for both input and output format specs.
88
83
  * Combines estimates from both if present.
89
84
  */
90
- function estimateFormatSpecsTokens(inputSpec, outputSpec, options = {}) {
85
+ export function estimateFormatSpecsTokens(inputSpec, outputSpec, options = {}) {
91
86
  const inputEstimate = inputSpec ? estimateInputSpecTokens(inputSpec, options) : null;
92
87
  const outputEstimate = outputSpec ? estimateSpecTokens(outputSpec, options) : null;
93
88
  // If only one is present, return it
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateSystemParts = validateSystemParts;
4
- const parser_js_1 = require("./parser.js");
5
- function validateSystemParts(spec) {
1
+ import { parseSystemPart } from './parser.js';
2
+ export function validateSystemParts(spec) {
6
3
  const errors = [];
7
4
  const warnings = [];
8
5
  for (const section of spec.sections) {
@@ -17,7 +14,7 @@ function validateSystemParts(spec) {
17
14
  }
18
15
  continue;
19
16
  }
20
- const systemPart = (0, parser_js_1.parseSystemPart)(section.instruction, kind);
17
+ const systemPart = parseSystemPart(section.instruction, kind);
21
18
  if (!systemPart) {
22
19
  warnings.push({
23
20
  sectionName: section.name,
package/dist/types.js CHANGED
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,19 +1,15 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkCompliance = checkCompliance;
4
- exports.hasFlexMdContract = hasFlexMdContract;
5
- const parser_js_1 = require("../ofs/parser.js");
1
+ import { parseFormatSpecs } from "../ofs/parser.js";
6
2
  /**
7
3
  * Check if instructions meet the required flex-md compliance level.
8
4
  * Returns detailed results including what's missing or wrong.
9
5
  * Now also checks for Input Format Spec if present.
10
6
  */
11
- async function checkCompliance(instructions, complianceLevel) {
7
+ export async function checkCompliance(instructions, complianceLevel) {
12
8
  const issues = [];
13
9
  const suggestions = [];
14
10
  const lower = instructions.toLowerCase();
15
11
  // Extract both input and output format specs
16
- const formatSpecs = (0, parser_js_1.parseFormatSpecs)(instructions);
12
+ const formatSpecs = parseFormatSpecs(instructions);
17
13
  const hasInputFormat = !!formatSpecs.input;
18
14
  const hasOutputFormat = !!formatSpecs.output;
19
15
  const hasMarkdownMention = lower.includes("markdown");
@@ -97,7 +93,7 @@ async function checkCompliance(instructions, complianceLevel) {
97
93
  * Check if instructions meet the required flex-md compliance level.
98
94
  * @deprecated Use checkCompliance for detailed results.
99
95
  */
100
- async function hasFlexMdContract(instructions, complianceLevel) {
96
+ export async function hasFlexMdContract(instructions, complianceLevel) {
101
97
  const result = await checkCompliance(instructions, complianceLevel);
102
98
  return result.meetsCompliance;
103
99
  }
@@ -1,14 +1,11 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkConnection = checkConnection;
4
- const outline_js_1 = require("../md/outline.js");
5
- const parse_js_1 = require("../md/parse.js");
1
+ import { buildOutline } from "../md/outline.js";
2
+ import { normalizeName } from "../md/parse.js";
6
3
  /**
7
4
  * Checks if a specific key (section) is "connected" in the given markdown.
8
5
  */
9
- function checkConnection(md, key) {
10
- const outline = (0, outline_js_1.buildOutline)(md);
11
- const normKey = (0, parse_js_1.normalizeName)(key);
6
+ export function checkConnection(md, key) {
7
+ const outline = buildOutline(md);
8
+ const normKey = normalizeName(key);
12
9
  const path = [];
13
10
  // Breadth-first search for the key
14
11
  const queue = outline.nodes.map(n => ({ node: n, currentPath: [n.title] }));
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateMarkdownAgainstOfs = validateMarkdownAgainstOfs;
4
- const parse_js_1 = require("../md/parse.js");
1
+ import { extractFencedBlocks, parseHeadingsAndSections, normalizeName, isIssuesEnvelopeCheck } from "../md/parse.js";
5
2
  function enforcementToSeverity(e) {
6
3
  if (e === "ignore")
7
4
  return null;
@@ -35,19 +32,19 @@ function isRequiredSection(spec, level) {
35
32
  function stripToWorkingMarkdown(input, level) {
36
33
  if (level < 2)
37
34
  return { working: input, container: null };
38
- const fences = (0, parse_js_1.extractFencedBlocks)(input);
35
+ const fences = extractFencedBlocks(input);
39
36
  if (fences.length === 1) {
40
37
  const f = fences[0];
41
38
  return { working: f.content, container: { fence: f } };
42
39
  }
43
40
  return { working: input, container: null };
44
41
  }
45
- function validateMarkdownAgainstOfs(input, spec, level, policyOverride) {
42
+ export function validateMarkdownAgainstOfs(input, spec, level, policyOverride) {
46
43
  const policy = { ...defaultPolicy(level), ...(policyOverride ?? {}) };
47
44
  const issues = [];
48
- const fencesAll = (0, parse_js_1.extractFencedBlocks)(input);
45
+ const fencesAll = extractFencedBlocks(input);
49
46
  if (level === 0) {
50
- const env = (0, parse_js_1.isIssuesEnvelopeCheck)(input);
47
+ const env = isIssuesEnvelopeCheck(input);
51
48
  return {
52
49
  ok: true,
53
50
  level,
@@ -61,7 +58,7 @@ function validateMarkdownAgainstOfs(input, spec, level, policyOverride) {
61
58
  },
62
59
  };
63
60
  }
64
- const env = (0, parse_js_1.isIssuesEnvelopeCheck)(input);
61
+ const env = isIssuesEnvelopeCheck(input);
65
62
  if (env.isIssuesEnvelope) {
66
63
  issues.push({
67
64
  code: "ISSUES_ENVELOPE_PRESENT",
@@ -110,10 +107,10 @@ function validateMarkdownAgainstOfs(input, spec, level, policyOverride) {
110
107
  }
111
108
  }
112
109
  const { working } = stripToWorkingMarkdown(input, level);
113
- const parsed = (0, parse_js_1.parseHeadingsAndSections)(working);
110
+ const parsed = parseHeadingsAndSections(working);
114
111
  const specByNorm = new Map();
115
112
  for (const s of spec.sections)
116
- specByNorm.set((0, parse_js_1.normalizeName)(s.name), s);
113
+ specByNorm.set(normalizeName(s.name), s);
117
114
  const occurrences = new Map();
118
115
  const bodiesByNorm = {};
119
116
  for (const sec of parsed) {
@@ -128,7 +125,7 @@ function validateMarkdownAgainstOfs(input, spec, level, policyOverride) {
128
125
  const req = isRequiredSection(s, level);
129
126
  if (!req)
130
127
  continue;
131
- const norm = (0, parse_js_1.normalizeName)(s.name);
128
+ const norm = normalizeName(s.name);
132
129
  const count = occurrences.get(norm) ?? 0;
133
130
  if (count === 0) {
134
131
  missingRequired.push(s.name);
@@ -144,12 +141,12 @@ function validateMarkdownAgainstOfs(input, spec, level, policyOverride) {
144
141
  const req = isRequiredSection(s, level);
145
142
  if (!req)
146
143
  continue;
147
- const norm = (0, parse_js_1.normalizeName)(s.name);
144
+ const norm = normalizeName(s.name);
148
145
  const bodies = bodiesByNorm[norm] ?? [];
149
146
  if (!bodies.length)
150
147
  continue;
151
148
  const allEmpty = bodies.every(b => b.trim().length === 0);
152
- const allNone = bodies.every(b => (0, parse_js_1.normalizeName)(b) === (0, parse_js_1.normalizeName)(noneValue));
149
+ const allNone = bodies.every(b => normalizeName(b) === normalizeName(noneValue));
153
150
  const emptyByPolicy = allEmpty || (!policy.noneIsAcceptableContent && allNone);
154
151
  if (emptyByPolicy) {
155
152
  addIssue(issues, policy.emptyRequiredSection, {
@@ -173,14 +170,14 @@ function validateMarkdownAgainstOfs(input, spec, level, policyOverride) {
173
170
  }
174
171
  if (level >= 3) {
175
172
  for (const s of spec.sections) {
176
- const norm = (0, parse_js_1.normalizeName)(s.name);
173
+ const norm = normalizeName(s.name);
177
174
  const bodies = bodiesByNorm[norm] ?? [];
178
175
  if (!bodies.length)
179
176
  continue;
180
177
  const kind = s.kind ?? "text";
181
178
  for (const body of bodies) {
182
179
  const b = body.trim();
183
- if ((0, parse_js_1.normalizeName)(b) === (0, parse_js_1.normalizeName)(noneValue))
180
+ if (normalizeName(b) === normalizeName(noneValue))
184
181
  continue;
185
182
  if (kind === "text")
186
183
  continue;
@@ -214,9 +211,9 @@ function validateMarkdownAgainstOfs(input, spec, level, policyOverride) {
214
211
  });
215
212
  continue;
216
213
  }
217
- const cols = (s.columns ?? []).map(c => (0, parse_js_1.normalizeName)(c));
214
+ const cols = (s.columns ?? []).map(c => normalizeName(c));
218
215
  if (cols.length) {
219
- const headerNorm = table.header.map(c => (0, parse_js_1.normalizeName)(c));
216
+ const headerNorm = table.header.map(c => normalizeName(c));
220
217
  const missingCols = cols.filter(c => !headerNorm.includes(c));
221
218
  if (missingCols.length) {
222
219
  addIssue(issues, policy.malformedTable, {
@@ -227,7 +224,7 @@ function validateMarkdownAgainstOfs(input, spec, level, policyOverride) {
227
224
  }
228
225
  }
229
226
  if (kind === "ordered_table") {
230
- const header0 = (0, parse_js_1.normalizeName)(table.header[0] ?? "");
227
+ const header0 = normalizeName(table.header[0] ?? "");
231
228
  if (header0 !== "#") {
232
229
  addIssue(issues, policy.malformedOrderedTable, {
233
230
  code: "MALFORMED_ORDERED_TABLE",
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const index_js_1 = require("../index.cjs");
5
+ (0, vitest_1.describe)("Diagnostics", () => {
6
+ (0, vitest_1.describe)("checkCompliance", () => {
7
+ (0, vitest_1.it)("should return meetsCompliance: true for L0 if Markdown is mentioned", async () => {
8
+ const res = await (0, index_js_1.checkCompliance)("Reply in Markdown.", "L0");
9
+ (0, vitest_1.expect)(res.meetsCompliance).toBe(true);
10
+ (0, vitest_1.expect)(res.issues).toHaveLength(0);
11
+ });
12
+ (0, vitest_1.it)("should return issues for L2 if container is missing", async () => {
13
+ const res = await (0, index_js_1.checkCompliance)("Reply in Markdown. Include headings.", "L2");
14
+ (0, vitest_1.expect)(res.meetsCompliance).toBe(false);
15
+ (0, vitest_1.expect)(res.issues.some(i => i.type === "missing-container")).toBe(true);
16
+ });
17
+ (0, vitest_1.it)("should return false for hasFlexMdContract if requirements not met", async () => {
18
+ const ok = await (0, index_js_1.hasFlexMdContract)("Hello", "L0");
19
+ (0, vitest_1.expect)(ok).toBe(false);
20
+ });
21
+ });
22
+ (0, vitest_1.describe)("enrichInstructionsWithFlexMd", () => {
23
+ (0, vitest_1.it)("should append guidance to existing instructions", async () => {
24
+ const res = await (0, index_js_1.enrichInstructionsWithFlexMd)("Do a good job.", "L0");
25
+ (0, vitest_1.expect)(res.enriched).toContain("Do a good job.");
26
+ (0, vitest_1.expect)(res.enriched).toContain("Reply in Markdown.");
27
+ (0, vitest_1.expect)(res.changes).toHaveLength(1);
28
+ (0, vitest_1.expect)(res.metadata?.guidanceAdded).toBe(true);
29
+ });
30
+ (0, vitest_1.it)("should track container addition for L2", async () => {
31
+ const res = await (0, index_js_1.enrichInstructionsWithFlexMd)("Do a good job.", "L2");
32
+ (0, vitest_1.expect)(res.changes.some(c => c.type === "added-container")).toBe(true);
33
+ (0, vitest_1.expect)(res.metadata?.containerAdded).toBe(true);
34
+ });
35
+ });
36
+ (0, vitest_1.describe)("validateFormat", () => {
37
+ (0, vitest_1.it)("should validate a correct flex-md OFS", async () => {
38
+ const ofs = `## Output format\n- Summary — prose\n- Actions — list`;
39
+ const res = await (0, index_js_1.validateFormat)(ofs);
40
+ (0, vitest_1.expect)(res.valid).toBe(true);
41
+ (0, vitest_1.expect)(res.metadata?.sectionCount).toBe(2);
42
+ });
43
+ (0, vitest_1.it)("should return errors for missing heading", async () => {
44
+ const ofs = `- Summary — prose`;
45
+ const res = await (0, index_js_1.validateFormat)(ofs);
46
+ (0, vitest_1.expect)(res.valid).toBe(false);
47
+ (0, vitest_1.expect)(res.issues.some(i => i.type === "missing-heading")).toBe(true);
48
+ });
49
+ (0, vitest_1.it)("should validate JSON schema", async () => {
50
+ const schema = `{"type": "object"}`;
51
+ const res = await (0, index_js_1.validateFormat)(schema, "json-schema");
52
+ (0, vitest_1.expect)(res.valid).toBe(true);
53
+ });
54
+ (0, vitest_1.it)("should fail on invalid JSON schema", async () => {
55
+ const schema = `{"type": "object"`;
56
+ const res = await (0, index_js_1.validateFormat)(schema, "json-schema");
57
+ (0, vitest_1.expect)(res.valid).toBe(false);
58
+ (0, vitest_1.expect)(res.issues[0].type).toBe("syntax-error");
59
+ });
60
+ });
61
+ });