@danieljvdm/dev-kit 0.11.3 → 0.12.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 (74) hide show
  1. package/README.md +70 -76
  2. package/dev-kit.example.jsonc +0 -4
  3. package/package.json +10 -6
  4. package/schema/dev-kit.schema.json +1 -46
  5. package/skills/build-effect-apis/SKILL.md +77 -0
  6. package/skills/build-effect-apis/agents/openai.yaml +4 -0
  7. package/skills/build-effect-apis/references/cloudflare-workers.md +71 -0
  8. package/skills/build-effect-apis/references/effect-atom-client.md +161 -0
  9. package/skills/build-effect-apis/references/effect-atom-lifecycle.md +78 -0
  10. package/skills/build-effect-apis/references/effect-atom-testing.md +74 -0
  11. package/skills/build-effect-apis/references/runtime-assembly.md +56 -0
  12. package/skills/build-effect-apis/references/server-and-middleware.md +174 -0
  13. package/skills/build-effect-apis/references/shared-contracts.md +108 -0
  14. package/skills/build-effect-apis/references/tanstack-start.md +86 -0
  15. package/skills/build-effect-apis/references/verification.md +50 -0
  16. package/skills/dev-kit/SKILL.md +58 -46
  17. package/skills/effect-architecture-audit/SKILL.md +26 -0
  18. package/skills/effect-architecture-audit/agents/openai.yaml +4 -0
  19. package/skills/effect-architecture-audit/references/service-and-boundary-audit.md +150 -0
  20. package/skills/effect-ts/SKILL.md +21 -256
  21. package/skills/effect-ts/agents/openai.yaml +3 -3
  22. package/skills/testing/SKILL.md +5 -0
  23. package/src/catalog-manager.ts +16 -17
  24. package/src/catalog.ts +71 -16
  25. package/src/effect-source.ts +46 -24
  26. package/src/effect-tsgo.ts +49 -24
  27. package/src/gitignore.ts +5 -5
  28. package/src/index.ts +0 -6
  29. package/src/manifest.ts +0 -34
  30. package/src/node-symbolic-link.ts +2 -2
  31. package/src/oxfmt.js +5 -0
  32. package/src/oxfmt.ts +5 -0
  33. package/src/oxlint.js +5 -0
  34. package/src/oxlint.ts +5 -0
  35. package/src/package-skill-source.ts +51 -59
  36. package/src/path-digest.ts +7 -7
  37. package/src/project-package.ts +8 -7
  38. package/src/project-process-lock.ts +17 -12
  39. package/src/project-state.ts +1 -1
  40. package/src/skill-manager.ts +16 -14
  41. package/src/skill-selector.ts +12 -0
  42. package/src/sync.ts +170 -120
  43. package/src/tool-ignore-patterns.js +9 -0
  44. package/src/tool-ignore-patterns.ts +15 -0
  45. package/src/vendor.ts +67 -61
  46. package/src/vite-plus-dependency.ts +10 -11
  47. package/src/vite-plus-hooks.ts +24 -14
  48. package/src/vite-plus-quality.ts +21 -172
  49. package/src/vite-plus.js +81 -0
  50. package/src/vite-plus.ts +102 -0
  51. package/templates/AGENTS.md +1 -1
  52. package/skills/effect-ts/UPSTREAM.md +0 -28
  53. package/skills/effect-ts/references/atom-cache-lifecycle.md +0 -78
  54. package/skills/effect-ts/references/atom-http-and-invalidation.md +0 -97
  55. package/skills/effect-ts/references/atom-tanstack-start.md +0 -69
  56. package/skills/effect-ts/references/atom-testing.md +0 -67
  57. package/skills/effect-ts/references/audit-services.md +0 -144
  58. package/skills/effect-ts/references/features.md +0 -525
  59. package/skills/effect-ts/references/guide-atom-data-fetching.md +0 -44
  60. package/skills/effect-ts/references/guide-cli.md +0 -107
  61. package/skills/effect-ts/references/guide-datetime.md +0 -72
  62. package/skills/effect-ts/references/guide-effect.md +0 -440
  63. package/skills/effect-ts/references/guide-error-handling.md +0 -565
  64. package/skills/effect-ts/references/guide-http-boundaries.md +0 -55
  65. package/skills/effect-ts/references/guide-layers.md +0 -989
  66. package/skills/effect-ts/references/guide-observability.md +0 -746
  67. package/skills/effect-ts/references/guide-retries.md +0 -434
  68. package/skills/effect-ts/references/guide-schedule.md +0 -343
  69. package/skills/effect-ts/references/guide-schema.md +0 -664
  70. package/skills/effect-ts/references/guide-sql.md +0 -536
  71. package/skills/effect-ts/references/guide-testing.md +0 -532
  72. package/skills/effect-ts/references/guide-type-safety-and-boundaries.md +0 -131
  73. package/skills/effect-ts/references/version-and-source.md +0 -86
  74. package/templates/vite-plus/vite.config.ts +0 -22
