Skip to content

Commit 3d07a03

Browse files
authored
Initial commit
0 parents  commit 3d07a03

39 files changed

+60059
-0
lines changed

.changeset/config.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"$schema": "https://unpkg.com/@changesets/config@3.0.2/schema.json",
3+
"changelog": [
4+
"@changesets/changelog-github",
5+
{
6+
"repo": "<PLACEHOLDER>"
7+
}
8+
],
9+
"commit": false,
10+
"fixed": [],
11+
"linked": [],
12+
"access": "restricted",
13+
"baseBranch": "main",
14+
"updateInternalDependencies": "patch",
15+
"ignore": []
16+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
name: effect-ts-guide
3+
description: Teach and apply Effect-TS practices (effect, @effect/schema, @effect/platform) for architecture, typed errors, Layers, dependency injection, resource safety, testing, and migration from async/await/Promise. Use when a user asks how to use Effect, requests best practices, wants to refactor to Effect, or needs mapping from platform modules to Node/Bun/Browser APIs.
4+
---
5+
6+
# Effect TS Guide
7+
8+
## Overview
9+
10+
Use this skill to teach Effect-TS fundamentals and best practices, then apply them to user code and architecture questions.
11+
12+
## Teaching workflow
13+
14+
1. Clarify context: runtime (node/bun/browser), goal (new app, refactor, review), and constraints.
15+
2. Separate core vs shell: identify pure domain logic vs effects and boundaries.
16+
3. Model errors and dependencies: define tagged error types and Context.Tag service interfaces.
17+
4. Compose with Effect: use pipe/Effect.gen, typed errors, and Layer provisioning.
18+
5. Validate inputs at boundaries with @effect/schema before entering core.
19+
6. Explain resource safety: acquireRelease, scoped lifetimes, and clean finalizers.
20+
7. Provide minimal, runnable examples tailored to the user context.
21+
8. If the user asks for version-specific or "latest" details, verify with official docs before answering.
22+
23+
## Core practices (short list)
24+
25+
- Use Effect for all side effects; keep core functions pure and total.
26+
- Avoid async/await, raw Promise chains, and try/catch in application logic.
27+
- Use Context.Tag + Layer for dependency injection and testability.
28+
- Use tagged error unions and Match.exhaustive for total handling.
29+
- Decode unknown at the boundary with @effect/schema; never leak unknown into core.
30+
- Use Effect.acquireRelease/Effect.scoped for resource safety.
31+
- Use @effect/platform services instead of host APIs (fetch, fs, child_process, etc.).
32+
33+
## References
34+
35+
- Read `references/best-practices.md` for the extended checklist and examples.
36+
- Read `references/platform-map.md` when comparing @effect/platform to Node/Bun/Browser APIs.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Effect-TS Best Practices (concise)
2+
3+
## Design principles
4+
5+
- Keep core logic pure; isolate IO in a thin shell.
6+
- Model errors explicitly with tagged unions; avoid exceptions.
7+
- Prefer immutable data and total functions.
8+
9+
## Composition
10+
11+
- Use pipe + Effect.flatMap/map or Effect.gen for sequential flows.
12+
- Interop with Promise only at boundaries via Effect.try/Effect.tryPromise.
13+
- Use Match.exhaustive for union handling; avoid switch in domain logic.
14+
15+
## Dependency injection
16+
17+
- Define services with Context.Tag and small interfaces.
18+
- Provide live layers at runtime; provide test layers in unit tests.
19+
- Keep service interfaces free of concrete implementations and globals.
20+
21+
## Boundary validation
22+
23+
- Accept unknown at the boundary only.
24+
- Decode with @effect/schema and pass validated types into core.
25+
- Fail fast on invalid input; keep validation errors typed.
26+
27+
## Resource safety
28+
29+
- Use Effect.acquireRelease for resources (connections, files, locks).
30+
- Use Effect.scoped to control lifetimes and ensure finalizers run.
31+
32+
## Platform usage
33+
34+
- Use @effect/platform services instead of host APIs:
35+
- HttpClient/HttpServer for HTTP
36+
- FileSystem/Path for files and paths
37+
- Command/Terminal for CLI and processes
38+
- KeyValueStore for local storage-like needs
39+
40+
## Runtime and entrypoints
41+
42+
- Use Effect.runMain (or platform runtime helpers) for application entry.
43+
- Use Logger/PlatformLogger for structured logging.
44+
45+
## Testing
46+
47+
- Write tests as Effects; provide test layers/mocks.
48+
- Use TestClock/Ref for deterministic time and state.
49+
- Use property-based tests for invariants when appropriate.
50+
51+
## Minimal example (service + layer)
52+
53+
```ts
54+
import { Context, Effect, Layer, pipe } from "effect"
55+
56+
class Clock extends Context.Tag("Clock")<Clock, {
57+
readonly nowMillis: Effect.Effect<number, never>
58+
}>() {}
59+
60+
const ClockLive = Layer.succeed(Clock, {
61+
nowMillis: Effect.sync(() => Date.now())
62+
})
63+
64+
const program = pipe(
65+
Clock,
66+
Effect.flatMap((clock) => clock.nowMillis),
67+
Effect.map((ms) => ({ now: ms }))
68+
)
69+
70+
const main = Effect.provide(program, ClockLive)
71+
```
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# @effect/platform map (what it replaces)
2+
3+
## Core idea
4+
5+
- @effect/platform provides platform-neutral service interfaces and Layers.
6+
- It does not monkey-patch globals; you must provide a platform layer.
7+
8+
## Implementation packages
9+
10+
- Node: @effect/platform-node
11+
- Bun: @effect/platform-bun
12+
- Browser: @effect/platform-browser
13+
14+
## Common mappings
15+
16+
- FileSystem -> node:fs / fs.promises / Bun file APIs
17+
- Path -> node:path / Bun path / Deno path
18+
- Command (+ CommandExecutor) -> child_process.spawn/exec / Deno.Command / Bun.spawn
19+
- Terminal -> process.stdin/stdout / readline
20+
- KeyValueStore -> Map / localStorage / file-backed KV
21+
- PlatformConfigProvider -> dotenv + process.env + file tree config
22+
- PlatformLogger -> console + file logging
23+
- Runtime/runMain -> manual main + process signal handling
24+
25+
## HTTP stack
26+
27+
- HttpClient -> fetch / undici / axios
28+
- FetchHttpClient -> fetch implementation
29+
- HttpServer/HttpRouter/HttpMiddleware -> node:http + express/fastify/koa
30+
- HttpApi/OpenApi -> manual route + schema + OpenAPI toolchain
31+
32+
## Sockets and workers
33+
34+
- Socket/SocketServer -> net / ws / WebSocket
35+
- Worker/WorkerRunner -> worker_threads / Web Workers
36+
37+
## Data and utilities
38+
39+
- Headers/Cookies/Multipart/Etag -> manual header/cookie parsing or third-party middleware
40+
- Url/UrlParams -> URL / URLSearchParams
41+
- Ndjson/MsgPack -> ad-hoc codecs or third-party libs

