clanka 0.2.18 → 0.2.20

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.
@@ -0,0 +1,219 @@
1
+ const patch = `*** Begin Patch
2
+ *** Update File: packages/effect/src/Cron.ts
3
+ @@
4
+ export const next = (cron: Cron, now?: DateTime.DateTime.Input): Date => {
5
+ + return stepCron(cron, now, "next")
6
+ +}
7
+ +
8
+ +/**
9
+ + * Returns the previous scheduled date/time for the given Cron instance.
10
+ + *
11
+ + * This function calculates the most recent date and time when the cron
12
+ + * schedule should have triggered, before the specified date (or current
13
+ + * time if not provided).
14
+ + *
15
+ + * @example
16
+ + * ```ts
17
+ + * import { Cron, Result } from "effect"
18
+ + *
19
+ + * const cron = Result.getOrThrow(Cron.parse("0 0 4 8-14 * *"))
20
+ + *
21
+ + * // Get previous run before a specific date
22
+ + * const before = new Date("2021-01-15T00:00:00Z")
23
+ + * const previousRun = Cron.prev(cron, before)
24
+ + * console.log(previousRun) // 2021-01-14T04:00:00.000Z
25
+ + *
26
+ + * // Get previous run from current time
27
+ + * const previousFromNow = Cron.prev(cron)
28
+ + * console.log(previousFromNow) // Previous occurrence from now
29
+ + * ```
30
+ + *
31
+ + * @since 4.0.0
32
+ + * @category utils
33
+ + */
34
+ +export const prev = (cron: Cron, now?: DateTime.DateTime.Input): Date => {
35
+ + return stepCron(cron, now, "prev")
36
+ +}
37
+ +
38
+ +const stepCron = (cron: Cron, now: DateTime.DateTime.Input | undefined, direction: "next" | "prev"): Date => {
39
+ const tz = Option.getOrUndefined(cron.tz)
40
+ const zoned = dateTime.makeZonedUnsafe(now ?? new Date(), {
41
+ timeZone: tz
42
+ })
43
+ +
44
+ + const reverse = direction === "prev"
45
+ + const tick = reverse ? -1 : 1
46
+ + const table = cron[direction]
47
+ + const boundary = reverse ? cron.last : cron.first
48
+ +
49
+ + const needsStep = reverse ?
50
+ + (next: number, current: number) => next < current :
51
+ + (next: number, current: number) => next > current
52
+
53
+ const utc = tz !== undefined && dateTime.isTimeZoneNamed(tz) && tz.id === "UTC"
54
+ const adjustDst = utc ? constVoid : (current: Date) => {
55
+ const adjusted = dateTime.makeZonedUnsafe(current, {
56
+ timeZone: zoned.zone,
57
+ - adjustForTimeZone: true
58
+ + adjustForTimeZone: true,
59
+ + disambiguation: reverse ? "later" : undefined
60
+ }).pipe(dateTime.toDate)
61
+
62
+ - // TODO: This implementation currently only skips forward when transitioning into daylight savings time.
63
+ const drift = current.getTime() - adjusted.getTime()
64
+ - if (drift > 0) {
65
+ - current.setTime(current.getTime() + drift)
66
+ + if (reverse ? drift !== 0 : drift > 0) {
67
+ + current.setTime(adjusted.getTime())
68
+ }
69
+ }
70
+
71
+ const result = dateTime.mutate(zoned, (current) => {
72
+ - current.setUTCSeconds(current.getUTCSeconds() + 1, 0)
73
+ + current.setUTCSeconds(current.getUTCSeconds() + tick, 0)
74
+
75
+ for (let i = 0; i < 10_000; i++) {
76
+ if (cron.seconds.size !== 0) {
77
+ const currentSecond = current.getUTCSeconds()
78
+ - const nextSecond = cron.next.second[currentSecond]
79
+ + const nextSecond = table.second[currentSecond]
80
+ if (nextSecond === undefined) {
81
+ - current.setUTCMinutes(current.getUTCMinutes() + 1, cron.first.second)
82
+ + current.setUTCMinutes(current.getUTCMinutes() + tick, boundary.second)
83
+ adjustDst(current)
84
+ continue
85
+ }
86
+ - if (nextSecond > currentSecond) {
87
+ + if (needsStep(nextSecond, currentSecond)) {
88
+ current.setUTCSeconds(nextSecond)
89
+ adjustDst(current)
90
+ continue
91
+ }
92
+ }
93
+
94
+ if (cron.minutes.size !== 0) {
95
+ const currentMinute = current.getUTCMinutes()
96
+ - const nextMinute = cron.next.minute[currentMinute]
97
+ + const nextMinute = table.minute[currentMinute]
98
+ if (nextMinute === undefined) {
99
+ - current.setUTCHours(current.getUTCHours() + 1, cron.first.minute, cron.first.second)
100
+ + current.setUTCHours(current.getUTCHours() + tick, boundary.minute, boundary.second)
101
+ adjustDst(current)
102
+ continue
103
+ }
104
+ - if (nextMinute > currentMinute) {
105
+ - current.setUTCMinutes(nextMinute, cron.first.second)
106
+ + if (needsStep(nextMinute, currentMinute)) {
107
+ + current.setUTCMinutes(nextMinute, boundary.second)
108
+ adjustDst(current)
109
+ continue
110
+ }
111
+ }
112
+
113
+ if (cron.hours.size !== 0) {
114
+ const currentHour = current.getUTCHours()
115
+ - const nextHour = cron.next.hour[currentHour]
116
+ + const nextHour = table.hour[currentHour]
117
+ if (nextHour === undefined) {
118
+ - current.setUTCDate(current.getUTCDate() + 1)
119
+ - current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
120
+ + current.setUTCDate(current.getUTCDate() + tick)
121
+ + current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
122
+ adjustDst(current)
123
+ continue
124
+ }
125
+ - if (nextHour > currentHour) {
126
+ - current.setUTCHours(nextHour, cron.first.minute, cron.first.second)
127
+ + if (needsStep(nextHour, currentHour)) {
128
+ + current.setUTCHours(nextHour, boundary.minute, boundary.second)
129
+ adjustDst(current)
130
+ continue
131
+ }
132
+ }
133
+
134
+ if (cron.weekdays.size !== 0 || cron.days.size !== 0) {
135
+ - let a: number = Infinity
136
+ - let b: number = Infinity
137
+ + let a: number = reverse ? -Infinity : Infinity
138
+ + let b: number = reverse ? -Infinity : Infinity
139
+
140
+ if (cron.weekdays.size !== 0) {
141
+ const currentWeekday = current.getUTCDay()
142
+ - const nextWeekday = cron.next.weekday[currentWeekday]
143
+ - a = nextWeekday === undefined ? 7 - currentWeekday + cron.first.weekday : nextWeekday - currentWeekday
144
+ + const nextWeekday = table.weekday[currentWeekday]
145
+ + if (nextWeekday === undefined) {
146
+ + a = reverse ?
147
+ + currentWeekday - 7 + boundary.weekday :
148
+ + 7 - currentWeekday + boundary.weekday
149
+ + } else {
150
+ + a = nextWeekday - currentWeekday
151
+ + }
152
+ }
153
+
154
+ if (cron.days.size !== 0 && a !== 0) {
155
+ const currentDay = current.getUTCDate()
156
+ - const nextDay = cron.next.day[currentDay]
157
+ - b = nextDay === undefined ? daysInMonth(current) - currentDay + cron.first.day : nextDay - currentDay
158
+ + const nextDay = table.day[currentDay]
159
+ + if (nextDay === undefined) {
160
+ + if (reverse) {
161
+ + const prevMonthDays = daysInMonth(new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), 0)))
162
+ + b = -(currentDay + (prevMonthDays - boundary.day))
163
+ + } else {
164
+ + b = daysInMonth(current) - currentDay + boundary.day
165
+ + }
166
+ + } else {
167
+ + b = nextDay - currentDay
168
+ + }
169
+ }
170
+
171
+ - const addDays = Math.min(a, b)
172
+ + const addDays = reverse ? Math.max(a, b) : Math.min(a, b)
173
+ if (addDays !== 0) {
174
+ current.setUTCDate(current.getUTCDate() + addDays)
175
+ - current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
176
+ + current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
177
+ adjustDst(current)
178
+ continue
179
+ }
180
+ }
181
+
182
+ if (cron.months.size !== 0) {
183
+ const currentMonth = current.getUTCMonth() + 1
184
+ - const nextMonth = cron.next.month[currentMonth]
185
+ + const nextMonth = table.month[currentMonth]
186
+ + const clampBoundaryDay = (targetMonthIndex: number): number => {
187
+ + if (cron.days.size !== 0) {
188
+ + return boundary.day
189
+ + }
190
+ + const maxDayInMonth = daysInMonth(new Date(Date.UTC(current.getUTCFullYear(), targetMonthIndex + 1, 0)))
191
+ + return Math.min(boundary.day, maxDayInMonth)
192
+ + }
193
+ if (nextMonth === undefined) {
194
+ - current.setUTCFullYear(current.getUTCFullYear() + 1)
195
+ - current.setUTCMonth(cron.first.month, cron.first.day)
196
+ - current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
197
+ + current.setUTCFullYear(current.getUTCFullYear() + tick)
198
+ + current.setUTCMonth(boundary.month, clampBoundaryDay(boundary.month))
199
+ + current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
200
+ adjustDst(current)
201
+ continue
202
+ }
203
+ - if (nextMonth > currentMonth) {
204
+ - current.setUTCMonth(nextMonth - 1, cron.first.day)
205
+ - current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
206
+ + if (needsStep(nextMonth, currentMonth)) {
207
+ + const targetMonthIndex = nextMonth - 1
208
+ + current.setUTCMonth(targetMonthIndex, clampBoundaryDay(targetMonthIndex))
209
+ + current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
210
+ adjustDst(current)
211
+ continue
212
+ }
213
+ }
214
+ @@
215
+ - throw new Error("Unable to find next cron date")
216
+ + throw new Error(`Unable to find ${direction} cron date`)
217
+ })
218
+ *** End Patch`
219
+ console.log(await applyPatch(patch))
@@ -0,0 +1,219 @@
1
+ const patch = `*** Begin Patch
2
+ *** Update File: packages/effect/src/Cron.ts
3
+ @@
4
+ export const next = (cron: Cron, now?: DateTime.DateTime.Input): Date => {
5
+ + return stepCron(cron, now, "next")
6
+ +}
7
+ +
8
+ +/**
9
+ + * Returns the previous scheduled date/time for the given Cron instance.
10
+ + *
11
+ + * This function calculates the most recent date and time when the cron
12
+ + * schedule should have triggered, before the specified date (or current
13
+ + * time if not provided).
14
+ + *
15
+ + * @example
16
+ + * \`\`\`ts
17
+ + * import { Cron, Result } from "effect"
18
+ + *
19
+ + * const cron = Result.getOrThrow(Cron.parse("0 0 4 8-14 * *"))
20
+ + *
21
+ + * // Get previous run before a specific date
22
+ + * const before = new Date("2021-01-15T00:00:00Z")
23
+ + * const previousRun = Cron.prev(cron, before)
24
+ + * console.log(previousRun) // 2021-01-14T04:00:00.000Z
25
+ + *
26
+ + * // Get previous run from current time
27
+ + * const previousFromNow = Cron.prev(cron)
28
+ + * console.log(previousFromNow) // Previous occurrence from now
29
+ + * \`\`\`
30
+ + *
31
+ + * @since 4.0.0
32
+ + * @category utils
33
+ + */
34
+ +export const prev = (cron: Cron, now?: DateTime.DateTime.Input): Date => {
35
+ + return stepCron(cron, now, "prev")
36
+ +}
37
+ +
38
+ +const stepCron = (cron: Cron, now: DateTime.DateTime.Input | undefined, direction: "next" | "prev"): Date => {
39
+ const tz = Option.getOrUndefined(cron.tz)
40
+ const zoned = dateTime.makeZonedUnsafe(now ?? new Date(), {
41
+ timeZone: tz
42
+ })
43
+ +
44
+ + const reverse = direction === "prev"
45
+ + const tick = reverse ? -1 : 1
46
+ + const table = cron[direction]
47
+ + const boundary = reverse ? cron.last : cron.first
48
+ +
49
+ + const needsStep = reverse ?
50
+ + (next: number, current: number) => next < current :
51
+ + (next: number, current: number) => next > current
52
+
53
+ const utc = tz !== undefined && dateTime.isTimeZoneNamed(tz) && tz.id === "UTC"
54
+ const adjustDst = utc ? constVoid : (current: Date) => {
55
+ const adjusted = dateTime.makeZonedUnsafe(current, {
56
+ timeZone: zoned.zone,
57
+ - adjustForTimeZone: true
58
+ + adjustForTimeZone: true,
59
+ + disambiguation: reverse ? "later" : undefined
60
+ }).pipe(dateTime.toDate)
61
+
62
+ - // TODO: This implementation currently only skips forward when transitioning into daylight savings time.
63
+ const drift = current.getTime() - adjusted.getTime()
64
+ - if (drift > 0) {
65
+ - current.setTime(current.getTime() + drift)
66
+ + if (reverse ? drift !== 0 : drift > 0) {
67
+ + current.setTime(adjusted.getTime())
68
+ }
69
+ }
70
+
71
+ const result = dateTime.mutate(zoned, (current) => {
72
+ - current.setUTCSeconds(current.getUTCSeconds() + 1, 0)
73
+ + current.setUTCSeconds(current.getUTCSeconds() + tick, 0)
74
+
75
+ for (let i = 0; i < 10_000; i++) {
76
+ if (cron.seconds.size !== 0) {
77
+ const currentSecond = current.getUTCSeconds()
78
+ - const nextSecond = cron.next.second[currentSecond]
79
+ + const nextSecond = table.second[currentSecond]
80
+ if (nextSecond === undefined) {
81
+ - current.setUTCMinutes(current.getUTCMinutes() + 1, cron.first.second)
82
+ + current.setUTCMinutes(current.getUTCMinutes() + tick, boundary.second)
83
+ adjustDst(current)
84
+ continue
85
+ }
86
+ - if (nextSecond > currentSecond) {
87
+ + if (needsStep(nextSecond, currentSecond)) {
88
+ current.setUTCSeconds(nextSecond)
89
+ adjustDst(current)
90
+ continue
91
+ }
92
+ }
93
+
94
+ if (cron.minutes.size !== 0) {
95
+ const currentMinute = current.getUTCMinutes()
96
+ - const nextMinute = cron.next.minute[currentMinute]
97
+ + const nextMinute = table.minute[currentMinute]
98
+ if (nextMinute === undefined) {
99
+ - current.setUTCHours(current.getUTCHours() + 1, cron.first.minute, cron.first.second)
100
+ + current.setUTCHours(current.getUTCHours() + tick, boundary.minute, boundary.second)
101
+ adjustDst(current)
102
+ continue
103
+ }
104
+ - if (nextMinute > currentMinute) {
105
+ - current.setUTCMinutes(nextMinute, cron.first.second)
106
+ + if (needsStep(nextMinute, currentMinute)) {
107
+ + current.setUTCMinutes(nextMinute, boundary.second)
108
+ adjustDst(current)
109
+ continue
110
+ }
111
+ }
112
+
113
+ if (cron.hours.size !== 0) {
114
+ const currentHour = current.getUTCHours()
115
+ - const nextHour = cron.next.hour[currentHour]
116
+ + const nextHour = table.hour[currentHour]
117
+ if (nextHour === undefined) {
118
+ - current.setUTCDate(current.getUTCDate() + 1)
119
+ - current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
120
+ + current.setUTCDate(current.getUTCDate() + tick)
121
+ + current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
122
+ adjustDst(current)
123
+ continue
124
+ }
125
+ - if (nextHour > currentHour) {
126
+ - current.setUTCHours(nextHour, cron.first.minute, cron.first.second)
127
+ + if (needsStep(nextHour, currentHour)) {
128
+ + current.setUTCHours(nextHour, boundary.minute, boundary.second)
129
+ adjustDst(current)
130
+ continue
131
+ }
132
+ }
133
+
134
+ if (cron.weekdays.size !== 0 || cron.days.size !== 0) {
135
+ - let a: number = Infinity
136
+ - let b: number = Infinity
137
+ + let a: number = reverse ? -Infinity : Infinity
138
+ + let b: number = reverse ? -Infinity : Infinity
139
+
140
+ if (cron.weekdays.size !== 0) {
141
+ const currentWeekday = current.getUTCDay()
142
+ - const nextWeekday = cron.next.weekday[currentWeekday]
143
+ - a = nextWeekday === undefined ? 7 - currentWeekday + cron.first.weekday : nextWeekday - currentWeekday
144
+ + const nextWeekday = table.weekday[currentWeekday]
145
+ + if (nextWeekday === undefined) {
146
+ + a = reverse ?
147
+ + currentWeekday - 7 + boundary.weekday :
148
+ + 7 - currentWeekday + boundary.weekday
149
+ + } else {
150
+ + a = nextWeekday - currentWeekday
151
+ + }
152
+ }
153
+
154
+ if (cron.days.size !== 0 && a !== 0) {
155
+ const currentDay = current.getUTCDate()
156
+ - const nextDay = cron.next.day[currentDay]
157
+ - b = nextDay === undefined ? daysInMonth(current) - currentDay + cron.first.day : nextDay - currentDay
158
+ + const nextDay = table.day[currentDay]
159
+ + if (nextDay === undefined) {
160
+ + if (reverse) {
161
+ + const prevMonthDays = daysInMonth(new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), 0)))
162
+ + b = -(currentDay + (prevMonthDays - boundary.day))
163
+ + } else {
164
+ + b = daysInMonth(current) - currentDay + boundary.day
165
+ + }
166
+ + } else {
167
+ + b = nextDay - currentDay
168
+ + }
169
+ }
170
+
171
+ - const addDays = Math.min(a, b)
172
+ + const addDays = reverse ? Math.max(a, b) : Math.min(a, b)
173
+ if (addDays !== 0) {
174
+ current.setUTCDate(current.getUTCDate() + addDays)
175
+ - current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
176
+ + current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
177
+ adjustDst(current)
178
+ continue
179
+ }
180
+ }
181
+
182
+ if (cron.months.size !== 0) {
183
+ const currentMonth = current.getUTCMonth() + 1
184
+ - const nextMonth = cron.next.month[currentMonth]
185
+ + const nextMonth = table.month[currentMonth]
186
+ + const clampBoundaryDay = (targetMonthIndex: number): number => {
187
+ + if (cron.days.size !== 0) {
188
+ + return boundary.day
189
+ + }
190
+ + const maxDayInMonth = daysInMonth(new Date(Date.UTC(current.getUTCFullYear(), targetMonthIndex + 1, 0)))
191
+ + return Math.min(boundary.day, maxDayInMonth)
192
+ + }
193
+ if (nextMonth === undefined) {
194
+ - current.setUTCFullYear(current.getUTCFullYear() + 1)
195
+ - current.setUTCMonth(cron.first.month, cron.first.day)
196
+ - current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
197
+ + current.setUTCFullYear(current.getUTCFullYear() + tick)
198
+ + current.setUTCMonth(boundary.month, clampBoundaryDay(boundary.month))
199
+ + current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
200
+ adjustDst(current)
201
+ continue
202
+ }
203
+ - if (nextMonth > currentMonth) {
204
+ - current.setUTCMonth(nextMonth - 1, cron.first.day)
205
+ - current.setUTCHours(cron.first.hour, cron.first.minute, cron.first.second)
206
+ + if (needsStep(nextMonth, currentMonth)) {
207
+ + const targetMonthIndex = nextMonth - 1
208
+ + current.setUTCMonth(targetMonthIndex, clampBoundaryDay(targetMonthIndex))
209
+ + current.setUTCHours(boundary.hour, boundary.minute, boundary.second)
210
+ adjustDst(current)
211
+ continue
212
+ }
213
+ }
214
+ @@
215
+ - throw new Error("Unable to find next cron date")
216
+ + throw new Error(\`Unable to find \${direction} cron date\`)
217
+ })
218
+ *** End Patch`
219
+ console.log(await applyPatch(patch))
@@ -0,0 +1,30 @@
1
+ await taskComplete(`Implemented backport of Cron reverse scheduling support.
2
+
3
+ ### ✅ Changes made
4
+ - Added internal reverse lookup support to \\`Cron\\`:
5
+ - new internal \\`last\\` boundary values
6
+ - new internal \\`prev\\` lookup tables
7
+ - generalized lookup table builder for both directions
8
+ - Added new public APIs in \\`packages/effect/src/Cron.ts\\`:
9
+ - \\`Cron.prev(cron, now?)\\`
10
+ - \\`Cron.sequenceReverse(cron, now?)\\`
11
+ - Refactored \\`Cron.next\\` and \\`Cron.prev\\` to share core stepping logic via internal \\`stepCron\\`.
12
+ - Included DST-aware reverse stepping behavior (including fall-back disambiguation handling).
13
+ - Added test coverage in \\`packages/effect/test/Cron.test.ts\\` for:
14
+ - basic \\`prev\\` behavior
15
+ - \\`sequenceReverse\\`
16
+ - month/day edge cases (e.g. day 31 skipping shorter months)
17
+ - month-clamping behavior with month-only constraints
18
+ - DST fall-back reverse behavior
19
+ - Added changeset:
20
+ - \\`.changeset/backport-cron-prev.md\\` (
21
+ \\`"effect": minor\\`
22
+ )
23
+
24
+ ### ✅ Validation run
25
+ - \\`pnpm lint-fix\\`
26
+ - \\`pnpm test packages/effect/test/Cron.test.ts\\`
27
+ - \\`pnpm check:tsgo\\`
28
+ - \\`pnpm docgen\\`
29
+
30
+ All completed successfully.`);
@@ -0,0 +1,30 @@
1
+ await taskComplete(`Implemented backport of Cron reverse scheduling support.
2
+
3
+ ### ✅ Changes made
4
+ - Added internal reverse lookup support to \`Cron\`:
5
+ - new internal \`last\` boundary values
6
+ - new internal \`prev\` lookup tables
7
+ - generalized lookup table builder for both directions
8
+ - Added new public APIs in \`packages/effect/src/Cron.ts\`:
9
+ - \`Cron.prev(cron, now?)\`
10
+ - \`Cron.sequenceReverse(cron, now?)\`
11
+ - Refactored \`Cron.next\` and \`Cron.prev\` to share core stepping logic via internal \`stepCron\`.
12
+ - Included DST-aware reverse stepping behavior (including fall-back disambiguation handling).
13
+ - Added test coverage in \`packages/effect/test/Cron.test.ts\` for:
14
+ - basic \`prev\` behavior
15
+ - \`sequenceReverse\`
16
+ - month/day edge cases (e.g. day 31 skipping shorter months)
17
+ - month-clamping behavior with month-only constraints
18
+ - DST fall-back reverse behavior
19
+ - Added changeset:
20
+ - \`.changeset/backport-cron-prev.md\` (
21
+ \`"effect": minor\`
22
+ )
23
+
24
+ ### ✅ Validation run
25
+ - \`pnpm lint-fix\`
26
+ - \`pnpm test packages/effect/test/Cron.test.ts\`
27
+ - \`pnpm check:tsgo\`
28
+ - \`pnpm docgen\`
29
+
30
+ All completed successfully.`);
@@ -0,0 +1,10 @@
1
+ const tasks = await listTasks({});
2
+ const task = tasks.find((t) => t.id === 'EFF-738');
3
+ if (!task) throw new Error('Task EFF-738 not found');
4
+ const addition = `\n\nDiscovery update:\n\n* Archived regression tests are in \\.repos/effect-old/packages/effect/test/Cron.test.ts (not Cron.ts) and include extensive \\`prev\\` + \\`sequenceReverse\\` coverage that maps cleanly to current APIs by renaming \\`unsafeParse\\` -> \\`parseUnsafe\\` and DateTime helpers to \\`zoneMakeNamedUnsafe\\` / \\`makeZonedUnsafe\\`.\n* Old \\`prev\\` implementation depends on internal cron metadata additions: \\`last\\` boundaries + reverse lookup tables \\`prev\\`; these need to be added to current \\`Cron.make\\` output before implementing reverse stepping.`;
5
+ await updateTask({
6
+ taskId: 'EFF-738',
7
+ description: task.description + addition,
8
+ state: 'in-progress'
9
+ });
10
+ console.log('updated task');
@@ -0,0 +1,10 @@
1
+ const tasks = await listTasks({});
2
+ const task = tasks.find((t) => t.id === 'EFF-738');
3
+ if (!task) throw new Error('Task EFF-738 not found');
4
+ const addition = `\n\nDiscovery update:\n\n* Archived regression tests are in .repos/effect-old/packages/effect/test/Cron.test.ts (not Cron.ts) and include extensive \`prev\` + \`sequenceReverse\` coverage that maps cleanly to current APIs by renaming \`unsafeParse\` -> \`parseUnsafe\` and DateTime helpers to \`zoneMakeNamedUnsafe\` / \`makeZonedUnsafe\`.\n* Old \`prev\` implementation depends on internal cron metadata additions: \`last\` boundaries + reverse lookup tables \`prev\`; these need to be added to current \`Cron.make\` output before implementing reverse stepping.`;
5
+ await updateTask({
6
+ taskId: 'EFF-738',
7
+ description: task.description + addition,
8
+ state: 'in-progress'
9
+ });
10
+ console.log('updated task');