dabke 0.82.0 → 0.83.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +6 -3
  3. package/dist/cpsat/rules/index.d.ts +3 -0
  4. package/dist/cpsat/rules/index.d.ts.map +1 -1
  5. package/dist/cpsat/rules/index.js +3 -0
  6. package/dist/cpsat/rules/index.js.map +1 -1
  7. package/dist/cpsat/rules/max-days-week.d.ts +44 -0
  8. package/dist/cpsat/rules/max-days-week.d.ts.map +1 -0
  9. package/dist/cpsat/rules/max-days-week.js +95 -0
  10. package/dist/cpsat/rules/max-days-week.js.map +1 -0
  11. package/dist/cpsat/rules/min-days-week.d.ts +34 -0
  12. package/dist/cpsat/rules/min-days-week.d.ts.map +1 -0
  13. package/dist/cpsat/rules/min-days-week.js +84 -0
  14. package/dist/cpsat/rules/min-days-week.js.map +1 -0
  15. package/dist/cpsat/rules/must-assign.d.ts +49 -0
  16. package/dist/cpsat/rules/must-assign.d.ts.map +1 -0
  17. package/dist/cpsat/rules/must-assign.js +86 -0
  18. package/dist/cpsat/rules/must-assign.js.map +1 -0
  19. package/dist/cpsat/rules/registry.d.ts +4 -1
  20. package/dist/cpsat/rules/registry.d.ts.map +1 -1
  21. package/dist/cpsat/rules/registry.js +4 -1
  22. package/dist/cpsat/rules/registry.js.map +1 -1
  23. package/dist/cpsat/rules/rules.types.d.ts +3 -0
  24. package/dist/cpsat/rules/rules.types.d.ts.map +1 -1
  25. package/dist/cpsat/rules/scope.types.d.ts +1 -1
  26. package/dist/index.d.ts +5 -3
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +4 -2
  29. package/dist/index.js.map +1 -1
  30. package/dist/schedule/cost.d.ts +204 -0
  31. package/dist/schedule/cost.d.ts.map +1 -0
  32. package/dist/schedule/cost.js +187 -0
  33. package/dist/schedule/cost.js.map +1 -0
  34. package/dist/schedule/coverage.d.ts +85 -0
  35. package/dist/schedule/coverage.d.ts.map +1 -0
  36. package/dist/schedule/coverage.js +33 -0
  37. package/dist/schedule/coverage.js.map +1 -0
  38. package/dist/schedule/definition.d.ts +227 -0
  39. package/dist/schedule/definition.d.ts.map +1 -0
  40. package/dist/{schedule.js → schedule/definition.js} +9 -673
  41. package/dist/schedule/definition.js.map +1 -0
  42. package/dist/schedule/index.d.ts +67 -0
  43. package/dist/schedule/index.d.ts.map +1 -0
  44. package/dist/schedule/index.js +69 -0
  45. package/dist/schedule/index.js.map +1 -0
  46. package/dist/schedule/rules.d.ts +353 -0
  47. package/dist/schedule/rules.d.ts.map +1 -0
  48. package/dist/schedule/rules.js +352 -0
  49. package/dist/schedule/rules.js.map +1 -0
  50. package/dist/schedule/shift-patterns.d.ts +34 -0
  51. package/dist/schedule/shift-patterns.d.ts.map +1 -0
  52. package/dist/schedule/shift-patterns.js +41 -0
  53. package/dist/schedule/shift-patterns.js.map +1 -0
  54. package/dist/schedule/time-periods.d.ts +69 -0
  55. package/dist/schedule/time-periods.d.ts.map +1 -0
  56. package/dist/schedule/time-periods.js +91 -0
  57. package/dist/schedule/time-periods.js.map +1 -0
  58. package/package.json +4 -9
  59. package/src/cpsat/rules/index.ts +3 -0
  60. package/src/cpsat/rules/max-days-week.ts +143 -0
  61. package/src/cpsat/rules/min-days-week.ts +120 -0
  62. package/src/cpsat/rules/must-assign.ts +108 -0
  63. package/src/cpsat/rules/registry.ts +6 -0
  64. package/src/cpsat/rules/rules.types.ts +3 -0
  65. package/src/cpsat/rules/scope.types.ts +1 -1
  66. package/src/index.ts +8 -3
  67. package/src/schedule/cost.ts +242 -0
  68. package/src/schedule/coverage.ts +135 -0
  69. package/src/schedule/definition.ts +958 -0
  70. package/src/schedule/index.ts +112 -0
  71. package/src/schedule/rules.ts +529 -0
  72. package/src/schedule/shift-patterns.ts +46 -0
  73. package/src/schedule/time-periods.ts +110 -0
  74. package/dist/llms.d.ts +0 -2
  75. package/dist/llms.d.ts.map +0 -1
  76. package/dist/llms.js +0 -3
  77. package/dist/llms.js.map +0 -1
  78. package/dist/schedule.d.ts +0 -917
  79. package/dist/schedule.d.ts.map +0 -1
  80. package/dist/schedule.js.map +0 -1
  81. package/llms.txt +0 -758
  82. package/src/llms.ts +0 -3
  83. package/src/schedule.ts +0 -1960
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Time period primitives: day constants and time constructors.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import type { DayOfWeek, TimeOfDay } from "../types.js";
8
+ import type {
9
+ SemanticTimeDef,
10
+ SemanticTimeVariant,
11
+ SemanticTimeEntry,
12
+ } from "../cpsat/semantic-time.js";
13
+
14
+ /**
15
+ * Creates a {@link TimeOfDay} value.
16
+ *
17
+ * @param hours - Hour component (0-23)
18
+ * @param minutes - Minute component (0-59)
19
+ *
20
+ * @example Hours only
21
+ * ```ts
22
+ * t(9) // { hours: 9, minutes: 0 }
23
+ * ```
24
+ *
25
+ * @example Hours and minutes
26
+ * ```ts
27
+ * t(17, 30) // { hours: 17, minutes: 30 }
28
+ * ```
29
+ *
30
+ * @category Time Periods
31
+ */
32
+ export function t(hours: number, minutes = 0): TimeOfDay {
33
+ return { hours, minutes };
34
+ }
35
+
36
+ /**
37
+ * Monday through Friday.
38
+ *
39
+ * @category Time Periods
40
+ */
41
+ export const weekdays = [
42
+ "monday",
43
+ "tuesday",
44
+ "wednesday",
45
+ "thursday",
46
+ "friday",
47
+ ] as const satisfies readonly [DayOfWeek, ...DayOfWeek[]];
48
+
49
+ /**
50
+ * Saturday and Sunday.
51
+ *
52
+ * @category Time Periods
53
+ */
54
+ export const weekend = ["saturday", "sunday"] as const satisfies readonly [
55
+ DayOfWeek,
56
+ ...DayOfWeek[],
57
+ ];
58
+
59
+ /**
60
+ * Define a named semantic time period.
61
+ *
62
+ * @remarks
63
+ * Each entry has `startTime`/`endTime` and optional `dayOfWeek` or `dates`
64
+ * scoping. Entries without scoping are the default.
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * times: {
69
+ * // Simple: same times every day
70
+ * lunch: time({ startTime: t(12), endTime: t(15) }),
71
+ *
72
+ * // Variants: different times on weekends
73
+ * dinner: time(
74
+ * { startTime: t(17), endTime: t(21) },
75
+ * { startTime: t(18), endTime: t(22), dayOfWeek: weekend },
76
+ * ),
77
+ *
78
+ * // Point-in-time window (keyholder at opening)
79
+ * opening: time({ startTime: t(8, 30), endTime: t(9) }),
80
+ * }
81
+ * ```
82
+ *
83
+ * @privateRemarks
84
+ * Resolution precedence: `dates` > `dayOfWeek` > default.
85
+ *
86
+ * @category Time Periods
87
+ */
88
+ export function time(
89
+ ...entries: [SemanticTimeVariant, ...SemanticTimeVariant[]]
90
+ ): SemanticTimeEntry {
91
+ // Validate: at most one default (no dayOfWeek and no dates)
92
+ const defaults = entries.filter((e) => !e.dayOfWeek && !e.dates);
93
+ if (defaults.length > 1) {
94
+ throw new Error(
95
+ "time() accepts at most one default entry (without dayOfWeek or dates). " +
96
+ `Found ${defaults.length} default entries.`,
97
+ );
98
+ }
99
+
100
+ // Single entry without scoping: simple SemanticTimeDef
101
+ if (entries.length === 1 && !entries[0].dayOfWeek && !entries[0].dates) {
102
+ return {
103
+ startTime: entries[0].startTime,
104
+ endTime: entries[0].endTime,
105
+ } satisfies SemanticTimeDef;
106
+ }
107
+
108
+ // Multiple entries or scoped entries: shallow-copy to decouple from caller
109
+ return entries.map((entry) => Object.assign({}, entry));
110
+ }
package/dist/llms.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare const apiDocs = "# dabke\n\n> Scheduling library powered by constraint programming (CP-SAT)\n\n---\n\n## Schedule Definition\n\n### `SolveResult`\n\nResult of `Schedule.solve`.\n\n**Properties:**\n- `status: SolveStatus` \u2014 Outcome of the solve attempt.\n- `assignments: ShiftAssignment[]` \u2014 Shift assignments (empty when infeasible or no solution).\n- `validation: ScheduleValidation` \u2014 Validation diagnostics from compilation.\n- `cost?: CostBreakdown` \u2014 Cost breakdown (present when cost rules are used and a solution is found).\n\n### `SolveOptions`\n\nOptions for `Schedule.solve` and `Schedule.compile`.\n\n**Properties:**\n- `dateRange: { start: string; end: string }` \u2014 The date range to schedule.\n- `pinned?: ShiftAssignment[]` \u2014 Fixed assignments from a prior solve (e.g., rolling schedule).\nThese are injected as fixed variables in the solver.\n\nNot yet implemented. Providing pinned assignments throws an error.\n\n### `ScheduleConfig`\n\nConfiguration for `schedule`.\n\nCoverage entries for the same semantic time and target stack additively.\nAn unscoped entry applies every day; adding a weekend-only entry on top\ndoubles the count on those days. Use mutually exclusive `dayOfWeek` on\nboth entries to avoid stacking. See `cover` for details.\n\n`roleIds`, `times`, `coverage`, and `shiftPatterns` are required.\nThese four fields form the minimum solvable schedule.\n\n**Properties:**\n- `roleIds: R` \u2014 Declared role IDs.\n- `skillIds?: S` \u2014 Declared skill IDs.\n- `times: T` \u2014 Named semantic time periods.\n- `coverage: CoverageEntry<keyof T & string, R[number] | NonNullable<S>[number]>[]` \u2014 Staffing requirements per time period (entries stack additively).\n- `shiftPatterns: ShiftPattern[]` \u2014 Available shift patterns.\n- `rules?: RuleEntry[]` \u2014 Scheduling rules and constraints.\n- `ruleFactories?: Record<string, CreateCpsatRuleFunction>` \u2014 Custom rule factories. Keys are rule names, values are functions\nthat take a config object and return a `CompilationRule`.\nBuilt-in rule names cannot be overridden.\n- `members?: SchedulingMember[]` \u2014 Team members (typically added via `.with()` at runtime).\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` \u2014 Days of the week the business operates (inclusion filter).\n- `weekStartsOn?: DayOfWeek` \u2014 Which day starts the week for weekly rules. Defaults to `\"monday\"`.\n\n### `schedule`\n\nCreate a schedule definition.\n\nReturns an immutable `Schedule` that can be composed via `.with()`\nand solved via `.solve()`.\n\n```typescript\nconst venue = schedule({\n roleIds: [\"waiter\", \"runner\", \"manager\"],\n skillIds: [\"senior\"],\n times: {\n lunch: time({ startTime: t(12), endTime: t(15) }),\n dinner: time(\n { startTime: t(17), endTime: t(21) },\n { startTime: t(18), endTime: t(22), dayOfWeek: weekend },\n ),\n },\n coverage: [\n cover(\"lunch\", \"waiter\", 2),\n cover(\"dinner\", \"waiter\", 4, { dayOfWeek: weekdays }),\n cover(\"dinner\", \"waiter\", 5, { dayOfWeek: weekend }),\n cover(\"dinner\", \"manager\", 1),\n ],\n shiftPatterns: [\n shift(\"lunch_shift\", t(11, 30), t(15)),\n shift(\"evening\", t(17), t(22)),\n ],\n rules: [\n maxHoursPerDay(10),\n maxHoursPerWeek(48),\n minRestBetweenShifts(11),\n ],\n});\n```\n\n### `partialSchedule`\n\nCreate a partial schedule for composition via `.with()`.\n\nUnlike `schedule`, all fields are optional. Use this for\nschedules that layer rules, coverage, or other config onto a\ncomplete base schedule.\n\n```typescript\nconst companyPolicy = partialSchedule({\n rules: [maxHoursPerWeek(40), minRestBetweenShifts(11)],\n});\n\nconst ready = venue.with(companyPolicy, teamMembers);\n```\n\n---\n\n## Time Periods\n\n### `t`\n\nCreates a `TimeOfDay` value.\n\nHours only\n```ts\nt(9) // { hours: 9, minutes: 0 }\n```\n\n**Parameters:**\n- `hours: number` \u2014 Hour component (0-23)\n- `minutes: number` \u2014 Minute component (0-59)\n\n**Returns:** `TimeOfDay`\n\n### `weekdays`\n\nMonday through Friday.\n\n```typescript\nreadonly [\"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\"]\n```\n\n### `weekend`\n\nSaturday and Sunday.\n\n```typescript\nreadonly [\"saturday\", \"sunday\"]\n```\n\n### `time`\n\nDefine a named semantic time period.\n\nEach entry has `startTime`/`endTime` and optional `dayOfWeek` or `dates`\nscoping. Entries without scoping are the default.\n\n```typescript\ntimes: {\n // Simple: same times every day\n lunch: time({ startTime: t(12), endTime: t(15) }),\n\n // Variants: different times on weekends\n dinner: time(\n { startTime: t(17), endTime: t(21) },\n { startTime: t(18), endTime: t(22), dayOfWeek: weekend },\n ),\n\n // Point-in-time window (keyholder at opening)\n opening: time({ startTime: t(8, 30), endTime: t(9) }),\n}\n```\n\n---\n\n## Coverage\n\n### `CoverageVariant`\n\nA day-specific count within a variant `cover` call.\n\nEach variant specifies a count and optional day/date scope. During\nresolution, the most specific matching variant wins for each day\n(`dates` > `dayOfWeek` > default), mirroring `SemanticTimeVariant`.\nAt most one variant may be unscoped (the default).\n\n```typescript\n// Default: 4 agents. Christmas Eve: 2.\ncover(\"peak_hours\", \"agent\",\n { count: 4 },\n { count: 2, dates: [\"2025-12-24\"] },\n)\n```\n\n**Properties:**\n- `count: number` \u2014 Number of people needed.\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` \u2014 Restrict this variant to specific days of the week.\n- `dates?: string[]` \u2014 Restrict this variant to specific dates (YYYY-MM-DD).\n- `priority?: Priority` \u2014 Defaults to `\"MANDATORY\"`.\n\n### `CoverageOptions`\n\nOptions for a `cover` call.\n\nDay/date scoping controls which days this coverage entry applies to.\nAn entry without `dayOfWeek` or `dates` applies every day in the\nscheduling period.\n\n**Properties:**\n- `skillIds?: [string, ...string[]]` \u2014 Additional skill ID filter (AND logic with the target role).\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` \u2014 Restrict to specific days of the week.\n- `dates?: string[]` \u2014 Restrict to specific dates (YYYY-MM-DD).\n- `priority?: Priority` \u2014 Defaults to `\"MANDATORY\"`.\n\n### `cover`\n\nDefines a staffing requirement for a semantic time period.\n\nEntries for the same time and role **stack additively**.\nFor weekday vs weekend staffing, use mutually exclusive `dayOfWeek`\non both entries.\n\n```typescript\ncoverage: [\n // 2 waiters during lunch\n cover(\"lunch\", \"waiter\", 2),\n\n // 1 manager OR supervisor during dinner\n cover(\"dinner\", [\"manager\", \"supervisor\"], 1),\n\n // 1 person with keyholder skill at opening\n cover(\"opening\", \"keyholder\", 1),\n\n // 1 senior waiter (role + skill AND)\n cover(\"lunch\", \"waiter\", 1, { skillIds: [\"senior\"] }),\n\n // Different counts by day (mutually exclusive dayOfWeek!)\n cover(\"lunch\", \"waiter\", 2, { dayOfWeek: weekdays }),\n cover(\"lunch\", \"waiter\", 3, { dayOfWeek: weekend }),\n]\n```\n\n**Parameters:**\n- `timeName: T` \u2014 Name of a declared semantic time\n- `target: R | [R, ...R[]]` \u2014 Role name (string), array of role names (OR logic), or skill name\n- `count: number` \u2014 Number of people needed\n- `opts?: CoverageOptions` \u2014 Options: `skillIds` (AND filter), `dayOfWeek`, `dates`, `priority`\n\n**Returns:** `CoverageEntry<T, R>`\n\n---\n\n## Shift Patterns\n\n### `shift`\n\nDefine a shift pattern: a time slot available for employee assignment.\n\nEach pattern repeats daily unless filtered by `dayOfWeek`.\n\n```typescript\nshiftPatterns: [\n shift(\"morning\", t(11, 30), t(15)),\n shift(\"evening\", t(17), t(22)),\n\n // Role-restricted shift\n shift(\"kitchen\", t(6), t(14), { roleIds: [\"chef\", \"prep_cook\"] }),\n\n // Day-restricted shift\n shift(\"saturday_short\", t(9), t(14), { dayOfWeek: [\"saturday\"] }),\n\n // Location-specific shift\n shift(\"terrace_lunch\", t(12), t(16), { locationId: \"terrace\" }),\n]\n```\n\n---\n\n## Rules\n\n### `RecurringPeriod`\n\nRecurring calendar period for time scoping.\n\n**Properties:**\n- `name: string`\n- `startMonth: number`\n- `startDay: number`\n- `endMonth: number`\n- `endDay: number`\n\n### `RuleOptions`\n\nScoping options shared by most rule functions.\n\nDefault priority is `MANDATORY`. Use `appliesTo` to scope to a\nrole, skill, or member ID. Use time scoping options (`dayOfWeek`,\n`dateRange`, `dates`) to limit when the rule applies.\nNot all rules support all scoping options. Entity-only rules\n(e.g., `maxConsecutiveDays`) ignore time scoping.\n\n**Properties:**\n- `appliesTo?: string | string[]` \u2014 Who this rule applies to (role name, skill name, or member ID).\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` \u2014 Restrict to specific days of the week.\n- `dateRange?: { start: string; end: string }` \u2014 Restrict to a date range.\n- `dates?: string[]` \u2014 Restrict to specific dates (YYYY-MM-DD).\n- `recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]]` \u2014 Restrict to recurring calendar periods.\n- `priority?: Priority` \u2014 Defaults to `\"MANDATORY\"`.\n\n### `EntityOnlyRuleOptions`\n\nOptions for rules that support entity scoping only (no time scoping).\n\nUsed by rules whose semantics are inherently per-day or per-week\n(e.g., `minHoursPerDay`, `maxConsecutiveDays`) and cannot\nbe meaningfully restricted to a date range or day of week.\n\n**Properties:**\n- `appliesTo?: string | string[]` \u2014 Who this rule applies to (role name, skill name, or member ID).\n- `priority?: Priority` \u2014 Defaults to `\"MANDATORY\"`.\n\n### `TimeOffOptions`\n\nOptions for `timeOff`.\n\nAt least one time scoping field is required (`dayOfWeek`, `dateRange`,\n`dates`, or `recurringPeriods`). Use `from`/`until` to block only part\nof a day.\n\n**Properties:**\n- `appliesTo?: string | string[]` \u2014 Who this rule applies to (role name, skill name, or member ID).\n- `from?: TimeOfDay` \u2014 Off from this time until end of day.\n- `until?: TimeOfDay` \u2014 Off from start of day until this time.\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` \u2014 Restrict to specific days of the week.\n- `dateRange?: { start: string; end: string }` \u2014 Restrict to a date range.\n- `dates?: string[]` \u2014 Restrict to specific dates (YYYY-MM-DD).\n- `recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]]` \u2014 Restrict to recurring calendar periods.\n- `priority?: Priority` \u2014 Defaults to `\"MANDATORY\"`.\n\n### `AssignTogetherOptions`\n\nOptions for `assignTogether`.\n\n**Properties:**\n- `priority?: Priority` \u2014 Defaults to `\"MANDATORY\"`.\n\n### `RuleResolveContext`\n\nContext passed to a rule's resolve function during compilation.\n\nContains the declared roles, skills, and member IDs so the resolver\ncan translate user-facing fields (like `appliesTo`) into internal\nscoping fields.\n\n**Properties:**\n- `roles: ReadonlySet<string>`\n- `skills: ReadonlySet<string>`\n- `memberIds: ReadonlySet<string>`\n\n### `defineRule`\n\nCreates a rule entry for use in `ScheduleConfig.rules`.\n\nBuilt-in rules use the helpers (`maxHoursPerDay`, `timeOff`, etc.).\nCustom rules can use `defineRule` to create entries that plug into the\nsame resolution and compilation pipeline.\n\n**Parameters:**\n- `name: string` \u2014 Rule name. Must match a key in the rule factory registry.\n- `fields: Record<string, unknown>` \u2014 Rule-specific configuration fields.\n- `resolve?: (ctx: RuleResolveContext) => Record<string, unknown> & { name: string }` \u2014 Optional custom resolver. When omitted, the default\nresolution applies: `appliesTo` is mapped to `roleIds`/`skillIds`/`memberIds`,\n`dates` is renamed to `specificDates`, and all other fields pass through.\n\n**Returns:** `RuleEntry`\n\n### `maxHoursPerDay`\n\nLimits hours per day.\n\n```typescript\nmaxHoursPerDay(10)\nmaxHoursPerDay(4, { appliesTo: \"student\", dayOfWeek: weekdays })\n```\n\n### `maxHoursPerWeek`\n\nLimits hours per scheduling week.\n\n```typescript\nmaxHoursPerWeek(48)\nmaxHoursPerWeek(20, { appliesTo: \"student\" })\n```\n\n### `minHoursPerDay`\n\nMinimum hours when assigned on a day.\n\n```typescript\nminHoursPerDay(4)\n```\n\n### `minHoursPerWeek`\n\nMinimum hours per scheduling week.\n\n```typescript\nminHoursPerWeek(20, { priority: \"HIGH\" })\n```\n\n### `maxShiftsPerDay`\n\nMaximum distinct shifts per day.\n\n```typescript\nmaxShiftsPerDay(1)\nmaxShiftsPerDay(2, { appliesTo: \"student\", dayOfWeek: weekend })\n```\n\n### `maxConsecutiveDays`\n\nMaximum consecutive working days.\n\n```typescript\nmaxConsecutiveDays(5)\n```\n\n### `minConsecutiveDays`\n\nOnce working, continue for at least this many consecutive days.\n\n```typescript\nminConsecutiveDays(2, { priority: \"HIGH\" })\n```\n\n### `minRestBetweenShifts`\n\nMinimum rest hours between shifts.\n\n```typescript\nminRestBetweenShifts(10)\n```\n\n### `preference`\n\nPrefer (`\"high\"`) or avoid (`\"low\"`) assigning. Requires `appliesTo`.\n\n```typescript\npreference(\"high\", { appliesTo: \"waiter\" })\npreference(\"low\", { appliesTo: \"student\", dayOfWeek: weekdays })\n```\n\n### `preferLocation`\n\nPrefer assigning to shifts at a specific location. Requires `appliesTo`.\n\n```typescript\npreferLocation(\"terrace\", { appliesTo: \"alice\" })\n```\n\n### `timeOff`\n\nBlock assignments during specified periods.\nRequires at least one time scope (`dayOfWeek`, `dateRange`, `dates`, or `from`/`until`).\n\n```typescript\n// Full days off\ntimeOff({ appliesTo: \"alice\", dateRange: { start: \"2024-02-01\", end: \"2024-02-05\" } })\n\n// Every weekend off\ntimeOff({ appliesTo: \"mauro\", dayOfWeek: weekend })\n\n// Wednesday afternoons off\ntimeOff({ appliesTo: \"student\", dayOfWeek: [\"wednesday\"], from: t(14) })\n```\n\n### `assignTogether`\n\nMembers work the same shifts on days they are both assigned.\n\n```typescript\nassignTogether([\"alice\", \"bob\"])\nassignTogether([\"alice\", \"bob\", \"charlie\"], { priority: \"HIGH\" })\n```\n\n---\n\n## Cost Optimization\n\n### `OvertimeTier`\n\nA single tier in a tiered overtime configuration.\n\n```typescript\n{ after: number; factor: number; }\n```\n\n### `CostRuleOptions`\n\nOptions for cost rules.\n\nCost rules are objective terms, not constraints. The `priority` field from\n`RuleOptions` does not apply.\n\n**Properties:**\n- `appliesTo?: string | string[]` \u2014 Who this rule applies to (role name, skill name, or member ID).\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` \u2014 Restrict to specific days of the week.\n- `dateRange?: { start: string; end: string }` \u2014 Restrict to a date range.\n- `dates?: string[]` \u2014 Restrict to specific dates (YYYY-MM-DD).\n- `recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]]` \u2014 Restrict to recurring calendar periods.\n\n### `minimizeCost`\n\nTells the solver to minimize total labor cost.\n\nWithout this rule, cost modifiers only affect post-solve calculation.\nWhen present, the solver actively prefers cheaper assignments.\n\nFor hourly members, penalizes each assignment proportionally to cost.\nFor salaried members, adds a fixed weekly salary cost when they have\nany assignment that week (zero marginal cost up to contracted hours).\n\nCost modifiers adjust the calculation:\n- `dayMultiplier(factor, opts?)` - multiply base rate on specific days\n- `daySurcharge(amount, opts?)` - flat extra per hour on specific days\n- `timeSurcharge(amount, window, opts?)` - flat extra per hour during a time window\n- `overtimeMultiplier({ after, factor }, opts?)` - weekly overtime multiplier\n- `overtimeSurcharge({ after, amount }, opts?)` - weekly overtime surcharge\n- `dailyOvertimeMultiplier({ after, factor }, opts?)` - daily overtime multiplier\n- `dailyOvertimeSurcharge({ after, amount }, opts?)` - daily overtime surcharge\n- `tieredOvertimeMultiplier(tiers, opts?)` - multiple overtime thresholds\n\n```ts\nminimizeCost()\n```\n\n### `dayMultiplier`\n\nMultiplies the base rate for assignments on specified days.\n\nThe base cost (1x) is already counted by `minimizeCost`;\nthis rule adds only the extra portion above 1x.\n\nWeekend multiplier\n```typescript\ndayMultiplier(1.5, { dayOfWeek: weekend })\n```\n\n### `daySurcharge`\n\nAdds a flat extra amount per hour for assignments on specified days.\n\nThe surcharge is independent of the member's base rate.\n\nWeekend surcharge\n```typescript\ndaySurcharge(500, { dayOfWeek: weekend })\n```\n\n### `timeSurcharge`\n\nAdds a flat surcharge per hour for the portion of a shift that overlaps a time-of-day window.\n\nThe window supports overnight spans (e.g., 22:00-06:00). The surcharge\nis independent of the member's base rate.\n\nNight differential\n```typescript\ntimeSurcharge(200, { from: t(22), until: t(6) })\n```\n\n**Parameters:**\n- `amountPerHour: number` \u2014 Flat surcharge per hour in smallest currency unit\n- `window: { from: TimeOfDay; until: TimeOfDay }` \u2014 Time-of-day window\n- `opts?: CostRuleOptions` \u2014 Entity and time scoping\n\n**Returns:** `RuleEntry`\n\n### `overtimeMultiplier`\n\nApplies a multiplier to hours beyond a weekly threshold.\n\nOnly the extra portion above 1x is added (the base cost is already\ncounted by `minimizeCost`).\n\n```typescript\novertimeMultiplier({ after: 40, factor: 1.5 })\n```\n\n### `overtimeSurcharge`\n\nAdds a flat surcharge per hour beyond a weekly threshold.\n\nThe surcharge is independent of the member's base rate.\n\n```typescript\novertimeSurcharge({ after: 40, amount: 1000 })\n```\n\n### `dailyOvertimeMultiplier`\n\nApplies a multiplier to hours beyond a daily threshold.\n\nOnly the extra portion above 1x is added (the base cost is already\ncounted by `minimizeCost`).\n\n```typescript\ndailyOvertimeMultiplier({ after: 8, factor: 1.5 })\n```\n\n### `dailyOvertimeSurcharge`\n\nAdds a flat surcharge per hour beyond a daily threshold.\n\nThe surcharge is independent of the member's base rate.\n\n```typescript\ndailyOvertimeSurcharge({ after: 8, amount: 500 })\n```\n\n### `tieredOvertimeMultiplier`\n\nApplies multiple overtime thresholds with increasing multipliers.\n\nEach tier applies only to the hours between its threshold and the next.\nTiers must be sorted by threshold ascending.\n\n```typescript\n// Hours 0-40: base rate\n// Hours 40-48: 1.5x\n// Hours 48+: 2.0x\ntieredOvertimeMultiplier([\n { after: 40, factor: 1.5 },\n { after: 48, factor: 2.0 },\n])\n```\n\n---\n\n## Supporting Types\n\n### `DayOfWeek`\n\nDay of the week identifier.\n\n```typescript\n\"monday\" | \"tuesday\" | \"wednesday\" | \"thursday\" | \"friday\" | \"saturday\" | \"sunday\"\n```\n\n### `TimeOfDay`\n\nTime of day (24-hour format).\n\n**Properties:**\n- `hours: number`\n- `minutes: number`\n\n### `SchedulingPeriod`\n\nDefines a scheduling period as a date range with optional filters.\n\nThe `dateRange` specifies the overall scheduling window. Use `dayOfWeek`\nand/or `dates` to narrow which days within the range are included.\nFilters compose: a day must pass all specified filters to be included.\n\nAll days in a week\n```typescript\nconst period: SchedulingPeriod = {\ndateRange: { start: '2025-02-03', end: '2025-02-09' },\n};\n```\n\n**Properties:**\n- `dateRange: { start: string; end: string }` \u2014 The overall scheduling window (start and end are inclusive).\nDates should be in YYYY-MM-DD format.\n- `dayOfWeek?: readonly DayOfWeek[]` \u2014 Include only these days of the week.\nIf omitted, all days of the week are included.\n- `dates?: string[]` \u2014 Include only these specific dates (YYYY-MM-DD) within the range.\nIf omitted, all dates in the range are included (subject to dayOfWeek filter).\n\n### `HourlyPay`\n\nPay per hour in the caller's smallest currency unit (e.g., pence, cents).\n\n**Properties:**\n- `hourlyRate: number` \u2014 Pay per hour in smallest currency unit.\n\n### `SalariedPay`\n\nAnnual salary with contracted weekly hours.\n\nThe solver treats salaried members as having a fixed weekly cost\n(`annual / 52`) that is incurred once they work any shift in a week.\nAdditional shifts within the same week have zero marginal cost.\n\nNote: overtime multiplier rules apply only to hourly members.\nOvertime surcharge rules apply to all members regardless of pay type.\n\n**Properties:**\n- `annual: number` \u2014 Annual salary in smallest currency unit.\n- `hoursPerWeek: number` \u2014 Contracted hours per week. Reserved for future overtime support.\n\n### `Priority`\n\nHow strictly the solver enforces a rule.\n\n- `\"LOW\"`, `\"MEDIUM\"`, `\"HIGH\"`: soft constraints with increasing penalty for violations\n- `\"MANDATORY\"`: hard constraint; the solver will not produce a solution that violates it\n\n```typescript\n\"LOW\" | \"MEDIUM\" | \"HIGH\" | \"MANDATORY\"\n```\n\n### `SchedulingMember`\n\nA team member available for scheduling.\n\nMembers are assigned to shift patterns by the solver based on\ncoverage requirements, rules, and constraints.\n\n**Properties:**\n- `id: string` \u2014 Unique identifier for this member. Must not contain colons.\n- `roleIds: string[]` \u2014 Role IDs this member can fill (e.g. \"nurse\", \"doctor\").\n- `skillIds?: string[]` \u2014 Skill IDs this member has (e.g. \"charge_nurse\", \"forklift\").\n- `pay?: HourlyPay | SalariedPay` \u2014 Base pay. Required when cost rules are used.\n\n### `ShiftPattern`\n\nA shift pattern defines WHEN people can work: the time slots available for assignment.\n\nShift patterns are templates that repeat across all scheduling days. The solver assigns\nteam members to these patterns based on coverage requirements and constraints.\n\n// Simple setup: one shift type, anyone can work it\nconst patterns: ShiftPattern[] = [\n { id: \"day\", startTime: { hours: 9 }, endTime: { hours: 17 } }\n];\n\n**Properties:**\n- `id: string` \u2014 Unique identifier for this shift pattern.\nUsed in assignments and rule configurations.\n- `roleIds?: [string, ...string[]]` \u2014 Restricts who can be assigned to this shift based on their role IDs.\n\n- If omitted: anyone can work this shift\n- If provided: only team members whose roles overlap with this list can be assigned\n\nMost venues have the same shifts for everyone and don't need this.\nUse it when different roles have different schedules (e.g., kitchen staff starts\nearlier than floor staff).\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` \u2014 Restricts which days of the week this shift pattern can be used.\n\n- If omitted: shift can be used on any day\n- If provided: shift can only be assigned on the specified days\n\n```typescript\n// Saturday-only short shift\n{ id: \"saturday_shift\", startTime: t(9), endTime: t(14), dayOfWeek: [\"saturday\"] }\n\n// Weekday-only full shift\n{ id: \"full_shift\", startTime: t(9), endTime: t(18), dayOfWeek: [\"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\"] }\n```\n- `locationId?: string` \u2014 Physical location where this shift takes place.\nUsed for multi-location scheduling and location-based constraints.\n- `startTime: TimeOfDay` \u2014 When the shift starts (e.g., `{ hours: 9, minutes: 0 }` for 9:00 AM)\n- `endTime: TimeOfDay` \u2014 When the shift ends (e.g., `{ hours: 17, minutes: 30 }` for 5:30 PM)\n\n";
2
- //# sourceMappingURL=llms.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"llms.d.ts","sourceRoot":"","sources":["../src/llms.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,owtBACkrsB,CAAC"}
package/dist/llms.js DELETED
@@ -1,3 +0,0 @@
1
- // Auto-generated — do not edit manually
2
- export const apiDocs = '# dabke\n\n> Scheduling library powered by constraint programming (CP-SAT)\n\n---\n\n## Schedule Definition\n\n### `SolveResult`\n\nResult of `Schedule.solve`.\n\n**Properties:**\n- `status: SolveStatus` — Outcome of the solve attempt.\n- `assignments: ShiftAssignment[]` — Shift assignments (empty when infeasible or no solution).\n- `validation: ScheduleValidation` — Validation diagnostics from compilation.\n- `cost?: CostBreakdown` — Cost breakdown (present when cost rules are used and a solution is found).\n\n### `SolveOptions`\n\nOptions for `Schedule.solve` and `Schedule.compile`.\n\n**Properties:**\n- `dateRange: { start: string; end: string }` — The date range to schedule.\n- `pinned?: ShiftAssignment[]` — Fixed assignments from a prior solve (e.g., rolling schedule).\nThese are injected as fixed variables in the solver.\n\nNot yet implemented. Providing pinned assignments throws an error.\n\n### `ScheduleConfig`\n\nConfiguration for `schedule`.\n\nCoverage entries for the same semantic time and target stack additively.\nAn unscoped entry applies every day; adding a weekend-only entry on top\ndoubles the count on those days. Use mutually exclusive `dayOfWeek` on\nboth entries to avoid stacking. See `cover` for details.\n\n`roleIds`, `times`, `coverage`, and `shiftPatterns` are required.\nThese four fields form the minimum solvable schedule.\n\n**Properties:**\n- `roleIds: R` — Declared role IDs.\n- `skillIds?: S` — Declared skill IDs.\n- `times: T` — Named semantic time periods.\n- `coverage: CoverageEntry<keyof T & string, R[number] | NonNullable<S>[number]>[]` — Staffing requirements per time period (entries stack additively).\n- `shiftPatterns: ShiftPattern[]` — Available shift patterns.\n- `rules?: RuleEntry[]` — Scheduling rules and constraints.\n- `ruleFactories?: Record<string, CreateCpsatRuleFunction>` — Custom rule factories. Keys are rule names, values are functions\nthat take a config object and return a `CompilationRule`.\nBuilt-in rule names cannot be overridden.\n- `members?: SchedulingMember[]` — Team members (typically added via `.with()` at runtime).\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` — Days of the week the business operates (inclusion filter).\n- `weekStartsOn?: DayOfWeek` — Which day starts the week for weekly rules. Defaults to `"monday"`.\n\n### `schedule`\n\nCreate a schedule definition.\n\nReturns an immutable `Schedule` that can be composed via `.with()`\nand solved via `.solve()`.\n\n```typescript\nconst venue = schedule({\n roleIds: ["waiter", "runner", "manager"],\n skillIds: ["senior"],\n times: {\n lunch: time({ startTime: t(12), endTime: t(15) }),\n dinner: time(\n { startTime: t(17), endTime: t(21) },\n { startTime: t(18), endTime: t(22), dayOfWeek: weekend },\n ),\n },\n coverage: [\n cover("lunch", "waiter", 2),\n cover("dinner", "waiter", 4, { dayOfWeek: weekdays }),\n cover("dinner", "waiter", 5, { dayOfWeek: weekend }),\n cover("dinner", "manager", 1),\n ],\n shiftPatterns: [\n shift("lunch_shift", t(11, 30), t(15)),\n shift("evening", t(17), t(22)),\n ],\n rules: [\n maxHoursPerDay(10),\n maxHoursPerWeek(48),\n minRestBetweenShifts(11),\n ],\n});\n```\n\n### `partialSchedule`\n\nCreate a partial schedule for composition via `.with()`.\n\nUnlike `schedule`, all fields are optional. Use this for\nschedules that layer rules, coverage, or other config onto a\ncomplete base schedule.\n\n```typescript\nconst companyPolicy = partialSchedule({\n rules: [maxHoursPerWeek(40), minRestBetweenShifts(11)],\n});\n\nconst ready = venue.with(companyPolicy, teamMembers);\n```\n\n---\n\n## Time Periods\n\n### `t`\n\nCreates a `TimeOfDay` value.\n\nHours only\n```ts\nt(9) // { hours: 9, minutes: 0 }\n```\n\n**Parameters:**\n- `hours: number` — Hour component (0-23)\n- `minutes: number` — Minute component (0-59)\n\n**Returns:** `TimeOfDay`\n\n### `weekdays`\n\nMonday through Friday.\n\n```typescript\nreadonly ["monday", "tuesday", "wednesday", "thursday", "friday"]\n```\n\n### `weekend`\n\nSaturday and Sunday.\n\n```typescript\nreadonly ["saturday", "sunday"]\n```\n\n### `time`\n\nDefine a named semantic time period.\n\nEach entry has `startTime`/`endTime` and optional `dayOfWeek` or `dates`\nscoping. Entries without scoping are the default.\n\n```typescript\ntimes: {\n // Simple: same times every day\n lunch: time({ startTime: t(12), endTime: t(15) }),\n\n // Variants: different times on weekends\n dinner: time(\n { startTime: t(17), endTime: t(21) },\n { startTime: t(18), endTime: t(22), dayOfWeek: weekend },\n ),\n\n // Point-in-time window (keyholder at opening)\n opening: time({ startTime: t(8, 30), endTime: t(9) }),\n}\n```\n\n---\n\n## Coverage\n\n### `CoverageVariant`\n\nA day-specific count within a variant `cover` call.\n\nEach variant specifies a count and optional day/date scope. During\nresolution, the most specific matching variant wins for each day\n(`dates` > `dayOfWeek` > default), mirroring `SemanticTimeVariant`.\nAt most one variant may be unscoped (the default).\n\n```typescript\n// Default: 4 agents. Christmas Eve: 2.\ncover("peak_hours", "agent",\n { count: 4 },\n { count: 2, dates: ["2025-12-24"] },\n)\n```\n\n**Properties:**\n- `count: number` — Number of people needed.\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` — Restrict this variant to specific days of the week.\n- `dates?: string[]` — Restrict this variant to specific dates (YYYY-MM-DD).\n- `priority?: Priority` — Defaults to `"MANDATORY"`.\n\n### `CoverageOptions`\n\nOptions for a `cover` call.\n\nDay/date scoping controls which days this coverage entry applies to.\nAn entry without `dayOfWeek` or `dates` applies every day in the\nscheduling period.\n\n**Properties:**\n- `skillIds?: [string, ...string[]]` — Additional skill ID filter (AND logic with the target role).\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` — Restrict to specific days of the week.\n- `dates?: string[]` — Restrict to specific dates (YYYY-MM-DD).\n- `priority?: Priority` — Defaults to `"MANDATORY"`.\n\n### `cover`\n\nDefines a staffing requirement for a semantic time period.\n\nEntries for the same time and role **stack additively**.\nFor weekday vs weekend staffing, use mutually exclusive `dayOfWeek`\non both entries.\n\n```typescript\ncoverage: [\n // 2 waiters during lunch\n cover("lunch", "waiter", 2),\n\n // 1 manager OR supervisor during dinner\n cover("dinner", ["manager", "supervisor"], 1),\n\n // 1 person with keyholder skill at opening\n cover("opening", "keyholder", 1),\n\n // 1 senior waiter (role + skill AND)\n cover("lunch", "waiter", 1, { skillIds: ["senior"] }),\n\n // Different counts by day (mutually exclusive dayOfWeek!)\n cover("lunch", "waiter", 2, { dayOfWeek: weekdays }),\n cover("lunch", "waiter", 3, { dayOfWeek: weekend }),\n]\n```\n\n**Parameters:**\n- `timeName: T` — Name of a declared semantic time\n- `target: R | [R, ...R[]]` — Role name (string), array of role names (OR logic), or skill name\n- `count: number` — Number of people needed\n- `opts?: CoverageOptions` — Options: `skillIds` (AND filter), `dayOfWeek`, `dates`, `priority`\n\n**Returns:** `CoverageEntry<T, R>`\n\n---\n\n## Shift Patterns\n\n### `shift`\n\nDefine a shift pattern: a time slot available for employee assignment.\n\nEach pattern repeats daily unless filtered by `dayOfWeek`.\n\n```typescript\nshiftPatterns: [\n shift("morning", t(11, 30), t(15)),\n shift("evening", t(17), t(22)),\n\n // Role-restricted shift\n shift("kitchen", t(6), t(14), { roleIds: ["chef", "prep_cook"] }),\n\n // Day-restricted shift\n shift("saturday_short", t(9), t(14), { dayOfWeek: ["saturday"] }),\n\n // Location-specific shift\n shift("terrace_lunch", t(12), t(16), { locationId: "terrace" }),\n]\n```\n\n---\n\n## Rules\n\n### `RecurringPeriod`\n\nRecurring calendar period for time scoping.\n\n**Properties:**\n- `name: string`\n- `startMonth: number`\n- `startDay: number`\n- `endMonth: number`\n- `endDay: number`\n\n### `RuleOptions`\n\nScoping options shared by most rule functions.\n\nDefault priority is `MANDATORY`. Use `appliesTo` to scope to a\nrole, skill, or member ID. Use time scoping options (`dayOfWeek`,\n`dateRange`, `dates`) to limit when the rule applies.\nNot all rules support all scoping options. Entity-only rules\n(e.g., `maxConsecutiveDays`) ignore time scoping.\n\n**Properties:**\n- `appliesTo?: string | string[]` — Who this rule applies to (role name, skill name, or member ID).\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` — Restrict to specific days of the week.\n- `dateRange?: { start: string; end: string }` — Restrict to a date range.\n- `dates?: string[]` — Restrict to specific dates (YYYY-MM-DD).\n- `recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]]` — Restrict to recurring calendar periods.\n- `priority?: Priority` — Defaults to `"MANDATORY"`.\n\n### `EntityOnlyRuleOptions`\n\nOptions for rules that support entity scoping only (no time scoping).\n\nUsed by rules whose semantics are inherently per-day or per-week\n(e.g., `minHoursPerDay`, `maxConsecutiveDays`) and cannot\nbe meaningfully restricted to a date range or day of week.\n\n**Properties:**\n- `appliesTo?: string | string[]` — Who this rule applies to (role name, skill name, or member ID).\n- `priority?: Priority` — Defaults to `"MANDATORY"`.\n\n### `TimeOffOptions`\n\nOptions for `timeOff`.\n\nAt least one time scoping field is required (`dayOfWeek`, `dateRange`,\n`dates`, or `recurringPeriods`). Use `from`/`until` to block only part\nof a day.\n\n**Properties:**\n- `appliesTo?: string | string[]` — Who this rule applies to (role name, skill name, or member ID).\n- `from?: TimeOfDay` — Off from this time until end of day.\n- `until?: TimeOfDay` — Off from start of day until this time.\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` — Restrict to specific days of the week.\n- `dateRange?: { start: string; end: string }` — Restrict to a date range.\n- `dates?: string[]` — Restrict to specific dates (YYYY-MM-DD).\n- `recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]]` — Restrict to recurring calendar periods.\n- `priority?: Priority` — Defaults to `"MANDATORY"`.\n\n### `AssignTogetherOptions`\n\nOptions for `assignTogether`.\n\n**Properties:**\n- `priority?: Priority` — Defaults to `"MANDATORY"`.\n\n### `RuleResolveContext`\n\nContext passed to a rule\'s resolve function during compilation.\n\nContains the declared roles, skills, and member IDs so the resolver\ncan translate user-facing fields (like `appliesTo`) into internal\nscoping fields.\n\n**Properties:**\n- `roles: ReadonlySet<string>`\n- `skills: ReadonlySet<string>`\n- `memberIds: ReadonlySet<string>`\n\n### `defineRule`\n\nCreates a rule entry for use in `ScheduleConfig.rules`.\n\nBuilt-in rules use the helpers (`maxHoursPerDay`, `timeOff`, etc.).\nCustom rules can use `defineRule` to create entries that plug into the\nsame resolution and compilation pipeline.\n\n**Parameters:**\n- `name: string` — Rule name. Must match a key in the rule factory registry.\n- `fields: Record<string, unknown>` — Rule-specific configuration fields.\n- `resolve?: (ctx: RuleResolveContext) => Record<string, unknown> & { name: string }` — Optional custom resolver. When omitted, the default\nresolution applies: `appliesTo` is mapped to `roleIds`/`skillIds`/`memberIds`,\n`dates` is renamed to `specificDates`, and all other fields pass through.\n\n**Returns:** `RuleEntry`\n\n### `maxHoursPerDay`\n\nLimits hours per day.\n\n```typescript\nmaxHoursPerDay(10)\nmaxHoursPerDay(4, { appliesTo: "student", dayOfWeek: weekdays })\n```\n\n### `maxHoursPerWeek`\n\nLimits hours per scheduling week.\n\n```typescript\nmaxHoursPerWeek(48)\nmaxHoursPerWeek(20, { appliesTo: "student" })\n```\n\n### `minHoursPerDay`\n\nMinimum hours when assigned on a day.\n\n```typescript\nminHoursPerDay(4)\n```\n\n### `minHoursPerWeek`\n\nMinimum hours per scheduling week.\n\n```typescript\nminHoursPerWeek(20, { priority: "HIGH" })\n```\n\n### `maxShiftsPerDay`\n\nMaximum distinct shifts per day.\n\n```typescript\nmaxShiftsPerDay(1)\nmaxShiftsPerDay(2, { appliesTo: "student", dayOfWeek: weekend })\n```\n\n### `maxConsecutiveDays`\n\nMaximum consecutive working days.\n\n```typescript\nmaxConsecutiveDays(5)\n```\n\n### `minConsecutiveDays`\n\nOnce working, continue for at least this many consecutive days.\n\n```typescript\nminConsecutiveDays(2, { priority: "HIGH" })\n```\n\n### `minRestBetweenShifts`\n\nMinimum rest hours between shifts.\n\n```typescript\nminRestBetweenShifts(10)\n```\n\n### `preference`\n\nPrefer (`"high"`) or avoid (`"low"`) assigning. Requires `appliesTo`.\n\n```typescript\npreference("high", { appliesTo: "waiter" })\npreference("low", { appliesTo: "student", dayOfWeek: weekdays })\n```\n\n### `preferLocation`\n\nPrefer assigning to shifts at a specific location. Requires `appliesTo`.\n\n```typescript\npreferLocation("terrace", { appliesTo: "alice" })\n```\n\n### `timeOff`\n\nBlock assignments during specified periods.\nRequires at least one time scope (`dayOfWeek`, `dateRange`, `dates`, or `from`/`until`).\n\n```typescript\n// Full days off\ntimeOff({ appliesTo: "alice", dateRange: { start: "2024-02-01", end: "2024-02-05" } })\n\n// Every weekend off\ntimeOff({ appliesTo: "mauro", dayOfWeek: weekend })\n\n// Wednesday afternoons off\ntimeOff({ appliesTo: "student", dayOfWeek: ["wednesday"], from: t(14) })\n```\n\n### `assignTogether`\n\nMembers work the same shifts on days they are both assigned.\n\n```typescript\nassignTogether(["alice", "bob"])\nassignTogether(["alice", "bob", "charlie"], { priority: "HIGH" })\n```\n\n---\n\n## Cost Optimization\n\n### `OvertimeTier`\n\nA single tier in a tiered overtime configuration.\n\n```typescript\n{ after: number; factor: number; }\n```\n\n### `CostRuleOptions`\n\nOptions for cost rules.\n\nCost rules are objective terms, not constraints. The `priority` field from\n`RuleOptions` does not apply.\n\n**Properties:**\n- `appliesTo?: string | string[]` — Who this rule applies to (role name, skill name, or member ID).\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` — Restrict to specific days of the week.\n- `dateRange?: { start: string; end: string }` — Restrict to a date range.\n- `dates?: string[]` — Restrict to specific dates (YYYY-MM-DD).\n- `recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]]` — Restrict to recurring calendar periods.\n\n### `minimizeCost`\n\nTells the solver to minimize total labor cost.\n\nWithout this rule, cost modifiers only affect post-solve calculation.\nWhen present, the solver actively prefers cheaper assignments.\n\nFor hourly members, penalizes each assignment proportionally to cost.\nFor salaried members, adds a fixed weekly salary cost when they have\nany assignment that week (zero marginal cost up to contracted hours).\n\nCost modifiers adjust the calculation:\n- `dayMultiplier(factor, opts?)` - multiply base rate on specific days\n- `daySurcharge(amount, opts?)` - flat extra per hour on specific days\n- `timeSurcharge(amount, window, opts?)` - flat extra per hour during a time window\n- `overtimeMultiplier({ after, factor }, opts?)` - weekly overtime multiplier\n- `overtimeSurcharge({ after, amount }, opts?)` - weekly overtime surcharge\n- `dailyOvertimeMultiplier({ after, factor }, opts?)` - daily overtime multiplier\n- `dailyOvertimeSurcharge({ after, amount }, opts?)` - daily overtime surcharge\n- `tieredOvertimeMultiplier(tiers, opts?)` - multiple overtime thresholds\n\n```ts\nminimizeCost()\n```\n\n### `dayMultiplier`\n\nMultiplies the base rate for assignments on specified days.\n\nThe base cost (1x) is already counted by `minimizeCost`;\nthis rule adds only the extra portion above 1x.\n\nWeekend multiplier\n```typescript\ndayMultiplier(1.5, { dayOfWeek: weekend })\n```\n\n### `daySurcharge`\n\nAdds a flat extra amount per hour for assignments on specified days.\n\nThe surcharge is independent of the member\'s base rate.\n\nWeekend surcharge\n```typescript\ndaySurcharge(500, { dayOfWeek: weekend })\n```\n\n### `timeSurcharge`\n\nAdds a flat surcharge per hour for the portion of a shift that overlaps a time-of-day window.\n\nThe window supports overnight spans (e.g., 22:00-06:00). The surcharge\nis independent of the member\'s base rate.\n\nNight differential\n```typescript\ntimeSurcharge(200, { from: t(22), until: t(6) })\n```\n\n**Parameters:**\n- `amountPerHour: number` — Flat surcharge per hour in smallest currency unit\n- `window: { from: TimeOfDay; until: TimeOfDay }` — Time-of-day window\n- `opts?: CostRuleOptions` — Entity and time scoping\n\n**Returns:** `RuleEntry`\n\n### `overtimeMultiplier`\n\nApplies a multiplier to hours beyond a weekly threshold.\n\nOnly the extra portion above 1x is added (the base cost is already\ncounted by `minimizeCost`).\n\n```typescript\novertimeMultiplier({ after: 40, factor: 1.5 })\n```\n\n### `overtimeSurcharge`\n\nAdds a flat surcharge per hour beyond a weekly threshold.\n\nThe surcharge is independent of the member\'s base rate.\n\n```typescript\novertimeSurcharge({ after: 40, amount: 1000 })\n```\n\n### `dailyOvertimeMultiplier`\n\nApplies a multiplier to hours beyond a daily threshold.\n\nOnly the extra portion above 1x is added (the base cost is already\ncounted by `minimizeCost`).\n\n```typescript\ndailyOvertimeMultiplier({ after: 8, factor: 1.5 })\n```\n\n### `dailyOvertimeSurcharge`\n\nAdds a flat surcharge per hour beyond a daily threshold.\n\nThe surcharge is independent of the member\'s base rate.\n\n```typescript\ndailyOvertimeSurcharge({ after: 8, amount: 500 })\n```\n\n### `tieredOvertimeMultiplier`\n\nApplies multiple overtime thresholds with increasing multipliers.\n\nEach tier applies only to the hours between its threshold and the next.\nTiers must be sorted by threshold ascending.\n\n```typescript\n// Hours 0-40: base rate\n// Hours 40-48: 1.5x\n// Hours 48+: 2.0x\ntieredOvertimeMultiplier([\n { after: 40, factor: 1.5 },\n { after: 48, factor: 2.0 },\n])\n```\n\n---\n\n## Supporting Types\n\n### `DayOfWeek`\n\nDay of the week identifier.\n\n```typescript\n"monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday"\n```\n\n### `TimeOfDay`\n\nTime of day (24-hour format).\n\n**Properties:**\n- `hours: number`\n- `minutes: number`\n\n### `SchedulingPeriod`\n\nDefines a scheduling period as a date range with optional filters.\n\nThe `dateRange` specifies the overall scheduling window. Use `dayOfWeek`\nand/or `dates` to narrow which days within the range are included.\nFilters compose: a day must pass all specified filters to be included.\n\nAll days in a week\n```typescript\nconst period: SchedulingPeriod = {\ndateRange: { start: \'2025-02-03\', end: \'2025-02-09\' },\n};\n```\n\n**Properties:**\n- `dateRange: { start: string; end: string }` — The overall scheduling window (start and end are inclusive).\nDates should be in YYYY-MM-DD format.\n- `dayOfWeek?: readonly DayOfWeek[]` — Include only these days of the week.\nIf omitted, all days of the week are included.\n- `dates?: string[]` — Include only these specific dates (YYYY-MM-DD) within the range.\nIf omitted, all dates in the range are included (subject to dayOfWeek filter).\n\n### `HourlyPay`\n\nPay per hour in the caller\'s smallest currency unit (e.g., pence, cents).\n\n**Properties:**\n- `hourlyRate: number` — Pay per hour in smallest currency unit.\n\n### `SalariedPay`\n\nAnnual salary with contracted weekly hours.\n\nThe solver treats salaried members as having a fixed weekly cost\n(`annual / 52`) that is incurred once they work any shift in a week.\nAdditional shifts within the same week have zero marginal cost.\n\nNote: overtime multiplier rules apply only to hourly members.\nOvertime surcharge rules apply to all members regardless of pay type.\n\n**Properties:**\n- `annual: number` — Annual salary in smallest currency unit.\n- `hoursPerWeek: number` — Contracted hours per week. Reserved for future overtime support.\n\n### `Priority`\n\nHow strictly the solver enforces a rule.\n\n- `"LOW"`, `"MEDIUM"`, `"HIGH"`: soft constraints with increasing penalty for violations\n- `"MANDATORY"`: hard constraint; the solver will not produce a solution that violates it\n\n```typescript\n"LOW" | "MEDIUM" | "HIGH" | "MANDATORY"\n```\n\n### `SchedulingMember`\n\nA team member available for scheduling.\n\nMembers are assigned to shift patterns by the solver based on\ncoverage requirements, rules, and constraints.\n\n**Properties:**\n- `id: string` — Unique identifier for this member. Must not contain colons.\n- `roleIds: string[]` — Role IDs this member can fill (e.g. "nurse", "doctor").\n- `skillIds?: string[]` — Skill IDs this member has (e.g. "charge_nurse", "forklift").\n- `pay?: HourlyPay | SalariedPay` — Base pay. Required when cost rules are used.\n\n### `ShiftPattern`\n\nA shift pattern defines WHEN people can work: the time slots available for assignment.\n\nShift patterns are templates that repeat across all scheduling days. The solver assigns\nteam members to these patterns based on coverage requirements and constraints.\n\n// Simple setup: one shift type, anyone can work it\nconst patterns: ShiftPattern[] = [\n { id: "day", startTime: { hours: 9 }, endTime: { hours: 17 } }\n];\n\n**Properties:**\n- `id: string` — Unique identifier for this shift pattern.\nUsed in assignments and rule configurations.\n- `roleIds?: [string, ...string[]]` — Restricts who can be assigned to this shift based on their role IDs.\n\n- If omitted: anyone can work this shift\n- If provided: only team members whose roles overlap with this list can be assigned\n\nMost venues have the same shifts for everyone and don\'t need this.\nUse it when different roles have different schedules (e.g., kitchen staff starts\nearlier than floor staff).\n- `dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]]` — Restricts which days of the week this shift pattern can be used.\n\n- If omitted: shift can be used on any day\n- If provided: shift can only be assigned on the specified days\n\n```typescript\n// Saturday-only short shift\n{ id: "saturday_shift", startTime: t(9), endTime: t(14), dayOfWeek: ["saturday"] }\n\n// Weekday-only full shift\n{ id: "full_shift", startTime: t(9), endTime: t(18), dayOfWeek: ["monday", "tuesday", "wednesday", "thursday", "friday"] }\n```\n- `locationId?: string` — Physical location where this shift takes place.\nUsed for multi-location scheduling and location-based constraints.\n- `startTime: TimeOfDay` — When the shift starts (e.g., `{ hours: 9, minutes: 0 }` for 9:00 AM)\n- `endTime: TimeOfDay` — When the shift ends (e.g., `{ hours: 17, minutes: 30 }` for 5:30 PM)\n\n';
3
- //# sourceMappingURL=llms.js.map
package/dist/llms.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"llms.js","sourceRoot":"","sources":["../src/llms.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,MAAM,CAAC,MAAM,OAAO,GAClB,ossBAAossB,CAAC"}