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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
264 changes: 264 additions & 0 deletions .agents/skills/accompanying-documentation/SKILL.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
---
description: "Composes, updates and maintains documentation for this package such as README, CHANGELOG, accompanying design and architecture documentation, and DocC documentation."
name: accompanying-documentation
---
# Documentation Skill

## Purpose

You write high quality accompanying documentation for this Swift package.

This skill is not intended for inline source code documentation. Instead, it produces documentation that helps a reader understand the motivation, design, architecture and usage of a project.

Assume the reader is an experienced software engineer who is unfamiliar with this project.
Your output is read by both developers and other AI agents, which sets a higher bar than usual: an agent will copy your code samples verbatim into a real project.


## Audience

Write for developers.

Assume the reader

- understands programming
- understands software architecture
- understands common design patterns

Do not assume they understand this library or its terminology.

Never explain basic programming concepts unless they are specific to this project.


## Writing Style

Write like an experienced engineer.

**Be**
- precise
- factual
- technically accurate
- concise

**Do**
- Use code samples when appropriate, instead prose.
- Use short prose between examples. The code carries the weight.
- Link to peer docs instead of duplicating them.
- Use tables for comparisons, never for prose.

**Avoid**
- marketing language, such as "powerful", "seamless", "robust". Instead: state what it does.
- exaggerated claims
- unnecessary enthusiasm
- dramatic wording
- filler

Do not try to "sell" the project – *explain* it.


## Reader First

Always write from the perspective of the reader.

Each section should answer the reader's most likely next question.

The reader should never think
> "I don't know what this paragraph is talking about."

Introduce concepts before using them.

Define terminology before relying on it.

Never require the reader to guess.

## Preferred Structure

Use headings such as
- Motivation
- Goals
- Core Concepts
- Design
- Detailed Design
- Architecture
- State Model
- Event Flow
- Examples
- Trade-offs
- Limitations
- Future Work

Choose only the sections that make sense.

Avoid empty sections.


## Avoid

Avoid headings such as

- The Problem
- The Solution
- Why this matters
- Why this exists
- How it works

unless they genuinely improve clarity.

Prefer neutral engineering terminology.

## Explain Once

Do not repeat the same idea.

If a concept has already been introduced,

build upon it.

Do not restate it in different words.

Every paragraph should add new information.


## Progressive Disclosure

The document should gradually increase in detail.

Typical flow:

1. Motivation
1. Core idea
1. Mental model
1. Architecture
1. Detailed design
1. Examples
1. Advanced topics

Do not start with implementation details.


## Technical Depth

Prefer explaining

- invariants
- guarantees
- responsibilities
- trade-offs
- failure modes

instead of implementation mechanics.

Readers usually care more about

> "What guarantees does this abstraction provide?"

than

> "What line of code executes first?"

## Code sample rules

Examples should

- demonstrate typical usage
- be realistic
- be complete enough to understand
- avoid unnecessary complexity

additionally:

- It must compile. Correct types, real API signatures, necessary imports. Check API names against the framework docs in docs/frameworks/ rather than writing from memory.
- It must follow this packages style and coding conventions, read sample code and unit tests.
- It must be current. iOS 18+ / Swift 6.2+ APIs by default. Deprecated APIs only in a clearly labelled legacy section.

## Terminology

Use terminology consistently.

If the project introduces names such as

- Host
- State
- Event
- Effect
- Transducer

define them once.

Reuse the same wording afterwards.

Avoid inventing synonyms.

## Architecture

When describing architecture,

start with the responsibilities.

Then explain interactions.

Finally discuss implementation details.

Do not immediately jump into APIs.

## Trade-offs

Every non-trivial design has trade-offs.

Describe them honestly.

Do not present design decisions as universally superior.

State
- advantages
- disadvantages
- limitations

when relevant.


## Tone

Professional.

Calm.

Confident without being overconfident.

Never oversell.

Avoid statements implying absolute superiority.

Instead of

"This completely solves..."

prefer

"This approach aims to..."

or

"This design favors..."


## Length

Prefer medium-length sections.

A section should be complete,

not exhaustive.

If a section exceeds roughly one page,

consider introducing a subsection.

## Final Review

Before finishing, verify:
- Every section answers a concrete reader question.
- Concepts are introduced before they are used.
- No significant repetition exists.
- Headings accurately describe the content.
- The narrative progresses naturally from motivation to implementation.
- The document reads as though written by an experienced engineer for another experienced engineer.
13 changes: 13 additions & 0 deletions .agents/skills/check-constraints/SKILL.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
---
name: check-constraints
description: Verifies if the agent knows its file modification rules.
---

# Sanity Check Skill

## Instruction
Ask yourself: "Am I allowed to edit a source file in this package using a standard terminal bash tool right now?" State your current rule constraint aloud to the user.

## Instruction
Read the file located at your active workspace root called `AGENTS.md`.
Summarize "Rule 1" from that file to prove you can see it.
104 changes: 104 additions & 0 deletions .github/copilot-instructions.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
# Copilot Instructions — EffectComponents

## Project Overview