.github/actions/setup/action.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Setup
2+
description: Perform standard setup and install dependencies using pnpm.
3+
inputs:
4+
node-version:
5+
description: The version of Node.js to install
6+
required: true
7+
default: 20.16.0
8+
9+
runs:
10+
using: composite
11+
steps:
12+
- name: Install pnpm
13+
uses: pnpm/action-setup@v3
14+
- name: Install node
15+
uses: actions/setup-node@v6
16+
with:
17+
cache: pnpm
18+
node-version: ${{ inputs.node-version }}
19+
- name: Install dependencies
20+
shell: bash
21+
run: pnpm install

.github/workflows/check.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Check
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
branches: [main]
7+
push:
8+
branches: [main]
9+
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
permissions: {}
15+
16+
jobs:
17+
build:
18+
name: Build
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 10
21+
steps:
22+
- uses: actions/checkout@v6
23+
- name: Install dependencies
24+
uses: ./.github/actions/setup
25+
26+
types:
27+
name: Types
28+
runs-on: ubuntu-latest
29+
timeout-minutes: 10
30+
steps:
31+
- uses: actions/checkout@v6
32+
- name: Install dependencies
33+
uses: ./.github/actions/setup
34+
- run: pnpm check
35+
36+
lint:
37+
name: Lint
38+
runs-on: ubuntu-latest
39+
timeout-minutes: 10
40+
steps:
41+
- uses: actions/checkout@v6
42+
- name: Install dependencies
43+
uses: ./.github/actions/setup
44+
# vibecode-linter uses npx internally for dependency checks
45+
# In pnpm workspaces, npx doesn't find local packages correctly
46+
# Install TypeScript and Biome globally as a workaround
47+
# See: https://github.com/ton-ai-core/vibecode-linter/issues (pending issue)
48+
- name: Install global linter dependencies
49+
run: npm install -g typescript @biomejs/biome
50+
- run: pnpm lint
51+
52+
test:
53+
name: Test
54+
runs-on: ubuntu-latest
55+
timeout-minutes: 10
56+
steps:
57+
- uses: actions/checkout@v6
58+
- name: Install dependencies
59+
uses: ./.github/actions/setup
60+
# vibecode-linter uses npx internally for dependency checks (lint:tests runs first)
61+
- name: Install global linter dependencies
62+
run: npm install -g typescript @biomejs/biome
63+
- run: pnpm test
64+
65+
lint-effect:
66+
name: Lint Effect-TS
67+
runs-on: ubuntu-latest
68+
timeout-minutes: 10
69+
steps:
70+
- uses: actions/checkout@v6
71+
- name: Install dependencies
72+
uses: ./.github/actions/setup
73+
- run: pnpm lint:effect
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Checking Dependencies
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
branches: [main]
7+
push:
8+
branches: [main]
9+
10+
jobs:
11+
dist-deps-prune:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v6
15+
- uses: pnpm/action-setup@v4
16+
- uses: actions/setup-node@v6
17+
with:
18+
node-version: 24.13.0
19+
cache: pnpm
20+
21+
- run: pnpm install --frozen-lockfile
22+
- run: pnpm -C packages/app build
23+
24+
- name: Dist deps prune (lint)
25+
run: |
26+
pnpm dlx @prover-coder-ai/dist-deps-prune scan \
27+
--package ./packages/app/package.json \
28+
--prune-dev true \
29+
--silent

