@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/dist/index.cjs CHANGED
@@ -8111,6 +8111,7 @@ __export(time_exports, {
8111
8111
  TIMEZONES: () => TIMEZONES,
8112
8112
  convertTime: () => convertTime,
8113
8113
  diffDates: () => diffDates,
8114
+ findCronOverlaps: () => findCronOverlaps,
8114
8115
  formatInTimezone: () => formatInTimezone,
8115
8116
  formatIso8601Duration: () => formatIso8601Duration,
8116
8117
  formatRelative: () => formatRelative,
@@ -8786,6 +8787,42 @@ function getRunInterval(dates) {
8786
8787
  const days = Math.round(diffMins / 1440);
8787
8788
  return `Every ${days} days`;
8788
8789
  }
8790
+ var MAX_CRON_OVERLAPS = 200;
8791
+ function findCronOverlaps(expressions, windowDays = 30, fromDate) {
8792
+ if (expressions.length < 2) return { error: "Provide at least two cron expressions to check for overlaps" };
8793
+ if (expressions.length > 10) return { error: "Provide 10 or fewer cron expressions" };
8794
+ if (windowDays < 1 || windowDays > 365) return { error: "windowDays must be between 1 and 365" };
8795
+ const parsedList = [];
8796
+ for (let i = 0; i < expressions.length; i++) {
8797
+ const parsed = parseCronExpression(expressions[i]);
8798
+ if (typeof parsed === "object" && "error" in parsed) {
8799
+ return { error: `Expression ${i + 1} ("${expressions[i]}"): ${parsed.error}` };
8800
+ }
8801
+ parsedList.push(parsed);
8802
+ }
8803
+ const start = fromDate ? new Date(fromDate) : /* @__PURE__ */ new Date();
8804
+ const cursor = new Date(start);
8805
+ cursor.setSeconds(0, 0);
8806
+ cursor.setMinutes(cursor.getMinutes() + 1);
8807
+ const endTime = cursor.getTime() + windowDays * 24 * 60 * 60 * 1e3;
8808
+ const overlaps = [];
8809
+ let truncated = false;
8810
+ while (cursor.getTime() < endTime) {
8811
+ const matched = [];
8812
+ for (let i = 0; i < parsedList.length; i++) {
8813
+ if (matchesCron(cursor, parsedList[i])) matched.push(i);
8814
+ }
8815
+ if (matched.length >= 2) {
8816
+ if (overlaps.length >= MAX_CRON_OVERLAPS) {
8817
+ truncated = true;
8818
+ break;
8819
+ }
8820
+ overlaps.push({ date: new Date(cursor), expressionIndexes: matched });
8821
+ }
8822
+ cursor.setMinutes(cursor.getMinutes() + 1);
8823
+ }
8824
+ return { overlaps, windowDays, truncated };
8825
+ }
8789
8826
  var DURATION_SECONDS_PER_YEAR = 365 * 86400;
8790
8827
  var DURATION_SECONDS_PER_MONTH = 30 * 86400;
8791
8828
  function humanizeDurationParts(parts) {
@@ -16791,6 +16828,7 @@ __export(code_exports, {
16791
16828
  envToExport: () => envToExport2,
16792
16829
  envToJson: () => envToJson2,
16793
16830
  extractMarkdownFootnotes: () => extractMarkdownFootnotes,
16831
+ extractMarkdownLinkReferences: () => extractMarkdownLinkReferences,
16794
16832
  extractSvgSpriteSymbols: () => extractSvgSpriteSymbols,
16795
16833
  formatCss: () => formatCss,
16796
16834
  formatGql: () => formatGql,
@@ -16802,6 +16840,7 @@ __export(code_exports, {
16802
16840
  getMethodColor: () => getMethodColor,
16803
16841
  isValidTag: () => isValidTag,
16804
16842
  lintConventionalCommit: () => lintConventionalCommit,
16843
+ lintDockerfile: () => lintDockerfile,
16805
16844
  lookupMime: () => lookupMime,
16806
16845
  minifyCss: () => minifyCss,
16807
16846
  minifyGql: () => minifyGql,
@@ -18632,6 +18671,111 @@ function normalizeRef(ref) {
18632
18671
  const tagPart = parsed.digest ? `@${parsed.digest}` : parsed.tag ? `:${parsed.tag}` : "";
18633
18672
  return `${parsed.registry}/${ns}${parsed.repository}${tagPart}`;
18634
18673
  }
18674
+ function _parseDockerfileInstructions(content) {
18675
+ const rawLines = content.replace(/\r\n/g, "\n").split("\n");
18676
+ const instructions = [];
18677
+ let buffer = "";
18678
+ let bufferStartLine = 0;
18679
+ for (let i = 0; i < rawLines.length; i++) {
18680
+ const lineNo = i + 1;
18681
+ const line = rawLines[i];
18682
+ const trimmed = line.trim();
18683
+ if (buffer === "") {
18684
+ if (trimmed === "" || trimmed.startsWith("#")) continue;
18685
+ bufferStartLine = lineNo;
18686
+ buffer = line.trimEnd();
18687
+ } else {
18688
+ buffer += "\n" + line.trimEnd();
18689
+ }
18690
+ if (buffer.endsWith("\\")) {
18691
+ buffer = buffer.slice(0, -1);
18692
+ continue;
18693
+ }
18694
+ const match = buffer.trim().match(/^([A-Za-z]+)\s*([\s\S]*)$/);
18695
+ if (match) {
18696
+ instructions.push({ instruction: match[1].toUpperCase(), args: match[2].trim(), line: bufferStartLine });
18697
+ }
18698
+ buffer = "";
18699
+ }
18700
+ return instructions;
18701
+ }
18702
+ var _DOCKERFILE_TAR_RE = /\.(tar(\.(gz|bz2|xz))?|tgz|tbz2|txz)$/i;
18703
+ function lintDockerfile(content) {
18704
+ if (!content || !content.trim()) return { error: "Dockerfile content is required" };
18705
+ const instructions = _parseDockerfileInstructions(content);
18706
+ if (instructions.length === 0) return { error: "No Dockerfile instructions found" };
18707
+ const fromInstructions = instructions.filter((i) => i.instruction === "FROM");
18708
+ if (fromInstructions.length === 0) return { error: "No FROM instruction found; this does not look like a valid Dockerfile" };
18709
+ const stageNames = /* @__PURE__ */ new Set();
18710
+ const stages = fromInstructions.map((inst, idx) => {
18711
+ const asMatch = inst.args.match(/^(\S+)(?:\s+AS\s+(\S+))?/i);
18712
+ const baseImage = asMatch ? asMatch[1] : inst.args.split(/\s+/)[0];
18713
+ const name = asMatch && asMatch[2] ? asMatch[2] : null;
18714
+ if (name) stageNames.add(name.toLowerCase());
18715
+ return { index: idx, name, baseImage, fromLine: inst.line };
18716
+ });
18717
+ const findings = [];
18718
+ for (const stage of stages) {
18719
+ const base = stage.baseImage;
18720
+ if (base.toLowerCase() === "scratch") continue;
18721
+ if (stageNames.has(base.toLowerCase())) continue;
18722
+ const withoutDigest = base.split("@")[0];
18723
+ const hasTag = withoutDigest.includes(":");
18724
+ const tag = hasTag ? withoutDigest.split(":").pop() : null;
18725
+ if (!hasTag) {
18726
+ findings.push({
18727
+ rule: "unpinned-base-image",
18728
+ severity: "warning",
18729
+ line: stage.fromLine,
18730
+ 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.`
18731
+ });
18732
+ } else if (tag === "latest") {
18733
+ findings.push({
18734
+ rule: "unpinned-base-image",
18735
+ severity: "warning",
18736
+ line: stage.fromLine,
18737
+ 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.`
18738
+ });
18739
+ }
18740
+ }
18741
+ const finalStage = stages[stages.length - 1];
18742
+ const finalStageInstructions = instructions.filter((i) => i.line >= finalStage.fromLine);
18743
+ if (!finalStageInstructions.some((i) => i.instruction === "WORKDIR")) {
18744
+ findings.push({
18745
+ rule: "missing-workdir",
18746
+ severity: "warning",
18747
+ line: finalStage.fromLine,
18748
+ message: 'No WORKDIR instruction in the final stage, so RUN/CMD/ENTRYPOINT execute from "/" by default. Set an explicit WORKDIR.'
18749
+ });
18750
+ }
18751
+ if (!finalStageInstructions.some((i) => i.instruction === "USER")) {
18752
+ findings.push({
18753
+ rule: "running-as-root",
18754
+ severity: "warning",
18755
+ line: finalStage.fromLine,
18756
+ 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."
18757
+ });
18758
+ }
18759
+ for (const inst of instructions) {
18760
+ if (inst.instruction !== "ADD") continue;
18761
+ const parts = inst.args.split(/\s+/).filter(Boolean).filter((p) => !p.startsWith("--"));
18762
+ if (parts.length < 2) continue;
18763
+ const sources = parts.slice(0, -1);
18764
+ for (const src of sources) {
18765
+ const isUrl = /^https?:\/\//i.test(src);
18766
+ const isTar = _DOCKERFILE_TAR_RE.test(src);
18767
+ if (!isUrl && !isTar) {
18768
+ findings.push({
18769
+ rule: "add-vs-copy",
18770
+ severity: "info",
18771
+ line: inst.line,
18772
+ 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.`
18773
+ });
18774
+ }
18775
+ }
18776
+ }
18777
+ return { findings, stages };
18778
+ }
18635
18779
  function removeJsComments(code) {
18636
18780
  let result = "";
18637
18781
  let i = 0;
@@ -21032,6 +21176,64 @@ function countSqlPlaceholders(sql) {
21032
21176
  numberedDuplicates
21033
21177
  };
21034
21178
  }
21179
+ var LINK_REF_DEFINITION_REGEX = /^ {0,3}\[([^\]]+)\]:\s*(\S+)(?:\s+(?:"([^"]*)"|'([^']*)'|\(([^)]*)\)))?\s*$/;
21180
+ var LINK_REF_USAGE_REGEX = /(!?)\[([^[\]\n]*)\]\[([^[\]\n]*)\]/g;
21181
+ function normalizeLinkLabel(label) {
21182
+ return label.trim().replace(/\s+/g, " ").toLowerCase();
21183
+ }
21184
+ function extractMarkdownLinkReferences(markdown) {
21185
+ const trimmed = markdown.trim();
21186
+ if (!trimmed) return { error: "Empty input" };
21187
+ const lines = markdown.replace(/\r\n/g, "\n").split("\n");
21188
+ const definitions = [];
21189
+ const definitionsByLabel = /* @__PURE__ */ new Map();
21190
+ for (const line of lines) {
21191
+ const match = line.match(LINK_REF_DEFINITION_REGEX);
21192
+ if (!match) continue;
21193
+ const label = match[1];
21194
+ const normalized = normalizeLinkLabel(label);
21195
+ if (definitionsByLabel.has(normalized)) continue;
21196
+ const def = {
21197
+ label,
21198
+ url: match[2],
21199
+ title: match[3] ?? match[4] ?? match[5] ?? void 0
21200
+ };
21201
+ definitionsByLabel.set(normalized, def);
21202
+ definitions.push(def);
21203
+ }
21204
+ const usages = [];
21205
+ for (const m of markdown.matchAll(LINK_REF_USAGE_REGEX)) {
21206
+ const image = m[1] === "!";
21207
+ const text = m[2];
21208
+ const rawRef = m[3];
21209
+ const label = rawRef.trim() === "" ? text : rawRef;
21210
+ usages.push({ text, label, image });
21211
+ }
21212
+ if (definitions.length === 0 && usages.length === 0) {
21213
+ return { error: "No reference-style links or definitions found" };
21214
+ }
21215
+ const usedLabels = /* @__PURE__ */ new Set();
21216
+ const resolved = [];
21217
+ const unresolvedReferences = [];
21218
+ for (const usage of usages) {
21219
+ const normalized = normalizeLinkLabel(usage.label);
21220
+ const def = definitionsByLabel.get(normalized);
21221
+ if (def) {
21222
+ usedLabels.add(normalized);
21223
+ resolved.push({ ...usage, url: def.url, title: def.title });
21224
+ } else {
21225
+ unresolvedReferences.push(usage);
21226
+ }
21227
+ }
21228
+ const unusedDefinitions = definitions.filter((d) => !usedLabels.has(normalizeLinkLabel(d.label)));
21229
+ return {
21230
+ referenceCount: usages.length,
21231
+ definitionCount: definitions.length,
21232
+ resolved,
21233
+ unresolvedReferences,
21234
+ unusedDefinitions
21235
+ };
21236
+ }
21035
21237
 
21036
21238
  // src/tools/color.ts
21037
21239
  var color_exports = {};
@@ -24632,6 +24834,7 @@ __export(ai_agent_exports, {
24632
24834
  extractEntities: () => extractEntities,
24633
24835
  extractJson: () => extractJson,
24634
24836
  extractKeywords: () => extractKeywords,
24837
+ extractPromptTemplateVariables: () => extractPromptTemplateVariables,
24635
24838
  extractTables: () => extractTables,
24636
24839
  extractUrls: () => extractUrls,
24637
24840
  flattenJson: () => flattenJson,
@@ -25785,6 +25988,45 @@ function calculateRetryBackoffSchedule(input) {
25785
25988
  totalWorstCaseMs: round0(totalWorstCaseMs)
25786
25989
  };
25787
25990
  }
25991
+ var PROMPT_TEMPLATE_VARIABLE_REGEX = /\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g;
25992
+ function extractPromptTemplateVariables(template, providedVars) {
25993
+ const trimmed = template.trim();
25994
+ if (!trimmed) return { error: "Empty input" };
25995
+ const order = [];
25996
+ const counts = /* @__PURE__ */ new Map();
25997
+ for (const m of template.matchAll(PROMPT_TEMPLATE_VARIABLE_REGEX)) {
25998
+ const name = m[1];
25999
+ if (!counts.has(name)) {
26000
+ counts.set(name, 0);
26001
+ order.push(name);
26002
+ }
26003
+ counts.set(name, (counts.get(name) ?? 0) + 1);
26004
+ }
26005
+ if (order.length === 0) return { error: "No {{variable}} placeholders found" };
26006
+ const variables = order.map((name) => ({ name, count: counts.get(name) ?? 0 }));
26007
+ const duplicates = order.filter((name) => (counts.get(name) ?? 0) > 1);
26008
+ let missing = [];
26009
+ const unused = [];
26010
+ if (providedVars !== void 0) {
26011
+ const providedSet = new Set(providedVars.map((v) => v.trim()).filter(Boolean));
26012
+ const usedSet = new Set(order);
26013
+ missing = order.filter((name) => !providedSet.has(name));
26014
+ const seenProvided = /* @__PURE__ */ new Set();
26015
+ for (const raw of providedVars) {
26016
+ const v = raw.trim();
26017
+ if (!v || usedSet.has(v) || seenProvided.has(v)) continue;
26018
+ seenProvided.add(v);
26019
+ unused.push(v);
26020
+ }
26021
+ }
26022
+ return {
26023
+ variableCount: order.length,
26024
+ variables,
26025
+ duplicates,
26026
+ missing,
26027
+ unused
26028
+ };
26029
+ }
25788
26030
 
25789
26031
  // src/tools/media.ts
25790
26032
  var media_exports = {};
package/dist/index.d.cts CHANGED
@@ -4,15 +4,15 @@ export { h as hashing } from './hashing-CJjlvqS_.cjs';
4
4
  export { t as text } from './text-CNn3whZA.cjs';
5
5
  export { d as data } from './data-DIyBrJ6l.cjs';
6
6
  export { g as generators } from './generators-DAXXrMvG.cjs';
7
- export { t as time } from './time-KqJjdqII.cjs';
7
+ export { t as time } from './time-VMAy_SrV.cjs';
8
8
  export { u as units } from './units-D7YRRwei.cjs';
9
9
  export { n as network } from './network-ylRtLPEs.cjs';
10
10
  export { a as api } from './api-CQnIUrVB.cjs';
11
- export { c as code } from './code-B8yHwP3m.cjs';
11
+ export { c as code } from './code-mkKV7BQ4.cjs';
12
12
  export { c as color } from './color-tPwZCr9H.cjs';
13
13
  export { c as css } from './css-Cf7AMGM-.cjs';
14
14
  export { m as misc } from './misc-CA3N198T.cjs';
15
- export { a as ai_agent } from './ai_agent-DeCy0oZK.cjs';
15
+ export { a as ai_agent } from './ai_agent-B9wWLBDf.cjs';
16
16
  export { m as media } from './media-DF8BS-iA.cjs';
17
17
 
18
18
  declare const version = "0.1.0";
package/dist/index.d.ts CHANGED
@@ -4,15 +4,15 @@ export { h as hashing } from './hashing-CJjlvqS_.js';
4
4
  export { t as text } from './text-CNn3whZA.js';
5
5
  export { d as data } from './data-DIyBrJ6l.js';
6
6
  export { g as generators } from './generators-DAXXrMvG.js';
7
- export { t as time } from './time-KqJjdqII.js';
7
+ export { t as time } from './time-VMAy_SrV.js';
8
8
  export { u as units } from './units-D7YRRwei.js';
9
9
  export { n as network } from './network-ylRtLPEs.js';
10
10
  export { a as api } from './api-CQnIUrVB.js';
11
- export { c as code } from './code-B8yHwP3m.js';
11
+ export { c as code } from './code-mkKV7BQ4.js';
12
12
  export { c as color } from './color-tPwZCr9H.js';
13
13
  export { c as css } from './css-Cf7AMGM-.js';
14
14
  export { m as misc } from './misc-CA3N198T.js';
15
- export { a as ai_agent } from './ai_agent-DeCy0oZK.js';
15
+ export { a as ai_agent } from './ai_agent-B9wWLBDf.js';
16
16
  export { m as media } from './media-DF8BS-iA.js';
17
17
 
18
18
  declare const version = "0.1.0";
package/dist/index.js CHANGED
@@ -2,18 +2,18 @@ export { media_exports as media } from './chunk-ZWFZRDQ4.js';
2
2
  export { units_exports as units } from './chunk-OFLNVDNX.js';
3
3
  export { network_exports as network } from './chunk-SW3J5CAI.js';
4
4
  export { api_exports as api } from './chunk-U2HREMZU.js';
5
- export { code_exports as code } from './chunk-FPFA4ZHC.js';
5
+ export { code_exports as code } from './chunk-RMXZMYSG.js';
6
6
  export { color_exports as color } from './chunk-BPVAB4P2.js';
7
7
  export { css_exports as css } from './chunk-6YPV2AB5.js';
8
8
  export { misc_exports as misc } from './chunk-GX7H6TAX.js';
9
- export { ai_agent_exports as ai_agent } from './chunk-HJLGUNSO.js';
9
+ export { ai_agent_exports as ai_agent } from './chunk-5VVC7BHS.js';
10
10
  export { json_exports as json } from './chunk-WUOZHCIC.js';
11
11
  export { encoding_exports as encoding } from './chunk-DOWQZUTP.js';
12
12
  export { hashing_exports as hashing } from './chunk-PET2CGTH.js';
13
13
  export { text_exports as text } from './chunk-QVOK3BXM.js';
14
14
  export { data_exports as data } from './chunk-XOUS3M5Z.js';
15
15
  export { generators_exports as generators } from './chunk-422ICOZX.js';
16
- export { time_exports as time } from './chunk-IEPWZERQ.js';
16
+ export { time_exports as time } from './chunk-6EJVNQSY.js';
17
17
  import './chunk-MLKGABMK.js';
18
18
 
19
19
  // src/index.ts
@@ -6,6 +6,7 @@
6
6
  * - date-diff : parseDate, humanizeDiff, diffDates, COMMON_DATE_PRESETS
7
7
  * - timezone : TIMEZONES, getTimezoneOffset, convertTime, formatInTimezone, getAllZonesForTime
8
8
  * - cron-next : parseCronExpression, getNextRuns, formatRunDate, getRunInterval
9
+ * - cron-overlap-detector : findCronOverlaps
9
10
  * - iso8601-duration : parseIso8601Duration, formatIso8601Duration
10
11
  */
11
12
  interface TimestampResult {
@@ -112,6 +113,22 @@ declare function getNextRuns(expr: string, count?: number, fromDate?: Date): Dat
112
113
  };
113
114
  declare function formatRunDate(date: Date, timezone?: string): string;
114
115
  declare function getRunInterval(dates: Date[]): string;
116
+ interface CronOverlap {
117
+ date: Date;
118
+ expressionIndexes: number[];
119
+ }
120
+ interface CronOverlapResult {
121
+ overlaps: CronOverlap[];
122
+ windowDays: number;
123
+ truncated: boolean;
124
+ }
125
+ /**
126
+ * Walk minute-by-minute over `windowDays` and flag every minute where two or
127
+ * more of the given 5-field cron expressions fire at once.
128
+ */
129
+ declare function findCronOverlaps(expressions: string[], windowDays?: number, fromDate?: Date): CronOverlapResult | {
130
+ error: string;
131
+ };
115
132
  interface DurationParseResult {
116
133
  input: string;
117
134
  years: number;
@@ -158,6 +175,8 @@ declare const time_COMMON_CRONS: typeof COMMON_CRONS;
158
175
  declare const time_COMMON_DATE_PRESETS: typeof COMMON_DATE_PRESETS;
159
176
  type time_CronField = CronField;
160
177
  type time_CronNextField = CronNextField;
178
+ type time_CronOverlap = CronOverlap;
179
+ type time_CronOverlapResult = CronOverlapResult;
161
180
  type time_CronResult = CronResult;
162
181
  type time_DateDiffResult = DateDiffResult;
163
182
  type time_DurationFormatResult = DurationFormatResult;
@@ -168,6 +187,7 @@ type time_TimestampResult = TimestampResult;
168
187
  type time_TimezoneEntry = TimezoneEntry;
169
188
  declare const time_convertTime: typeof convertTime;
170
189
  declare const time_diffDates: typeof diffDates;
190
+ declare const time_findCronOverlaps: typeof findCronOverlaps;
171
191
  declare const time_formatInTimezone: typeof formatInTimezone;
172
192
  declare const time_formatIso8601Duration: typeof formatIso8601Duration;
173
193
  declare const time_formatRelative: typeof formatRelative;
@@ -185,7 +205,7 @@ declare const time_parseCronExpression: typeof parseCronExpression;
185
205
  declare const time_parseDate: typeof parseDate;
186
206
  declare const time_parseIso8601Duration: typeof parseIso8601Duration;
187
207
  declare namespace time {
188
- export { time_COMMON_CRONS as COMMON_CRONS, time_COMMON_DATE_PRESETS as COMMON_DATE_PRESETS, type time_CronField as CronField, type time_CronNextField as CronNextField, type time_CronResult as CronResult, type time_DateDiffResult as DateDiffResult, type time_DurationFormatResult as DurationFormatResult, type time_DurationParseResult as DurationParseResult, type time_ParsedCron as ParsedCron, time_TIMEZONES as TIMEZONES, type time_TimestampResult as TimestampResult, type time_TimezoneEntry as TimezoneEntry, time_convertTime as convertTime, time_diffDates as diffDates, time_formatInTimezone as formatInTimezone, time_formatIso8601Duration as formatIso8601Duration, time_formatRelative as formatRelative, time_formatRunDate as formatRunDate, time_fromIsoString as fromIsoString, time_fromUnix as fromUnix, time_getAllZonesForTime as getAllZonesForTime, time_getNextRuns as getNextRuns, time_getNow as getNow, time_getRunInterval as getRunInterval, time_getTimezoneOffset as getTimezoneOffset, time_humanizeDiff as humanizeDiff, time_parseCron as parseCron, time_parseCronExpression as parseCronExpression, time_parseDate as parseDate, time_parseIso8601Duration as parseIso8601Duration };
208
+ export { time_COMMON_CRONS as COMMON_CRONS, time_COMMON_DATE_PRESETS as COMMON_DATE_PRESETS, type time_CronField as CronField, type time_CronNextField as CronNextField, type time_CronOverlap as CronOverlap, type time_CronOverlapResult as CronOverlapResult, type time_CronResult as CronResult, type time_DateDiffResult as DateDiffResult, type time_DurationFormatResult as DurationFormatResult, type time_DurationParseResult as DurationParseResult, type time_ParsedCron as ParsedCron, time_TIMEZONES as TIMEZONES, type time_TimestampResult as TimestampResult, type time_TimezoneEntry as TimezoneEntry, time_convertTime as convertTime, time_diffDates as diffDates, time_findCronOverlaps as findCronOverlaps, time_formatInTimezone as formatInTimezone, time_formatIso8601Duration as formatIso8601Duration, time_formatRelative as formatRelative, time_formatRunDate as formatRunDate, time_fromIsoString as fromIsoString, time_fromUnix as fromUnix, time_getAllZonesForTime as getAllZonesForTime, time_getNextRuns as getNextRuns, time_getNow as getNow, time_getRunInterval as getRunInterval, time_getTimezoneOffset as getTimezoneOffset, time_humanizeDiff as humanizeDiff, time_parseCron as parseCron, time_parseCronExpression as parseCronExpression, time_parseDate as parseDate, time_parseIso8601Duration as parseIso8601Duration };
189
209
  }
190
210
 
191
- export { parseIso8601Duration as A, COMMON_CRONS as C, type DateDiffResult as D, type ParsedCron as P, TIMEZONES as T, COMMON_DATE_PRESETS as a, type CronField as b, type CronNextField as c, type CronResult as d, type DurationFormatResult as e, type DurationParseResult as f, type TimestampResult as g, type TimezoneEntry as h, convertTime as i, diffDates as j, formatInTimezone as k, formatIso8601Duration as l, formatRelative as m, formatRunDate as n, fromIsoString as o, fromUnix as p, getAllZonesForTime as q, getNextRuns as r, getNow as s, time as t, getRunInterval as u, getTimezoneOffset as v, humanizeDiff as w, parseCron as x, parseCronExpression as y, parseDate as z };
211
+ export { parseCron as A, parseCronExpression as B, COMMON_CRONS as C, type DateDiffResult as D, parseDate as E, parseIso8601Duration as F, type ParsedCron as P, TIMEZONES as T, COMMON_DATE_PRESETS as a, type CronField as b, type CronNextField as c, type CronOverlap as d, type CronOverlapResult as e, type CronResult as f, type DurationFormatResult as g, type DurationParseResult as h, type TimestampResult as i, type TimezoneEntry as j, convertTime as k, diffDates as l, findCronOverlaps as m, formatInTimezone as n, formatIso8601Duration as o, formatRelative as p, formatRunDate as q, fromIsoString as r, fromUnix as s, time as t, getAllZonesForTime as u, getNextRuns as v, getNow as w, getRunInterval as x, getTimezoneOffset as y, humanizeDiff as z };
@@ -6,6 +6,7 @@
6
6
  * - date-diff : parseDate, humanizeDiff, diffDates, COMMON_DATE_PRESETS
7
7
  * - timezone : TIMEZONES, getTimezoneOffset, convertTime, formatInTimezone, getAllZonesForTime
8
8
  * - cron-next : parseCronExpression, getNextRuns, formatRunDate, getRunInterval
9
+ * - cron-overlap-detector : findCronOverlaps
9
10
  * - iso8601-duration : parseIso8601Duration, formatIso8601Duration
10
11
  */
11
12
  interface TimestampResult {
@@ -112,6 +113,22 @@ declare function getNextRuns(expr: string, count?: number, fromDate?: Date): Dat
112
113
  };
113
114
  declare function formatRunDate(date: Date, timezone?: string): string;
114
115
  declare function getRunInterval(dates: Date[]): string;
116
+ interface CronOverlap {
117
+ date: Date;
118
+ expressionIndexes: number[];
119
+ }
120
+ interface CronOverlapResult {
121
+ overlaps: CronOverlap[];
122
+ windowDays: number;
123
+ truncated: boolean;
124
+ }
125
+ /**
126
+ * Walk minute-by-minute over `windowDays` and flag every minute where two or
127
+ * more of the given 5-field cron expressions fire at once.
128
+ */
129
+ declare function findCronOverlaps(expressions: string[], windowDays?: number, fromDate?: Date): CronOverlapResult | {
130
+ error: string;
131
+ };
115
132
  interface DurationParseResult {
116
133
  input: string;
117
134
  years: number;
@@ -158,6 +175,8 @@ declare const time_COMMON_CRONS: typeof COMMON_CRONS;
158
175
  declare const time_COMMON_DATE_PRESETS: typeof COMMON_DATE_PRESETS;
159
176
  type time_CronField = CronField;
160
177
  type time_CronNextField = CronNextField;
178
+ type time_CronOverlap = CronOverlap;
179
+ type time_CronOverlapResult = CronOverlapResult;
161
180
  type time_CronResult = CronResult;
162
181
  type time_DateDiffResult = DateDiffResult;
163
182
  type time_DurationFormatResult = DurationFormatResult;
@@ -168,6 +187,7 @@ type time_TimestampResult = TimestampResult;
168
187
  type time_TimezoneEntry = TimezoneEntry;
169
188
  declare const time_convertTime: typeof convertTime;
170
189
  declare const time_diffDates: typeof diffDates;
190
+ declare const time_findCronOverlaps: typeof findCronOverlaps;
171
191
  declare const time_formatInTimezone: typeof formatInTimezone;
172
192
  declare const time_formatIso8601Duration: typeof formatIso8601Duration;
173
193
  declare const time_formatRelative: typeof formatRelative;
@@ -185,7 +205,7 @@ declare const time_parseCronExpression: typeof parseCronExpression;
185
205
  declare const time_parseDate: typeof parseDate;
186
206
  declare const time_parseIso8601Duration: typeof parseIso8601Duration;
187
207
  declare namespace time {
188
- export { time_COMMON_CRONS as COMMON_CRONS, time_COMMON_DATE_PRESETS as COMMON_DATE_PRESETS, type time_CronField as CronField, type time_CronNextField as CronNextField, type time_CronResult as CronResult, type time_DateDiffResult as DateDiffResult, type time_DurationFormatResult as DurationFormatResult, type time_DurationParseResult as DurationParseResult, type time_ParsedCron as ParsedCron, time_TIMEZONES as TIMEZONES, type time_TimestampResult as TimestampResult, type time_TimezoneEntry as TimezoneEntry, time_convertTime as convertTime, time_diffDates as diffDates, time_formatInTimezone as formatInTimezone, time_formatIso8601Duration as formatIso8601Duration, time_formatRelative as formatRelative, time_formatRunDate as formatRunDate, time_fromIsoString as fromIsoString, time_fromUnix as fromUnix, time_getAllZonesForTime as getAllZonesForTime, time_getNextRuns as getNextRuns, time_getNow as getNow, time_getRunInterval as getRunInterval, time_getTimezoneOffset as getTimezoneOffset, time_humanizeDiff as humanizeDiff, time_parseCron as parseCron, time_parseCronExpression as parseCronExpression, time_parseDate as parseDate, time_parseIso8601Duration as parseIso8601Duration };
208
+ export { time_COMMON_CRONS as COMMON_CRONS, time_COMMON_DATE_PRESETS as COMMON_DATE_PRESETS, type time_CronField as CronField, type time_CronNextField as CronNextField, type time_CronOverlap as CronOverlap, type time_CronOverlapResult as CronOverlapResult, type time_CronResult as CronResult, type time_DateDiffResult as DateDiffResult, type time_DurationFormatResult as DurationFormatResult, type time_DurationParseResult as DurationParseResult, type time_ParsedCron as ParsedCron, time_TIMEZONES as TIMEZONES, type time_TimestampResult as TimestampResult, type time_TimezoneEntry as TimezoneEntry, time_convertTime as convertTime, time_diffDates as diffDates, time_findCronOverlaps as findCronOverlaps, time_formatInTimezone as formatInTimezone, time_formatIso8601Duration as formatIso8601Duration, time_formatRelative as formatRelative, time_formatRunDate as formatRunDate, time_fromIsoString as fromIsoString, time_fromUnix as fromUnix, time_getAllZonesForTime as getAllZonesForTime, time_getNextRuns as getNextRuns, time_getNow as getNow, time_getRunInterval as getRunInterval, time_getTimezoneOffset as getTimezoneOffset, time_humanizeDiff as humanizeDiff, time_parseCron as parseCron, time_parseCronExpression as parseCronExpression, time_parseDate as parseDate, time_parseIso8601Duration as parseIso8601Duration };
189
209
  }
190
210
 
191
- export { parseIso8601Duration as A, COMMON_CRONS as C, type DateDiffResult as D, type ParsedCron as P, TIMEZONES as T, COMMON_DATE_PRESETS as a, type CronField as b, type CronNextField as c, type CronResult as d, type DurationFormatResult as e, type DurationParseResult as f, type TimestampResult as g, type TimezoneEntry as h, convertTime as i, diffDates as j, formatInTimezone as k, formatIso8601Duration as l, formatRelative as m, formatRunDate as n, fromIsoString as o, fromUnix as p, getAllZonesForTime as q, getNextRuns as r, getNow as s, time as t, getRunInterval as u, getTimezoneOffset as v, humanizeDiff as w, parseCron as x, parseCronExpression as y, parseDate as z };
211
+ export { parseCron as A, parseCronExpression as B, COMMON_CRONS as C, type DateDiffResult as D, parseDate as E, parseIso8601Duration as F, type ParsedCron as P, TIMEZONES as T, COMMON_DATE_PRESETS as a, type CronField as b, type CronNextField as c, type CronOverlap as d, type CronOverlapResult as e, type CronResult as f, type DurationFormatResult as g, type DurationParseResult as h, type TimestampResult as i, type TimezoneEntry as j, convertTime as k, diffDates as l, findCronOverlaps as m, formatInTimezone as n, formatIso8601Duration as o, formatRelative as p, formatRunDate as q, fromIsoString as r, fromUnix as s, time as t, getAllZonesForTime as u, getNextRuns as v, getNow as w, getRunInterval as x, getTimezoneOffset as y, humanizeDiff as z };
@@ -1137,6 +1137,45 @@ function calculateRetryBackoffSchedule(input) {
1137
1137
  totalWorstCaseMs: round0(totalWorstCaseMs)
1138
1138
  };
1139
1139
  }
1140
+ var PROMPT_TEMPLATE_VARIABLE_REGEX = /\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g;
1141
+ function extractPromptTemplateVariables(template, providedVars) {
1142
+ const trimmed = template.trim();
1143
+ if (!trimmed) return { error: "Empty input" };
1144
+ const order = [];
1145
+ const counts = /* @__PURE__ */ new Map();
1146
+ for (const m of template.matchAll(PROMPT_TEMPLATE_VARIABLE_REGEX)) {
1147
+ const name = m[1];
1148
+ if (!counts.has(name)) {
1149
+ counts.set(name, 0);
1150
+ order.push(name);
1151
+ }
1152
+ counts.set(name, (counts.get(name) ?? 0) + 1);
1153
+ }
1154
+ if (order.length === 0) return { error: "No {{variable}} placeholders found" };
1155
+ const variables = order.map((name) => ({ name, count: counts.get(name) ?? 0 }));
1156
+ const duplicates = order.filter((name) => (counts.get(name) ?? 0) > 1);
1157
+ let missing = [];
1158
+ const unused = [];
1159
+ if (providedVars !== void 0) {
1160
+ const providedSet = new Set(providedVars.map((v) => v.trim()).filter(Boolean));
1161
+ const usedSet = new Set(order);
1162
+ missing = order.filter((name) => !providedSet.has(name));
1163
+ const seenProvided = /* @__PURE__ */ new Set();
1164
+ for (const raw of providedVars) {
1165
+ const v = raw.trim();
1166
+ if (!v || usedSet.has(v) || seenProvided.has(v)) continue;
1167
+ seenProvided.add(v);
1168
+ unused.push(v);
1169
+ }
1170
+ }
1171
+ return {
1172
+ variableCount: order.length,
1173
+ variables,
1174
+ duplicates,
1175
+ missing,
1176
+ unused
1177
+ };
1178
+ }
1140
1179
 
1141
1180
  exports.MODEL_PRICING = MODEL_PRICING;
1142
1181
  exports.calculateRetryBackoffSchedule = calculateRetryBackoffSchedule;
@@ -1155,6 +1194,7 @@ exports.expandQuery = expandQuery;
1155
1194
  exports.extractEntities = extractEntities;
1156
1195
  exports.extractJson = extractJson;
1157
1196
  exports.extractKeywords = extractKeywords;
1197
+ exports.extractPromptTemplateVariables = extractPromptTemplateVariables;
1158
1198
  exports.extractTables = extractTables;
1159
1199
  exports.extractUrls = extractUrls;
1160
1200
  exports.flattenJson = flattenJson;
@@ -1 +1 @@
1
- export { C as ChunkStrategy, b as CompressHtmlResult, c as CompressJsonResult, d as CompressMarkdownResult, e as CostEstimate, D as DedupeResult, f as DedupeStrategy, g as DiffEntry2, h as DiffOp2, i as DiffResult2, E as Entity2, j as EntityType2, k as ExtractJsonResult, l as ExtractKeywordsResult, m as ExtractUrlsResult, F as FewShotExample, n as FewShotFormat, o as FewShotFormatResult, I as InjectionDetectResult, p as InjectionFinding, J as JsonBlock, q as JsonRepairResult, K as Keyword, M as MODEL_PRICING, r as MergeResult, s as MergeStrategy, t as ModelPricing, P as PiiDetectResult, u as PiiFinding, v as PiiType, R as RankedChunk, w as RelevanceResult, x as RetryBackoffAttempt, y as RetryBackoffInput, z as RetryBackoffResult, A as RetryJitterMode, S as SanitizeResult, B as SecretDetectResult, G as SecretFinding, H as SecretType, L as SummaryResult, T as TableResult2, N as TextChunk, O as TokenEstimate, Q as TokenEstimateResult, U as ToolSchemaIssue, V as ToolSchemaLintResult, W as TrimResult, X as TrimStrategy, Y as UrlMatch, Z as ValidationError, _ as ValidationResult, $ as VectorSimilarityResult, a0 as calculateRetryBackoffSchedule, a1 as chunkText, a2 as compressHtml, a3 as compressJson, a4 as compressMarkdown, a5 as deduplicateLines, a6 as detectPii, a7 as detectPromptInjection, a8 as detectSecrets, a9 as diffJson, aa as estimateCost, ab as estimateTokens, ac as expandQuery, ad as extractEntities, ae as extractJson, af as extractKeywords, ag as extractTables, ah as extractUrls, ai as flattenJson, aj as formatFewShotExamples, ak as lintToolSchema, al as mergeJson, am as redactPii, an as repairJson, ao as rerankChunks, ap as sanitizeHtml, aq as scoreRelevance, ar as summarizeForLlm, as as trimToTokens, at as unflattenJson, au as validateJsonSchema, av as vectorSimilarity } from '../ai_agent-DeCy0oZK.cjs';
1
+ export { C as ChunkStrategy, b as CompressHtmlResult, c as CompressJsonResult, d as CompressMarkdownResult, e as CostEstimate, D as DedupeResult, f as DedupeStrategy, g as DiffEntry2, h as DiffOp2, i as DiffResult2, E as Entity2, j as EntityType2, k as ExtractJsonResult, l as ExtractKeywordsResult, m as ExtractUrlsResult, F as FewShotExample, n as FewShotFormat, o as FewShotFormatResult, I as InjectionDetectResult, p as InjectionFinding, J as JsonBlock, q as JsonRepairResult, K as Keyword, M as MODEL_PRICING, r as MergeResult, s as MergeStrategy, t as ModelPricing, P as PiiDetectResult, u as PiiFinding, v as PiiType, w as PromptTemplateVariable, x as PromptTemplateVariableResult, R as RankedChunk, y as RelevanceResult, z as RetryBackoffAttempt, A as RetryBackoffInput, B as RetryBackoffResult, G as RetryJitterMode, S as SanitizeResult, H as SecretDetectResult, L as SecretFinding, N as SecretType, O as SummaryResult, T as TableResult2, Q as TextChunk, U as TokenEstimate, V as TokenEstimateResult, W as ToolSchemaIssue, X as ToolSchemaLintResult, Y as TrimResult, Z as TrimStrategy, _ as UrlMatch, $ as ValidationError, a0 as ValidationResult, a1 as VectorSimilarityResult, a2 as calculateRetryBackoffSchedule, a3 as chunkText, a4 as compressHtml, a5 as compressJson, a6 as compressMarkdown, a7 as deduplicateLines, a8 as detectPii, a9 as detectPromptInjection, aa as detectSecrets, ab as diffJson, ac as estimateCost, ad as estimateTokens, ae as expandQuery, af as extractEntities, ag as extractJson, ah as extractKeywords, ai as extractPromptTemplateVariables, aj as extractTables, ak as extractUrls, al as flattenJson, am as formatFewShotExamples, an as lintToolSchema, ao as mergeJson, ap as redactPii, aq as repairJson, ar as rerankChunks, as as sanitizeHtml, at as scoreRelevance, au as summarizeForLlm, av as trimToTokens, aw as unflattenJson, ax as validateJsonSchema, ay as vectorSimilarity } from '../ai_agent-B9wWLBDf.cjs';
@@ -1 +1 @@
1
- export { C as ChunkStrategy, b as CompressHtmlResult, c as CompressJsonResult, d as CompressMarkdownResult, e as CostEstimate, D as DedupeResult, f as DedupeStrategy, g as DiffEntry2, h as DiffOp2, i as DiffResult2, E as Entity2, j as EntityType2, k as ExtractJsonResult, l as ExtractKeywordsResult, m as ExtractUrlsResult, F as FewShotExample, n as FewShotFormat, o as FewShotFormatResult, I as InjectionDetectResult, p as InjectionFinding, J as JsonBlock, q as JsonRepairResult, K as Keyword, M as MODEL_PRICING, r as MergeResult, s as MergeStrategy, t as ModelPricing, P as PiiDetectResult, u as PiiFinding, v as PiiType, R as RankedChunk, w as RelevanceResult, x as RetryBackoffAttempt, y as RetryBackoffInput, z as RetryBackoffResult, A as RetryJitterMode, S as SanitizeResult, B as SecretDetectResult, G as SecretFinding, H as SecretType, L as SummaryResult, T as TableResult2, N as TextChunk, O as TokenEstimate, Q as TokenEstimateResult, U as ToolSchemaIssue, V as ToolSchemaLintResult, W as TrimResult, X as TrimStrategy, Y as UrlMatch, Z as ValidationError, _ as ValidationResult, $ as VectorSimilarityResult, a0 as calculateRetryBackoffSchedule, a1 as chunkText, a2 as compressHtml, a3 as compressJson, a4 as compressMarkdown, a5 as deduplicateLines, a6 as detectPii, a7 as detectPromptInjection, a8 as detectSecrets, a9 as diffJson, aa as estimateCost, ab as estimateTokens, ac as expandQuery, ad as extractEntities, ae as extractJson, af as extractKeywords, ag as extractTables, ah as extractUrls, ai as flattenJson, aj as formatFewShotExamples, ak as lintToolSchema, al as mergeJson, am as redactPii, an as repairJson, ao as rerankChunks, ap as sanitizeHtml, aq as scoreRelevance, ar as summarizeForLlm, as as trimToTokens, at as unflattenJson, au as validateJsonSchema, av as vectorSimilarity } from '../ai_agent-DeCy0oZK.js';
1
+ export { C as ChunkStrategy, b as CompressHtmlResult, c as CompressJsonResult, d as CompressMarkdownResult, e as CostEstimate, D as DedupeResult, f as DedupeStrategy, g as DiffEntry2, h as DiffOp2, i as DiffResult2, E as Entity2, j as EntityType2, k as ExtractJsonResult, l as ExtractKeywordsResult, m as ExtractUrlsResult, F as FewShotExample, n as FewShotFormat, o as FewShotFormatResult, I as InjectionDetectResult, p as InjectionFinding, J as JsonBlock, q as JsonRepairResult, K as Keyword, M as MODEL_PRICING, r as MergeResult, s as MergeStrategy, t as ModelPricing, P as PiiDetectResult, u as PiiFinding, v as PiiType, w as PromptTemplateVariable, x as PromptTemplateVariableResult, R as RankedChunk, y as RelevanceResult, z as RetryBackoffAttempt, A as RetryBackoffInput, B as RetryBackoffResult, G as RetryJitterMode, S as SanitizeResult, H as SecretDetectResult, L as SecretFinding, N as SecretType, O as SummaryResult, T as TableResult2, Q as TextChunk, U as TokenEstimate, V as TokenEstimateResult, W as ToolSchemaIssue, X as ToolSchemaLintResult, Y as TrimResult, Z as TrimStrategy, _ as UrlMatch, $ as ValidationError, a0 as ValidationResult, a1 as VectorSimilarityResult, a2 as calculateRetryBackoffSchedule, a3 as chunkText, a4 as compressHtml, a5 as compressJson, a6 as compressMarkdown, a7 as deduplicateLines, a8 as detectPii, a9 as detectPromptInjection, aa as detectSecrets, ab as diffJson, ac as estimateCost, ad as estimateTokens, ae as expandQuery, af as extractEntities, ag as extractJson, ah as extractKeywords, ai as extractPromptTemplateVariables, aj as extractTables, ak as extractUrls, al as flattenJson, am as formatFewShotExamples, an as lintToolSchema, ao as mergeJson, ap as redactPii, aq as repairJson, ar as rerankChunks, as as sanitizeHtml, at as scoreRelevance, au as summarizeForLlm, av as trimToTokens, aw as unflattenJson, ax as validateJsonSchema, ay as vectorSimilarity } from '../ai_agent-B9wWLBDf.js';
@@ -1,2 +1,2 @@
1
- export { MODEL_PRICING, 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 } from '../chunk-HJLGUNSO.js';
1
+ export { MODEL_PRICING, 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 } from '../chunk-5VVC7BHS.js';
2
2
  import '../chunk-MLKGABMK.js';