@danieljvdm/dev-kit 0.14.0 → 0.16.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 +155 -99
- package/dev-kit.example.jsonc +4 -3
- package/package.json +1 -1
- package/schema/dev-kit.schema.json +19 -42
- package/skills/build-effect-apis/SKILL.md +13 -31
- package/skills/build-effect-apis/references/verification.md +3 -3
- package/skills/dev-kit/SKILL.md +115 -222
- package/skills/effect-atom-state/SKILL.md +97 -0
- package/skills/effect-atom-state/agents/openai.yaml +4 -0
- package/skills/effect-atom-state/references/effect-atom-workflows.md +180 -0
- package/skills/open-pull-request/SKILL.md +62 -23
- package/src/bin/dev-kit.ts +21 -0
- package/src/catalog.ts +39 -15
- package/src/effect-source.ts +70 -4
- package/src/global-cache.ts +304 -0
- package/src/index.ts +6 -6
- package/src/manifest.ts +28 -29
- package/src/oxlint.js +23 -0
- package/src/oxlint.ts +37 -1
- package/src/path-digest.ts +0 -13
- package/src/project-package.ts +127 -12
- package/src/project-state.ts +3 -0
- package/src/scaffold.ts +79 -0
- package/src/sync.ts +100 -173
- package/src/vite-plus-workflow.ts +82 -0
- package/src/vite-plus.js +8 -1
- package/src/vite-plus.ts +15 -1
- package/src/worktrunk-config.ts +88 -0
- package/templates/vite-plus/github-actions-check.yml +0 -2
- package/templates/worktrunk/wt.toml +27 -0
- package/src/vite-plus-quality.ts +0 -148
- /package/skills/{build-effect-apis → effect-atom-state}/references/effect-atom-client.md +0 -0
- /package/skills/{build-effect-apis → effect-atom-state}/references/effect-atom-lifecycle.md +0 -0
- /package/skills/{build-effect-apis → effect-atom-state}/references/effect-atom-testing.md +0 -0
- /package/skills/{build-effect-apis → effect-atom-state}/references/tanstack-start.md +0 -0
package/README.md
CHANGED
|
@@ -137,6 +137,7 @@ the root package itself.
|
|
|
137
137
|
| `dev-kit gitignore` | Add `.repos/` and `.dev-kit/` to `.gitignore`. |
|
|
138
138
|
| `dev-kit effect sync` | Sync `.repos/effect` to the installed Effect version. |
|
|
139
139
|
| `dev-kit tsgo patch` | Validate and patch Effect TypeScript-Go directly. |
|
|
140
|
+
| `dev-kit cache prune` | Evict stale machine-global cache content (`--all` wipes). |
|
|
140
141
|
| `dev-kit catalog refresh` | Maintainer command to approve current upstream refs. |
|
|
141
142
|
| `dev-kit catalog add <repository>` | Inspect a repository and approve selected skills. |
|
|
142
143
|
| `dev-kit catalog remove <source-or-skill>` | Revoke an approval (`--yes` outside a terminal). |
|
|
@@ -199,21 +200,15 @@ tool versions. A project-local process lock also prevents concurrent applies.
|
|
|
199
200
|
```
|
|
200
201
|
|
|
201
202
|
- `dev-kit` installs guidance for operating the toolkit itself.
|
|
202
|
-
- `
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
processes, runtime entrypoints, and script/CLI testing.
|
|
210
|
-
- Prefer individual external skills such as `workers-best-practices` and
|
|
211
|
-
`wrangler`, selected after scanning the project for relevant technologies.
|
|
212
|
-
- `serve-sim` selects the approved Evan Bacon simulator skill directly.
|
|
203
|
+
- `effect` is a built-in family: the `effect-ts` bootstrap,
|
|
204
|
+
`effect-architecture-audit`, `build-effect-apis`, `effect-atom-state`, and
|
|
205
|
+
`build-effect-clis`.
|
|
206
|
+
- External Git skills (`workers-best-practices`, `serve-sim`, …) are selected
|
|
207
|
+
individually after scanning the project for relevant technologies. An
|
|
208
|
+
approved source ID selects every skill from that source; use it only when
|
|
209
|
+
the scan confirms that every member applies.
|
|
213
210
|
- `@tanstack/ai#ai-core` explicitly selects a skill discovered in that direct
|
|
214
211
|
project dependency; discovery alone never selects it.
|
|
215
|
-
- An approved source ID is broad shorthand that selects every skill from that
|
|
216
|
-
source. Use it only when the scan confirms that every member applies.
|
|
217
212
|
|
|
218
213
|
Dev Kit reserves `.repos/<source-id>` for project-local source checkouts. Run
|
|
219
214
|
`dev-kit gitignore` to add `.repos/` and `.dev-kit/` to the project ignore file.
|
|
@@ -239,18 +234,17 @@ bridge in the manifest:
|
|
|
239
234
|
`AGENTS.md`, preserving handwritten project guidance around them. The Dev Kit
|
|
240
235
|
section contains a short description and a pointer to the installed `dev-kit`
|
|
241
236
|
skill. When the root `package.json` declares `vite-plus` directly, Dev Kit
|
|
242
|
-
renders its own repository-specific Vite+ guidance
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
owned update. Ambiguous or malformed managed markers fail closed.
|
|
237
|
+
renders its own repository-specific Vite+ guidance — toolchain overview, help
|
|
238
|
+
and documentation entry points, `vp env doctor` troubleshooting — rather than
|
|
239
|
+
importing Vite+'s generic `AGENTS.md`, which can contradict the repository's
|
|
240
|
+
exact commands; transitive installations do not opt a project in. Ambiguous or
|
|
241
|
+
malformed managed markers fail closed.
|
|
248
242
|
|
|
249
243
|
The Dev Kit section also renders an opinionated project command policy. A
|
|
250
244
|
direct Vite+ dependency makes `vp` the only supported front door: built-in
|
|
251
245
|
format, lint, and test commands use `vp`, while repository tasks and package
|
|
252
|
-
scripts use `vp run`. When
|
|
253
|
-
full validation and typecheck commands are `vp run check` and
|
|
246
|
+
scripts use `vp run`. When the manifest enables the Vite+ workflow scaffold,
|
|
247
|
+
the canonical full validation and typecheck commands are `vp run check` and
|
|
254
248
|
`vp run typecheck`; `vp check` alone is only the Vite+ static-check command.
|
|
255
249
|
Without Vite+, Bun is the required package-script runner and Dev Kit lists only
|
|
256
250
|
quality scripts the root package actually declares. The package manager named
|
|
@@ -291,7 +285,7 @@ worktree converges its own copy during install while the project-owned
|
|
|
291
285
|
## Vite+ quality setup
|
|
292
286
|
|
|
293
287
|
The repository always owns `vite.config.ts`. Compose Dev Kit's quality defaults
|
|
294
|
-
from that project-owned config, then opt into the
|
|
288
|
+
from that project-owned config, then opt into the scaffolded GitHub Actions
|
|
295
289
|
workflow independently:
|
|
296
290
|
|
|
297
291
|
```ts
|
|
@@ -321,13 +315,6 @@ Project and framework-generated paths belong in `ignorePatterns` as shown;
|
|
|
321
315
|
custom harness target paths belong there too. Dev Kit does not grow a global
|
|
322
316
|
framework ignore list.
|
|
323
317
|
|
|
324
|
-
Vite+ 0.2.6 forwards JavaScript-plugin declarations into its effective lint
|
|
325
|
-
config but its bundled native Oxlint path does not register or execute those
|
|
326
|
-
rules. Native Oxlint rules and Oxfmt settings remain active; run standalone
|
|
327
|
-
Oxlint when enforcement of Dev Kit's `effect/*` or
|
|
328
|
-
`stylistic/padding-line-between-statements` rules is required. This limitation
|
|
329
|
-
can be removed once a supported Vite+ release executes configured JS plugins.
|
|
330
|
-
|
|
331
318
|
```jsonc
|
|
332
319
|
{
|
|
333
320
|
"include": ["dev-kit", "effect"],
|
|
@@ -335,19 +322,24 @@ can be removed once a supported Vite+ release executes configured JS plugins.
|
|
|
335
322
|
"effectTsgo": { "enabled": true },
|
|
336
323
|
"vitePlus": {
|
|
337
324
|
"hooks": { "enabled": true },
|
|
338
|
-
"
|
|
339
|
-
"workflow": { "enabled": true },
|
|
340
|
-
},
|
|
325
|
+
"workflow": { "enabled": true },
|
|
341
326
|
},
|
|
342
327
|
},
|
|
343
328
|
}
|
|
344
329
|
```
|
|
345
330
|
|
|
346
|
-
`
|
|
347
|
-
rewrites, adopts, or removes `vite.config.ts`.
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
331
|
+
`setup.vitePlus.workflow` scaffolds `.github/workflows/check.yml` and never
|
|
332
|
+
reads, rewrites, adopts, or removes `vite.config.ts`. Scaffolds are
|
|
333
|
+
create-only: the file is written only when missing, never recorded in
|
|
334
|
+
`dev-kit.lock.json`, and never touched again — the repository owns it from
|
|
335
|
+
creation, and disabling the task leaves it in place. Edit the YAML directly
|
|
336
|
+
for repository-specific preparation steps or a custom typecheck command; when
|
|
337
|
+
the shipped template improves, compare against the installed copy under
|
|
338
|
+
`node_modules/@danieljvdm/dev-kit/templates/` and merge what fits.
|
|
339
|
+
Scaffolding requires direct `@danieljvdm/dev-kit`, `vite-plus`, `effect`,
|
|
340
|
+
`@effect/tsgo`, and native TypeScript dependencies with
|
|
341
|
+
`setup.effectTsgo.enabled`, and the installed Vite+ must satisfy Dev Kit's
|
|
342
|
+
peer range.
|
|
351
343
|
|
|
352
344
|
Workspaces select bounded, dependency-ordered typechecking in their config:
|
|
353
345
|
|
|
@@ -363,44 +355,98 @@ export default defineConfig(
|
|
|
363
355
|
);
|
|
364
356
|
```
|
|
365
357
|
|
|
366
|
-
Each listed package must expose a pure `typecheck` script.
|
|
367
|
-
|
|
358
|
+
Each listed package must expose a pure `typecheck` script.
|
|
359
|
+
|
|
360
|
+
The scaffolded workflow performs one frozen, script-suppressed install, runs
|
|
361
|
+
`dev-kit apply --locked`, and only then runs formatting, linting, tests, and
|
|
362
|
+
`vp run typecheck`. See the primary
|
|
363
|
+
[`setup-vp` versioning guidance](https://github.com/voidzero-dev/setup-vp#versioning),
|
|
364
|
+
[Vite+ install guide](https://viteplus.dev/guide/install), and
|
|
365
|
+
[Vite Task run guide](https://viteplus.dev/guide/run) when maintaining the
|
|
366
|
+
templates.
|
|
367
|
+
|
|
368
|
+
### Absolute (path-alias) imports
|
|
369
|
+
|
|
370
|
+
Opt into enforcing path-alias imports for selected app sources. The factory
|
|
371
|
+
appends an Oxlint override that errors on `../` imports inside the given
|
|
372
|
+
globs, so those files import through tsconfig path aliases such as `@/*`:
|
|
373
|
+
|
|
374
|
+
```ts
|
|
375
|
+
export default defineConfig(
|
|
376
|
+
createRecommendedVitePlusConfig({
|
|
377
|
+
absoluteImports: {
|
|
378
|
+
files: ["apps/app/src/**/*.{ts,tsx}", "apps/mobile/src/**/*.{ts,tsx}"],
|
|
379
|
+
},
|
|
380
|
+
}),
|
|
381
|
+
);
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
The lint rule only forbids relative parent imports; each covered app must map
|
|
385
|
+
the alias itself. Add the `paths` entry to the app's `tsconfig.json`:
|
|
368
386
|
|
|
369
387
|
```jsonc
|
|
370
388
|
{
|
|
389
|
+
"compilerOptions": {
|
|
390
|
+
"paths": { "@/*": ["./src/*"] },
|
|
391
|
+
},
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Vite-built apps also resolve the alias from the same tsconfig by setting
|
|
396
|
+
`resolve: { tsconfigPaths: true }` in the app's Vite config. Expo apps need no
|
|
397
|
+
Metro configuration: Expo SDK 49+ resolves tsconfig `paths` by default.
|
|
398
|
+
|
|
399
|
+
Standalone Oxlint projects compose the same override directly:
|
|
400
|
+
|
|
401
|
+
```ts
|
|
402
|
+
// oxlint.config.ts
|
|
403
|
+
import {
|
|
404
|
+
createAbsoluteImportsOxlintOverride,
|
|
405
|
+
recommendedOxlintConfig,
|
|
406
|
+
} from "@danieljvdm/dev-kit/oxlint";
|
|
407
|
+
import { defineConfig } from "oxlint";
|
|
408
|
+
|
|
409
|
+
export default defineConfig({
|
|
410
|
+
extends: [recommendedOxlintConfig],
|
|
411
|
+
overrides: [createAbsoluteImportsOxlintOverride({ files: ["src/**/*.{ts,tsx}"] })],
|
|
412
|
+
});
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Worktrunk project config
|
|
416
|
+
|
|
417
|
+
Enable a scaffolded default [Worktrunk](https://worktrunk.dev) project config
|
|
418
|
+
in the manifest:
|
|
419
|
+
|
|
420
|
+
```jsonc
|
|
421
|
+
{
|
|
422
|
+
"include": ["dev-kit"],
|
|
371
423
|
"setup": {
|
|
372
|
-
"
|
|
373
|
-
"vitePlus": {
|
|
374
|
-
"quality": {
|
|
375
|
-
"workflow": {
|
|
376
|
-
"enabled": true,
|
|
377
|
-
"beforeChecks": [
|
|
378
|
-
{
|
|
379
|
-
"name": "Install media tools",
|
|
380
|
-
"run": ["sudo apt-get update", "sudo apt-get install --yes ffmpeg"],
|
|
381
|
-
},
|
|
382
|
-
],
|
|
383
|
-
"typecheck": [
|
|
384
|
-
"vp run -F './apps/*' -F './packages/*' check",
|
|
385
|
-
"vp exec tsc --noEmit -p scripts/tsconfig.json",
|
|
386
|
-
],
|
|
387
|
-
},
|
|
388
|
-
},
|
|
389
|
-
},
|
|
424
|
+
"worktrunk": { "config": { "enabled": true } },
|
|
390
425
|
},
|
|
391
426
|
}
|
|
392
427
|
```
|
|
393
428
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
429
|
+
`setup.worktrunk.config` scaffolds `.config/wt.toml` with the portable hooks an
|
|
430
|
+
app repository wants in every worktree: a `pre-start` pipeline that copies
|
|
431
|
+
gitignored files matched by `.worktreeinclude` (a no-op without that file) and
|
|
432
|
+
then installs dependencies, plus a `pre-merge` full-validation hook. Hook
|
|
433
|
+
commands render for the repository's command runner: a direct `vite-plus`
|
|
434
|
+
dependency selects `vp install` and `vp run check`; otherwise Dev Kit requires
|
|
435
|
+
a declared root `check` package script, runs it through `bun run check`, and
|
|
436
|
+
takes the install command from the detected package manager. Repositories with
|
|
437
|
+
neither fail the plan instead of shipping a broken hook.
|
|
438
|
+
|
|
439
|
+
The config follows the same create-only scaffold semantics as the check
|
|
440
|
+
workflow above: created once, never locked or touched again, owned by the
|
|
441
|
+
repository. Edit hooks freely after creation.
|
|
442
|
+
|
|
443
|
+
The config intentionally carries no worktree-path template or other user
|
|
444
|
+
preferences—those belong in each user's `~/.config/worktrunk/config.toml`. A
|
|
445
|
+
commented `post-start` block shows how to run a per-worktree dev server on a
|
|
446
|
+
stable branch-derived port (`{{ branch | hash_port }}`) under `wt step tether`;
|
|
447
|
+
point it at the repository's dev entrypoint and uncomment to opt in. Worktrunk
|
|
448
|
+
never runs project hooks until each user approves them with
|
|
449
|
+
`wt config approvals add`.
|
|
404
450
|
|
|
405
451
|
## Effect source checkout
|
|
406
452
|
|
|
@@ -416,9 +462,12 @@ Enable a local checkout of the exact installed Effect release in the manifest:
|
|
|
416
462
|
```
|
|
417
463
|
|
|
418
464
|
`dev-kit apply` reads `node_modules/effect/package.json`, then shallow-clones or
|
|
419
|
-
updates `.repos/effect` to the detached `effect@<version>` tag.
|
|
420
|
-
|
|
421
|
-
|
|
465
|
+
updates `.repos/effect` to the detached `effect@<version>` tag. Tag fetches go
|
|
466
|
+
through a shared clone in the machine-global cache, so a new worktree or
|
|
467
|
+
project reuses tags already cached on the machine and only contacts the
|
|
468
|
+
network for a tag the cache has never seen. It skips the checkout in CI,
|
|
469
|
+
leaves the repository in place when the task is disabled, and refuses to
|
|
470
|
+
switch a checkout with local changes or an unexpected origin.
|
|
422
471
|
|
|
423
472
|
The path, package name, and repository URL may be overridden for compatible
|
|
424
473
|
Effect package layouts. Use `dev-kit effect sync --dry-run` to inspect this
|
|
@@ -522,31 +571,20 @@ bun x dev-kit add @tanstack/ai#ai-core
|
|
|
522
571
|
That writes `@tanstack/ai#ai-core` to `dev-kit.jsonc` and, unless
|
|
523
572
|
`--no-apply` is passed, installs it through the normal ownership-safe sync
|
|
524
573
|
path. The qualifier prevents ambiguity when two dependencies publish the same
|
|
525
|
-
skill name, and the installed output carries it
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
`devDependencies`, `optionalDependencies`, or `peerDependencies` are
|
|
540
|
-
scanned;
|
|
541
|
-
- package code is never imported or executed;
|
|
542
|
-
- npm-style and pnpm/workspace symlinks under `node_modules` are supported;
|
|
543
|
-
- Yarn Plug'n'Play and transitive dependency traversal are not scanned; and
|
|
544
|
-
- immediate `skills/<name>/SKILL.md` roots are listed. Nested topic skills and
|
|
545
|
-
references remain part of that root and are copied with it.
|
|
546
|
-
|
|
547
|
-
The last rule adapts Intent's routed, nested skill trees to the immediate folder
|
|
548
|
-
and frontmatter-name invariants expected by Agent Skills targets. Dev Kit does
|
|
549
|
-
not rewrite nested names or ask Intent to manage agent configuration.
|
|
574
|
+
skill name, and the installed output carries it: the copied directory flattens
|
|
575
|
+
the package name and appends the skill name (`@tanstack/ai#ai-core` →
|
|
576
|
+
`tanstack-ai-ai-core`), and the copied `SKILL.md` frontmatter `name:` is
|
|
577
|
+
rewritten to match because harnesses identify a skill by its directory name.
|
|
578
|
+
Symlink-mode targets link straight into `node_modules`, so only the link
|
|
579
|
+
carries the qualified name. Two selections that would write the same
|
|
580
|
+
destination are rejected before any output changes.
|
|
581
|
+
|
|
582
|
+
The compatibility boundary is intentionally small and deterministic: only the
|
|
583
|
+
root project's direct dependencies are scanned, package code is never imported
|
|
584
|
+
or executed, npm-style and pnpm/workspace symlinks are supported (Yarn
|
|
585
|
+
Plug'n'Play and transitive traversal are not), and only immediate
|
|
586
|
+
`skills/<name>/SKILL.md` roots are listed — nested topic skills and references
|
|
587
|
+
are copied as part of their root.
|
|
550
588
|
|
|
551
589
|
The project `dev-kit.lock.json` records the selected package name, installed
|
|
552
590
|
version, original bare skill name, and the `node_modules` content digest.
|
|
@@ -601,9 +639,23 @@ names and paths, rejects symlinks and collisions, extracts descriptions, and
|
|
|
601
639
|
updates `skill-sources.lock.json`.
|
|
602
640
|
|
|
603
641
|
When a project selects one of these Git-backed skills, Dev Kit fetches the
|
|
604
|
-
approved commit into
|
|
605
|
-
|
|
606
|
-
|
|
642
|
+
approved commit into a machine-global cache and installs it through the same
|
|
643
|
+
ownership-safe sync path. Cache entries are keyed by resolved commit SHA, so
|
|
644
|
+
every project and git worktree on the machine shares one download; a warm
|
|
645
|
+
`dev-kit plan` or `dev-kit apply` performs no network operations. The cache
|
|
646
|
+
lives in `$XDG_CACHE_HOME/dev-kit` (falling back to `~/Library/Caches/dev-kit`
|
|
647
|
+
on macOS and `~/.cache/dev-kit` elsewhere) and may be overridden with
|
|
648
|
+
`DEV_KIT_CACHE_DIR`; it is safe to delete at any time. Populating this
|
|
649
|
+
immutable commit-keyed cache is not project state, so planning and `--locked`
|
|
650
|
+
verification use it too. Only a reviewed catalog refresh changes the approved
|
|
651
|
+
Git content.
|
|
652
|
+
|
|
653
|
+
The cache does not grow without bounds: every use refreshes a recency stamp,
|
|
654
|
+
and `dev-kit apply` sweeps content unused for 30 days at most once a day.
|
|
655
|
+
Shared Effect repositories drop unused tags individually and are removed whole
|
|
656
|
+
once empty. Run `dev-kit cache prune` to sweep on demand (`--max-age-days` to
|
|
657
|
+
tune the threshold, `--all` to clear the cache entirely); an evicted entry is
|
|
658
|
+
simply fetched again the next time a project needs it.
|
|
607
659
|
|
|
608
660
|
## Oxlint and Oxfmt configurations
|
|
609
661
|
|
|
@@ -652,7 +704,11 @@ export default defineConfig({
|
|
|
652
704
|
The Oxlint preset enables `stylistic/padding-line-between-statements`: adjacent
|
|
653
705
|
variable declarations remain grouped, while the next logical statement and
|
|
654
706
|
all `return` statements require a separating blank line. The rule is fixable,
|
|
655
|
-
so `vp lint --fix` repairs missing spacing automatically.
|
|
707
|
+
so `vp lint --fix` repairs missing spacing automatically. Vite+ 0.2.6 forwards
|
|
708
|
+
the preset's JavaScript-plugin declarations but its native Oxlint path does not
|
|
709
|
+
execute their rules — run standalone Oxlint when `effect/*` or the padding rule
|
|
710
|
+
must be enforced, until a supported Vite+ release executes configured JS
|
|
711
|
+
plugins.
|
|
656
712
|
|
|
657
713
|
The preset also registers the shared `effect` JavaScript plugin. Effect
|
|
658
714
|
projects opt into its rules in path-specific overrides, for example
|
package/dev-kit.example.jsonc
CHANGED
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
"effectTsgo": { "enabled": true },
|
|
9
9
|
"vitePlus": {
|
|
10
10
|
"hooks": { "enabled": true },
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
"workflow": { "enabled": true },
|
|
12
|
+
},
|
|
13
|
+
"worktrunk": {
|
|
14
|
+
"config": { "enabled": true },
|
|
14
15
|
},
|
|
15
16
|
},
|
|
16
17
|
"targets": {
|
package/package.json
CHANGED
|
@@ -48,6 +48,9 @@
|
|
|
48
48
|
},
|
|
49
49
|
"vitePlus": {
|
|
50
50
|
"$ref": "#/$defs/vitePlusSetup"
|
|
51
|
+
},
|
|
52
|
+
"worktrunk": {
|
|
53
|
+
"$ref": "#/$defs/worktrunkSetup"
|
|
51
54
|
}
|
|
52
55
|
},
|
|
53
56
|
"default": {}
|
|
@@ -144,8 +147,8 @@
|
|
|
144
147
|
"hooks": {
|
|
145
148
|
"$ref": "#/$defs/vitePlusHooksSetup"
|
|
146
149
|
},
|
|
147
|
-
"
|
|
148
|
-
"$ref": "#/$defs/
|
|
150
|
+
"workflow": {
|
|
151
|
+
"$ref": "#/$defs/vitePlusWorkflowSetup"
|
|
149
152
|
}
|
|
150
153
|
}
|
|
151
154
|
},
|
|
@@ -160,61 +163,35 @@
|
|
|
160
163
|
}
|
|
161
164
|
}
|
|
162
165
|
},
|
|
163
|
-
"
|
|
164
|
-
"description": "
|
|
166
|
+
"vitePlusWorkflowSetup": {
|
|
167
|
+
"description": "Scaffold the canonical GitHub Actions check workflow (.github/workflows/check.yml); the repository owns the file after creation.",
|
|
165
168
|
"type": "object",
|
|
166
169
|
"additionalProperties": false,
|
|
167
170
|
"properties": {
|
|
168
|
-
"
|
|
169
|
-
"
|
|
171
|
+
"enabled": {
|
|
172
|
+
"type": "boolean",
|
|
173
|
+
"default": false
|
|
170
174
|
}
|
|
171
175
|
}
|
|
172
176
|
},
|
|
173
|
-
"
|
|
174
|
-
"description": "Manage
|
|
177
|
+
"worktrunkSetup": {
|
|
178
|
+
"description": "Manage project-local Worktrunk setup tasks.",
|
|
175
179
|
"type": "object",
|
|
176
180
|
"additionalProperties": false,
|
|
177
181
|
"properties": {
|
|
178
|
-
"
|
|
179
|
-
"
|
|
180
|
-
"default": false
|
|
181
|
-
},
|
|
182
|
-
"beforeChecks": {
|
|
183
|
-
"description": "Repository-specific preparation steps inserted after locked setup verification and before quality checks.",
|
|
184
|
-
"type": "array",
|
|
185
|
-
"items": {
|
|
186
|
-
"$ref": "#/$defs/vitePlusQualityWorkflowStep"
|
|
187
|
-
},
|
|
188
|
-
"default": []
|
|
189
|
-
},
|
|
190
|
-
"typecheck": {
|
|
191
|
-
"description": "Shell commands for the workflow's pure typecheck step.",
|
|
192
|
-
"type": "array",
|
|
193
|
-
"minItems": 1,
|
|
194
|
-
"items": {
|
|
195
|
-
"type": "string",
|
|
196
|
-
"minLength": 1
|
|
197
|
-
},
|
|
198
|
-
"default": ["vp run typecheck"]
|
|
182
|
+
"config": {
|
|
183
|
+
"$ref": "#/$defs/worktrunkConfigSetup"
|
|
199
184
|
}
|
|
200
185
|
}
|
|
201
186
|
},
|
|
202
|
-
"
|
|
187
|
+
"worktrunkConfigSetup": {
|
|
188
|
+
"description": "Scaffold the default Worktrunk project config (.config/wt.toml) with portable pre-start and pre-merge hooks rendered for the repository's command runner; the repository owns the file after creation.",
|
|
203
189
|
"type": "object",
|
|
204
190
|
"additionalProperties": false,
|
|
205
|
-
"required": ["name", "run"],
|
|
206
191
|
"properties": {
|
|
207
|
-
"
|
|
208
|
-
"type": "
|
|
209
|
-
"
|
|
210
|
-
},
|
|
211
|
-
"run": {
|
|
212
|
-
"type": "array",
|
|
213
|
-
"minItems": 1,
|
|
214
|
-
"items": {
|
|
215
|
-
"type": "string",
|
|
216
|
-
"minLength": 1
|
|
217
|
-
}
|
|
192
|
+
"enabled": {
|
|
193
|
+
"type": "boolean",
|
|
194
|
+
"default": false
|
|
218
195
|
}
|
|
219
196
|
}
|
|
220
197
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: build-effect-apis
|
|
3
|
-
description: Build
|
|
3
|
+
description: Build contract-first Effect HTTP APIs. Use when defining shared HttpApiEndpoint/HttpApiGroup contracts, implementing HttpApiBuilder or HttpApiServer handlers and middleware, assembling server runtimes and OpenAPI docs, or serving on Cloudflare Workers/effect-cf. For consuming an API from client state, use $effect-atom-state.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Build Effect APIs
|
|
@@ -9,12 +9,11 @@ Treat the shared `HttpApi` value as the **contract spine**: schemas, server,
|
|
|
9
9
|
OpenAPI, and clients all derive from it. Keep transport contracts isomorphic;
|
|
10
10
|
keep runtime behavior in handlers, services, layers, and client state modules.
|
|
11
11
|
|
|
12
|
-
Effect HTTP
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
from another version.
|
|
12
|
+
Effect HTTP APIs are version-sensitive. Read the target repository's manifests
|
|
13
|
+
and lockfile, inspect its existing imports, and confirm exact signatures from
|
|
14
|
+
the installed package declarations before editing. In current Effect v4 betas
|
|
15
|
+
the server module is `HttpApiBuilder`; a request that mentions `HttpApiServer`
|
|
16
|
+
may refer to the same server-building responsibility from another version.
|
|
18
17
|
|
|
19
18
|
## Build the contract spine
|
|
20
19
|
|
|
@@ -31,35 +30,21 @@ from another version.
|
|
|
31
30
|
decoded boundary adapters into application services and assemble all
|
|
32
31
|
requirements at the runtime edge. Finish when each endpoint identifier has
|
|
33
32
|
exactly one handler and every declared middleware has a provided layer.
|
|
34
|
-
4.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
atoms, and one reactivity-key vocabulary.
|
|
40
|
-
- For non-React Effect code, use the direct `HttpApiClient` branch in
|
|
41
|
-
[effect-atom-client.md](references/effect-atom-client.md).
|
|
42
|
-
|
|
43
|
-
Finish when consumers call the shared contract rather than redefining wire
|
|
44
|
-
types or using ad hoc `fetch` for declared endpoints.
|
|
45
|
-
|
|
33
|
+
4. Route consumer changes through the `$effect-atom-state` skill: deriving
|
|
34
|
+
`AtomHttpApi` or direct `HttpApiClient` clients, query and mutation atoms,
|
|
35
|
+
reactivity keys, and React integration all live there. Finish when consumers
|
|
36
|
+
call the shared contract rather than redefining wire types or using ad hoc
|
|
37
|
+
`fetch` for declared endpoints.
|
|
46
38
|
5. Read [verification.md](references/verification.md). Run the repository's
|
|
47
39
|
format, lint, typecheck, and test commands. Finish when changed schemas
|
|
48
|
-
round-trip, middleware failures use declared error channels, server and
|
|
49
|
-
client agree on every request shape
|
|
50
|
-
deterministic coverage.
|
|
40
|
+
round-trip, middleware failures use declared error channels, and server and
|
|
41
|
+
client agree on every request shape.
|
|
51
42
|
|
|
52
43
|
## Optional branches
|
|
53
44
|
|
|
54
45
|
- Read [runtime-assembly.md](references/runtime-assembly.md) when wiring a
|
|
55
46
|
conventional Node/Bun server, generated API docs, process entrypoint, or
|
|
56
47
|
serverless web handler.
|
|
57
|
-
- Read [effect-atom-testing.md](references/effect-atom-testing.md) when changing
|
|
58
|
-
Atom cache retention, SWR, polling, invalidation, cancellation, aggregation,
|
|
59
|
-
provider placement, SSR, or hydration behavior.
|
|
60
|
-
- Read [tanstack-start.md](references/tanstack-start.md) when the client is
|
|
61
|
-
TanStack Start, SSR, hydration, `ClientOnly`, loaders, server functions, or a
|
|
62
|
-
proxied separate API.
|
|
63
48
|
- Read [cloudflare-workers.md](references/cloudflare-workers.md) when the server
|
|
64
49
|
runs on Cloudflare Workers or uses `effect-cf`, bindings, Durable Objects,
|
|
65
50
|
Queues, WebSockets, streaming, or raw byte routes.
|
|
@@ -94,6 +79,3 @@ but the boundary and type reasoning remain the source of truth.
|
|
|
94
79
|
- Let handlers own transport-to-application mapping and boundary invariants.
|
|
95
80
|
- Let application services own orchestration, persistence, retries, and
|
|
96
81
|
transactions.
|
|
97
|
-
- Let client data modules own API services, query identity, cache policy,
|
|
98
|
-
invalidation keys, and mutation atoms; let UI action owners own navigation,
|
|
99
|
-
toasts, optimistic presentation, and form reset.
|
|
@@ -48,9 +48,9 @@ decoding are skipped.
|
|
|
48
48
|
`HttpApiMiddleware.layerClient` and assert that it transforms the request.
|
|
49
49
|
- Assert params, query, headers, payload, and expected errors at least once for
|
|
50
50
|
every changed request shape.
|
|
51
|
-
- For Atom clients, complete every applicable scenario
|
|
52
|
-
|
|
53
|
-
invalidation, and lifecycle remain observable.
|
|
51
|
+
- For Atom clients, complete every applicable scenario in the
|
|
52
|
+
`$effect-atom-state` skill's testing reference; use a deterministic HTTP
|
|
53
|
+
layer so request encoding, invalidation, and lifecycle remain observable.
|
|
54
54
|
|
|
55
55
|
## Completion matrix
|
|
56
56
|
|