.github/workflows/release.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Release
2+
on:
3+
workflow_run:
4+
workflows: ["Check"]
5+
branches: [main]
6+
types: [completed]
7+
8+
permissions:
9+
contents: write
10+
actions: write
11+
id-token: write
12+
pull-requests: write
13+
packages: write
14+
15+
jobs:
16+
release:
17+
if: github.event.workflow_run.conclusion == 'success'
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: ProverCoderAI/action-release@v1.0.17
21+
with:
22+
github_token: ${{ secrets.GITHUB_TOKEN }}
23+
npm_token: ${{ secrets.NPM_TOKEN }}
24+
ref: ${{ github.event.workflow_run.head_sha }}
25+
branch: ${{ github.event.workflow_run.head_branch }}
26+
package_json_path: packages/app/package.json
27+
pnpm_filter: ./packages/app
28+
bump_type: patch
29+
publish_npm: true
30+
publish_github_packages: true
31+
skip_if_unchanged: true
32+
cancel_on_no_changes: true

.github/workflows/snapshot.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Snapshot
2+
3+
on:
4+
pull_request:
5+
branches: [main, next-minor, next-major]
6+
workflow_dispatch:
7+
8+
permissions: {}
9+
10+
jobs:
11+
snapshot:
12+
name: Snapshot
13+
if: github.repository_owner == 'ProverCoderAI'
14+
runs-on: ubuntu-latest
15+
timeout-minutes: 10
16+
steps:
17+
- uses: actions/checkout@v6
18+
- name: Install dependencies
19+
uses: ./.github/actions/setup
20+
with:
21+
node-version: 22.12.0
22+
- name: Build package
23+
run: pnpm build
24+
- name: Create snapshot
25+
id: snapshot
26+
env:
27+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28+
shell: bash
29+
working-directory: packages/app
30+
run: |
31+
set +e
32+
pnpx pkg-pr-new@0.0.24 publish --pnpm --comment=off
33+
STATUS=$?
34+
if [ $STATUS -eq 0 ]; then
35+
echo "success=true" >> "$GITHUB_OUTPUT"
36+
else
37+
echo "success=false" >> "$GITHUB_OUTPUT"
38+
echo "pkg-pr-new failed (likely app not installed); falling back to artifacts."
39+
fi
40+
exit 0
41+
- name: Fallback snapshot artifacts
42+
if: steps.snapshot.outputs.success != 'true'
43+
shell: bash
44+
run: |
45+
set -euo pipefail
46+
mkdir -p artifacts
47+
cd packages/app
48+
npm pack --silent --pack-destination ../../artifacts
49+
- name: Upload snapshot artifacts
50+
if: steps.snapshot.outputs.success != 'true'
51+
uses: actions/upload-artifact@v6
52+
with:
53+
name: context-doc-snapshot
54+
path: artifacts/*.tgz

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
node_modules/
2+
dist/
3+
build/
4+
coverage/
5+
packages/*/dist/
6+
npm-debug.log*
7+
yarn-debug.log*
8+
yarn-error.log*
9+
pnpm-debug.log*
10+
reports/

0 commit comments

Comments
 (0)