@utilix-tech/sdk 0.82.0 → 0.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  Full release notes for all Utilix surfaces (browser tools, REST API, SDKs, MCP server) live at [utilix.tech/changelog](https://utilix.tech/changelog). This file tracks just this package.
4
4
 
5
+ ## 0.84.0
6
+ - Add `findCronOverlaps` (cron-overlap-detector): walk minute-by-minute over a window of days and flag every minute where two or more cron schedules fire at once, listing which expressions collided.
7
+ - Add `lintDockerfile` (dockerfile-linter): lint a Dockerfile for an unpinned or `:latest` base image, a final stage missing WORKDIR or USER, and ADD used on a plain local file where COPY would do.
8
+
9
+ ## 0.83.0
10
+ - Add `extractMarkdownLinkReferences` (markdown-link-reference-extractor): extract reference-style Markdown links (`[text][ref]`, the `[text][]` shortcut, and `![alt][ref]` image references) and match them against their `[ref]: url` definitions, flagging unresolved references and unused definitions.
11
+ - Add `extractPromptTemplateVariables` (prompt-template-variable-extractor): extract `{{variable}}`-style placeholders from a prompt template, report occurrence counts, flag duplicates, and optionally cross-check against a list of provided variable names.
12
+
5
13
  ## 0.82.0
6
14
  - Add `generateRobotsTxt` (robots-txt-generator): build a robots.txt file from User-agent groups with Allow/Disallow rules and an optional Crawl-delay, plus a list of Sitemap URLs. The generator-side sibling of `validateRobotsTxt`.
7
15
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @utilix-tech/sdk
2
2
 
3
- **716 developer utility functions for Node.js: runs locally, no API key required.**
3
+ **721 developer utility functions for Node.js: runs locally, no API key required.**
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@utilix-tech/sdk?style=flat-square&color=cb3837)](https://www.npmjs.com/package/@utilix-tech/sdk)
6
6
  [![npm downloads](https://img.shields.io/npm/dm/@utilix-tech/sdk?style=flat-square)](https://www.npmjs.com/package/@utilix-tech/sdk)
@@ -877,6 +877,11 @@ extractMarkdownFootnotes("A claim[^1].\n\n[^1]: The source.");
877
877
  import { validateAria } from "@utilix-tech/sdk/code";
878
878
  validateAria('<div role="checkbox">Opt in</div>');
879
879
  // { elementCount: 1, elementsWithRoleOrAria: 1, valid: false, issues: [{ severity: "error", message: 'role="checkbox" is missing required attribute aria-checked', ... }] }
880
+
881
+ // Extract reference-style Markdown links ([text][ref], [text][], ![alt][ref]) and match them against [ref]: url definitions
882
+ import { extractMarkdownLinkReferences } from "@utilix-tech/sdk/code";
883
+ extractMarkdownLinkReferences("See the [docs][api-ref].\n\n[api-ref]: https://example.com/api \"API Reference\"");
884
+ // { referenceCount: 1, definitionCount: 1, resolved: [{ text: "docs", label: "api-ref", image: false, url: "https://example.com/api", title: "API Reference" }], unresolvedReferences: [], unusedDefinitions: [] }
880
885
  ```
881
886
 
882
887
  ---
@@ -1050,11 +1055,11 @@ readMidiInfo(new Uint8Array(midiBytes));
1050
1055
  | `@utilix-tech/sdk/units` | Bytes, CSS px/rem, number bases, currency format, credit card/IBAN/barcode/ISBN/VIN/ISIN validation, loan calculator, EMI calculator, compound/simple interest calculators, VAT/sales tax calculator, tip/bill split calculator, break-even point calculator, Rule of 72 calculator, savings goal calculator, ROI calculator, cash denomination/till calculator, payback period calculator, CD maturity calculator, debt-to-income ratio calculator, freelancer hourly rate calculator, debt snowball/avalanche payoff planner, tax-equivalent yield calculator, mortgage discount points break-even calculator, loan prepayment penalty calculator, data transfer time / required bandwidth estimator, real rate of return (Fisher equation) calculator |
1051
1056
  | `@utilix-tech/sdk/network` | HTTP status codes, IP validation, country flags, geolocation URLs, HAR file parsing, User-Agent parsing, IPv6 address compress/expand, Permissions-Policy header builder, Client Hints header builder/parser, Content-Disposition header builder/parser, X-Content-Type-Options header builder/risk assessor, sitemap.xml validator, sitemap index splitter, robots.txt validator, robots.txt generator, Prefer header builder/parser (RFC 7240), Retry-After header builder/parser (RFC 9110), Priority header builder/parser (RFC 9218), WebSocket close code reference/lookup, Strict-Transport-Security (HSTS) header builder/parser, X-Robots-Tag header builder/parser, WebSocket frame opcode reference/lookup, robots meta tag builder/parser, Cookie header byte-size budget calculator |
1052
1057
  | `@utilix-tech/sdk/api` | cURL build/parse, JWT decode/sign, JWKS parse, CORS headers, CSP header, TOTP/HOTP code generator, webhook HMAC signature verifier |
1053
- | `@utilix-tech/sdk/code` | SQL format/minify, HTML format/minify, regex tester, GraphQL format, MIME type lookup, GitHub URL parsing, regex ReDoS detector, Conventional Commits linter, package.json exports field validator, package.json dependency range auditor, regex capture group/backreference visualizer, SVG sprite symbol extractor, ARIA role & attribute validator, database connection string parser, Markdown code fence language tag validator, SQL query parameter placeholder counter |
1058
+ | `@utilix-tech/sdk/code` | SQL format/minify, HTML format/minify, regex tester, GraphQL format, MIME type lookup, GitHub URL parsing, regex ReDoS detector, Conventional Commits linter, package.json exports field validator, package.json dependency range auditor, regex capture group/backreference visualizer, SVG sprite symbol extractor, ARIA role & attribute validator, database connection string parser, Markdown code fence language tag validator, SQL query parameter placeholder counter, Markdown link reference extractor |
1054
1059
  | `@utilix-tech/sdk/color` | Hex/RGB/HSL/HSV/CMYK convert, palette generation, contrast check |
1055
1060
  | `@utilix-tech/sdk/css` | CSS gradient, box-shadow, border-radius, keyframe animation generators |
1056
1061
  | `@utilix-tech/sdk/misc` | SVG optimize/sanitize, file size format, Unicode inspector |
1057
- | `@utilix-tech/sdk/ai_agent` | Token estimate/trim, chunk text, extract URLs/JSON/keywords, sanitize HTML, flatten/merge JSON, dedupe lines, validate schema, PII/secret/injection detect, vector similarity, few-shot prompt formatter, tool-definition schema linter, retry/backoff schedule calculator |
1062
+ | `@utilix-tech/sdk/ai_agent` | Token estimate/trim, chunk text, extract URLs/JSON/keywords, sanitize HTML, flatten/merge JSON, dedupe lines, validate schema, PII/secret/injection detect, vector similarity, few-shot prompt formatter, tool-definition schema linter, retry/backoff schedule calculator, prompt template variable extractor |
1058
1063
  | `@utilix-tech/sdk/media` | Image format & dimension reading from raw bytes (PNG, JPEG, GIF, WebP, BMP); PDF metadata reading; PDF page dimension/orientation listing; WAV audio info; ID3 tags; ICO favicon inspection; FLAC metadata reading; MP4/WebM video info; GIF frame/loop inspection |
1059
1064
 
1060
1065
  ---
@@ -409,6 +409,30 @@ interface RetryBackoffResult {
409
409
  declare function calculateRetryBackoffSchedule(input: RetryBackoffInput): RetryBackoffResult | {
410
410
  error: string;
411
411
  };
412
+ interface PromptTemplateVariable {
413
+ name: string;
414
+ count: number;
415
+ }
416
+ interface PromptTemplateVariableResult {
417
+ variableCount: number;
418
+ variables: PromptTemplateVariable[];
419
+ duplicates: string[];
420
+ missing: string[];
421
+ unused: string[];
422
+ }
423
+ /**
424
+ * Extract every {{variable}}-style placeholder from a prompt template,
425
+ * reporting each unique variable's occurrence count and flagging ones used
426
+ * more than once. When providedVars is given, also cross-checks the
427
+ * template against it: variables the template uses but providedVars is
428
+ * missing, and names in providedVars the template never references. Only
429
+ * double-curly {{name}} syntax is recognized (dotted/dashed names like
430
+ * {{user.name}} are allowed); single-brace, triple-brace, and Jinja-style
431
+ * {% %} tags are out of scope.
432
+ */
433
+ declare function extractPromptTemplateVariables(template: string, providedVars?: string[]): PromptTemplateVariableResult | {
434
+ error: string;
435
+ };
412
436
 
413
437
  type ai_agent_ChunkStrategy = ChunkStrategy;
414
438
  type ai_agent_CompressHtmlResult = CompressHtmlResult;
@@ -440,6 +464,8 @@ type ai_agent_ModelPricing = ModelPricing;
440
464
  type ai_agent_PiiDetectResult = PiiDetectResult;
441
465
  type ai_agent_PiiFinding = PiiFinding;
442
466
  type ai_agent_PiiType = PiiType;
467
+ type ai_agent_PromptTemplateVariable = PromptTemplateVariable;
468
+ type ai_agent_PromptTemplateVariableResult = PromptTemplateVariableResult;
443
469
  type ai_agent_RankedChunk = RankedChunk;
444
470
  type ai_agent_RelevanceResult = RelevanceResult;
445
471
  type ai_agent_RetryBackoffAttempt = RetryBackoffAttempt;
@@ -479,6 +505,7 @@ declare const ai_agent_expandQuery: typeof expandQuery;
479
505
  declare const ai_agent_extractEntities: typeof extractEntities;
480
506
  declare const ai_agent_extractJson: typeof extractJson;
481
507
  declare const ai_agent_extractKeywords: typeof extractKeywords;
508
+ declare const ai_agent_extractPromptTemplateVariables: typeof extractPromptTemplateVariables;
482
509
  declare const ai_agent_extractTables: typeof extractTables;
483
510
  declare const ai_agent_extractUrls: typeof extractUrls;
484
511
  declare const ai_agent_flattenJson: typeof flattenJson;
@@ -496,7 +523,7 @@ declare const ai_agent_unflattenJson: typeof unflattenJson;
496
523
  declare const ai_agent_validateJsonSchema: typeof validateJsonSchema;
497
524
  declare const ai_agent_vectorSimilarity: typeof vectorSimilarity;
498
525
  declare namespace ai_agent {
499
- export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_FewShotExample as FewShotExample, type ai_agent_FewShotFormat as FewShotFormat, type ai_agent_FewShotFormatResult as FewShotFormatResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_RetryBackoffAttempt as RetryBackoffAttempt, type ai_agent_RetryBackoffInput as RetryBackoffInput, type ai_agent_RetryBackoffResult as RetryBackoffResult, type ai_agent_RetryJitterMode as RetryJitterMode, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_ToolSchemaIssue as ToolSchemaIssue, type ai_agent_ToolSchemaLintResult as ToolSchemaLintResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, type ai_agent_VectorSimilarityResult as VectorSimilarityResult, ai_agent_calculateRetryBackoffSchedule as calculateRetryBackoffSchedule, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_formatFewShotExamples as formatFewShotExamples, ai_agent_lintToolSchema as lintToolSchema, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema, ai_agent_vectorSimilarity as vectorSimilarity };
526
+ export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_FewShotExample as FewShotExample, type ai_agent_FewShotFormat as FewShotFormat, type ai_agent_FewShotFormatResult as FewShotFormatResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_PromptTemplateVariable as PromptTemplateVariable, type ai_agent_PromptTemplateVariableResult as PromptTemplateVariableResult, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_RetryBackoffAttempt as RetryBackoffAttempt, type ai_agent_RetryBackoffInput as RetryBackoffInput, type ai_agent_RetryBackoffResult as RetryBackoffResult, type ai_agent_RetryJitterMode as RetryJitterMode, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_ToolSchemaIssue as ToolSchemaIssue, type ai_agent_ToolSchemaLintResult as ToolSchemaLintResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, type ai_agent_VectorSimilarityResult as VectorSimilarityResult, ai_agent_calculateRetryBackoffSchedule as calculateRetryBackoffSchedule, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractPromptTemplateVariables as extractPromptTemplateVariables, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_formatFewShotExamples as formatFewShotExamples, ai_agent_lintToolSchema as lintToolSchema, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema, ai_agent_vectorSimilarity as vectorSimilarity };
500
527
  }
501
528
 
502
- export { type VectorSimilarityResult as $, type RetryJitterMode as A, type SecretDetectResult as B, type ChunkStrategy as C, type DedupeResult as D, type Entity2 as E, type FewShotExample as F, type SecretFinding as G, type SecretType as H, type InjectionDetectResult as I, type JsonBlock as J, type Keyword as K, type SummaryResult as L, MODEL_PRICING as M, type TextChunk as N, type TokenEstimate as O, type PiiDetectResult as P, type TokenEstimateResult as Q, type RankedChunk as R, type SanitizeResult as S, type TableResult2 as T, type ToolSchemaIssue as U, type ToolSchemaLintResult as V, type TrimResult as W, type TrimStrategy as X, type UrlMatch as Y, type ValidationError as Z, type ValidationResult as _, ai_agent as a, calculateRetryBackoffSchedule as a0, chunkText as a1, compressHtml as a2, compressJson as a3, compressMarkdown as a4, deduplicateLines as a5, detectPii as a6, detectPromptInjection as a7, detectSecrets as a8, diffJson as a9, estimateCost as aa, estimateTokens as ab, expandQuery as ac, extractEntities as ad, extractJson as ae, extractKeywords as af, extractTables as ag, extractUrls as ah, flattenJson as ai, formatFewShotExamples as aj, lintToolSchema as ak, mergeJson as al, redactPii as am, repairJson as an, rerankChunks as ao, sanitizeHtml as ap, scoreRelevance as aq, summarizeForLlm as ar, trimToTokens as as, unflattenJson as at, validateJsonSchema as au, vectorSimilarity as av, type CompressHtmlResult as b, type CompressJsonResult as c, type CompressMarkdownResult as d, type CostEstimate as e, type DedupeStrategy as f, type DiffEntry2 as g, type DiffOp2 as h, type DiffResult2 as i, type EntityType2 as j, type ExtractJsonResult as k, type ExtractKeywordsResult as l, type ExtractUrlsResult as m, type FewShotFormat as n, type FewShotFormatResult as o, type InjectionFinding as p, type JsonRepairResult as q, type MergeResult as r, type MergeStrategy as s, type ModelPricing as t, type PiiFinding as u, type PiiType as v, type RelevanceResult as w, type RetryBackoffAttempt as x, type RetryBackoffInput as y, type RetryBackoffResult as z };
529
+ export { type ValidationError as $, type RetryBackoffInput as A, type RetryBackoffResult as B, type ChunkStrategy as C, type DedupeResult as D, type Entity2 as E, type FewShotExample as F, type RetryJitterMode as G, type SecretDetectResult as H, type InjectionDetectResult as I, type JsonBlock as J, type Keyword as K, type SecretFinding as L, MODEL_PRICING as M, type SecretType as N, type SummaryResult as O, type PiiDetectResult as P, type TextChunk as Q, type RankedChunk as R, type SanitizeResult as S, type TableResult2 as T, type TokenEstimate as U, type TokenEstimateResult as V, type ToolSchemaIssue as W, type ToolSchemaLintResult as X, type TrimResult as Y, type TrimStrategy as Z, type UrlMatch as _, ai_agent as a, type ValidationResult as a0, type VectorSimilarityResult as a1, calculateRetryBackoffSchedule as a2, chunkText as a3, compressHtml as a4, compressJson as a5, compressMarkdown as a6, deduplicateLines as a7, detectPii as a8, detectPromptInjection as a9, detectSecrets as aa, diffJson as ab, estimateCost as ac, estimateTokens as ad, expandQuery as ae, extractEntities as af, extractJson as ag, extractKeywords as ah, extractPromptTemplateVariables as ai, extractTables as aj, extractUrls as ak, flattenJson as al, formatFewShotExamples as am, lintToolSchema as an, mergeJson as ao, redactPii as ap, repairJson as aq, rerankChunks as ar, sanitizeHtml as as, scoreRelevance as at, summarizeForLlm as au, trimToTokens as av, unflattenJson as aw, validateJsonSchema as ax, vectorSimilarity as ay, type CompressHtmlResult as b, type CompressJsonResult as c, type CompressMarkdownResult as d, type CostEstimate as e, type DedupeStrategy as f, type DiffEntry2 as g, type DiffOp2 as h, type DiffResult2 as i, type EntityType2 as j, type ExtractJsonResult as k, type ExtractKeywordsResult as l, type ExtractUrlsResult as m, type FewShotFormat as n, type FewShotFormatResult as o, type InjectionFinding as p, type JsonRepairResult as q, type MergeResult as r, type MergeStrategy as s, type ModelPricing as t, type PiiFinding as u, type PiiType as v, type PromptTemplateVariable as w, type PromptTemplateVariableResult as x, type RelevanceResult as y, type RetryBackoffAttempt as z };
@@ -409,6 +409,30 @@ interface RetryBackoffResult {
409
409
  declare function calculateRetryBackoffSchedule(input: RetryBackoffInput): RetryBackoffResult | {
410
410
  error: string;
411
411
  };
412
+ interface PromptTemplateVariable {
413
+ name: string;
414
+ count: number;
415
+ }
416
+ interface PromptTemplateVariableResult {
417
+ variableCount: number;
418
+ variables: PromptTemplateVariable[];
419
+ duplicates: string[];
420
+ missing: string[];
421
+ unused: string[];
422
+ }
423
+ /**
424
+ * Extract every {{variable}}-style placeholder from a prompt template,
425
+ * reporting each unique variable's occurrence count and flagging ones used
426
+ * more than once. When providedVars is given, also cross-checks the
427
+ * template against it: variables the template uses but providedVars is
428
+ * missing, and names in providedVars the template never references. Only
429
+ * double-curly {{name}} syntax is recognized (dotted/dashed names like
430
+ * {{user.name}} are allowed); single-brace, triple-brace, and Jinja-style
431
+ * {% %} tags are out of scope.
432
+ */
433
+ declare function extractPromptTemplateVariables(template: string, providedVars?: string[]): PromptTemplateVariableResult | {
434
+ error: string;
435
+ };
412
436
 
413
437
  type ai_agent_ChunkStrategy = ChunkStrategy;
414
438
  type ai_agent_CompressHtmlResult = CompressHtmlResult;
@@ -440,6 +464,8 @@ type ai_agent_ModelPricing = ModelPricing;
440
464
  type ai_agent_PiiDetectResult = PiiDetectResult;
441
465
  type ai_agent_PiiFinding = PiiFinding;
442
466
  type ai_agent_PiiType = PiiType;
467
+ type ai_agent_PromptTemplateVariable = PromptTemplateVariable;
468
+ type ai_agent_PromptTemplateVariableResult = PromptTemplateVariableResult;
443
469
  type ai_agent_RankedChunk = RankedChunk;
444
470
  type ai_agent_RelevanceResult = RelevanceResult;
445
471
  type ai_agent_RetryBackoffAttempt = RetryBackoffAttempt;
@@ -479,6 +505,7 @@ declare const ai_agent_expandQuery: typeof expandQuery;
479
505
  declare const ai_agent_extractEntities: typeof extractEntities;
480
506
  declare const ai_agent_extractJson: typeof extractJson;
481
507
  declare const ai_agent_extractKeywords: typeof extractKeywords;
508
+ declare const ai_agent_extractPromptTemplateVariables: typeof extractPromptTemplateVariables;
482
509
  declare const ai_agent_extractTables: typeof extractTables;
483
510
  declare const ai_agent_extractUrls: typeof extractUrls;
484
511
  declare const ai_agent_flattenJson: typeof flattenJson;
@@ -496,7 +523,7 @@ declare const ai_agent_unflattenJson: typeof unflattenJson;
496
523
  declare const ai_agent_validateJsonSchema: typeof validateJsonSchema;
497
524
  declare const ai_agent_vectorSimilarity: typeof vectorSimilarity;
498
525
  declare namespace ai_agent {
499
- export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_FewShotExample as FewShotExample, type ai_agent_FewShotFormat as FewShotFormat, type ai_agent_FewShotFormatResult as FewShotFormatResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_RetryBackoffAttempt as RetryBackoffAttempt, type ai_agent_RetryBackoffInput as RetryBackoffInput, type ai_agent_RetryBackoffResult as RetryBackoffResult, type ai_agent_RetryJitterMode as RetryJitterMode, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_ToolSchemaIssue as ToolSchemaIssue, type ai_agent_ToolSchemaLintResult as ToolSchemaLintResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, type ai_agent_VectorSimilarityResult as VectorSimilarityResult, ai_agent_calculateRetryBackoffSchedule as calculateRetryBackoffSchedule, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_formatFewShotExamples as formatFewShotExamples, ai_agent_lintToolSchema as lintToolSchema, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema, ai_agent_vectorSimilarity as vectorSimilarity };
526
+ export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_FewShotExample as FewShotExample, type ai_agent_FewShotFormat as FewShotFormat, type ai_agent_FewShotFormatResult as FewShotFormatResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_PromptTemplateVariable as PromptTemplateVariable, type ai_agent_PromptTemplateVariableResult as PromptTemplateVariableResult, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_RetryBackoffAttempt as RetryBackoffAttempt, type ai_agent_RetryBackoffInput as RetryBackoffInput, type ai_agent_RetryBackoffResult as RetryBackoffResult, type ai_agent_RetryJitterMode as RetryJitterMode, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_ToolSchemaIssue as ToolSchemaIssue, type ai_agent_ToolSchemaLintResult as ToolSchemaLintResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, type ai_agent_VectorSimilarityResult as VectorSimilarityResult, ai_agent_calculateRetryBackoffSchedule as calculateRetryBackoffSchedule, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractPromptTemplateVariables as extractPromptTemplateVariables, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_formatFewShotExamples as formatFewShotExamples, ai_agent_lintToolSchema as lintToolSchema, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema, ai_agent_vectorSimilarity as vectorSimilarity };
500
527
  }
501
528
 
502
- export { type VectorSimilarityResult as $, type RetryJitterMode as A, type SecretDetectResult as B, type ChunkStrategy as C, type DedupeResult as D, type Entity2 as E, type FewShotExample as F, type SecretFinding as G, type SecretType as H, type InjectionDetectResult as I, type JsonBlock as J, type Keyword as K, type SummaryResult as L, MODEL_PRICING as M, type TextChunk as N, type TokenEstimate as O, type PiiDetectResult as P, type TokenEstimateResult as Q, type RankedChunk as R, type SanitizeResult as S, type TableResult2 as T, type ToolSchemaIssue as U, type ToolSchemaLintResult as V, type TrimResult as W, type TrimStrategy as X, type UrlMatch as Y, type ValidationError as Z, type ValidationResult as _, ai_agent as a, calculateRetryBackoffSchedule as a0, chunkText as a1, compressHtml as a2, compressJson as a3, compressMarkdown as a4, deduplicateLines as a5, detectPii as a6, detectPromptInjection as a7, detectSecrets as a8, diffJson as a9, estimateCost as aa, estimateTokens as ab, expandQuery as ac, extractEntities as ad, extractJson as ae, extractKeywords as af, extractTables as ag, extractUrls as ah, flattenJson as ai, formatFewShotExamples as aj, lintToolSchema as ak, mergeJson as al, redactPii as am, repairJson as an, rerankChunks as ao, sanitizeHtml as ap, scoreRelevance as aq, summarizeForLlm as ar, trimToTokens as as, unflattenJson as at, validateJsonSchema as au, vectorSimilarity as av, type CompressHtmlResult as b, type CompressJsonResult as c, type CompressMarkdownResult as d, type CostEstimate as e, type DedupeStrategy as f, type DiffEntry2 as g, type DiffOp2 as h, type DiffResult2 as i, type EntityType2 as j, type ExtractJsonResult as k, type ExtractKeywordsResult as l, type ExtractUrlsResult as m, type FewShotFormat as n, type FewShotFormatResult as o, type InjectionFinding as p, type JsonRepairResult as q, type MergeResult as r, type MergeStrategy as s, type ModelPricing as t, type PiiFinding as u, type PiiType as v, type RelevanceResult as w, type RetryBackoffAttempt as x, type RetryBackoffInput as y, type RetryBackoffResult as z };
529
+ export { type ValidationError as $, type RetryBackoffInput as A, type RetryBackoffResult as B, type ChunkStrategy as C, type DedupeResult as D, type Entity2 as E, type FewShotExample as F, type RetryJitterMode as G, type SecretDetectResult as H, type InjectionDetectResult as I, type JsonBlock as J, type Keyword as K, type SecretFinding as L, MODEL_PRICING as M, type SecretType as N, type SummaryResult as O, type PiiDetectResult as P, type TextChunk as Q, type RankedChunk as R, type SanitizeResult as S, type TableResult2 as T, type TokenEstimate as U, type TokenEstimateResult as V, type ToolSchemaIssue as W, type ToolSchemaLintResult as X, type TrimResult as Y, type TrimStrategy as Z, type UrlMatch as _, ai_agent as a, type ValidationResult as a0, type VectorSimilarityResult as a1, calculateRetryBackoffSchedule as a2, chunkText as a3, compressHtml as a4, compressJson as a5, compressMarkdown as a6, deduplicateLines as a7, detectPii as a8, detectPromptInjection as a9, detectSecrets as aa, diffJson as ab, estimateCost as ac, estimateTokens as ad, expandQuery as ae, extractEntities as af, extractJson as ag, extractKeywords as ah, extractPromptTemplateVariables as ai, extractTables as aj, extractUrls as ak, flattenJson as al, formatFewShotExamples as am, lintToolSchema as an, mergeJson as ao, redactPii as ap, repairJson as aq, rerankChunks as ar, sanitizeHtml as as, scoreRelevance as at, summarizeForLlm as au, trimToTokens as av, unflattenJson as aw, validateJsonSchema as ax, vectorSimilarity as ay, type CompressHtmlResult as b, type CompressJsonResult as c, type CompressMarkdownResult as d, type CostEstimate as e, type DedupeStrategy as f, type DiffEntry2 as g, type DiffOp2 as h, type DiffResult2 as i, type EntityType2 as j, type ExtractJsonResult as k, type ExtractKeywordsResult as l, type ExtractUrlsResult as m, type FewShotFormat as n, type FewShotFormatResult as o, type InjectionFinding as p, type JsonRepairResult as q, type MergeResult as r, type MergeStrategy as s, type ModelPricing as t, type PiiFinding as u, type PiiType as v, type PromptTemplateVariable as w, type PromptTemplateVariableResult as x, type RelevanceResult as y, type RetryBackoffAttempt as z };
@@ -20,6 +20,7 @@ __export(ai_agent_exports, {
20
20
  extractEntities: () => extractEntities,
21
21
  extractJson: () => extractJson,
22
22
  extractKeywords: () => extractKeywords,
23
+ extractPromptTemplateVariables: () => extractPromptTemplateVariables,
23
24
  extractTables: () => extractTables,
24
25
  extractUrls: () => extractUrls,
25
26
  flattenJson: () => flattenJson,
@@ -1173,5 +1174,44 @@ function calculateRetryBackoffSchedule(input) {
1173
1174
  totalWorstCaseMs: round0(totalWorstCaseMs)
1174
1175
  };
1175
1176
  }
1177
+ var PROMPT_TEMPLATE_VARIABLE_REGEX = /\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g;
1178
+ function extractPromptTemplateVariables(template, providedVars) {
1179
+ const trimmed = template.trim();
1180
+ if (!trimmed) return { error: "Empty input" };
1181
+ const order = [];
1182
+ const counts = /* @__PURE__ */ new Map();
1183
+ for (const m of template.matchAll(PROMPT_TEMPLATE_VARIABLE_REGEX)) {
1184
+ const name = m[1];
1185
+ if (!counts.has(name)) {
1186
+ counts.set(name, 0);
1187
+ order.push(name);
1188
+ }
1189
+ counts.set(name, (counts.get(name) ?? 0) + 1);
1190
+ }
1191
+ if (order.length === 0) return { error: "No {{variable}} placeholders found" };
1192
+ const variables = order.map((name) => ({ name, count: counts.get(name) ?? 0 }));
1193
+ const duplicates = order.filter((name) => (counts.get(name) ?? 0) > 1);
1194
+ let missing = [];
1195
+ const unused = [];
1196
+ if (providedVars !== void 0) {
1197
+ const providedSet = new Set(providedVars.map((v) => v.trim()).filter(Boolean));
1198
+ const usedSet = new Set(order);
1199
+ missing = order.filter((name) => !providedSet.has(name));
1200
+ const seenProvided = /* @__PURE__ */ new Set();
1201
+ for (const raw of providedVars) {
1202
+ const v = raw.trim();
1203
+ if (!v || usedSet.has(v) || seenProvided.has(v)) continue;
1204
+ seenProvided.add(v);
1205
+ unused.push(v);
1206
+ }
1207
+ }
1208
+ return {
1209
+ variableCount: order.length,
1210
+ variables,
1211
+ duplicates,
1212
+ missing,
1213
+ unused
1214
+ };
1215
+ }
1176
1216
 
1177
- export { MODEL_PRICING, ai_agent_exports, calculateRetryBackoffSchedule, chunkText, compressHtml, compressJson, compressMarkdown, deduplicateLines, detectPii, detectPromptInjection, detectSecrets, diffJson, estimateCost, estimateTokens, expandQuery, extractEntities, extractJson, extractKeywords, extractTables, extractUrls, flattenJson, formatFewShotExamples, lintToolSchema, mergeJson, redactPii, repairJson, rerankChunks, sanitizeHtml, scoreRelevance, summarizeForLlm, trimToTokens, unflattenJson, validateJsonSchema, vectorSimilarity };
1217
+ export { MODEL_PRICING, ai_agent_exports, calculateRetryBackoffSchedule, chunkText, compressHtml, compressJson, compressMarkdown, deduplicateLines, detectPii, detectPromptInjection, detectSecrets, diffJson, estimateCost, estimateTokens, expandQuery, extractEntities, extractJson, extractKeywords, extractPromptTemplateVariables, extractTables, extractUrls, flattenJson, formatFewShotExamples, lintToolSchema, mergeJson, redactPii, repairJson, rerankChunks, sanitizeHtml, scoreRelevance, summarizeForLlm, trimToTokens, unflattenJson, validateJsonSchema, vectorSimilarity };
@@ -8,6 +8,7 @@ __export(time_exports, {
8
8
  TIMEZONES: () => TIMEZONES,
9
9
  convertTime: () => convertTime,
10
10
  diffDates: () => diffDates,
11
+ findCronOverlaps: () => findCronOverlaps,
11
12
  formatInTimezone: () => formatInTimezone,
12
13
  formatIso8601Duration: () => formatIso8601Duration,
13
14
  formatRelative: () => formatRelative,
@@ -683,6 +684,42 @@ function getRunInterval(dates) {
683
684
  const days = Math.round(diffMins / 1440);
684
685
  return `Every ${days} days`;
685
686
  }
687
+ var MAX_CRON_OVERLAPS = 200;
688
+ function findCronOverlaps(expressions, windowDays = 30, fromDate) {
689
+ if (expressions.length < 2) return { error: "Provide at least two cron expressions to check for overlaps" };
690
+ if (expressions.length > 10) return { error: "Provide 10 or fewer cron expressions" };
691
+ if (windowDays < 1 || windowDays > 365) return { error: "windowDays must be between 1 and 365" };
692
+ const parsedList = [];
693
+ for (let i = 0; i < expressions.length; i++) {
694
+ const parsed = parseCronExpression(expressions[i]);
695
+ if (typeof parsed === "object" && "error" in parsed) {
696
+ return { error: `Expression ${i + 1} ("${expressions[i]}"): ${parsed.error}` };
697
+ }
698
+ parsedList.push(parsed);
699
+ }
700
+ const start = fromDate ? new Date(fromDate) : /* @__PURE__ */ new Date();
701
+ const cursor = new Date(start);
702
+ cursor.setSeconds(0, 0);
703
+ cursor.setMinutes(cursor.getMinutes() + 1);
704
+ const endTime = cursor.getTime() + windowDays * 24 * 60 * 60 * 1e3;
705
+ const overlaps = [];
706
+ let truncated = false;
707
+ while (cursor.getTime() < endTime) {
708
+ const matched = [];
709
+ for (let i = 0; i < parsedList.length; i++) {
710
+ if (matchesCron(cursor, parsedList[i])) matched.push(i);
711
+ }
712
+ if (matched.length >= 2) {
713
+ if (overlaps.length >= MAX_CRON_OVERLAPS) {
714
+ truncated = true;
715
+ break;
716
+ }
717
+ overlaps.push({ date: new Date(cursor), expressionIndexes: matched });
718
+ }
719
+ cursor.setMinutes(cursor.getMinutes() + 1);
720
+ }
721
+ return { overlaps, windowDays, truncated };
722
+ }
686
723
  var DURATION_SECONDS_PER_YEAR = 365 * 86400;
687
724
  var DURATION_SECONDS_PER_MONTH = 30 * 86400;
688
725
  function humanizeDurationParts(parts) {
@@ -775,4 +812,4 @@ function formatIso8601Duration(seconds) {
775
812
  };
776
813
  }
777
814
 
778
- export { COMMON_CRONS, COMMON_DATE_PRESETS, TIMEZONES, convertTime, diffDates, formatInTimezone, formatIso8601Duration, formatRelative, formatRunDate, fromIsoString, fromUnix, getAllZonesForTime, getNextRuns, getNow, getRunInterval, getTimezoneOffset, humanizeDiff, parseCron, parseCronExpression, parseDate, parseIso8601Duration, time_exports };
815
+ export { COMMON_CRONS, COMMON_DATE_PRESETS, TIMEZONES, convertTime, diffDates, findCronOverlaps, formatInTimezone, formatIso8601Duration, formatRelative, formatRunDate, fromIsoString, fromUnix, getAllZonesForTime, getNextRuns, getNow, getRunInterval, getTimezoneOffset, humanizeDiff, parseCron, parseCronExpression, parseDate, parseIso8601Duration, time_exports };
@@ -27,6 +27,7 @@ __export(code_exports, {
27
27
  envToExport: () => envToExport,
28
28
  envToJson: () => envToJson,
29
29
  extractMarkdownFootnotes: () => extractMarkdownFootnotes,
30
+ extractMarkdownLinkReferences: () => extractMarkdownLinkReferences,
30
31
  extractSvgSpriteSymbols: () => extractSvgSpriteSymbols,
31
32
  formatCss: () => formatCss,
32
33
  formatGql: () => formatGql,
@@ -38,6 +39,7 @@ __export(code_exports, {
38
39
  getMethodColor: () => getMethodColor,
39
40
  isValidTag: () => isValidTag,
40
41
  lintConventionalCommit: () => lintConventionalCommit,
42
+ lintDockerfile: () => lintDockerfile,
41
43
  lookupMime: () => lookupMime,
42
44
  minifyCss: () => minifyCss,
43
45
  minifyGql: () => minifyGql,
@@ -1868,6 +1870,111 @@ function normalizeRef(ref) {
1868
1870
  const tagPart = parsed.digest ? `@${parsed.digest}` : parsed.tag ? `:${parsed.tag}` : "";
1869
1871
  return `${parsed.registry}/${ns}${parsed.repository}${tagPart}`;
1870
1872
  }
1873
+ function _parseDockerfileInstructions(content) {
1874
+ const rawLines = content.replace(/\r\n/g, "\n").split("\n");
1875
+ const instructions = [];
1876
+ let buffer = "";
1877
+ let bufferStartLine = 0;
1878
+ for (let i = 0; i < rawLines.length; i++) {
1879
+ const lineNo = i + 1;
1880
+ const line = rawLines[i];
1881
+ const trimmed = line.trim();
1882
+ if (buffer === "") {
1883
+ if (trimmed === "" || trimmed.startsWith("#")) continue;
1884
+ bufferStartLine = lineNo;
1885
+ buffer = line.trimEnd();
1886
+ } else {
1887
+ buffer += "\n" + line.trimEnd();
1888
+ }
1889
+ if (buffer.endsWith("\\")) {
1890
+ buffer = buffer.slice(0, -1);
1891
+ continue;
1892
+ }
1893
+ const match = buffer.trim().match(/^([A-Za-z]+)\s*([\s\S]*)$/);
1894
+ if (match) {
1895
+ instructions.push({ instruction: match[1].toUpperCase(), args: match[2].trim(), line: bufferStartLine });
1896
+ }
1897
+ buffer = "";
1898
+ }
1899
+ return instructions;
1900
+ }
1901
+ var _DOCKERFILE_TAR_RE = /\.(tar(\.(gz|bz2|xz))?|tgz|tbz2|txz)$/i;
1902
+ function lintDockerfile(content) {
1903
+ if (!content || !content.trim()) return { error: "Dockerfile content is required" };
1904
+ const instructions = _parseDockerfileInstructions(content);
1905
+ if (instructions.length === 0) return { error: "No Dockerfile instructions found" };
1906
+ const fromInstructions = instructions.filter((i) => i.instruction === "FROM");
1907
+ if (fromInstructions.length === 0) return { error: "No FROM instruction found; this does not look like a valid Dockerfile" };
1908
+ const stageNames = /* @__PURE__ */ new Set();
1909
+ const stages = fromInstructions.map((inst, idx) => {
1910
+ const asMatch = inst.args.match(/^(\S+)(?:\s+AS\s+(\S+))?/i);
1911
+ const baseImage = asMatch ? asMatch[1] : inst.args.split(/\s+/)[0];
1912
+ const name = asMatch && asMatch[2] ? asMatch[2] : null;
1913
+ if (name) stageNames.add(name.toLowerCase());
1914
+ return { index: idx, name, baseImage, fromLine: inst.line };
1915
+ });
1916
+ const findings = [];
1917
+ for (const stage of stages) {
1918
+ const base = stage.baseImage;
1919
+ if (base.toLowerCase() === "scratch") continue;
1920
+ if (stageNames.has(base.toLowerCase())) continue;
1921
+ const withoutDigest = base.split("@")[0];
1922
+ const hasTag = withoutDigest.includes(":");
1923
+ const tag = hasTag ? withoutDigest.split(":").pop() : null;
1924
+ if (!hasTag) {
1925
+ findings.push({
1926
+ rule: "unpinned-base-image",
1927
+ severity: "warning",
1928
+ line: stage.fromLine,
1929
+ message: `FROM ${base} has no tag, so it resolves to ":latest", which can silently change what gets built on a future run. Pin an explicit version tag instead.`
1930
+ });
1931
+ } else if (tag === "latest") {
1932
+ findings.push({
1933
+ rule: "unpinned-base-image",
1934
+ severity: "warning",
1935
+ line: stage.fromLine,
1936
+ message: `FROM ${base} is explicitly pinned to the "latest" tag, which is a moving target rather than a fixed version. Pin an explicit version tag instead.`
1937
+ });
1938
+ }
1939
+ }
1940
+ const finalStage = stages[stages.length - 1];
1941
+ const finalStageInstructions = instructions.filter((i) => i.line >= finalStage.fromLine);
1942
+ if (!finalStageInstructions.some((i) => i.instruction === "WORKDIR")) {
1943
+ findings.push({
1944
+ rule: "missing-workdir",
1945
+ severity: "warning",
1946
+ line: finalStage.fromLine,
1947
+ message: 'No WORKDIR instruction in the final stage, so RUN/CMD/ENTRYPOINT execute from "/" by default. Set an explicit WORKDIR.'
1948
+ });
1949
+ }
1950
+ if (!finalStageInstructions.some((i) => i.instruction === "USER")) {
1951
+ findings.push({
1952
+ rule: "running-as-root",
1953
+ severity: "warning",
1954
+ line: finalStage.fromLine,
1955
+ message: "No USER instruction in the final stage, so the container runs as root by default. Add a non-root USER unless root is genuinely required."
1956
+ });
1957
+ }
1958
+ for (const inst of instructions) {
1959
+ if (inst.instruction !== "ADD") continue;
1960
+ const parts = inst.args.split(/\s+/).filter(Boolean).filter((p) => !p.startsWith("--"));
1961
+ if (parts.length < 2) continue;
1962
+ const sources = parts.slice(0, -1);
1963
+ for (const src of sources) {
1964
+ const isUrl = /^https?:\/\//i.test(src);
1965
+ const isTar = _DOCKERFILE_TAR_RE.test(src);
1966
+ if (!isUrl && !isTar) {
1967
+ findings.push({
1968
+ rule: "add-vs-copy",
1969
+ severity: "info",
1970
+ line: inst.line,
1971
+ message: `ADD ${src} copies a local file/directory, not a URL or an auto-extracting archive. Use COPY instead, since ADD's extra behavior (remote fetch, tar auto-extract) doesn't apply here.`
1972
+ });
1973
+ }
1974
+ }
1975
+ }
1976
+ return { findings, stages };
1977
+ }
1871
1978
  function removeJsComments(code) {
1872
1979
  let result = "";
1873
1980
  let i = 0;
@@ -4268,5 +4375,63 @@ function countSqlPlaceholders(sql) {
4268
4375
  numberedDuplicates
4269
4376
  };
4270
4377
  }
4378
+ var LINK_REF_DEFINITION_REGEX = /^ {0,3}\[([^\]]+)\]:\s*(\S+)(?:\s+(?:"([^"]*)"|'([^']*)'|\(([^)]*)\)))?\s*$/;
4379
+ var LINK_REF_USAGE_REGEX = /(!?)\[([^[\]\n]*)\]\[([^[\]\n]*)\]/g;
4380
+ function normalizeLinkLabel(label) {
4381
+ return label.trim().replace(/\s+/g, " ").toLowerCase();
4382
+ }
4383
+ function extractMarkdownLinkReferences(markdown) {
4384
+ const trimmed = markdown.trim();
4385
+ if (!trimmed) return { error: "Empty input" };
4386
+ const lines = markdown.replace(/\r\n/g, "\n").split("\n");
4387
+ const definitions = [];
4388
+ const definitionsByLabel = /* @__PURE__ */ new Map();
4389
+ for (const line of lines) {
4390
+ const match = line.match(LINK_REF_DEFINITION_REGEX);
4391
+ if (!match) continue;
4392
+ const label = match[1];
4393
+ const normalized = normalizeLinkLabel(label);
4394
+ if (definitionsByLabel.has(normalized)) continue;
4395
+ const def = {
4396
+ label,
4397
+ url: match[2],
4398
+ title: match[3] ?? match[4] ?? match[5] ?? void 0
4399
+ };
4400
+ definitionsByLabel.set(normalized, def);
4401
+ definitions.push(def);
4402
+ }
4403
+ const usages = [];
4404
+ for (const m of markdown.matchAll(LINK_REF_USAGE_REGEX)) {
4405
+ const image = m[1] === "!";
4406
+ const text = m[2];
4407
+ const rawRef = m[3];
4408
+ const label = rawRef.trim() === "" ? text : rawRef;
4409
+ usages.push({ text, label, image });
4410
+ }
4411
+ if (definitions.length === 0 && usages.length === 0) {
4412
+ return { error: "No reference-style links or definitions found" };
4413
+ }
4414
+ const usedLabels = /* @__PURE__ */ new Set();
4415
+ const resolved = [];
4416
+ const unresolvedReferences = [];
4417
+ for (const usage of usages) {
4418
+ const normalized = normalizeLinkLabel(usage.label);
4419
+ const def = definitionsByLabel.get(normalized);
4420
+ if (def) {
4421
+ usedLabels.add(normalized);
4422
+ resolved.push({ ...usage, url: def.url, title: def.title });
4423
+ } else {
4424
+ unresolvedReferences.push(usage);
4425
+ }
4426
+ }
4427
+ const unusedDefinitions = definitions.filter((d) => !usedLabels.has(normalizeLinkLabel(d.label)));
4428
+ return {
4429
+ referenceCount: usages.length,
4430
+ definitionCount: definitions.length,
4431
+ resolved,
4432
+ unresolvedReferences,
4433
+ unusedDefinitions
4434
+ };
4435
+ }
4271
4436
 
4272
- export { ALL_FLAGS, CHEATSHEET, DEFAULT_COMMIT_TYPES, KNOWN_LANGUAGE_TAGS, MIME_TABLE, OPERATIONS, SQL_DEFAULT_OPTIONS, analyzeRegexGroups, auditDependencyRanges, buildDockerPull, buildDockerRun, buildGitCommand, code_exports, collapseHtmlWhitespace, collapseJsWhitespace, countProperties, countRules, countSqlPlaceholders, detectDialect, detectOperationType, detectRedos, envToExport, envToJson, extractMarkdownFootnotes, extractSvgSpriteSymbols, formatCss, formatGql, formatHtml, formatSql, getEndpointsByTag, getHtmlStats, getJsStats, getMethodColor, isValidTag, lintConventionalCommit, lookupMime, minifyCss, minifyGql, minifyHtml, minifyJs, minifySql, normalizeRef, parseCommitTrailers, parseConnectionString, parseDockerImage, parseEnv, parseGitCommand, parseGithubUrl, parseSpec, removeConsoleCalls, removeEmptyAttributes, removeHtmlComments, removeJsComments, removeRedundantAttributes, searchCheatsheet, searchEndpoints, splitStatements, testGitignorePatterns, testPattern, testRegex, validateAria, validateEditorConfig, validateEnvKey, validateFenceLanguageTags, validatePackageExports, validateTsconfig };
4437
+ export { ALL_FLAGS, CHEATSHEET, DEFAULT_COMMIT_TYPES, KNOWN_LANGUAGE_TAGS, MIME_TABLE, OPERATIONS, SQL_DEFAULT_OPTIONS, analyzeRegexGroups, auditDependencyRanges, buildDockerPull, buildDockerRun, buildGitCommand, code_exports, collapseHtmlWhitespace, collapseJsWhitespace, countProperties, countRules, countSqlPlaceholders, detectDialect, detectOperationType, detectRedos, envToExport, envToJson, extractMarkdownFootnotes, extractMarkdownLinkReferences, extractSvgSpriteSymbols, formatCss, formatGql, formatHtml, formatSql, getEndpointsByTag, getHtmlStats, getJsStats, getMethodColor, isValidTag, lintConventionalCommit, lintDockerfile, lookupMime, minifyCss, minifyGql, minifyHtml, minifyJs, minifySql, normalizeRef, parseCommitTrailers, parseConnectionString, parseDockerImage, parseEnv, parseGitCommand, parseGithubUrl, parseSpec, removeConsoleCalls, removeEmptyAttributes, removeHtmlComments, removeJsComments, removeRedundantAttributes, searchCheatsheet, searchEndpoints, splitStatements, testGitignorePatterns, testPattern, testRegex, validateAria, validateEditorConfig, validateEnvKey, validateFenceLanguageTags, validatePackageExports, validateTsconfig };