@@ -1,434 +0,0 @@
1
- # Retries Guide
2
-
3
- Use Effect test services and `TestClock` for retry timing tests. Do not add
4
- wall-clock sleeps to make a retry test pass.
5
-
6
- This guide is based on retry patterns and `ExecutionPlan` usage in the canonical Effect source.
7
-
8
- Key source files:
9
-
10
- - `packages/effect/src/Effect.ts`
11
- - `packages/effect/src/Schedule.ts`
12
- - `packages/effect/src/ExecutionPlan.ts`
13
- - `packages/effect/test/Effect.test.ts`
14
- - `packages/effect/test/ExecutionPlan.test.ts`
15
-
16
- Representative repo usage:
17
-
18
- - `packages/effect/src/unstable/workflow/Activity.ts`
19
- - `packages/effect/src/unstable/workflow/WorkflowEngine.ts`
20
- - `packages/effect/src/unstable/rpc/RpcClient.ts`
21
- - `packages/effect/src/unstable/observability/OtlpExporter.ts`
22
- - `packages/vitest/src/internal/internal.ts`
23
-
24
- ## Mental Model
25
-
26
- Retries in Effect are not just loops.
27
-
28
- The repo uses three increasingly powerful levels:
29
-
30
- 1. simple `Effect.retry` options for bounded or condition-based retries
31
- 2. `Schedule` for timing-aware retry policies
32
- 3. `ExecutionPlan` for fallback across different provided resources or layers
33
-
34
- Choose the smallest model that correctly expresses the retry policy.
35
-
36
- ## Preferred Rule
37
-
38
- Prefer structured retry policies over ad hoc retry loops.
39
-
40
- Use:
41
-
42
- - simple `Effect.retry({ ... })` for straightforward conditions
43
- - `Effect.retry(schedule)` when timing matters
44
- - `ExecutionPlan` when retries should escalate across different layers or resources
45
-
46
- Avoid:
47
-
48
- - hand-written loops with mutable counters
49
- - inline `catch` plus recursive retry logic
50
- - resource fallback logic encoded as nested `catch` chains when `ExecutionPlan` is a better fit
51
-
52
- ## `Effect.retry`
53
-
54
- `Effect.retry` is the main retry operator.
55
-
56
- The canonical tests show several important supported forms.
57
-
58
- ## Retry On Success vs Failure
59
-
60
- `Effect.retry` only retries failures.
61
-
62
- If the effect succeeds, nothing is retried.
63
-
64
- This is explicitly covered in the module tests.
65
-
66
- ## Simple Retry Options
67
-
68
- ### `{ times: n }`
69
-
70
- Use this for the simplest bounded retry case.
71
-
72
- ```ts
73
- const retried = effect.pipe(Effect.retry({ times: 3 }));
74
- ```
75
-
76
- Use this when:
77
-
78
- - timing does not matter
79
- - you only need a fixed retry count
80
-
81
- ### `{ until: predicate }`
82
-
83
- Use `until` when retries should stop once the failure value satisfies a condition.
84
-
85
- The module tests show:
86
-
87
- - pure `until`
88
- - effectful `until`
89
- - that `until` is still evaluated at least once
90
-
91
- Example:
92
-
93
- ```ts
94
- const retried = effect.pipe(Effect.retry({ until: (error) => error._tag === "Done" }));
95
- ```
96
-
97
- ### `{ while: predicate }`
98
-
99
- Use `while` when retries should continue only while the failure value satisfies a condition.
100
-
101
- The tests also show pure and effectful `while` variants.
102
-
103
- Example:
104
-
105
- ```ts
106
- const retried = effect.pipe(Effect.retry({ while: (error) => error._tag === "Retryable" }));
107
- ```
108
-
109
- ## Retry With Schedule
110
-
111
- Use a `Schedule` whenever timing matters.
112
-
113
- ```ts
114
- const retried = effect.pipe(Effect.retry(Schedule.recurs(3)));
115
- ```
116
-
117
- Or with the richer object form:
118
-
119
- ```ts
120
- const retried = effect.pipe(
121
- Effect.retry({
122
- schedule: Schedule.recurs(3),
123
- while: (error) => error._tag === "Retryable",
124
- }),
125
- );
126
- ```
127
-
128
- This is a very important repo pattern because it lets you combine:
129
-
130
- - retry timing
131
- - retry limits
132
- - retry predicates
133
-
134
- ## Current Schedule Metadata During Retries
135
-
136
- The module tests show that retry execution updates `Schedule.CurrentMetadata`.
137
-
138
- This means retry policies and retry-aware effects can inspect:
139
-
140
- - attempt number
141
- - elapsed time
142
- - previous delay timing
143
- - schedule output
144
-
145
- Use this when:
146
-
147
- - logging retry behavior
148
- - building retry-aware diagnostics
149
- - implementing advanced adaptive retry behavior
150
-
151
- ## When To Use Simple Options Vs Schedule
152
-
153
- Prefer simple options when:
154
-
155
- - only the retry count matters
156
- - retry timing does not matter
157
- - the retry rule is just a condition on the error
158
-
159
- Prefer a schedule when:
160
-
161
- - retry timing matters
162
- - backoff matters
163
- - jitter matters
164
- - the policy should evolve over time
165
-
166
- ## Common Retry Schedules In The Repo
167
-
168
- The canonical source repeatedly uses these patterns:
169
-
170
- ### Fixed retry count
171
-
172
- ```ts
173
- Schedule.recurs(3);
174
- ```
175
-
176
- ### Exponential backoff
177
-
178
- ```ts
179
- Schedule.exponential("500 millis", 1.5);
180
- ```
181
-
182
- ### Exponential plus steady fallback spacing
183
-
184
- ```ts
185
- Schedule.exponential("500 millis", 1.5).pipe(
186
- Schedule.upTo({ times: 4 }),
187
- Schedule.andThen(Schedule.spaced("5 seconds")),
188
- );
189
- ```
190
-
191
- This appears in production modules such as RPC and workflow code.
192
-
193
- ### Error-sensitive delay policy
194
-
195
- ```ts
196
- Schedule.forever.pipe(
197
- Schedule.setInputType<RetryableError>(),
198
- Schedule.addDelay(({ input: error }) => Effect.succeed(error.retryAfter ?? "1 second")),
199
- );
200
- ```
201
-
202
- The OTLP exporter uses this shape to derive delays from actual HTTP failure details such as rate limits.
203
-
204
- ## Retry Only For Specific Failures
205
-
206
- The workflow `Activity` module shows an important advanced pattern:
207
-
208
- - sandbox the effect
209
- - retry only when the `Cause` matches a specific retryable category
210
- - fail or die differently once retries are exhausted
211
-
212
- Example shape from the repo:
213
-
214
- ```ts
215
- effect.pipe(
216
- Effect.sandbox,
217
- Effect.retry(policy),
218
- Effect.catch((cause) => {
219
- if (!Cause.hasInterrupts(cause)) {
220
- return Effect.failCause(cause);
221
- }
222
- return Effect.die("interrupted and retries exhausted");
223
- }),
224
- );
225
- ```
226
-
227
- Use this when:
228
-
229
- - retryability depends on the full cause, not just typed failures
230
- - interrupt-specific retry behavior is required
231
- - infrastructure policy is more nuanced than a simple tagged error rule
232
-
233
- ## Retry Observability
234
-
235
- Retry logic should be observable.
236
-
237
- Good patterns:
238
-
239
- - keep retries inside named `Effect.fn` operations
240
- - use `Schedule.CurrentMetadata` for diagnostics when needed
241
- - log or annotate retry attempts at meaningful boundaries
242
- - prefer central retry policies over duplicating timing logic everywhere
243
-
244
- Do not spread retry behavior across many small helpers where it becomes hard to see the operational policy.
245
-
246
- ## `ExecutionPlan`
247
-
248
- Use `ExecutionPlan` when retries should escalate across different provided resources or layers.
249
-
250
- This is not just about retry timing. It is about retrying the same operation under different provided environments.
251
-
252
- The core use case from `ExecutionPlan.ts` is:
253
-
254
- - try one layer some number of times
255
- - possibly with a schedule and conditions
256
- - then fall back to another layer
257
- - then possibly fall back again
258
-
259
- ### What `ExecutionPlan` Solves
260
-
261
- `ExecutionPlan` is the right tool when:
262
-
263
- - the same effect should be retried against multiple alternative providers
264
- - fallback should move across tiers, regions, models, or implementations
265
- - retry policy includes both attempt counts and provider changes
266
-
267
- Examples:
268
-
269
- - fail over between multiple language model providers
270
- - try one upstream cluster, then another
271
- - fall back from a fast but unreliable service to a slower but more reliable one
272
-
273
- ## `ExecutionPlan.make`
274
-
275
- Use `ExecutionPlan.make(...)` to define ordered retry/fallback steps.
276
-
277
- Each step can include:
278
-
279
- - `provide`
280
- - `attempts`
281
- - `while`
282
- - `schedule`
283
-
284
- Example shape:
285
-
286
- ```ts
287
- const Plan = ExecutionPlan.make(
288
- {
289
- provide: FastLayer,
290
- attempts: 2,
291
- schedule: Schedule.spaced("3 seconds"),
292
- },
293
- {
294
- provide: SafeLayer,
295
- attempts: 3,
296
- schedule: Schedule.spaced("1 second"),
297
- },
298
- {
299
- provide: FinalFallbackLayer,
300
- },
301
- );
302
- ```
303
-
304
- ### Step Semantics
305
-
306
- For each step:
307
-
308
- - `provide` is the context or layer to use
309
- - `attempts` bounds how many times that step is tried
310
- - `while` can stop retries for that step based on the input
311
- - `schedule` defines the timing policy for retries within that step
312
-
313
- If `attempts` is omitted, the step attempts once unless a schedule is involved in a way that causes further retries.
314
-
315
- ## `Effect.withExecutionPlan` And `Stream.withExecutionPlan`
316
-
317
- Use:
318
-
319
- - `Effect.withExecutionPlan` for effects
320
- - `Stream.withExecutionPlan` for streams
321
-
322
- The canonical tests focus on `Stream.withExecutionPlan` and demonstrate:
323
-
324
- - fallback from one provider to another
325
- - fallback after partial stream failure
326
- - the ability to prevent fallback on partial streams
327
-
328
- This is a strong signal that `ExecutionPlan` is particularly useful for long-running or streaming integrations where failure can happen after partial success.
329
-
330
- ## `ExecutionPlan.CurrentMetadata`
331
-
332
- `ExecutionPlan` exposes metadata with:
333
-
334
- - `attempt`
335
- - `stepIndex`
336
-
337
- This is useful for:
338
-
339
- - diagnostics
340
- - logging which fallback tier is being used
341
- - understanding which plan step ultimately succeeded
342
-
343
- ## `captureRequirements`
344
-
345
- Every plan exposes a `captureRequirements` Effect that converts the plan into
346
- one whose requirements are satisfied from the current context.
347
-
348
- Use this when the plan should be frozen with the current environment before being applied later.
349
-
350
- ```ts
351
- const capturedPlan = yield * Plan.captureRequirements;
352
- ```
353
-
354
- ## `ExecutionPlan.merge`
355
-
356
- Use `ExecutionPlan.merge(...)` when you need to concatenate multiple plans into one ordered plan.
357
-
358
- This is useful for assembling more complex fallback policies out of smaller ones.
359
-
360
- ## When To Use `ExecutionPlan` Instead Of `Schedule`
361
-
362
- Use `Schedule` when:
363
-
364
- - only timing and retry conditions change
365
- - the same environment/provider is used for every retry
366
-
367
- Use `ExecutionPlan` when:
368
-
369
- - the provider or layer should change across retry phases
370
- - retries are tied to alternative resources, not just delays
371
- - fallback is part of dependency provisioning strategy
372
-
373
- ## Recommended Patterns
374
-
375
- ### Pattern: simple bounded retry
376
-
377
- ```ts
378
- const retried = effect.pipe(Effect.retry({ times: 3 }));
379
- ```
380
-
381
- ### Pattern: retryable-error backoff
382
-
383
- ```ts
384
- const retryPolicy = Schedule.exponential("500 millis", 1.5).pipe(
385
- Schedule.upTo({ times: 4 }),
386
- Schedule.andThen(Schedule.spaced("5 seconds")),
387
- );
388
-
389
- const retried = effect.pipe(
390
- Effect.retry({
391
- schedule: retryPolicy,
392
- while: (error) => error._tag === "Retryable",
393
- }),
394
- );
395
- ```
396
-
397
- ### Pattern: fallback across providers
398
-
399
- ```ts
400
- const Plan = ExecutionPlan.make(
401
- {
402
- provide: PrimaryLayer,
403
- attempts: 2,
404
- schedule: Schedule.spaced("1 second"),
405
- },
406
- {
407
- provide: SecondaryLayer,
408
- attempts: 3,
409
- schedule: Schedule.exponential(500, 1.5),
410
- },
411
- {
412
- provide: FinalFallbackLayer,
413
- },
414
- );
415
- ```
416
-
417
- ## Anti-Patterns
418
-
419
- - hand-writing retry recursion instead of using `Effect.retry`
420
- - embedding sleep and counters directly in business logic
421
- - using `ExecutionPlan` when a simple `Schedule` is enough
422
- - encoding provider fallback as a maze of nested `catch` branches
423
- - retrying indiscriminately without checking whether the failure is actually retryable
424
-
425
- ## Good Repo Examples To Study
426
-
427
- - `packages/effect/test/Effect.test.ts`
428
- - `packages/effect/src/Schedule.ts`
429
- - `packages/effect/src/ExecutionPlan.ts`
430
- - `packages/effect/test/ExecutionPlan.test.ts`
431
- - `packages/effect/src/unstable/workflow/Activity.ts`
432
- - `packages/effect/src/unstable/workflow/WorkflowEngine.ts`
433
- - `packages/effect/src/unstable/rpc/RpcClient.ts`
434
- - `packages/effect/src/unstable/observability/OtlpExporter.ts`