You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit c92c57d
Browse filesBrowse the repository at this point in the historyBrowse files
|**medium**| New optimistic-mutation code that bypasses `Atom.optimistic` / `Atom.optimisticFn` and rolls its own pending state. Or a mixed read/write where the read goes through the plain query atom and the write goes through the optimistic mutation. |
52
-
|**low**| Subtle defects in an `Atom.optimisticFn` reducer that work today but degrade under racing (clock-based identity, missing `Atom.family` wrapper, computed-once captures of `scopeId`). |
52
+
|**low**| Subtle defects in an `Atom.optimisticFn` reducer that work today but degrade under racing (clock-based identity, missing `Atom.family` wrapper, computed-once captures of `scopeId`).|
53
53
54
54
Do not invent `high`. Pick `low` when in doubt and explain why.
Use `Effect.fail(...)` in non-generator combinator code:
@@ -167,16 +167,14 @@ Effect.ignore(
167
167
Bad in domain code:
168
168
169
169
```ts
170
-
program.pipe(Effect.orDie)
171
-
Effect.die(error)
170
+
program.pipe(Effect.orDie);
171
+
Effect.die(error);
172
172
```
173
173
174
174
Good:
175
175
176
176
```ts
177
-
program.pipe(
178
-
Effect.mapError((cause) =>newDomainError({ message: "Operation failed", cause })),
179
-
)
177
+
program.pipe(Effect.mapError((cause) =>newDomainError({ message: "Operation failed", cause })));
180
178
```
181
179
182
180
`Effect.die`, `Effect.dieMessage`, `Effect.orDie`, and `Effect.orDieWith` turn typed failures into defects. Use them only at a true runtime boundary where the host cannot represent typed failures, and keep that usage behind a narrow lint suppression with a `boundary:` reason. Do not use `orDie` to avoid threading an error type through normal Effect code.
Copy file name to clipboardExpand all lines: .skills/cli-release/SKILL.md
+9Lines changed: 9 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,16 +6,19 @@ description: Runbook for releasing the `executor` CLI package (stable and beta).
6
6
# Executor CLI release runbook
7
7
8
8
## Authoritative doc
9
+
9
10
`RELEASING.md` at repo root is the source of truth. This skill encodes the owner's preferences on top of it.
10
11
11
12
## What the `executor` CLI actually ships
12
13
13
14
The CLI binary bundles:
15
+
14
16
-`apps/cli/**` — CLI source + daemon
15
17
-`apps/local/**` — the web UI (embedded as a virtual module via `apps/cli/src/build.ts:178`) + drizzle migrations (`build.ts:205`)
16
18
-`packages/**` — `core`, `kernel`, `hosts/mcp`, `runtime-quickjs`, and every plugin under `packages/plugins/**`
17
19
18
20
Does **not** ship in the CLI:
21
+
19
22
-`apps/cloud/**` (Cloudflare Workers deployment)
20
23
-`apps/marketing/**`, `apps/desktop/**`
21
24
-`examples/**`, `tests/**`
@@ -37,14 +40,17 @@ The owner doesn't want GitHub's auto-generated "PR title by @user" list. Release
37
40
**`apps/cli/release-notes/next.md` is the canonical user-facing changelog.** Per-package workspace `CHANGELOG.md` files are one-line stubs required by `changesets/action@v1` (the GitHub Action wrapping the CLI in `release.yml`) — it reads each bumped package's `CHANGELOG.md` to build the Version Packages PR description and crashes with `ENOENT` if any is missing. The stubs satisfy that read; don't put release content in them.
38
41
39
42
### How it's wired
43
+
40
44
`apps/cli/src/release.ts` reads `apps/cli/release-notes/next.md` and uses
41
45
its contents as the GitHub Release body. If the file is missing or empty,
42
46
falls back to `gh release create --generate-notes`. There's no
43
47
per-version archive in the repo — historical release bodies live on
44
48
GitHub Releases (durable, indexed, linkable).
45
49
46
50
### Writing conventions
51
+
47
52
Structure release-notes files as:
53
+
48
54
```
49
55
## Highlights
50
56
### <user-facing story> # e.g. "Per-user OAuth for OpenAPI and MCP sources"
@@ -74,17 +80,20 @@ External contributor bullets end with `Thanks @<user> (#PR)`:
74
80
Do not `Thanks` maintainers, bots, or the repo owner — the lint script rejects `@claude`, `@anthropic`, `@github-actions`, `@dependabot`, `@renovate`, `@rhyssullivan`, `@rhys-sullivan`. Run `bun run lint:release-notes` before pushing notes.
75
81
76
82
### When drafting from `git log`
83
+
77
84
- Look at `git diff v<last>..HEAD -- README.md` first — it's the best single view of user-facing changes.
78
85
- Read commit messages in bulk (`git log --oneline v<last>..HEAD -- apps/cli apps/local packages`), then bucket by theme before writing prose.
79
86
- Don't list every commit. Merge PRs and refactor-chain commits into one line.
80
87
81
88
### Pairing with changesets
89
+
82
90
- A `.changeset/*.md` describes the version bump (semver level + a short summary for the Version Packages PR description). It is **not** the user-facing changelog.
83
91
- If your PR adds a `.changeset/*.md` for the `executor` package, also edit `apps/cli/release-notes/next.md` for the user-facing story. They have different audiences.
84
92
- The `.changeset/*.md` body can be a one-liner pointing at the release-notes section it expands; users read the GitHub release body, not the changeset.
85
93
- Frontmatter is `"executor": patch` (or `minor`/`major` if owner says so).
86
94
87
95
### Starting a new release cycle
96
+
88
97
There's no post-release rename step. When you start work on the next
89
98
release, replace the existing `next.md` content with new entries — the
90
99
previous cycle's content is already preserved on the matching `vX.Y.Z`
0 commit comments