@martinffx/atelier 0.1.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 (130) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/LICENSE +21 -0
  3. package/README.md +285 -0
  4. package/agents/architect.md +38 -0
  5. package/agents/oracle.md +40 -0
  6. package/agents/recon.md +39 -0
  7. package/dist/atelier.js +33082 -0
  8. package/package.json +44 -0
  9. package/skills/code-conventional-commit/SKILL.md +134 -0
  10. package/skills/code-conventional-commit/evals/evals.json +23 -0
  11. package/skills/code-conventional-commit/workspace/iteration-1/eval-0/with_skill/outputs/commit-message.txt +4 -0
  12. package/skills/code-conventional-commit/workspace/iteration-1/eval-0/with_skill/outputs/eval_metadata.json +6 -0
  13. package/skills/code-conventional-commit/workspace/iteration-1/eval-1/with_skill/outputs/eval_metadata.json +6 -0
  14. package/skills/code-conventional-commit/workspace/iteration-1/eval-1/with_skill/outputs/validation-result.txt +16 -0
  15. package/skills/code-conventional-commit/workspace/iteration-1/eval-2/with_skill/outputs/commit-message.txt +8 -0
  16. package/skills/code-conventional-commit/workspace/iteration-1/eval-2/with_skill/outputs/eval_metadata.json +6 -0
  17. package/skills/code-conventional-commit/workspace/iteration-1/report.html +1325 -0
  18. package/skills/code-debug/SKILL.md +271 -0
  19. package/skills/code-debug/references/language-tools.md +139 -0
  20. package/skills/code-debug/references/techniques.md +117 -0
  21. package/skills/code-docs/SKILL.md +171 -0
  22. package/skills/code-docs/references/api-docs.md +116 -0
  23. package/skills/code-docs/references/changelog.md +64 -0
  24. package/skills/code-docs/references/readme-structure.md +94 -0
  25. package/skills/code-git-worktrees/SKILL.md +218 -0
  26. package/skills/code-perf/SKILL.md +163 -0
  27. package/skills/code-perf/references/common-bottlenecks.md +124 -0
  28. package/skills/code-perf/references/optimization-patterns.md +167 -0
  29. package/skills/code-perf/references/profiling-tools.md +126 -0
  30. package/skills/code-review/SKILL.md +78 -0
  31. package/skills/code-review/references/output.md +200 -0
  32. package/skills/code-review/references/reviewers.md +719 -0
  33. package/skills/code-review/references/rq.md +357 -0
  34. package/skills/code-review/references/rs.md +30 -0
  35. package/skills/code-security/SKILL.md +183 -0
  36. package/skills/code-security/references/owasp-top-10.md +129 -0
  37. package/skills/code-security/references/security-tools.md +102 -0
  38. package/skills/code-security/references/vulnerability-patterns.md +129 -0
  39. package/skills/code-stacked-commit/SKILL.md +155 -0
  40. package/skills/code-subagents/SKILL.md +184 -0
  41. package/skills/code-subagents/references/code-quality-reviewer-prompt.md +48 -0
  42. package/skills/code-subagents/references/implementor-prompt.md +79 -0
  43. package/skills/code-subagents/references/spec-reviewer-prompt.md +62 -0
  44. package/skills/oracle-architect/SKILL.md +246 -0
  45. package/skills/oracle-architect/references/api-design.md +345 -0
  46. package/skills/oracle-architect/references/data-modeling.md +318 -0
  47. package/skills/oracle-architect/references/ddd-patterns.md +247 -0
  48. package/skills/oracle-challenge/SKILL.md +126 -0
  49. package/skills/oracle-testing/SKILL.md +237 -0
  50. package/skills/oracle-testing/references/anti-patterns.md +618 -0
  51. package/skills/oracle-testing/references/boundaries.md +579 -0
  52. package/skills/oracle-testing/references/core-testing.md +691 -0
  53. package/skills/oracle-testing/references/edge-testing.md +794 -0
  54. package/skills/oracle-testing/references/stub-driven-tdd.md +322 -0
  55. package/skills/oracle-thinkdeep/SKILL.md +164 -0
  56. package/skills/python-architecture/SKILL.md +148 -0
  57. package/skills/python-architecture/references/data-modeling.md +558 -0
  58. package/skills/python-architecture/references/ddd.md +569 -0
  59. package/skills/python-architecture/references/functional-core.md +337 -0
  60. package/skills/python-build-tools/SKILL.md +153 -0
  61. package/skills/python-build-tools/references/basedpyright.md +321 -0
  62. package/skills/python-build-tools/references/ruff.md +225 -0
  63. package/skills/python-build-tools/references/uv.md +257 -0
  64. package/skills/python-fastapi/SKILL.md +184 -0
  65. package/skills/python-fastapi/references/api-design.md +563 -0
  66. package/skills/python-fastapi/references/dependencies.md +479 -0
  67. package/skills/python-fastapi/references/middleware.md +475 -0
  68. package/skills/python-fastapi/references/validation.md +497 -0
  69. package/skills/python-modern-python/SKILL.md +201 -0
  70. package/skills/python-modern-python/references/async.md +76 -0
  71. package/skills/python-modern-python/references/pattern-matching.md +89 -0
  72. package/skills/python-modern-python/references/typing.md +96 -0
  73. package/skills/python-monorepo/SKILL.md +146 -0
  74. package/skills/python-monorepo/references/docker.md +515 -0
  75. package/skills/python-monorepo/references/namespace-packages.md +426 -0
  76. package/skills/python-monorepo/references/workspace-config.md +341 -0
  77. package/skills/python-sqlalchemy/SKILL.md +119 -0
  78. package/skills/python-sqlalchemy/references/async.md +51 -0
  79. package/skills/python-sqlalchemy/references/models.md +67 -0
  80. package/skills/python-sqlalchemy/references/queries.md +57 -0
  81. package/skills/python-temporal/SKILL.md +128 -0
  82. package/skills/python-temporal/references/patterns.md +87 -0
  83. package/skills/python-temporal/references/testing.md +54 -0
  84. package/skills/python-testing/SKILL.md +161 -0
  85. package/skills/python-testing/references/boundaries.md +449 -0
  86. package/skills/python-testing/references/mocking.md +449 -0
  87. package/skills/python-testing/references/pytest.md +524 -0
  88. package/skills/spec-brainstorm/SKILL.md +325 -0
  89. package/skills/spec-finish/SKILL.md +159 -0
  90. package/skills/spec-implement/SKILL.md +296 -0
  91. package/skills/spec-orchestrator/SKILL.md +156 -0
  92. package/skills/spec-plan/SKILL.md +248 -0
  93. package/skills/typescript-api-design/SKILL.md +396 -0
  94. package/skills/typescript-api-design/references/error-responses.md +469 -0
  95. package/skills/typescript-build-tools/SKILL.md +447 -0
  96. package/skills/typescript-build-tools/references/biome.md +436 -0
  97. package/skills/typescript-build-tools/references/bun.md +432 -0
  98. package/skills/typescript-build-tools/references/turborepo.md +426 -0
  99. package/skills/typescript-build-tools/references/vitest.md +518 -0
  100. package/skills/typescript-drizzle-orm/SKILL.md +398 -0
  101. package/skills/typescript-drizzle-orm/references/cloudflare.md +392 -0
  102. package/skills/typescript-drizzle-orm/references/entity-pattern.md +412 -0
  103. package/skills/typescript-drizzle-orm/references/postgresql.md +191 -0
  104. package/skills/typescript-drizzle-orm/references/repository-pattern.md +479 -0
  105. package/skills/typescript-drizzle-orm/references/sqlite.md +291 -0
  106. package/skills/typescript-dynamodb-toolbox/SKILL.md +370 -0
  107. package/skills/typescript-dynamodb-toolbox/references/entity-layer.md +574 -0
  108. package/skills/typescript-dynamodb-toolbox/references/error-handling.md +495 -0
  109. package/skills/typescript-dynamodb-toolbox/references/modeling.md +332 -0
  110. package/skills/typescript-dynamodb-toolbox/references/repository-layer.md +631 -0
  111. package/skills/typescript-dynamodb-toolbox/references/testing.md +718 -0
  112. package/skills/typescript-dynamodb-toolbox/references/transactions.md +423 -0
  113. package/skills/typescript-effect-ts/SKILL.md +341 -0
  114. package/skills/typescript-effect-ts/references/core.md +412 -0
  115. package/skills/typescript-effect-ts/references/error-handling.md +468 -0
  116. package/skills/typescript-effect-ts/references/resources.md +476 -0
  117. package/skills/typescript-effect-ts/references/schema.md +536 -0
  118. package/skills/typescript-effect-ts/references/services.md +461 -0
  119. package/skills/typescript-fastify/SKILL.md +405 -0
  120. package/skills/typescript-fastify/references/plugins.md +329 -0
  121. package/skills/typescript-fastify/references/typeid.md +315 -0
  122. package/skills/typescript-functional-patterns/SKILL.md +402 -0
  123. package/skills/typescript-functional-patterns/references/adts.md +497 -0
  124. package/skills/typescript-functional-patterns/references/branded-types.md +542 -0
  125. package/skills/typescript-functional-patterns/references/migration-guide.md +695 -0
  126. package/skills/typescript-functional-patterns/references/option-result.md +585 -0
  127. package/skills/typescript-testing/SKILL.md +353 -0
  128. package/skills/typescript-testing/references/mocking.md +675 -0
  129. package/skills/typescript-testing/references/msw.md +852 -0
  130. package/skills/typescript-testing/references/snapshot-testing.md +774 -0
