Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .claude/skills/effect-program-design/REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ conventions from another repository.
| Durable tagged data | `packages/fold-core/src/EventLog/Schemas.ts` | `Schema.TaggedStruct`, `Schema.Union`, versioning, and decode-time compatibility. |
| Provider/runtime ownership | `packages/fold-core/src/Api/Provisioning.ts` | Scope ownership, fresh memo maps, provider layers, and resource lifetime. |
| Complete tagged dispatch | `packages/fold-agent/src/Session/SessionLayout.ts` | An exhaustive `Match` over a Fold-owned tagged union. |
| Focused tag guard | `packages/fold-core/src/HookRunner/Errors.ts` | A reusable `Predicate.isTagged` guard. |
| Focused tag guard | `packages/fold-core/src/Subagents/SubagentsLayer.ts` | `Predicate.isTagged` guards over decoded log entries. |
| Pure projection policy | `packages/fold-core/src/Compaction/CompactionEngine.ts` | Pure projections and the distinction between simple loop guards and transformations. |

## Public Fold shape
Expand Down
213 changes: 203 additions & 10 deletions .oxlintrc.jsonc
Original file line number Diff line number Diff line change
@@ -1,28 +1,148 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"$schema": "./node_modules/@effect/tsgo/oxlint-schema.json",
// Effect-aware type-aware rules from the patched oxlint-tsgolint (`effect-tsgo patch --oxlint`).
"extends": ["./node_modules/@effect/tsgo/oxlint-presets/recommended.json"],
// The `correctness` category is enabled by default. Keep the broader Effect Channels
// plugin set and Vitest's test-specific rules.
"plugins": ["typescript", "import", "oxc", "eslint", "unicorn", "node", "vitest"],
"plugins": ["typescript", "import", "oxc", "eslint", "unicorn", "node", "vitest", "effecttsgo"],
"jsPlugins": [
{ "name": "anti-slop", "specifier": "./tools/oxlint/anti-slop/index.ts" },
{ "name": "anti-slop-effect", "specifier": "./tools/oxlint/anti-slop/effect/index.ts" },
{ "name": "automation", "specifier": "./tools/oxlint/automation/index.ts" },
{ "name": "import-extensions", "specifier": "./tools/oxlint/import-extensions.mjs" },
],
"ignorePatterns": [
"**/node_modules/**",
"**/dist/**",
".release/**",
".agent/**",
".agents/**",
".claude/**",
".codex/**",
".cursor/**",
".humanlayer/**",
".opencode/**",
".pi/**",
"tools/**",
"scripts/**",
"packages/fold/postinstall.mjs",
],
"ignorePatterns": ["**/node_modules/**", "**/dist/**", ".release/**", "tools/oxlint/**"],
"rules": {
// The @effect/tsgo preset ships most rules as warnings; Fold holds them at zero, so they fail lint.
"effecttsgo/abort-controller-in-effect": "error",
"effecttsgo/acquire-release-disposable": "error",
"effecttsgo/all-of-map-to-for-each": "error",
"effecttsgo/catch-all-tag-dispatch-to-catch-tag": "error",
"effecttsgo/catch-all-to-map-error": "error",
"effecttsgo/catch-chain-to-first-success-of": "error",
"effecttsgo/catch-conditional-refail-to-catch-if": "error",
"effecttsgo/catch-die-to-or-die": "error",
"effecttsgo/catch-if-tag-to-catch-tag": "error",
"effecttsgo/catch-refail-to-tap-error": "error",
"effecttsgo/catch-tag-to-catch-reason": "error",
"effecttsgo/catch-to-ignore": "error",
"effecttsgo/catch-to-or-else-succeed": "error",
"effecttsgo/catch-unfailable-effect": "error",
"effecttsgo/duplicate-package": "error",
"effecttsgo/effect-fn-iife": "error",
"effecttsgo/effect-fn-opportunity": "error",
"effecttsgo/effect-gen-uses-adapter": "error",
"effecttsgo/effect-in-failure": "error",
"effecttsgo/effect-in-void-success": "error",
"effecttsgo/effect-map-flatten": "error",
"effecttsgo/effect-map-void": "error",
"effecttsgo/effect-succeed-with-void": "error",
"effecttsgo/flat-map-conditional-to-filter-or-fail": "error",
"effecttsgo/flat-map-ignored-param-to-and-then": "error",
"effecttsgo/flat-map-to-map": "error",
"effecttsgo/generic-effect-services": "error",
"effecttsgo/global-error-in-effect-catch": "error",
"effecttsgo/global-error-in-effect-failure": "error",
"effecttsgo/layer-merge-all-with-dependencies": "error",
"effecttsgo/lazy-effect": "error",
"effecttsgo/lazy-promise-in-effect-sync": "error",
"effecttsgo/leaking-requirements": "error",
"effecttsgo/map-some-to-as-some": "error",
"effecttsgo/match-effect-to-map-both": "error",
"effecttsgo/match-effect-to-match": "error",
"effecttsgo/multiple-catch-tag": "error",
"effecttsgo/multiple-effect-provide": "error",
"effecttsgo/obsolete-match-import": "error",
"effecttsgo/obsolete-schema-import": "error",
"effecttsgo/option-match-to-from-option": "error",
"effecttsgo/outdated-api": "error",
"effecttsgo/prefer-succeed-some-or-none": "error",
"effecttsgo/prefer-typed-schema-decoder": "error",
"effecttsgo/prefer-unsafe-constructor": "error",
"effecttsgo/promise-in-effect-success": "error",
"effecttsgo/provide-layer-succeed-to-provide-service": "error",
"effecttsgo/race-first-with-sleep-to-timeout": "error",
"effecttsgo/redundant-map-error": "error",
"effecttsgo/redundant-or-die": "error",
"effecttsgo/redundant-schema-tag-identifier": "error",
"effecttsgo/return-effect-in-gen": "error",
"effecttsgo/run-effect-inside-effect": "error",
"effecttsgo/run-of-exit-to-run-exit": "error",
"effecttsgo/schema-number": "error",
"effecttsgo/schema-struct-with-tag": "error",
"effecttsgo/schema-sync-in-effect": "error",
"effecttsgo/scope-in-layer-effect": "error",
"effecttsgo/sync-to-succeed": "error",
"effecttsgo/timeout-catch-tag-to-timeout-or-else": "error",
"effecttsgo/try-catch-in-effect-gen": "error",
"effecttsgo/unknown-in-effect-catch": "error",
"effecttsgo/unnecessary-effect-gen": "error",
"effecttsgo/unnecessary-fail-yieldable-error": "error",
"effecttsgo/unnecessary-pipe": "error",
"effecttsgo/unnecessary-pipe-chain": "error",
"effecttsgo/unnecessary-typeof-type": "error",
"anti-slop/no-conditional-empty-object-spread": "error",
"anti-slop/no-module-mocking": "error",
"anti-slop/no-object-parameters": "error",
"automation/no-shadowed-standard-array-static": "error",
"automation/no-disable-validation": "error",
"automation/no-silent-error-swallow": "error",
"automation/no-manual-tag-comparison": "error",
"automation/no-manual-tagged-construction": "error",
"automation/no-service-option": "error",
"automation/prefer-effect-match": "error",
"automation/prefer-option-from-nullable": "error",
"automation/prefer-tagged-error-handling": "error",
"automation/no-ambient-nondeterminism": "error",
"anti-slop/no-reflect-apply": "error",
"anti-slop/no-unknown-type-aliases": "error",
"anti-slop/no-widen-then-assert": "error",
"anti-slop-effect/no-manual-effect-error-tag": "error",
"anti-slop-effect/no-manual-tag-comparison": "error",
"anti-slop-effect/prefer-effect-match": "error",
"automation/no-cascading-layer-provide": "error",
"automation/no-nested-effect-array-methods": "error",
"automation/no-nested-layer-provide": "error",
"automation/no-sql-type-parameter": "error",
"automation/no-static-effect-service-forwarders": "error",
"automation/pipe-max-arguments": "error",
"automation/require-context-service-in-services": "error",
"anti-slop/max-ternary-depth": "error",
"anti-slop/no-chained-type-assertions": "error",
"anti-slop/no-reflect-get": "error",
"anti-slop/no-reprovide-ambient-service": "error",
"anti-slop/no-shape-in-symbol-names": "error",
"anti-slop/no-unknown-returns": "error",
"anti-slop/require-safety-comment-for-type-assertion": "error",
"automation/no-banned-type-assertions": "error",
"automation/no-direct-fetch": "error",
"automation/no-global-json": "error",
"automation/no-in-operator": "error",
"automation/no-switch": "error",
"automation/no-type-assertion": "error",
"automation/no-try-catch": "error",
"automation/no-typeof-object": "error",
"anti-slop/no-runtime-typeof": "error",
"anti-slop/no-unknown-parameters": "error",
"anti-slop/no-unsafe-dictionary-type": "error",
"anti-slop-effect/no-service-constructor-imports": "error",
"anti-slop/no-conditional-spread": "error",
"anti-slop/no-conditional-empty-array-spread": "error",
"anti-slop-effect/no-manual-tagged-construction": "error",
"anti-slop/no-known-value-widening": "error",
"import-extensions/no-relative-source-extensions": "error",
"typescript/consistent-type-imports": ["error", { "fixStyle": "inline-type-imports" }],
"typescript/no-import-type-side-effects": "error",
"import/no-duplicates": "error",
Expand All @@ -31,6 +151,18 @@
"typescript/no-unnecessary-type-assertion": "error",
"typescript/no-unnecessary-type-constraint": "error",
"typescript/no-useless-empty-export": "error",
"typescript/await-thenable": "error",
"typescript/no-base-to-string": "error",
"typescript/no-floating-promises": "error",
"typescript/no-meaningless-void-operator": "error",
"typescript/no-misused-promises": "error",
"typescript/no-misused-spread": "error",
"typescript/no-redundant-type-constituents": "error",
"typescript/restrict-template-expressions": "error",
"typescript/unbound-method": "error",
"eslint/complexity": ["error", { "max": 20 }],
"eslint/no-empty-function": "error",
"eslint/no-eq-null": "error",
"eslint/no-console": "error",
"eslint/no-var": "error",
"eslint/no-useless-constructor": "error",
Expand Down Expand Up @@ -59,6 +191,8 @@
// Effect generator, which the vitest plugin can't see as a test block. Disabled to
// avoid a false positive on every Effect test.
"vitest/no-standalone-expect": "off",
// Vitest's `expect(value, message)` takes an optional failure message as its second argument.
"vitest/valid-expect": ["error", { "maxArgs": 2 }],
// Disallow `.ts` extensions in imports; TypeScript resolves them without extensions.
"import/extensions": ["error", "never"],
},
Expand All @@ -76,16 +210,39 @@
"anti-slop/no-module-mocking": "off",
"anti-slop/no-object-parameters": "off",
"anti-slop/no-reflect-apply": "off",
"anti-slop-effect/no-manual-tag-comparison": "off",
"anti-slop-effect/prefer-effect-match": "off",
"eslint/complexity": "off",
"automation/no-disable-validation": "off",
"automation/no-shadowed-standard-array-static": "off",
"automation/no-silent-error-swallow": "off",
"automation/no-manual-tag-comparison": "off",
"automation/no-manual-tagged-construction": "off",
"automation/no-service-option": "off",
"automation/prefer-effect-match": "off",
"automation/prefer-option-from-nullable": "off",
"automation/prefer-tagged-error-handling": "off",
"automation/no-ambient-nondeterminism": "off",
"anti-slop/max-ternary-depth": "off",
"anti-slop/no-chained-type-assertions": "off",
"anti-slop/no-reflect-get": "off",
"anti-slop/no-reprovide-ambient-service": "off",
"anti-slop/no-shape-in-symbol-names": "off",
"anti-slop/no-unknown-returns": "off",
"anti-slop/require-safety-comment-for-type-assertion": "off",
"automation/no-banned-type-assertions": "off",
"automation/no-direct-fetch": "off",
"automation/no-global-json": "off",
"automation/no-in-operator": "off",
"automation/no-switch": "off",
"automation/no-type-assertion": "off",
"automation/no-try-catch": "off",
"automation/no-typeof-object": "off",
"anti-slop/no-runtime-typeof": "off",
"anti-slop/no-unknown-parameters": "off",
"anti-slop/no-unsafe-dictionary-type": "off",
"anti-slop-effect/no-service-constructor-imports": "off",
"anti-slop/no-conditional-spread": "off",
"anti-slop/no-conditional-empty-array-spread": "off",
"anti-slop-effect/no-manual-tagged-construction": "off",
"anti-slop/no-known-value-widening": "off",
},
},
{
Expand All @@ -101,7 +258,42 @@
"**/examples/**",
],
"rules": {
"automation/no-manual-tagged-construction": "off",
"anti-slop-effect/no-manual-tagged-construction": "off",
},
},
{
// The CLI commands build option objects field by field; they are exempt from the widening rule.
"files": ["packages/fold-cli/src/**"],
"rules": {
"anti-slop/no-known-value-widening": "off",
},
},
{
// Tests may cast to build deliberately invalid inputs, build JSON fixtures directly, and inspect raw values.
"files": [
"**/test/**",
"**/tests/**",
"**/*.test.ts",
"**/*.test.tsx",
"**/*.vi.test.ts",
"**/*.vi.test.tsx",
"**/fixtures/**",
],
"rules": {
"anti-slop/no-chained-type-assertions": "off",
"anti-slop/require-safety-comment-for-type-assertion": "off",
"automation/no-banned-type-assertions": "off",
"automation/no-global-json": "off",
"automation/no-type-assertion": "off",
"automation/no-try-catch": "off",
"automation/no-typeof-object": "off",
"anti-slop/no-runtime-typeof": "off",
"anti-slop/no-unknown-parameters": "off",
"anti-slop/no-unsafe-dictionary-type": "off",
"anti-slop/no-known-value-widening": "off",
"anti-slop-effect/no-service-constructor-imports": "off",
"anti-slop/no-conditional-spread": "off",
"anti-slop/no-conditional-empty-array-spread": "off",
},
},
{
Expand All @@ -126,6 +318,7 @@
"files": ["packages/vitest-config/**/*.ts"],
"rules": {
"import/extensions": "off",
"import-extensions/no-relative-source-extensions": "off",
},
},
{
Expand Down
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ Bun monorepo. Packages live in `packages/*` and run TypeScript directly (no buil
- **Framework:** Effect **v4** (`4.0.0-rc.109`)
- **Testing:** Vitest + `@effect/vitest`
- **Lint / format:** oxlint + oxfmt (120 col, no semicolons)
- **Effect editor tooling:** `@effect/tsgo` with the `@effect/language-service` TS plugin. `tsc` is patched for
build-time Effect diagnostics via the `prepare` script (`effect-tsgo patch --typescript`).
- **Effect editor tooling:** `@effect/tsgo` with the `@effect/language-service` TS plugin. `tsc` and oxlint are patched
for Effect diagnostics via the `prepare` script (`effect-tsgo patch --typescript --oxlint --force`).

## Commands

- `bun install` — install deps (also patches TypeScript for Effect diagnostics)
- `bun run test` / `bun run test:watch` — run tests
- `bun run typecheck` — typecheck every package
- `bun run lint` / `bun run lint:fix` — oxlint
- `bun run lint` / `bun run lint:fix` — oxlint (with the `@effect/tsgo` recommended preset), then the typed rules in `tools/typed`; see `tools/oxlint/README.md`
- `bun run format` / `bun run format:check` — oxfmt

## Dependency versions
Expand Down
Loading
Loading