Repository navigation
Adopt anti-slop, automation, and typed lint rules and fix the code to pass them - #51
Merged
K-Mistele merged 14 commits intoOct 2, 2026
Merged
Conversation
- Upgrade oxlint/@oxlint/plugins 1.86.0, oxlint-tsgolint 7.0.2003, @effect/tsgo 0.47.0; patch oxlint in `prepare` and extend the @effect/tsgo recommended preset. - Enable type-aware built-ins plus complexity (20), no-eq-null, no-empty-function, no-misused-spread, and fix the code they flagged. - Vendor the full kyle-anti-slop plugin (generic + Effect), the upstream automation rules, the import-extensions plugin, and the typed rule engine; enable every rule the codebase already passes. - Run the typed rules as part of `bun run lint`; replace array `.length` emptiness checks with Effect Array predicates. - Move fold-codex tests and example that need fold-agent into fold-agent, removing the reverse dependency. - Keep TUI code exempt from rules it violates. Rules still off are listed in tools/oxlint/README.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
Turn on no-reprovide-ambient-service, no-switch, no-in-operator, no-unknown-returns, no-direct-fetch, no-shape-in-symbol-names, no-reflect-get, max-ternary-depth, the type-assertion rules, and no-global-json (code only), and fix every hit: - Layers yield their services once and define methods over them, so ToolRuntime, AgentRuntime, Compaction and skill sources no longer re-provide captured services. - Switches become exhaustive Match. - JSON and unknown values decode through Schema (fromJsonString). - fetch becomes HttpClient; the CLI provides FetchHttpClient.layer. - Add effect to root devDependencies for scripts/. Tests are exempt from the cast rules and no-global-json. no-reexport-only-modules stays off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
Turn on no-try-catch, no-typeof-object, no-runtime-typeof, no-unknown-parameters and no-unsafe-dictionary-type for code (tests and the TUI are exempt), exclude scripts/ and postinstall.mjs from lint, and fix every hit plus every remaining warning: - Image pipeline: Photon service, scoped image memory, tagged errors. - Tools can declare a layer the session builds once; read, web fetch and web search use it for Photon and the HTTP client. - ManagedBinaries: a service over FileSystem, ChildProcessSpawner and HttpClient with an Effect cache; failures always logged. - One schema-based SKILL.md frontmatter parser with tagged errors. - Shared message-content helpers; auth files, JWT claims, and tool inputs decoded with Schema; Codex stalls are tagged errors. - Custom event log and skill sources die on setup failure instead of leaking unknown errors; the TUI session host carries real error types. - Effect language-service fixes (Schema.Finite, typed decoders, etc.). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
Tools, agents, subagents, event logs, skill sources, and sessions now record the host services they need in their types (FoldTool<R>, AgentDefinition<R>, FoldSession<R>, ...), so startSession requires exactly what its tools use and the host provides it once. This replaces the untyped grab-and-cast of platform services in startSession and the per-tool `layer` option. - defineTool infers a tool's needs from its handler; the `dependencies` and `layer` options and the PlatformServices alias are gone. - The subagent roster rides on the tool value instead of a hidden WeakMap. - OutputStore is keyed by a directory; the bash tool asks for it, Launch provides one per session, and the retention sweep is a plain function. - fold-cli provides Photon at the top; fold-agent exports layerCodingToolServices for hosts that start sessions themselves. - Refresh the vendored-rule counts in tools/oxlint/README.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
- Rename helpers that build plain values, not services: ansiPalette, the CLI output renderers, toolStateServiceBuilder, and the issuer HTTP clients. - storedLogEntry takes the event id instead of the whole Ids service. - The Codex and Grok compatibility loaders return a FoldSkills descriptor (codexSkills / grokSkills), like skillsFromDisk, instead of a built source. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
SessionControls and Profiles now export layerSessionControls/layerProfiles instead of make functions that callers wrapped in Layer.effect. The hook runner, toolset resolver, and system prompt builders already returned layers, so they are renamed to layerHookRunner/layerToolsetResolver/layerSystemPrompt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
…ervices Codex, xAI and OpenCode credential stores and logins are now services with layers. Each model builds its login from its own provider name and fold home, so logins saved under a non-default provider name are no longer ignored. FoldModel carries the services its `make` needs, like tools do. The built-in OpenAI/Anthropic models and the provider models use the app's HTTP client and filesystem instead of building their own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
…o-service-constructor-imports The Subagents and AgentProvisioner services needed each other, so startSession installed a placeholder Subagents and filled it in after construction. Both services are gone: dispatchSubagent, forkSubagent, resumeSubagent, continueSubagent and provisionAgentRuntime are plain Effects that take the session's services from their surroundings, so a subagent's tools calling them again is ordinary recursion. A new SessionAgents service carries the registry, tool realization, the root agent's current setup and the auto-compact policy. ToolHandlerServices lists the session services every tool runs inside; stored handlers still require only the per-call services. The session handle is the one place that runs work inside the session's services. Turn on anti-slop-effect/no-service-constructor-imports (TUI and tests exempt). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
…les errors Build lists from values that are known to be present instead of spreading conditionals: optional option lists get defaults where they are read, "maybe one item" lists are built from Options with Arr.getSomes (or filtered with Predicate.isNotUndefined), a possibly-empty home directory is an Option<string>, and resume flags use small valueFlag/switchFlag helpers. Turn on anti-slop/no-conditional-spread and no-conditional-empty-array-spread (TUI and tests exempt), and set every @effect/tsgo preset rule that ships as a warning to error so they stay at zero. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
Declare hand-written tagged unions with Data.TaggedEnum next to their
existing Data.taggedEnum constructors, and name log-entry variants with the
exported entry types instead of Extract<LogEntry, { _tag: ... }>.
The vendored rule now allows `_tag: Schema.tag(...)` and
`Schema.tagDefaultOmit(...)` schema fields, which declare a tag rather than
build a tagged value (the OpenCode device-token response carries none).
TUI, tests, fixtures and examples are exempt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
Build option objects in one expression instead of field by field through Mutable<...>: Struct.pick copies optional fields only when set, null-backed values choose between two explicit shapes, and Effect library options take `value ?? undefined`. Lookup tables use `as const satisfies Record<...>`, managed binary checksums are a ReadonlyMap, resolveCredentials returns only the credential field it has, and inline return types are inferred. The CLI commands, TUI and tests are exempt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
automation/no-manual-tag-comparison, no-manual-tagged-construction, and prefer-effect-match overlap the stricter anti-slop-effect rules of the same names, which stay on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
…d-j2c8f7 Resolve conflicts with main's file-tools bundle and alchemy-cloudflare example: - package.json keeps main's examples workspace in typecheck/test and this branch's lint command. - codingTools uses main's fileTools with this branch's service types; the `tools/files` entry also exports Photon, which the read tool needs. - startSession ports main's fix that keeps a tool's session services over a turn's own (Workers carry their own FileSystem), using the host services the session already holds. - The alchemy-cloudflare example moves to this branch's APIs (storedLogEntry, no Subagents stub, Photon and HttpClient provided) and passes the lint rules: structured log annotations instead of JSON.stringify, Effect.try and Schema instead of try/catch, typeof, and `in`, and decoded tool results in its test helper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> HumanLayer-Session: https://app.dev.codelayer.gg/sessions/01a0ef65-e340-707e-9917-609260f74450
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the
kyle-anti-slop(anti-slop,anti-slop-effect),automation, and typed lint rules into fold, turns them on, and fixes the code to pass them. The TUI and test folders are exempt from the stricter rules.Lint setup
tools/oxlint/andtools/typed/;bun run lintruns oxlint (with the@effect/tsgopreset) and then the typed rules.@effect/tsgopreset rule that ships as a warning is now an error.automation/no-manual-tag-comparison,no-manual-tagged-construction, andprefer-effect-match; the stricteranti-slop-effectrules with the same names replace them.no-comments,no-reexport-only-modules,no-effect-asvoid,no-optional-function-parameters,private-function-prefix,no-multiple-function-params,no-single-use-private-functions.Services carried in types (
no-service-constructor-imports)startSessionrequires them, and the app provides them once at the top.SubagentsandAgentProvisionerservices are replaced by plain functions (dispatchSubagent,forkSubagent,resumeSubagent,continueSubagent,provisionAgentRuntime) that take the session's services from their surroundings. This removes the placeholderstartSessionused to break their construction loop. A newSessionAgentsservice carries the registry, tool realization, the root agent's current setup, and the auto-compact policy.Other rule fixes
Option+Arr.getSomes,.filter(Predicate.isNotUndefined), defaults where options are read)._tag: internal tagged unions are declared withData.TaggedEnum, and log-entry variants use the named entry types. Fold's copy of the rule allows_tag: Schema.tag(...)/Schema.tagDefaultOmit(...)schema fields.Struct.pickfor optional pass-through fields) instead ofMutable<...>builders; lookup tables useas const satisfies Record<...>.Testing
bun run typecheck,bun run lint, andbun run format:checkpass.bun run testpasses in every package;CodexModelCredentials.vi.test.tsis new and covers the non-default provider-name login fix.🤖 Generated with Claude Code