@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.
- package/README.md +70 -76
- package/dev-kit.example.jsonc +0 -4
- package/package.json +10 -6
- package/schema/dev-kit.schema.json +1 -46
- package/skills/build-effect-apis/SKILL.md +77 -0
- package/skills/build-effect-apis/agents/openai.yaml +4 -0
- package/skills/build-effect-apis/references/cloudflare-workers.md +71 -0
- package/skills/build-effect-apis/references/effect-atom-client.md +161 -0
- package/skills/build-effect-apis/references/effect-atom-lifecycle.md +78 -0
- package/skills/build-effect-apis/references/effect-atom-testing.md +74 -0
- package/skills/build-effect-apis/references/runtime-assembly.md +56 -0
- package/skills/build-effect-apis/references/server-and-middleware.md +174 -0
- package/skills/build-effect-apis/references/shared-contracts.md +108 -0
- package/skills/build-effect-apis/references/tanstack-start.md +86 -0
- package/skills/build-effect-apis/references/verification.md +50 -0
- package/skills/dev-kit/SKILL.md +58 -46
- package/skills/effect-architecture-audit/SKILL.md +26 -0
- package/skills/effect-architecture-audit/agents/openai.yaml +4 -0
- package/skills/effect-architecture-audit/references/service-and-boundary-audit.md +150 -0
- package/skills/effect-ts/SKILL.md +21 -256
- package/skills/effect-ts/agents/openai.yaml +3 -3
- package/skills/testing/SKILL.md +5 -0
- package/src/catalog-manager.ts +16 -17
- package/src/catalog.ts +71 -16
- package/src/effect-source.ts +46 -24
- package/src/effect-tsgo.ts +49 -24
- package/src/gitignore.ts +5 -5
- package/src/index.ts +0 -6
- package/src/manifest.ts +0 -34
- package/src/node-symbolic-link.ts +2 -2
- package/src/oxfmt.js +5 -0
- package/src/oxfmt.ts +5 -0
- package/src/oxlint.js +5 -0
- package/src/oxlint.ts +5 -0
- package/src/package-skill-source.ts +51 -59
- package/src/path-digest.ts +7 -7
- package/src/project-package.ts +8 -7
- package/src/project-process-lock.ts +17 -12
- package/src/project-state.ts +1 -1
- package/src/skill-manager.ts +16 -14
- package/src/skill-selector.ts +12 -0
- package/src/sync.ts +170 -120
- package/src/tool-ignore-patterns.js +9 -0
- package/src/tool-ignore-patterns.ts +15 -0
- package/src/vendor.ts +67 -61
- package/src/vite-plus-dependency.ts +10 -11
- package/src/vite-plus-hooks.ts +24 -14
- package/src/vite-plus-quality.ts +21 -172
- package/src/vite-plus.js +81 -0
- package/src/vite-plus.ts +102 -0
- package/templates/AGENTS.md +1 -1
- package/skills/effect-ts/UPSTREAM.md +0 -28
- package/skills/effect-ts/references/atom-cache-lifecycle.md +0 -78
- package/skills/effect-ts/references/atom-http-and-invalidation.md +0 -97
- package/skills/effect-ts/references/atom-tanstack-start.md +0 -69
- package/skills/effect-ts/references/atom-testing.md +0 -67
- package/skills/effect-ts/references/audit-services.md +0 -144
- package/skills/effect-ts/references/features.md +0 -525
- package/skills/effect-ts/references/guide-atom-data-fetching.md +0 -44
- package/skills/effect-ts/references/guide-cli.md +0 -107
- package/skills/effect-ts/references/guide-datetime.md +0 -72
- package/skills/effect-ts/references/guide-effect.md +0 -440
- package/skills/effect-ts/references/guide-error-handling.md +0 -565
- package/skills/effect-ts/references/guide-http-boundaries.md +0 -55
- package/skills/effect-ts/references/guide-layers.md +0 -989
- package/skills/effect-ts/references/guide-observability.md +0 -746
- package/skills/effect-ts/references/guide-retries.md +0 -434
- package/skills/effect-ts/references/guide-schedule.md +0 -343
- package/skills/effect-ts/references/guide-schema.md +0 -664
- package/skills/effect-ts/references/guide-sql.md +0 -536
- package/skills/effect-ts/references/guide-testing.md +0 -532
- package/skills/effect-ts/references/guide-type-safety-and-boundaries.md +0 -131
- package/skills/effect-ts/references/version-and-source.md +0 -86
- package/templates/vite-plus/vite.config.ts +0 -22
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# Effect Atom TanStack Start integration
|
|
2
|
-
|
|
3
|
-
TanStack Start code is isomorphic by default, including route loaders. Treat every module used by a route as server-capable unless an explicit boundary says otherwise.
|
|
4
|
-
|
|
5
|
-
## Choose an SSR strategy
|
|
6
|
-
|
|
7
|
-
Use one of these models deliberately:
|
|
8
|
-
|
|
9
|
-
### Client-only atom data
|
|
10
|
-
|
|
11
|
-
- Put one `RegistryProvider` in the app/root component so client navigations share a registry.
|
|
12
|
-
- Render atom consumers that touch browser-only APIs inside `ClientOnly` from `@tanstack/react-router`.
|
|
13
|
-
- Accept that the fallback is the server-rendered state and fetching begins on the client.
|
|
14
|
-
- Keep the client runtime and API service as module singletons.
|
|
15
|
-
|
|
16
|
-
```tsx
|
|
17
|
-
import { RegistryProvider } from "@effect/atom-react";
|
|
18
|
-
import { ClientOnly } from "@tanstack/react-router";
|
|
19
|
-
|
|
20
|
-
export function AppShell() {
|
|
21
|
-
return (
|
|
22
|
-
<RegistryProvider defaultIdleTTL={30_000}>
|
|
23
|
-
<ClientOnly fallback={<DashboardSkeleton />}>
|
|
24
|
-
<Dashboard />
|
|
25
|
-
</ClientOnly>
|
|
26
|
-
</RegistryProvider>
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### SSR plus hydration
|
|
32
|
-
|
|
33
|
-
- Create the registry and any request-specific runtime/layers per request; never share user/auth state through a process-global registry or memo map.
|
|
34
|
-
- Give decoded query atoms deterministic `serializationKey` values.
|
|
35
|
-
- Mount/run the required serializable atoms on the server, dehydrate only the intended values, and pass them through the document safely.
|
|
36
|
-
- Create the client registry once, then hydrate matching atom identities before descendants consume them. Use `HydrationBoundary` where the installed React adapter supports it.
|
|
37
|
-
- Verify that server and client construct the same API service, family arguments, and serialization keys.
|
|
38
|
-
|
|
39
|
-
Prefer framework loaders/server functions when they already own SSR data. Do not build a second atom SSR cache merely to mirror loader data; seed atoms from the loader or keep atom fetching client-only.
|
|
40
|
-
|
|
41
|
-
## Focus is browser-only
|
|
42
|
-
|
|
43
|
-
`Atom.windowFocusSignal` reads `window` and `document.visibilityState` when mounted. Do not mount it during SSR. Put focus-enabled consumers behind `ClientOnly`, or inject a no-op server signal and the browser signal on the client.
|
|
44
|
-
|
|
45
|
-
```ts
|
|
46
|
-
const project = projectAtom(projectId).pipe(
|
|
47
|
-
Atom.swr({
|
|
48
|
-
staleTime: "30 seconds",
|
|
49
|
-
revalidateOnFocus: true,
|
|
50
|
-
focusSignal: Atom.windowFocusSignal,
|
|
51
|
-
}),
|
|
52
|
-
);
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
`revalidateOnFocus: true` respects `staleTime`; `"always"` forces a request on every focus signal.
|
|
56
|
-
|
|
57
|
-
## In-memory limits
|
|
58
|
-
|
|
59
|
-
Effect Atom's registry cache is in memory and scoped to that registry:
|
|
60
|
-
|
|
61
|
-
- a new tab, hard reload, server process, or newly created provider starts another cache;
|
|
62
|
-
- idle TTL evicts only unused atoms and is not a maximum-entry or byte-size bound;
|
|
63
|
-
- `keepAlive` and infinite TTL can grow memory with unbounded family keys;
|
|
64
|
-
- browser memory is not durable or shared across users/devices;
|
|
65
|
-
- hydration transfers a snapshot, not a persistent distributed cache.
|
|
66
|
-
|
|
67
|
-
For large or unbounded parameter spaces, use finite TTLs and avoid `keepAlive`. Put durable/shared caching at the HTTP, server, CDN, or database layer.
|
|
68
|
-
|
|
69
|
-
Primary TanStack references: [execution model](https://tanstack.com/start/latest/docs/framework/react/guide/execution-model) and [`ClientOnly`](https://tanstack.com/router/latest/docs/api/router/clientOnlyComponent).
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# Deterministic Effect Atom lifecycle testing
|
|
2
|
-
|
|
3
|
-
Test cache policy below React first with `AtomRegistry.make()`. Add a React integration test only for provider placement, hook behavior, a browser-only SSR boundary, or hydration.
|
|
4
|
-
|
|
5
|
-
Use fake timers, a request counter, controllable Effects, and explicit mounts:
|
|
6
|
-
|
|
7
|
-
```ts
|
|
8
|
-
const registry = AtomRegistry.make({ defaultIdleTTL: 1_000 });
|
|
9
|
-
const unmount = registry.mount(queryAtom);
|
|
10
|
-
const first = registry.get(queryAtom);
|
|
11
|
-
|
|
12
|
-
// Advance the Effect scheduler/microtasks as required by the installed version.
|
|
13
|
-
// Assert with AsyncResult predicates and request counts.
|
|
14
|
-
|
|
15
|
-
unmount();
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Avoid wall-clock sleeps. Flush Effect work with the repository's established `Effect.yieldNow`/test-clock pattern and advance the test runner's fake timers.
|
|
19
|
-
|
|
20
|
-
Prefer the installed test APIs over invented helpers or matchers. The upstream Effect tests use `assert(AsyncResult.isSuccess(result))`, `Effect.runPromise(Effect.yieldNow)`, `vitest.advanceTimersByTimeAsync(...)`, and the cleanup returned by `registry.mount(atom)`.
|
|
21
|
-
|
|
22
|
-
## Required scenarios
|
|
23
|
-
|
|
24
|
-
### Remount reuse
|
|
25
|
-
|
|
26
|
-
1. Mount and resolve the query; assert request count `1`.
|
|
27
|
-
2. Unmount, advance less than idle TTL, remount the same atom identity.
|
|
28
|
-
3. Assert the cached success is immediately available and no request occurs while still fresh.
|
|
29
|
-
|
|
30
|
-
### Stale refresh
|
|
31
|
-
|
|
32
|
-
1. Resolve once through an SWR wrapper.
|
|
33
|
-
2. Advance past `staleTime` but not idle TTL.
|
|
34
|
-
3. Remount or emit the injected focus signal.
|
|
35
|
-
4. Assert the previous success stays available with `waiting: true`, then a second success arrives and request count becomes `2`.
|
|
36
|
-
5. Also prove a fresh mount/focus does not request.
|
|
37
|
-
|
|
38
|
-
### TTL eviction
|
|
39
|
-
|
|
40
|
-
1. Resolve and unmount.
|
|
41
|
-
2. Advance to just before TTL; assert reuse.
|
|
42
|
-
3. Advance to/after TTL and flush disposal; remount.
|
|
43
|
-
4. Assert `Initial`/waiting behavior and a new request.
|
|
44
|
-
|
|
45
|
-
### Polling cleanup
|
|
46
|
-
|
|
47
|
-
1. Mount the `Atom.withRefresh` wrapper and resolve once.
|
|
48
|
-
2. Advance one interval; assert one forced refresh.
|
|
49
|
-
3. Unmount and advance several intervals.
|
|
50
|
-
4. Assert the counter does not change. This catches leaked timers or accidental `keepAlive`.
|
|
51
|
-
|
|
52
|
-
### Mutation invalidation
|
|
53
|
-
|
|
54
|
-
1. Mount list and detail queries with explicit keys.
|
|
55
|
-
2. Run a successful mutation with matching keys; assert only the intended queries refresh.
|
|
56
|
-
3. Run a failed mutation; assert no invalidation.
|
|
57
|
-
4. Assert cleanup removes invalidation handlers after query disposal.
|
|
58
|
-
|
|
59
|
-
### React Strict Mode and action ownership
|
|
60
|
-
|
|
61
|
-
Use a React integration test when hook cleanup or action ownership is part of the behavior. Render the owner inside `StrictMode` and assert the development setup-cleanup replay does not write `Atom.Interrupt` or publish an interrupted failure before an explicit cancellation. When an action spans multiple requests, unmount during the sequence and prove the chosen policy: either the stable owner completes every step, or an explicit cancellation interrupts it intentionally. If the atom is shared, also prove unmounting one consumer does not cancel work still owned by another.
|
|
62
|
-
|
|
63
|
-
### Aggregate stability
|
|
64
|
-
|
|
65
|
-
Mount a route atom that uses `AsyncResult.all`, resolve every input, unmount, and remount inside the retention window. Assert the aggregate never returns to `Initial`. Then let one input expire and prove the aggregate reset is caused by that input, not the retained queries.
|
|
66
|
-
|
|
67
|
-
For runtime/layer tests, seed `runtime.layer` through `RegistryProvider initialValues` with a deterministic test layer. This replaces network services without changing the production atom graph.
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
# Auditing Effect Services
|
|
2
|
-
|
|
3
|
-
Use this for an audit across a codebase, package, feature slice, or diff. Apply
|
|
4
|
-
the service and test rules from the other references selected by
|
|
5
|
-
`effect-ts`.
|
|
6
|
-
|
|
7
|
-
## Contents
|
|
8
|
-
|
|
9
|
-
- [Establish Local Rules](#1-establish-local-rules)
|
|
10
|
-
- [Build The Inventory](#2-build-the-inventory)
|
|
11
|
-
- [Trace Authority And Requirements](#3-trace-authority-and-requirements)
|
|
12
|
-
- [Classify Each Candidate](#4-classify-each-candidate)
|
|
13
|
-
- [Audit Test Strategies](#5-audit-test-strategies)
|
|
14
|
-
- [Report Actionable Findings](#6-report-actionable-findings)
|
|
15
|
-
|
|
16
|
-
## 1. Establish Local Rules
|
|
17
|
-
|
|
18
|
-
Read the project architecture guidance, Effect conventions, pinned Effect
|
|
19
|
-
version or source, and relevant version-matched examples. Record the governing
|
|
20
|
-
conventions and APIs that later decisions must follow.
|
|
21
|
-
|
|
22
|
-
Complete this step when the applicable project guidance and pinned source
|
|
23
|
-
examples are named.
|
|
24
|
-
|
|
25
|
-
## 2. Build The Inventory
|
|
26
|
-
|
|
27
|
-
Enumerate source and test files, then find:
|
|
28
|
-
|
|
29
|
-
- Every `Context.Service`, tag, `Layer`, `make`, `provide`, and
|
|
30
|
-
`provideService`.
|
|
31
|
-
- Service-shaped interfaces or classes with effectful methods.
|
|
32
|
-
- Dependencies passed through parameters, properties, constructors, callbacks,
|
|
33
|
-
options bags, or Layers.
|
|
34
|
-
- Direct access to time, randomness, cryptography, IDs, configuration, HTTP,
|
|
35
|
-
persistence, registries, renderers, filesystems, runtime bindings, and
|
|
36
|
-
mutable globals.
|
|
37
|
-
- Test fakes, in-memory implementations, module mocks, and hand-built
|
|
38
|
-
`Layer.succeed` values.
|
|
39
|
-
- Public Effects with `unknown` or `any` error types.
|
|
40
|
-
- Assertions, non-null assertions, custom type predicates, structural probes,
|
|
41
|
-
JSON parsing, Promise catch mappers, and `throw` statements.
|
|
42
|
-
- Local schemas, codecs, JSON types, and runtime helpers that overlap Effect or
|
|
43
|
-
platform APIs.
|
|
44
|
-
|
|
45
|
-
Record one row per discovered service or candidate:
|
|
46
|
-
|
|
47
|
-
| Field | Question |
|
|
48
|
-
| ------------- | ----------------------------------------------------------- |
|
|
49
|
-
| Owner | Which module owns the capability's meaning? |
|
|
50
|
-
| Contract | Where are its interface and tag? |
|
|
51
|
-
| Construction | Does construction yield every runtime dependency? |
|
|
52
|
-
| Production | Who owns the concrete implementation and Layer choice? |
|
|
53
|
-
| Tests | Does it have an intentional and honest substitute strategy? |
|
|
54
|
-
| Consumers | Are capabilities yielded or drilled as values? |
|
|
55
|
-
| Requirements | Do requirements remain visible to the composition root? |
|
|
56
|
-
| Type boundary | Who owns decoding, narrowing, and error translation? |
|
|
57
|
-
| Verdict | Keep, deepen, relocate, merge, remove, or create? |
|
|
58
|
-
|
|
59
|
-
Build a companion type-safety inventory using
|
|
60
|
-
[`guide-type-safety-and-boundaries.md`](guide-type-safety-and-boundaries.md).
|
|
61
|
-
Attach each
|
|
62
|
-
occurrence to its owning service or boundary and record its input provenance,
|
|
63
|
-
intended type or error, and target disposition.
|
|
64
|
-
|
|
65
|
-
Complete this step when every discovered service, tag, Layer, service-shaped
|
|
66
|
-
candidate, and type-safety occurrence appears exactly once.
|
|
67
|
-
|
|
68
|
-
## 3. Trace Authority And Requirements
|
|
69
|
-
|
|
70
|
-
For each inventory row:
|
|
71
|
-
|
|
72
|
-
1. Trace one caller-visible operation to every effect it performs.
|
|
73
|
-
2. Mark where each dependency first appears and whether code yields it, passes
|
|
74
|
-
it, captures it, or provides it concretely.
|
|
75
|
-
3. Verify that the module selecting a concrete Layer owns that implementation
|
|
76
|
-
choice.
|
|
77
|
-
4. Check project-compatible Effect capabilities before recommending an
|
|
78
|
-
application wrapper.
|
|
79
|
-
5. Follow every requirement to a composition root or an explicit value
|
|
80
|
-
boundary.
|
|
81
|
-
|
|
82
|
-
Inspect dependency drilling, Layer arguments, dependency bags, handler-builder
|
|
83
|
-
service values, inner `Effect.provide` calls, direct runtime access, and
|
|
84
|
-
contracts or Layers scattered across unrelated owners.
|
|
85
|
-
|
|
86
|
-
Complete this step when every capability has an unbroken path from use to its
|
|
87
|
-
composition root or documented value boundary.
|
|
88
|
-
|
|
89
|
-
## 4. Classify Each Candidate
|
|
90
|
-
|
|
91
|
-
Apply the authority seam and deletion tests, then assign one classification:
|
|
92
|
-
|
|
93
|
-
- **Built-in Effect capability** — yield the existing capability.
|
|
94
|
-
- **Application-owned authority** — define a narrow port beside the operation
|
|
95
|
-
that needs it.
|
|
96
|
-
- **Technology adapter** — implement an application-owned port in the adapter.
|
|
97
|
-
- **Request or domain value** — keep the value explicit.
|
|
98
|
-
- **Framework boundary** — contain the framework-required API in its adapter or
|
|
99
|
-
composition root.
|
|
100
|
-
- **Pass-through abstraction** — fold it into the real owner.
|
|
101
|
-
|
|
102
|
-
Prefer an existing owner or a merge of duplicated capabilities over a generic
|
|
103
|
-
registry or dependency bag.
|
|
104
|
-
|
|
105
|
-
Complete this step when every candidate has one evidence-backed classification
|
|
106
|
-
and each service-or-value decision states why the alternative was rejected.
|
|
107
|
-
|
|
108
|
-
## 5. Audit Test Strategies
|
|
109
|
-
|
|
110
|
-
Record how tests replace or control each production service. Verify that
|
|
111
|
-
exported test and in-memory Layers implement the behavior their names promise,
|
|
112
|
-
and keep focused partial fixtures local to their tests.
|
|
113
|
-
|
|
114
|
-
Complete this step when every production service has an intentional test
|
|
115
|
-
strategy or an explicit production-only rationale.
|
|
116
|
-
|
|
117
|
-
## 6. Report Actionable Findings
|
|
118
|
-
|
|
119
|
-
Prioritize by correctness and requirement visibility:
|
|
120
|
-
|
|
121
|
-
- **P0** — hidden authority, unsafe direct runtime access, broken or duplicated
|
|
122
|
-
capability, wrong Layer ownership, untyped expected failures, or unchecked
|
|
123
|
-
external data.
|
|
124
|
-
- **P1** — repeated dependency drilling, hidden requirements, scattered service
|
|
125
|
-
ownership, manual shape discovery, unjustified assertions, custom substitutes
|
|
126
|
-
for Effect APIs, or a missing intentional test strategy.
|
|
127
|
-
- **P2** — naming or co-location cleanup that should accompany a nearby
|
|
128
|
-
refactor.
|
|
129
|
-
|
|
130
|
-
For each finding include:
|
|
131
|
-
|
|
132
|
-
1. File, line, or symbol evidence.
|
|
133
|
-
2. The hidden requirement or caller burden.
|
|
134
|
-
3. The smallest target shape using the project's Effect conventions.
|
|
135
|
-
4. The composition-root and test impact.
|
|
136
|
-
5. The behavior and modules that should remain unchanged.
|
|
137
|
-
|
|
138
|
-
End with explicit keep decisions for values, pure functions, framework
|
|
139
|
-
boundaries, correctly separated ports and adapters, and request-scoped
|
|
140
|
-
services.
|
|
141
|
-
|
|
142
|
-
Complete the audit when every inventory row and type-safety occurrence has a
|
|
143
|
-
disposition, every proposed change names its owner and target shape, and every
|
|
144
|
-
proposal remains evidence-backed and scoped to observed code.
|