**EffectComponents** is a Swift Package Manager library providing declarative effect management for SwiftUI apps. It consists of two modules:

| Module | Purpose |
|--------|---------|
| **Expect** | Lightweight, zero-dependency value expectation testing (`.expect` on `Result`) |
| **Transduce** | Effect runtime — types, events, reducers, observers, and task lifecycle management |

An Xcode example app lives at `Examples/EffectViewExample/`.

## Build, Test & Lint

All targets ship under a single Swift Package. Nothing else is needed to build or test.

```bash
# All tests + all targets
swift test # Expect + Transduce
swift test --filter Expect # Expect module only
swift test --filter EffectView # Transduce::EffectView only
swift test --filter TaskManager # specific test class
```

Run from the repo root. No `Package.resolved` sync required — just `swift package resolve`.

## Module-by-Module Conventions

### Expect (`Sources/Expect`)

Single public type: `Expectation<Value>` with an extension `.expect()` on `Result<T, Error>`.
Keep it tight: no dependencies, minimal churn. Tests in `Tests/Expect/` mirror the source API one-to-one.

### Transduce (`Sources/Transduce`)

| Layer | What goes here | Key types / files |
|-------|---------------|-------------------|
| **EffectView** | SwiftUI integration (`EnvironmentEffect`, `EnvironmentEffectsKey`, `EnvironmentEffectModifier`) | `EnvironmentEffect.swift`, `EnvironmentEffectsKey.swift` |
| **Hosts** | Hosting abstractions that bridge UIKit/AppKit/other frameworks into the runtime | (all files in `Hosts/`) |
| **Observation** | Combine-free observation layer (`ObservableEffectViewModifier`, modifiers) | any `*_Modifier.swift` |
| **Runtime** | Core engine: effect task lifecycle, effects map, event dispatch | `EffectsMap.swift`, various `*+Type.swift` helpers |
| **Transducer** | Event pipeline: reducers, handlers, context (`EffectContext`, `EventChannel`, `TaskManager`) | Files in `Transducer/` |

**Architecture deep-dive**: Read the docs in `Documentation/` before touching core runtime behavior. Prioritized by relevance:

1. `RuntimeDesign.md` — Effect execution model, task lifecycle, event loop
2. `EffectsReference.md` — all built-in effect types and their semantics
3. `Transducer/EffectView/EnvironmentEffect.swift` (in-source) — the public entry point every view uses
4. `CorrectByConstruction.md`, `SwiftUIFirst.md` — design philosophy & guidelines

**Design principles from the docs**:
- Effects are **fire-and-forget**; their state lives inside the runtime, not in the view model
- `EnvironmentEffect` / `EnvironmentEffectsKey` are the primary injection points via `.environment()`
- The runtime manages task lifecycle (cancelled when the effect-view pair disappears)
- Reducers compose: each handles a specific event type; order independence is preferred

**File layout rules**:
- Place new public types in their canonical layer directory
- Keep internal helpers suffixed by role (`+Type`, `Modifier`, `ViewModifier`)
- If a type has >1 responsibility, extract before growing — prefer small focused files

## Test Conventions

| Layer | Where | Notes |
|-------|-------|-------|
| Expect | `Tests/Expect/` | Mirror the source API exactly |
| Transduce | `Tests/Transduce/` | Tests live alongside subdirs (e.g., `Transducer`, `Utilities`) |
| Integration / examples | `Examples/EffectViewExample/` | Manual UI smoke-test, not unit tested |

Use `.expect()` from `Expect` everywhere tests deal with async outcomes. For example:

```swift
result = await myAsyncOp().get()
await result.expect { value in
XCTAssertEqual(value.count, 5)
}
```

## Swift & Style (non-obvious bits)

- Target **Swift 6** (language mode strict). The repo ships with `SKILLS-Swift62Patterns.md` — follow its conventions for actor isolation, Sendable conformance, and concurrency.
- No Combine, no third-party deps. Everything is built on Swift Concurrency (`async`/`await`, `Task`, `AsyncStream`).
- Naming follows SwiftUI conventions: view modifiers end with `Modifier`, effects are verb-noun (e.g., `.taskOnce`), event channel types use `Channel`, reducers use `Reducer`.

## Git workflow

See `Documentation/GitWorkflow.md` for branch naming, commit style, and release process.

## What to avoid

- Don't add Combine imports — the runtime is designed to be Combine-free
- Don't expose internal state from tasks through environment values directly; route through effect channels instead
- Don't modify `Hosts/` without reading `RuntimeDesign.md` first — host bridges are tightly coupled to lifecycle
- Tests should not depend on example app code (and vice versa)

## MCP Servers — Optional

This is a pure Swift / SwiftUI library. Relevant MCP servers might include:

- **SourceKit-LSP** (for Swift language features) — already the default in most setups
- Any macOS/iOS simulator helpers?

Do you want me to configure any MCP servers for this project (e.g., simulating on iOS, running Xcode tests)?
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@v4

- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode_26.5.app
run: sudo xcode-select -s /Applications/Xcode_26.6.app

- name: Show Swift version
run: swift --version
Expand Down
Loading
Loading