@@ -0,0 +1,412 @@
1
+ # Effect Core Concepts
2
+
3
+ The Effect type is the foundation of the Effect-TS library. It represents a computation that can succeed, fail, or require dependencies.
4
+
5
+ ## The Effect Type
6
+
7
+ ```typescript
8
+ Effect<Success, Error, Requirements>
9
+ ```
10
+
11
+ - **Success (A)**: The type of value produced on success
12
+ - **Error (E)**: The type of error that may occur (use `never` if cannot fail)
13
+ - **Requirements (R)**: The context/services required to run (use `never` if none)
14
+
15
+ ### Type Examples
16
+
17
+ ```typescript
18
+ import { Effect } from "effect"
19
+
20
+ // Succeeds with number, cannot fail, no requirements
21
+ type PureComputation = Effect.Effect<number>
22
+ // Equivalent to: Effect.Effect<number, never, never>
23
+
24
+ // May fail with Error, no requirements
25
+ type FallibleComputation = Effect.Effect<string, Error>
26
+ // Equivalent to: Effect.Effect<string, Error, never>
27
+
28
+ // Requires Database service, may fail with DbError
29
+ type ServiceComputation = Effect.Effect<User, DbError, Database>
30
+ ```
31
+
32
+ ## Creating Effects
33
+
34
+ ### From Values (Synchronous)
35
+
36
+ ```typescript
37
+ import { Effect } from "effect"
38
+
39
+ // Always succeeds with given value
40
+ const succeed = Effect.succeed(42)
41
+ // Effect<number, never, never>
42
+
43
+ // Lazy evaluation - thunk called when effect runs
44
+ const sync = Effect.sync(() => {
45
+ console.log("Computing...")
46
+ return Date.now()
47
+ })
48
+ // Effect<number, never, never>
49
+
50
+ // Suspend effect creation (useful for recursion)
51
+ const suspend = Effect.suspend(() => Effect.succeed(42))
52
+ ```
53
+
54
+ ### From Failures
55
+
56
+ ```typescript
57
+ import { Effect } from "effect"
58
+
59
+ // Typed error (recoverable)
60
+ const fail = Effect.fail(new Error("Something went wrong"))
61
+ // Effect<never, Error, never>
62
+
63
+ // Defect (unrecoverable, not in error type)
64
+ const die = Effect.die("Unexpected error")
65
+ // Effect<never, never, never> - defects aren't tracked in E
66
+
67
+ // Die if condition not met
68
+ const dieIf = Effect.dieIf(value === null, "Value was null")
69
+ ```
70
+
71
+ ### From Try/Catch
72
+
73
+ ```typescript
74
+ import { Effect } from "effect"
75
+
76
+ // Wrap throwing code
77
+ const tryEffect = Effect.try({
78
+ try: () => JSON.parse(invalidJson),
79
+ catch: (error) => new ParseError(String(error))
80
+ })
81
+ // Effect<unknown, ParseError, never>
82
+
83
+ // Simpler form (wraps with UnknownException)
84
+ const trySimple = Effect.try(() => JSON.parse(json))
85
+ // Effect<unknown, UnknownException, never>
86
+ ```
87
+
88
+ ### From Promises
89
+
90
+ ```typescript
91
+ import { Effect } from "effect"
92
+
93
+ // From promise with error mapping
94
+ const tryPromise = Effect.tryPromise({
95
+ try: () => fetch("/api/users").then(r => r.json()),
96
+ catch: (error) => new FetchError(String(error))
97
+ })
98
+ // Effect<unknown, FetchError, never>
99
+
100
+ // From promise (wraps rejection with UnknownException)
101
+ const promise = Effect.promise(() => fetch("/api/users"))
102
+ // Effect<Response, UnknownException, never>
103
+ ```
104
+
105
+ ### From Nullable Values
106
+
107
+ ```typescript
108
+ import { Effect } from "effect"
109
+
110
+ // Convert nullable to Effect
111
+ const fromNullable = Effect.fromNullable(value)
112
+ // Effect<T, NoSuchElementException, never>
113
+
114
+ // With custom error
115
+ const fromNullableWithError = Effect.fromNullable(value).pipe(
116
+ Effect.mapError(() => new ValueNotFound())
117
+ )
118
+ ```
119
+
120
+ ### From Either/Option
121
+
122
+ ```typescript
123
+ import { Effect, Either, Option } from "effect"
124
+
125
+ // From Either
126
+ const either: Either.Either<number, string> = Either.right(42)
127
+ const fromEither = Effect.fromEither(either)
128
+ // Effect<number, string, never>
129
+
130
+ // From Option
131
+ const option: Option.Option<number> = Option.some(42)
132
+ const fromOption = Effect.fromOption(option)
133
+ // Effect<number, NoSuchElementException, never>
134
+ ```
135
+
136
+ ## Running Effects
137
+
138
+ ### Synchronous Execution
139
+
140
+ ```typescript
141
+ import { Effect } from "effect"
142
+
143
+ const program = Effect.succeed(42)
144
+
145
+ // Run synchronously - throws if async or fails
146
+ const result = Effect.runSync(program) // 42
147
+
148
+ // Run with exit status
149
+ const exit = Effect.runSyncExit(program)
150
+ // Exit<number, never>
151
+ ```
152
+
153
+ **Warning**: `runSync` throws if the effect:
154
+ - Contains async operations
155
+ - Fails with an error
156
+ - Requires services not provided
157
+
158
+ ### Promise-based Execution
159
+
160
+ ```typescript
161
+ import { Effect } from "effect"
162
+
163
+ const program = Effect.succeed(42)
164
+
165
+ // Returns Promise that rejects on failure
166
+ const promise = Effect.runPromise(program)
167
+ // Promise<number>
168
+
169
+ // Returns Promise<Exit> (never rejects)
170
+ const exitPromise = Effect.runPromiseExit(program)
171
+ // Promise<Exit<number, never>>
172
+ ```
173
+
174
+ ### Fiber-based Execution
175
+
176
+ ```typescript
177
+ import { Effect } from "effect"
178
+
179
+ // Fork to run in background
180
+ const fiber = Effect.runFork(program)
181
+
182
+ // Join to await result
183
+ const result = await Effect.runPromise(Fiber.join(fiber))
184
+
185
+ // Interrupt if needed
186
+ await Effect.runPromise(Fiber.interrupt(fiber))
187
+ ```
188
+
189
+ ## Effect.gen Generators
190
+
191
+ Generators provide async/await-like syntax with full type safety:
192
+
193
+ ```typescript
194
+ import { Effect } from "effect"
195
+
196
+ // Basic generator pattern
197
+ const program = Effect.gen(function* () {
198
+ const a = yield* Effect.succeed(1)
199
+ const b = yield* Effect.succeed(2)
200
+ return a + b
201
+ })
202
+ // Effect<number, never, never>
203
+
204
+ // With error handling
205
+ const withErrors = Effect.gen(function* () {
206
+ const user = yield* fetchUser(userId)
207
+ // If fetchUser fails, error propagates automatically
208
+ const posts = yield* fetchPosts(user.id)
209
+ return { user, posts }
210
+ })
211
+ ```
212
+
213
+ ### Generator vs Pipe Style
214
+
215
+ ```typescript
216
+ // Generator style - more readable for sequential operations
217
+ const genStyle = Effect.gen(function* () {
218
+ const user = yield* getUser(id)
219
+ const profile = yield* getProfile(user.id)
220
+ const settings = yield* getSettings(user.id)
221
+ return { user, profile, settings }
222
+ })
223
+
224
+ // Pipe style - useful for transformations
225
+ const pipeStyle = getUser(id).pipe(
226
+ Effect.flatMap(user => getProfile(user.id).pipe(
227
+ Effect.flatMap(profile => getSettings(user.id).pipe(
228
+ Effect.map(settings => ({ user, profile, settings }))
229
+ ))
230
+ ))
231
+ )
232
+
233
+ // Both produce the same result
234
+ ```
235
+
236
+ ### Early Return in Generators
237
+
238
+ ```typescript
239
+ import { Effect } from "effect"
240
+
241
+ const program = Effect.gen(function* () {
242
+ const user = yield* getUser(id)
243
+
244
+ // Early return with fail
245
+ if (!user.isActive) {
246
+ return yield* Effect.fail(new UserInactive(id))
247
+ }
248
+
249
+ const data = yield* loadUserData(user)
250
+ return data
251
+ })
252
+ ```
253
+
254
+ ## Pipe and Composition
255
+
256
+ ### Basic Pipe
257
+
258
+ ```typescript
259
+ import { Effect, pipe } from "effect"
260
+
261
+ // Using .pipe method
262
+ const result = Effect.succeed(1).pipe(
263
+ Effect.map(n => n + 1),
264
+ Effect.map(n => n * 2)
265
+ )
266
+
267
+ // Using pipe function
268
+ const result2 = pipe(
269
+ Effect.succeed(1),
270
+ Effect.map(n => n + 1),
271
+ Effect.map(n => n * 2)
272
+ )
273
+ ```
274
+
275
+ ### Common Operators
276
+
277
+ ```typescript
278
+ import { Effect } from "effect"
279
+
280
+ // Transform success value
281
+ const mapped = effect.pipe(
282
+ Effect.map(value => value.toUpperCase())
283
+ )
284
+
285
+ // Chain effects
286
+ const chained = effect.pipe(
287
+ Effect.flatMap(value => anotherEffect(value))
288
+ )
289
+
290
+ // Transform error
291
+ const mappedError = effect.pipe(
292
+ Effect.mapError(error => new WrappedError(error))
293
+ )
294
+
295
+ // Transform both
296
+ const mapBoth = effect.pipe(
297
+ Effect.mapBoth({
298
+ onSuccess: value => value.toUpperCase(),
299
+ onFailure: error => new WrappedError(error)
300
+ })
301
+ )
302
+
303
+ // Run side effect without changing value
304
+ const tapped = effect.pipe(
305
+ Effect.tap(value => Effect.sync(() => console.log(value)))
306
+ )
307
+
308
+ // Run side effect on error
309
+ const tappedError = effect.pipe(
310
+ Effect.tapError(error => Effect.sync(() => console.error(error)))
311
+ )
312
+ ```
313
+
314
+ ### Combining Multiple Effects
315
+
316
+ ```typescript
317
+ import { Effect } from "effect"
318
+
319
+ const effects = [effect1, effect2, effect3]
320
+
321
+ // Run all, collect results (fails fast on first error)
322
+ const all = Effect.all(effects)
323
+ // Effect<[A1, A2, A3], E, R>
324
+
325
+ // Run all, collect only successes
326
+ const allSuccesses = Effect.allSuccesses(effects)
327
+ // Effect<A[], never, R>
328
+
329
+ // Run first to succeed
330
+ const race = Effect.race(effect1, effect2)
331
+
332
+ // Run both, return tuple
333
+ const zip = Effect.zip(effect1, effect2)
334
+ // Effect<[A1, A2], E1 | E2, R1 | R2>
335
+
336
+ // Run both, combine results
337
+ const zipWith = Effect.zipWith(
338
+ effect1,
339
+ effect2,
340
+ (a, b) => a + b
341
+ )
342
+ ```
343
+
344
+ ### Concurrency Control
345
+
346
+ ```typescript
347
+ import { Effect } from "effect"
348
+
349
+ const tasks = [task1, task2, task3, task4, task5]
350
+
351
+ // Sequential (one at a time)
352
+ const sequential = Effect.all(tasks, { concurrency: 1 })
353
+
354
+ // Parallel (all at once)
355
+ const parallel = Effect.all(tasks, { concurrency: "unbounded" })
356
+
357
+ // Limited parallelism
358
+ const limited = Effect.all(tasks, { concurrency: 3 })
359
+
360
+ // Inherit from context
361
+ const inherited = Effect.all(tasks, { concurrency: "inherit" })
362
+ ```
363
+
364
+ ## Interop with Async/Await
365
+
366
+ ### Using Effect in Async Functions
367
+
368
+ ```typescript
369
+ // Call Effect from async function
370
+ async function main() {
371
+ const result = await Effect.runPromise(myEffect)
372
+ console.log(result)
373
+ }
374
+
375
+ // Handle exit for error details
376
+ async function mainWithExit() {
377
+ const exit = await Effect.runPromiseExit(myEffect)
378
+ if (Exit.isSuccess(exit)) {
379
+ console.log("Success:", exit.value)
380
+ } else {
381
+ console.error("Failure:", exit.cause)
382
+ }
383
+ }
384
+ ```
385
+
386
+ ### Wrapping Async Functions
387
+
388
+ ```typescript
389
+ import { Effect } from "effect"
390
+
391
+ // Wrap existing async function
392
+ const fetchUserEffect = (id: string) =>
393
+ Effect.tryPromise({
394
+ try: () => fetchUser(id), // existing async function
395
+ catch: (error) => new FetchError(String(error))
396
+ })
397
+
398
+ // Use in Effect.gen
399
+ const program = Effect.gen(function* () {
400
+ const user = yield* fetchUserEffect("123")
401
+ return user
402
+ })
403
+ ```
404
+
405
+ ## Best Practices
406
+
407
+ 1. **Keep effects lazy** - Don't run effects until necessary
408
+ 2. **Use generators for sequential code** - More readable than nested flatMap
409
+ 3. **Prefer specific error types** - Use tagged classes over generic Error
410
+ 4. **Run at the edge** - Call `runPromise`/`runSync` only at application boundaries
411
+ 5. **Compose with pipe** - Build complex effects from simple ones
412
+ 6. **Use appropriate concurrency** - Don't default to unbounded parallelism