Skip to content

Commit 76275fc

Browse files
authored
refactor: move Pty into pty/index.ts with self-reexport (#22881)
1 parent 6c3b28d commit 76275fc

3 files changed

Lines changed: 413 additions & 368 deletions

File tree

packages/opencode/specs/effect/namespace-treeshake.md

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,59 @@ import regressions at runtime — the typechecker does not catch these.
196196
## Rules for new code
197197

198198
- No new `export namespace`.
199-
- Every module file that wants a namespace gets a self-reexport at the
199+
- Every module directory has a single canonical file — typically
200+
`dir/index.ts` — with flat top-level exports and a self-reexport at the
200201
bottom:
201-
`export * as Foo from "./foo"`
202-
- Consumers import from the file itself:
203-
`import { Foo } from "../path/to/foo"`
204-
- No new barrel `index.ts` files for internal code.
202+
`export * as Foo from "."`
203+
- Consumers import from the directory:
204+
`import { Foo } from "@/dir"` or `import { Foo } from "../dir"`.
205+
- No sibling barrel files. If a directory has multiple independent
206+
namespaces, they each get their own file (e.g. `config/config.ts`,
207+
`config/plugin.ts`) and their own self-reexport; the `index.ts` in that
208+
directory stays minimal or does not exist.
205209
- If a file needs a sibling, import the sibling file directly:
206210
`import * as Sibling from "./sibling"`, not `from "."`.
207211

212+
### Why `dir/index.ts` + `"."` is fine for us
213+
214+
A single-file module (e.g. `pty/`) can live entirely in `dir/index.ts`
215+
with `export * as Foo from "."` at the bottom. Consumers write the
216+
short form:
217+
218+
```ts
219+
import { Pty } from "@/pty"
220+
```
221+
222+
This works in Bun runtime, Bun build, esbuild, and Rollup. It does NOT
223+
work under Node's `--experimental-strip-types` runner:
224+
225+
```
226+
node --experimental-strip-types entry.ts
227+
ERR_UNSUPPORTED_DIR_IMPORT: Directory import '/.../pty' is not supported
228+
```
229+
230+
Node requires an explicit file or a `package.json#exports` map for ESM.
231+
We don't care about that target right now because the opencode CLI is
232+
built with Bun and the web apps are built with Vite/Rollup. If we ever
233+
want to run raw `.ts` through Node, we'll need to either use explicit
234+
`.ts` extensions everywhere or add per-directory `package.json` exports
235+
maps.
236+
237+
### When NOT to collapse to `index.ts`
238+
239+
Some directories contain multiple independent namespaces where
240+
`dir/index.ts` would be misleading. Examples:
241+
242+
- `config/` has `Config`, `ConfigPaths`, `ConfigMarkdown`, `ConfigPlugin`,
243+
`ConfigKeybinds`. Each lives in its own file with its own self-reexport
244+
(`config/config.ts`, `config/plugin.ts`, etc.). Consumers import the
245+
specific one: `import { ConfigPlugin } from "@/config/plugin"`.
246+
- Same shape for `session/`, `server/`, etc.
247+
248+
Collapsing one of those into `index.ts` would mean picking a single
249+
"canonical" namespace for the directory, which breaks the symmetry and
250+
hides the other files.
251+
208252
## Scope
209253

210254
There are still dozens of `export namespace` files left across the codebase.

0 commit comments

Comments
 (0)