Skip to content

integrate(mdx-8je): Cloudflare-native kernel round 1 — prune to workerd-only, mdxdb root, @mdxe/cli-core + @mdxe/tui seam, sqlite pools + $init, mdxld 1.9.2 alias release - #14

Merged
nathanclevenger merged 82 commits into
mainfrom
integrate/mdx-8je
Sep 9, 2026

Conversation

@nathanclevenger

@nathanclevenger nathanclevenger commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Lands epic mdx-8je (Cloudflare-native kernel, round 1) on main: rounds 1-4 from the integrate branch plus the round-5 work that had never been integrated.

Included issues

  • Build green groundwork: mdx-8je.1 (oauth.do wrapper packages/mdxe/src/auth.ts; RPC re-export dropped), .2 (primitives from npm ^2.4.0, MDXLD alias), .3, .4, .14, .16, .18, .21, .25, .27, .28, .29, .31, .33, .34, .35, .39, .40, .43, .44, .54, .55, .57, .58, .59, .61
  • Prune to Cloudflare-native: .7 (18 packages + apps/desktop, apps/mobile removed behind test/repo/package-allowlist.test.ts), .6 (@mdxe/rpc, @mdxai/agentkit removed; RPC home is rpc.do), .62 (allowlist reconciled: keep sqlite, cloudflare, cli-core, tui), .60 (never-shipped mdxdb CLI references dropped; mdxdb-release.yml deleted)
  • mdxdb root: .11 (packages/mdxdb 2.0.0 — DB() facade over ai-database, DATABASE_URL resolution, @mdxdb/do primary backend)
  • @mdxdb/sqlite: .5 (node + workers vitest pools), .19, .22, .23 (Worker Loader witness), .24 ($init(name) handshake — was missing from integrate; merged from worktree-wf_3d4080bf-321-15)
  • mdxe CLI + @mdxe/cli-core leaf: .26, .30, .32 (ci.yml: test:integration/test:e2e steps removed — those root scripts never existed on main, so no coverage is lost; lanes tracked in .36), .45 (changesets config repaired)
  • @mdxe/tui seam + Ink 7 viewer: .13, .15 (opentui allowlisted ahead), .17
  • @mdxe/vitest on ai-evaluate: .37 (h/Fragment bound for JSX blocks)
  • mdxld release: .20 (.changeset/mdxld-restore-mdxld-alias.md → mdxld 1.9.2; test/repo/mdxld-surface-for-primitives.test.ts)

Not included: mdx-8je.9 (blocked on primitives aip-263g; no commits exist), mdx-8je.8 (mdxui deletion deferred — nothing under packages/@mdxui or packages/mdxui is removed here), mdx-8je.64 (npm deprecations run by the publisher after this merge).

Integration fixes made on this branch

  • Lockfile regenerated after the mdxdb/prune merges: only the packages/mdxdb importer was added.
  • packages/mdxe/src/schemas.ts platform enums aligned with the pruned targets (do/cloudflare); cast-hidden vercel test removed.
  • mdxdb/src/resolve.ts maps only module-resolution errors to AdapterNotInstalledError.
  • @mdxe/tui BenchmarkReport.installPackages typed (no cast in @mdxe/ink bench).

Verification (worktree, fresh pnpm install --frozen-lockfile)

  • pnpm test:repo: 10 files / 251 tests, typecheck lane clean.
  • turbo typecheck build test for mdxld, mdxdb, mdxe, @mdxe/tui, @mdxe/ink, @mdxe/cli-core, @mdxld/evaluate, @mdxld/compile, @mdxdb/sqlite, @mdxdb/do: all builds and tests green (mdxe 800 passed / 3 skipped; mdxdb 109 + 26 workers; sqlite 56 + 38 workers; tui 30; ink 20; cli-core 75; mdxld 165). Typecheck: mdxe 7 pre-existing errors (37 on main), @mdxdb/do 62 pre-existing (66 on main) — filed as mdx-w89.1.
  • Root turbo run build --continue: 87/91. Root turbo run test --continue: 156/171. The failing set is exactly the pre-existing red recorded in mdx-8je.63 — builds: @mdxai/claude, mdxai, @mdxui/plan, storybook; tests: @mdxdb/{api,rpc,clickhouse,parquet,fumadocs}, @mdxui/{headless,jsx,radix,slides,video}, mdxai. Nothing new.

Follow-ups filed under mdx-w89

mdx-w89.1 (@mdxdb/do typecheck + dts), mdx-w89.2 (root ai-evaluate entry used outside workerd in mdxe runTest and @mdxld/evaluate), mdx-w89.3 (release versioning: linked groups push mdxe/@mdxe//@mdxdb/ to 3.0.0; ink/tui/mdxdb have no changesets), mdx-w89.4 (review nits).

🤖 Generated with Claude Code

nathanclevenger and others added 18 commits September 8, 2026 06:40
…mark harness (mdx-8je.13)

Kestrel ADR-0052 §4 doctrine: renderers are pure tree → bytes; a TUI is a shell
that displays bytes and handles input, never a fourth renderer. @mdxe/tui is the
seam @mdxe/ink (.14) and @mdxe/opentui (.15) implement.

- Viewer { mount(stream, input), unmount }, MountHandle, Terminal, KeyEvent /
  PasteEvent / ResizeEvent, Action, Keymap, ViewerError (NOT_A_TTY, ALREADY_MOUNTED)
- input abstraction: decodeInput (CSI keys, ctrl/meta chords, bracketed paste),
  defaultKeymap, mapActions, createInputSource over a live terminal
- tty guard: canAttach / assertAttachable — never attaches on a piped stdout or
  stdin (raw mode fails open on pipes)
- conformance suite (@mdxe/tui/conformance): strip(paint(bytes)) === bytes,
  identical action mapping, refuses non-TTYs, unmount releases raw mode and
  paints nothing afterwards, quit unmounts; runner-agnostic runConformance plus
  describeViewerConformance binding; createFakeTerminal + fixtures exported
- benchmark harness (@mdxe/tui/benchmark): startupMs, installBytes (recursive
  dir size, lazily imports node:fs), repaint p50/p95/max per streamed frame;
  formatReport emits JSON; `pnpm --filter @mdxe/tui bench` runs it on the stub
- reference stub viewer (@mdxe/tui/stub) the suite is proven green against
- root entry is dependency- and framework-free; heavier pieces are lazy subpaths

Verified: 29/29 tests, tsc, eslint, tsup build, bench emits valid JSON.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…yaml} their own tsconfig so tsc stops sweeping the monorepo (mdx-8je.4)

These packages ran `tsc --noEmit` with no tsconfig.json, so tsc walked up to the root tsconfig.json, which has no `include`, and type-checked all ~1,300 files in the repo: 11,802 phantom errors per package that hid the packages' real errors.

Each package now extends @mdxld/config/typescript/library.json with include src/** and test/**, and declares @mdxld/config as a devDependency (lockfile importer blocks updated to match). The issue names markdown, typescript and diff; csv, html, json, xlsx and yaml had the byte-identical defect and get the byte-identical fix, so the new repo-level guard can assert the invariant without an exclusion list.

tests/tsconfig-includes.test.ts asserts, for every package under packages/: any package whose typecheck script runs tsc has its own tsconfig.json, and every tsconfig's include/files entries, effective include roots after extends, and resolved file list stay inside the package directory (208 assertions; goes red when a tsconfig is removed).

Result for the three named packages: 35,406 -> 32 errors, all real, all in src/index.test.ts (tracked in mdx-qxi).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pm collapse (mdx-8je.2)

The primitives/ submodule and workspace glob were already removed in
7346df8; this finishes the job and restores the type ai-database needs.

- mdxld: export `MDXLD<TData>` as a deprecated alias of `MDXLDDocument`.
  Published ai-database@2.4.0 (dist/types.d.ts) does
  `import type { MDXLD } from 'mdxld'` and `ThingExpanded extends MDXLD`;
  no current mdxld exported that name. Type-level test guards the alias
  (structural equality + interface extension) under `tsc --noEmit`.
- mdxld: ambient `*?raw` module declaration so primitives.test.ts
  typechecks (it was the only thing failing `pnpm --filter mdxld typecheck`).
- @mdxdb/fs tsconfig: drop the `paths` alias into the deleted
  primitives/packages/ai-database checkout; ai-database now resolves from npm.
- vitest.mdx.config.ts: drop the alias into primitives/packages/ai-sandbox.
- test/repo/primitives-collapse.test.ts (+ vitest.repo.config.ts,
  `pnpm test:repo`, chained into `test` / `test:unit`): asserts no
  primitives/ workspace entry, submodule, or directory; no ai-* dep via
  workspace:/file:/link:; no tsconfig or vitest alias into a local
  primitives checkout.
- Docs: CLAUDE.md + mdxe/mdxld READMEs describe primitives as npm ^2.4.0.

Verified: pnpm install --frozen-lockfile (exit 0); mdxld typecheck, test
(165 passing), lint clean on touched files; @mdxdb/fs builds against npm
ai-database/mdxld; pnpm test:repo (5 passing).

Model gaps filed: mdx-8je.20 (published ai-database imports MDXLD that no
published mdxld exports; pnpm resolves its mdxld from the registry, so a
mdxld release is needed), mdx-8je.21 (ai-sandbox unpublished but imported
by @mdxe/vitest and @mdxld/evaluate; ai-tests unused so not added).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…test-pool-workers (mdx-8je.5)

The Durable Object imports cloudflare:workers, which only workerd provides,
so the suite is now two pools:

- vitest.config.ts (node): schema + MDXClient tests under tests/*.test.ts
- vitest.workers.config.ts (workerd): MDXDatabase DO tests under
  tests/workers/, with the DO declared in wrangler.test.jsonc
  (new_sqlite_classes). `pnpm test` runs both.

The pre-rewrite tests (compliance, miniflare, schema) targeted the API
removed in 19b37ab (events/actions/artifacts/search, createInMemoryBinding,
ai-database/tests) and could not pass under any pool, so they are replaced
by tests against the current _data/_rels surface. See mdx-8je.19.

Harness notes (mdx-8je.23): isolatedStorage is off because the pool cannot
snapshot SQLite-backed DOs (each test uses its own DO name instead), and
the optional @mdxe/isolate peer is aliased to a throwing stub so the suite
does not require a sibling build. The DO-name -> $id contract does not
hold in workerd (ctx.id.name is undefined); kept as it.fails, tracked in
mdx-8je.24.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ke function-body output runnable

@mdxld/evaluate still dynamically imported 'ai-sandbox', which was renamed to
ai-evaluate on 2025-12-20, so `tsc` failed with TS2307 and the dts build broke.

- @mdxld/evaluate: depend on ai-evaluate ^2.4.0 (already in the lockfile via
  mdxe); import it in evaluateInSandbox; externalize it in tsup; forward the
  already-declared `timeout` and `allowNetwork` SandboxOptions, which were
  documented (default false) but never sent - ai-evaluate allows network by
  default. Drop the unsafe `as SandboxResult` cast: EvaluateResult is
  structurally assignable.
- Tests: evaluate() of a trivial MDX module returns its default export; run();
  frontmatter; and evaluateInSandbox() must answer with ai-evaluate's own
  worker_loaders refusal rather than a module-resolution error, so the test
  actually witnesses the import resolving.
- @mdxld/compile: the new evaluate() test exposed that `function-body` output
  (the default) was not a function body. transformJSX hard-coded esbuild
  `format: 'esm'`; a top-level `return` makes esbuild treat the input as
  CommonJS, wrap it in a __commonJS shim and emit `export default`, which
  `new Function` rejects. TransformJSXOptions gains `format` (default 'esm';
  `null` leaves the code unwrapped) and compile() passes null for
  function-body. Tests pin both output shapes.

Verified: pnpm --filter @mdxld/evaluate build && test (6/6) && typecheck;
pnpm --filter @mdxld/compile build && test (6/6) && typecheck;
pnpm install --lockfile-only --frozen-lockfile --offline.

Refs: mdx-8je.3

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ds (mdx-8je.1)

oauth.do's root entry ships a tsup-mangled .d.ts (`ensureLoggedIn as e`,
TS2460/TS2339 for importers) and its runtime ESM bundle does not export
ensureLoggedIn at all, so `import { ensureLoggedIn } from 'oauth.do'` was
both a type error and `undefined` at runtime. Every published 0.1.x and
0.2.x build has the same shape, so pinning cannot fix it. Only the
`oauth.do/node` subpath re-exports the symbol under its real name.

- mdxe: add src/auth.ts as the single import site (re-exports from
  oauth.do/node); commands/deploy.ts, commands/db.ts and the managed-deploy
  E2E import from it. src/auth.test.ts asserts ensureLoggedIn/getToken are
  functions so future drift fails in one place.
- @mdxe/do, @mdxe/cloudflare, @mdxe/github, @mdxe/vercel: import from
  oauth.do/node (they do not depend on mdxe); test mocks follow.
- mdxe tests/deploy-extended: mock the auth wrapper. deployViaManagedApi
  authenticates before it builds, so the spawn-mocked build tests were
  silently depending on a live auth.apis.do login.
- mdxe optional-deps.d.ts: ambient shims for @mdxe/workers/local and
  @hono/node-server, which dev-server.ts imports dynamically but mdxe never
  declares; their TS2307s were hiding behind the oauth.do error in the same
  DTS build. Tracked as mdx-nzh.

Verified: tsup build green for mdxe, @mdxe/do, @mdxe/cloudflare,
@mdxe/github, @mdxe/vercel; unit suites green (mdxe 759/762, the 3 reds are
the live-network E2E cases while auth.apis.do returns 522 - mdx-d5s).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Both packages duplicated primitives that already ship in the workspace:
@mdxe/rpc reimplemented RPCServer/RPCClient over fetch while advertising
capnweb (ai-functions RPC / RPCPromise), and @mdxai/agentkit overlapped
autonomous-agents, which mdxai already depends on.

- git rm packages/@mdxe/rpc and packages/@mdxai/agentkit
- drop the docs page for agentkit and its fumadocs .source entries
- README / CLAUDE.md / ROADMAP / mdxe + @mdxe/mcp docs now point at
  ai-functions RPC and autonomous-agents instead
- tests/removed-packages.test.ts asserts no package.json in the workspace
  names or depends on either package, the directories stay gone, and mdxe
  keeps re-exporting RPC / RPCPromise types from ai-functions directly
- tests/readme-taxonomy.test.ts updated for the removed @mdxe/rpc row
- pnpm-lock.yaml: only the two importer blocks removed
- changeset (minor for mdxe and mdxai; mdxe never re-exported @mdxe/rpc)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…LI (mdx-8je.16)

New packages/mdxe/src/cli/{context,caller,errors,args,orient,tokens}.ts, ported from kestrel (MIT, attributed in each header) with mdxe env names (MDXE_AGENT, MDXE_COLOR) and one extra ladder rung for HTTP faces (Accept).

- resolveOutputCtx: --json/--format > Accept > --agent/agent env > CI > !isTTY > TTY; NO_COLOR presence beats --color always; bad --format/--color is USAGE even alongside --json; frozen ctx, width=Infinity off-TTY.
- resolveCaller: env beats TTY (CLAUDECODE, CLAUDE_CODE_CHILD_SESSION, CURSOR_AGENT, GEMINI_CLI, OPENCODE, AI_AGENT, AGENT, MDXE_AGENT, CODEX_*), then CI, then TTY probe; interactive only for a confident human.
- errors: CliError with stable codes; EXIT {0,1,2,3,4,5,6,130}; REFUSED(6) distinguishes fail-closed-working from a crash; fail() renders to stderr only.
- args: extractGlobals peels the render/meta flags before the router; unknown flags rejected before value consumption.
- orient: bare invocation renders a task-grouped orientation (text/json/human) and exits 0 without reading stdin — it never starts the dev server.
- tokens: labelled TokenCount (tiktoken lazy-optional / chars-approx / fable-native offline cache that fails closed on a miss or base drift).

cli.ts: main(argv) resolves ctx+caller once, fast-paths help/version before any dynamic import, threads the frozen ctx via CliOptions.ctx, returns the exit code (process.exit only at the entrypoint, guarded so importing the module never runs main). parseArgs fails closed: unknown command, unknown flag, malformed --env, bad enumerations are USAGE (exit 2) instead of silent fallthrough to dev; requireValue/validatePort throw instead of process.exit(1); --path aliases --dir; tail receives --json/--no-color from the resolved ctx.

Tests: ported context/caller matrices plus args/errors/orient/tokens units, a source-level light-import guard, and a spawned-bin e2e (esbuild code-split build) proving CLAUDECODE=1 + open stdin => orientation, exit 0, no hang; USAGE exits 2 with stderr-only errors.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e/mdx-8je

# Conflicts:
#	CLAUDE.md
#	packages/mdxe/README.md
… worktree-wf_3d4080bf-321-17

# Conflicts:
#	CLAUDE.md
#	packages/mdxe/README.md
… worktree-wf_3d4080bf-321-17

# Conflicts:
#	CLAUDE.md
@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown

Review

Reviewed the merge diff (113 files, ~5.4k additions) integrating the 7 mdx-8je child branches. Overall this is a clean, well-disciplined integration — the risks that typically bite in a large multi-branch merge (dangling imports to removed packages, secrets leaking into test configs, taxonomy violations, injection-prone CLI code) all came back clean on direct inspection.

Findings

Major — stale/broken guard test contract (tests/removed-packages.test.ts:61, packages/mdxe/src/index.ts:219-223)
The guard test asserts mdxe/src/index.ts re-exports RPC, RPCPromise from ai-functions, but ai-functions@2.4.0 exports neither symbol — this is why mdxe's tsup DTS build is red. It's honestly disclosed in the PR body as pre-existing on main, and CLAUDE.md's own worked example (import { RPC } from 'ai-functions') still points at this broken surface. Not introduced by this PR, but worth prioritizing the follow-up (mdx-8je.29) before this merges to main, since the guard test currently locks in the wrong invariant rather than catching drift.

Minor — CLAUDE.md dependency tree missed the tui addition (CLAUDE.md:329)
The "Dependency Structure" ASCII tree lists @mdxe/* (node, bun, workers, hono, next, ink, mcp, vitest) — correctly dropped rpc, but never added tui, even though the taxonomy table earlier in the same file (~line 96) does list it. The PR body's note about resolving the .6/.13 conflict by "keeping the new tui row, dropping the removed rpc row" only applies to one of the two @mdxe/* listings in the file.

Minor / worth a second look — unsandboxed eval as the default API (packages/@mdxld/evaluate/src/index.ts:101)
evaluate()/run() execute compiled MDX via new Function(...) with no sandboxing; evaluateInSandbox() is the safer alternative but is named like an opt-in extra rather than the recommended default. This is disclosed in JSDoc, so it's a deliberate tradeoff rather than an oversight, but since these are newly-exported public APIs, consider either flipping the naming (make the sandboxed path the obvious default) or calling out the trust boundary prominently in the package README so downstream consumers don't reach for evaluate() on untrusted MDX by default.

Verified clean / positives worth calling out

  • @mdxe/rpc / @mdxai/agentkit removal: no package.json anywhere in the workspace still depends on either package, backed by a real guard test.
  • @mdxdb/sqlite workers pool (wrangler.test.jsonc, vitest.workers.config.ts): no secrets, minimal DO binding, test-only config clearly marked non-deploy.
  • mdxld alias restore (types.ts, mdxld-alias.test.ts): clean deprecated-alias pattern with a type-level guard test, no circular deps.
  • primitives-from-npm collapse guard (test/repo/primitives-collapse.test.ts): thorough coverage of workspace.yaml, submodule absence, workspace: protocol bans, version pinning.
  • mdxe CLI modules (caller.ts, context.ts, errors.ts, args.ts, orient.ts, tokens.ts): no child_process/exec usage; the one spawn() call in cli.ts uses array-form args with fixed runtime strings, no shell interpolation / injection risk.
  • @mdxe/tui: ansi.ts/input.ts are pure decoders with no injection risk from untrusted input; tty.ts/stub.ts are meaningfully exercised via conformance.test.ts's lifecycle tests rather than just smoke tests.
  • Per-package tsconfig additions (csv/diff/html/json/markdown/typescript/xlsx/yaml): correctly scoped under @mdxld/, backed by tests/tsconfig-includes.test.ts.
  • @mdxld/evaluate tests: solid coverage — default export, JSX rendering, frontmatter, run(), and sandbox-fallback error-message behavior.

Test coverage

No package with meaningful source changes was found lacking a corresponding test file; the newest packages (@mdxld/evaluate, @mdxe/tui) both ship real behavioral tests rather than smoke tests.

Nice work keeping this integration tight — the two real gaps above are documentation/consistency issues rather than runtime bugs, and the RPC re-export was already flagged by the author as a known follow-up.

🤖 Generated with Claude Code

nathanclevenger and others added 7 commits September 8, 2026 08:22
…-8je.30)

Repo-level invariant tests were split between tests/ (on no script's
include path; turbo only runs per-package scripts) and test/repo/
(pnpm test:repo, branch 3), so removed-packages, tsconfig-includes and
readme-taxonomy sat on no CI path at all.

- test/repo/ is the single canonical home; tests/ is .mdx fixtures only
- vitest.repo.config.ts includes test/repo/**/*.test.ts, and sweeps
  tests/**/*.test.ts so a misplaced guard still executes instead of
  silently going dark
- test/repo/guard-test-home.test.ts fails the build with a git-mv
  pointer if a *.test.ts appears under tests/, and asserts the
  package.json + ci.yml wiring cannot regress
- tests/readme-taxonomy.test.ts moved to test/repo/
- package.json: test:repo script, chained into test and test:unit
  (byte-identical to branch 3's lines so the merge is clean)
- ci.yml: "Run repo guard tests" step (pnpm test:repo) in the test job
- CLAUDE.md + test/repo/README.md document the convention

Post-merge note: branches 5 and 7 add removed-packages.test.ts and
tsconfig-includes.test.ts under tests/; the guard will name them and
they need `git mv tests/<f> test/repo/`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… ai-sandbox (mdx-8je.21)

@mdxe/vitest's generateTestCode() pushed `import { evaluate } from 'ai-sandbox'`
into every generated test file that needs the sandbox (JSX, hooks, Hono app).
ai-sandbox was renamed ai-evaluate on 2025-12-20; npm ai-sandbox is a 0.0.0
placeholder and the primitives/ submodule alias is gone, so those files could
not resolve in any install.

- Emit `ai-evaluate/node` (exported as SANDBOX_MODULE). Generated files run
  under vitest in Node, so the /node entry (Miniflare fallback) is the right
  one; the root entry requires a Cloudflare worker_loaders binding.
- Declare ai-evaluate >=2.4.0 as an optional peerDependency: the generated
  import resolves from the consumer project via the vitest transform plugin,
  the same way `vitest` itself is a peer. Add it as a devDependency so the
  test suite can witness resolution. Lockfile: only the @mdxe/vitest importer
  entry is added (ai-evaluate@2.4.0 was already resolved); the unrelated
  --no-frozen-lockfile churn (mdx-33k) was reverted by hand.
- Tests: no sandbox import for plain tests; sandbox tests import from
  ai-evaluate/node and never ai-sandbox; the emitted specifier actually
  imports to a real evaluate() (ai-evaluate/node lazy-loads miniflare, so
  this has no side effects).
- README: document sandboxed tests and the optional peer. CLAUDE.md: the
  `mdxe test` line still named ai-sandbox.

The other call site named by the issue, @mdxld/evaluate evaluateInSandbox,
was already repointed to ai-evaluate in 8cbbba9 (mdx-8je.3); nothing in the
repo references ai-sandbox as a module specifier any more (remaining hits
are comments and a wrangler service name).

ai-tests: not added. ai-evaluate's `tests` mode already provides
describe/it/expect inside the sandbox; ai-tests is only the optional TEST
service binding for Workers deployments and nothing here consumes it.

Verified: pnpm --filter @mdxe/vitest test (132/132, was 129) and build green;
typecheck (32x TS2532) and lint (10) fail identically before and after this
change on pre-existing lines - filed as mdx-b7m.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ot ship (mdx-8je.27)

ai-functions@2.4.0 exports no RPC or RPCPromise (dist/index.d.ts has zero
occurrences; no ./rpc subpath). The type re-export in src/index.ts was TS2305
and failed tsup's DTS step, so mdxe built no .d.ts. Remove the re-export and
the README/INTEGRATION docs that advertised 'import type { RPC, RPCPromise }
from mdxe', plus the no-op 'should have RPC types available' test.

Witnessed: tsc --noEmit 40 -> 38 errors, 0 in src/index.ts; tsup DTS exits 0
and ships dist/index.d.ts when combined with the oauth.do fix from mdx-8je.1
(b8e95c7), which is the only remaining DTS error.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ate/mdx-8je

.31 reconciled .2 -> .6 -> .13 in parallel with round 1's integration; net
delta on this branch is the @mdxe/tui entry in the dependency tree, the root
README's stale ./primitives/ link -> npm link, and one CLAUDE.md line.
Conflict: CLAUDE.md ai-functions line (two wordings of the same claim) ->
kept round 1's wording.
…ate/mdx-8je

Conflict: vitest.repo.config.ts add/add (round-1 .2's include of test/repo
only vs .30's include of test/repo plus a sweep of tests/ so a stray guard
still executes) -> took .30's, a superset.
…ds from tests/ to test/repo/

The post-merge step .30 named: round-1's .6 and .4 added these under tests/,
which no script ran; test/repo/guard-test-home.test.ts now flags them. Moved
with git mv and repointed the repo root from __dirname/.. to __dirname/../..
@nathanclevenger nathanclevenger changed the title integrate(mdx-8je): round 1 — build green groundwork, primitives from npm, sqlite pools, mdxe CLI, @mdxe/tui seam integrate(mdx-8je): rounds 1-2 - build green groundwork, primitives from npm, sqlite pools, mdxe CLI, @mdxe/tui seam, ai-evaluate in @mdxe/vitest, repo guard home Sep 8, 2026
nathanclevenger and others added 3 commits September 8, 2026 08:48
…ot ship (mdx-8je.27)

ai-functions@2.4.0 exports no RPC or RPCPromise (dist/index.d.ts has zero
occurrences; no ./rpc subpath). The type re-export in src/index.ts was TS2305
and failed tsup's DTS step, so mdxe built no .d.ts. Remove the re-export and
the README/INTEGRATION docs that advertised 'import type { RPC, RPCPromise }
from mdxe', plus the no-op 'should have RPC types available' test.

Witnessed: tsc --noEmit 40 -> 38 errors, 0 in src/index.ts; tsup DTS exits 0
and ships dist/index.d.ts when combined with the oauth.do fix from mdx-8je.1
(b8e95c7), which is the only remaining DTS error.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ing root scripts (mdx-8je.32)

The Test job ran 'pnpm test:integration' and 'pnpm test:e2e' but root
package.json defines neither (ERR_PNPM_NO_SCRIPT), so the job went red
after the unit-test step on every push/PR to main.

The package-level test:integration / test:e2e scripts (@mdxdb/github,
@mdxdb/do, @mdxdb/studio, @mdxui/editor, mdxld-vscode) all need
resources CI does not provision (GITHUB_TOKEN + test repo, ClickHouse,
wrangler/workerd, Playwright browsers, VS Code download), so wiring
them as turbo tasks would keep the job red. They remain runnable per
package locally; a CI lane for them is tracked separately.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…mdx-8je.34)

mdx-8je.27 dropped 'export type { RPC, RPCPromise } from ai-functions' from
packages/mdxe/src/index.ts (TS2305; ai-functions@2.4.0 ships neither symbol),
but the mdx-8je.6 guard pinned that exact text and the mdx-8je.31 docs
re-asserted it, so integrate + .27 turned test/repo/removed-packages.test.ts
red on pnpm test:repo / CI (mdx-8je.30 sweep).

- test/repo/removed-packages.test.ts: replace the source-text pin with its
  negation - mdxe imports nothing from ai-functions, and no source file under
  packages/ imports RPC / RPCPromise from ai-functions. Witnessed red when the
  re-export is appended back, green without it.
- packages/mdxe/package.json + pnpm-lock.yaml: drop ai-functions, which
  nothing in mdxe imports after .27 (frozen-lockfile clean).
- Docs (CLAUDE.md, README.md, packages/mdxe/{INTEGRATION,ECOSYSTEM}.md,
  packages/@mdxe/mcp/README.md, .changeset/remove-rpc-and-agentkit.md):
  stop claiming mdxe re-exports RPC types or that ai-functions ships RPC;
  point at rpc.do (RPC<T>(url), RPCPromise; capnweb via @dotdo/capnweb),
  which @mdxdb/rpc, @mdxdb/server and @mdxdb/do already depend on.

Verified: pnpm test:repo 241/241; mdxe tsc 30 errors, 0 in src/index.ts,
0 mentioning ai-functions; mdxe vitest 866 passed / 7 failed, the same 7
failing at baseline (oauth.do drift mdx-8je.1, unbuilt @mdxe/fumadocs dist).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@nathanclevenger nathanclevenger changed the title integrate(mdx-8je): rounds 1-3 - build green groundwork, primitives from npm, sqlite pools, mdxe CLI, @mdxe/tui seam, ai-evaluate in @mdxe/vitest, repo guard home, RPC re-export reconciled, sandbox assertion messages integrate(mdx-8je): rounds 1-4 - build green groundwork, primitives from npm, sqlite pools + Worker Loader witness, mdxe CLI + @mdxe/cli-core leaf, @mdxe/tui seam + Ink 7 viewer, ai-evaluate in @mdxe/vitest, repo guards, RPC home in rpc.do, oauth.do wrapper Sep 8, 2026
nathanclevenger and others added 7 commits September 8, 2026 11:44
… (mdx-8je.45)

`changeset status` (and therefore scripts/release.sh) failed at config validation:
- `ignore: ["@mdxld/config"]` errored for all 61 publishable packages that
  devDepend on it. @mdxld/config is private, so it is never published anyway; drop
  the ignore entry and set privatePackages {version:false, tag:false} instead.
- linked group `["mdxdb", "@mdxdb/*"]` errored because no `mdxdb` root package
  exists yet (mdx-8je.11 creates it). Use one brace glob so the group is valid now
  and picks up the root package once it lands.

Verified: `changeset status` and `changeset version` now pass config validation
(remaining non-fatal dependency warnings tracked in mdx-8je.54).

Same change as 6b28125 on worktree-wf_3d4080bf-321-16 (filed there under mdx-8je.20).

Closes mdx-8je.45

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ds (mdx-8je.1)

oauth.do's root entry ships a tsup-mangled .d.ts (`ensureLoggedIn as e`,
TS2460/TS2339 for importers) and its runtime ESM bundle does not export
ensureLoggedIn at all, so `import { ensureLoggedIn } from 'oauth.do'` was
both a type error and `undefined` at runtime. Every published 0.1.x and
0.2.x build has the same shape, so pinning cannot fix it. Only the
`oauth.do/node` subpath re-exports the symbol under its real name.

- mdxe: add src/auth.ts as the single import site (re-exports from
  oauth.do/node); commands/deploy.ts, commands/db.ts and the managed-deploy
  E2E import from it. src/auth.test.ts asserts ensureLoggedIn/getToken are
  functions so future drift fails in one place.
- @mdxe/do, @mdxe/cloudflare, @mdxe/github, @mdxe/vercel: import from
  oauth.do/node (they do not depend on mdxe); test mocks follow.
- mdxe tests/deploy-extended: mock the auth wrapper. deployViaManagedApi
  authenticates before it builds, so the spawn-mocked build tests were
  silently depending on a live auth.apis.do login.
- mdxe optional-deps.d.ts: ambient shims for @mdxe/workers/local and
  @hono/node-server, which dev-server.ts imports dynamically but mdxe never
  declares; their TS2307s were hiding behind the oauth.do error in the same
  DTS build. Tracked as mdx-nzh.

Verified: tsup build green for mdxe, @mdxe/do, @mdxe/cloudflare,
@mdxe/github, @mdxe/vercel; unit suites green (mdxe 759/762, the 3 reds are
the live-network E2E cases while auth.apis.do returns 522 - mdx-d5s).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…mdx-8je.1)

Second break in the same mdxe DTS build, hidden behind the oauth.do error and
invisible to the earlier verification: commit 7346df8 moved mdxe to
ai-functions ^2.4.0, and the 2.4.0 primitives train no longer exports RPC or
RPCPromise from ai-functions (they live in rpc.do now). src/index.ts still
re-exported both, so `tsup` failed with TS2305 on the committed lockfile.

Nothing in packages/, apps/ or examples/ imported those types via mdxe, and
mdxe does not depend on rpc.do, so the re-export is removed rather than
re-pointed (a new dependency would need a lockfile change). @mdxe/rpc has the
same stale re-export; tracked as mdx-8je.55 (model-gap).

Verified against the committed lockfile in a fresh worktree (not symlinked
node_modules): turbo build green for mdxe, @mdxe/do, @mdxe/cloudflare,
@mdxe/github, @mdxe/vercel; unit suites do 57/57, cloudflare 85/85,
github 89/89, vercel 158/158, mdxe 759/762 (3 reds = managed-deploy E2E
against auth.apis.do, still 522 - mdx-d5s).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… (mdx-8je.55)

Items 1 and 2 of mdx-8je.55 are already true on integrate/mdx-8je, which this
branch is based on: packages/@mdxe/rpc is deleted (mdx-8je.6), no source file
imports RPC / RPCPromise from ai-functions (removed-packages guard, mdx-8je.34)
and CLAUDE.md points RPC users at rpc.do.

Item 3 - verification-by-symlink resolving a different lockfile than the
committed one - gets a mechanism instead of a checkout policy: a repo guard
that reads the importers section of pnpm-lock.yaml and asserts every
primitive / .do dependency is installed under its importer at exactly the
resolved version, and that the ai-* train is one version workspace-wide.
Witnessed red with ai-functions faked at 0.4.0 under packages/mdxai, green
after pnpm install --frozen-lockfile.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…base with @mdxdb/do as primary backend (mdx-8je.11)

packages/mdxdb@2.0.0 (the npm name was never published; 1.x never existed):

- DB(schema, { url?, env?, provider? }) — synchronous facade over ai-database's
  DB(); the backend resolves lazily from DATABASE_URL (options.url, then
  env.DATABASE_URL, then process.env.DATABASE_URL, then ./content).
- parseDatabaseUrl(): do://<name>[?binding=&vectorize=&r2=] (primary, @mdxdb/do),
  sqlite://<name> (alias), ./content|file:// (@mdxdb/fs),
  clickhouse[s]://user:pass@host:port/db (@mdxdb/clickhouse HTTP),
  http(s):// (@mdxdb/api), :memory:. Unknown schemes, libsql:// and chdb://
  fail closed — never a silent memory fallback.
- DOProvider: ai-database DBProvider over an MDXDurableObject Workers RPC stub
  (typed structurally, no @mdxdb/do import). Flattens Things to
  { ...data, $id, $type }, $init(name) handshake with $id() fallback, maps DO
  errors onto EntityAlreadyExistsError/EntityNotFoundError, writes the schema's
  reverse predicate on edges so relatedBy works natively.
- ApiProvider over @mdxdb/api DBApiClient.
- withSchemaRelations(): 'Author.posts' reverse fields resolve on every backend
  (single relation fields become edges on create/update).
- mdxdb/tests: shared provider contract suite (things, listing, relationships,
  search, and the CLAUDE.md example through DB()).

Tests: 109 node (url, resolve, DO provider on an in-process fake, contract on
memory/@mdxdb/fs/fake DO, DB() facade) + 26 under @cloudflare/vitest-pool-workers
against the real @mdxdb/do MDXDurableObject in workerd, including the CLAUDE.md
"Database Interface" example verbatim. typecheck/lint/build green.

CLAUDE.md: Database Interface imports DB from 'mdxdb'; DATABASE_URL list now
matches what ships.

Model gaps filed: mdx-8je.56 (ai-database DI ignored by entity ops),
mdx-8je.57 (backref parsed without direction, DBPromise untyped getters),
mdx-8je.58 (chdb://, sqlite://path, libsql:// documented but unimplemented),
mdx-8je.59 (@mdxdb/do ships no .d.ts), mdx-8je.60 (stale mdxdb CLI references).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…(mdx-8je.7)

mdx.org.ai is Cloudflare-native only: code executes through Dynamic Worker
Loaders (workerd) in production and under Miniflare locally; Node and Bun are
thin CLI shells, never evaluation runtimes. Delete the packages that existed to
serve other deployment models and pin the surviving surface with an allowlist.

Removed (history stays in git):
- @mdxe/{node,bun,next,honox,electron,expo,remotion,slidev,vercel,github,payload}
- @mdxdb/{desktop,mobile,mongo,postgres,payload,studio,git}
- apps/desktop, apps/mobile (workspace:* consumers of electron/expo)

'?' entries decided: keep @mdxe/fumadocs (OpenNext on Workers), @mdxdb/fumadocs,
@mdxdb/github (Octokit/fetch), @mdxdb/rpc (rpc.do), @mdxdb/server (Hono),
@mdxdb/sources (until mdx-8je.17); drop @mdxdb/git (node:fs + isomorphic-git
http/node). @mdxdb/sqlite, @mdxe/cloudflare, cli-core and tui were missing from
the issue text and are kept (mdx-8je.62).

Tests first: test/repo/package-allowlist.test.ts enumerates packages/@mdxe and
packages/@mdxdb against the allowlist, asserts the removed dirs and app shells
are gone, and that no package.json or source file references a removed package.

Consumers:
- @mdxe/deploy: Platform is 'do' | 'cloudflare'; Vercel/GitHub providers,
  types, helpers and vercel.json detection removed; deps now workspace:*.
- mdxe: 'admin' command and 'db studio' gone; --platform accepts do|cloudflare;
  DeployOptions.platform / SourceTypeInfo.adapter narrowed; @mdxe/deploy is
  workspace:*; optional-deps and tsup externals trimmed.
- @mdxe/cloudflare: adapter 'do' replaces 'postgres' | 'mongo'.
- @mdxai/claude: mdxe_deploy platform enum do|cloudflare|custom.
- @mdxe/fumadocs, @mdxui/notebook: "test": "vitest run" so root pnpm test can
  terminate (mdx-8je.61).
- Docs, READMEs, CLAUDE.md, ROADMAP, ECOSYSTEM, publish scripts, apps/docs
  .source, readme-taxonomy guard updated; pnpm-lock trimmed (-14k lines).

Changeset: major for mdxe, @mdxe/deploy, @mdxe/cloudflare; minor @mdxai/claude.
npm deprecations for the 4 published packages are tracked in mdx-8je.64 (the
local npm token is 401).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…te/mdx-8je

Adds test/repo/lockfile-drift.test.ts: every primitive / .do dependency in
pnpm-lock.yaml importers must be installed under its importer at exactly the
resolved version, and the ai-* train must be one version workspace-wide.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@nathanclevenger nathanclevenger changed the title integrate(mdx-8je): rounds 1-4 - build green groundwork, primitives from npm, sqlite pools + Worker Loader witness, mdxe CLI + @mdxe/cli-core leaf, @mdxe/tui seam + Ink 7 viewer, ai-evaluate in @mdxe/vitest, repo guards, RPC home in rpc.do, oauth.do wrapper integrate(mdx-8je): rounds 1-5 - build green groundwork, primitives from npm, sqlite pools + Worker Loader witness, mdxe CLI + @mdxe/cli-core leaf, @mdxe/tui seam + Ink 7 viewer, ai-evaluate in @mdxe/vitest, repo guards incl. lockfile-drift, RPC home in rpc.do, oauth.do wrapper Sep 8, 2026
nathanclevenger and others added 16 commits September 8, 2026 14:30
…ient (mdx-8je.60)

mdxdb 2.0 is a DB() facade library; it has no src/cli.ts, no DBClient, and no
Database/NotFoundError/createDB/createApiClient exports. Bring the automation
and docs in line with what actually ships:

- .github/workflows/mdxdb-release.yml: deleted. It ran `bun build src/cli.ts
  --compile` in packages/mdxdb and published GitHub-release binaries; tagging
  mdxdb-v* would run red. Nothing links to it.
- .github/workflows/mdxe-release.yml: release notes no longer claim a bundled
  "mdxdb CLI".
- package.json `studio`: retargeted from the non-existent
  packages/mdxdb/dist/cli.js to @mdxdb/studio's real bin (dist/cli.js --path).
- docs/(Structured Data)/mdxdb/{getting-started,adapters/index}.mdx: the
  document-level Database interface and its option/result types come from
  the adapters (@mdxdb/fs); `mdxdb` is documented as the DB() facade. Error
  handling now matches reality: get() returns null on both surfaces, and the
  facade throws EntityNotFoundError/DatabaseError from writes.
- examples/docs.buildercss.dev/views/editor.mdx, packages/mdxe/ECOSYSTEM.md,
  packages/@mdxdb/fumadocs/README.md: samples use DB() / @mdxdb/api.

vitest.setup.ts (MemoryDBClient/DBClient imports) is intentionally left to
mdx-8je.39, which owns the root MDX test harness.

Verified: package.json parses, mdxe-release.yml parses as YAML, the three
changed .mdx files compile with @mdx-js/mdx 3.1.1, and every remaining
`from 'mdxdb'` import names an export in packages/mdxdb/src/index.ts (877abc3).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…built (mdx-8je.62)

The mdx-8je.7 issue text listed @mdxdb as "do, vectorize, parquet, clickhouse,
fs, git?, github?, api, rpc?, server?, sources" and @mdxe without cloudflare,
cli-core or tui, while mdx-8je.5/.19/.22/.23/.24 built @mdxdb/sqlite,
mdx-8je.26 built @mdxe/cli-core, mdx-8je.13 built @mdxe/tui and @mdxe/deploy
needs @mdxe/cloudflare. The allowlist file is now the source of truth: every
entry is tagged ISSUE / '?' / SIBLING with the reason it stays, the four '?'
entries are decided (git DROP; github, rpc, server, fumadocs KEEP; sources KEEP
until mdx-8je.17), and the "rpc-via-ai-functions" line is recorded as
deliberately not a directory (rpc.do; test/repo/rpc-home.test.ts).

Guard the reverse direction too: an allowlisted entry with no package.json on
disk fails unless it is in PENDING with the issue that creates it
(@mdxe/opentui -> mdx-8je.15); PENDING must itself be a subset of ALLOWED and
not yet exist; ALLOWED and REMOVED_PACKAGES must be disjoint. Witnessed red on
a stale entry, green on the tree. Prettier-formatted (the file was already
non-conforming).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…o integrate/mdx-8je

# Conflicts:
#	packages/mdxe/src/index.ts
… into integrate/mdx-8je

# Conflicts:
#	packages/mdxe/README.md
#	packages/mdxe/src/index.ts
… into integrate/mdx-8je

# Conflicts:
#	package.json
…e.11 and mdx-8je.7

pnpm install --frozen-lockfile failed after the merges because the mdxdb root
package's importer was missing (its branch conflicted with the prune's lockfile
and HEAD's was kept). Regenerated with pnpm install; the only change is the
added importer, no resolved-package churn.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The merge of worktree-wf_3d4080bf-321-2 kept a comment naming the removed
RPC promise type verbatim, which test/repo/removed-packages.test.ts forbids
in packages/mdxe/src/index.ts.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The brace glob was a workaround from before packages/mdxdb existed
(mdx-8je.45 predates mdx-8je.11). Same match set; changeset status unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
mdx-8je.7 narrowed DeployOptions.platform to 'do' | 'cloudflare' | 'custom'
and the CLI to 'do' | 'cloudflare', but src/schemas.ts still accepted
vercel/github/netlify (and DeployOptionsSchema rejected 'do'). Align both
enums, pin the rejection in validation.test.ts, drop the cli.test.ts case that
cast 'vercel' to 'do', and remove the dead 'ai-functions' tsup external.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ate/mdx-8je

# Conflicts:
#	packages/@mdxdb/sqlite/src/client.ts
…h report field

- mdxdb resolve.ts mapped any error whose message contained 'not found' to
  AdapterNotInstalledError, which would mislabel an installed adapter's own
  init failure. Match only module-resolution errors (code or message).
- @mdxe/tui BenchmarkReport gains an optional installPackages so @mdxe/ink's
  bench no longer smuggles it through a cast.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@nathanclevenger nathanclevenger changed the title integrate(mdx-8je): rounds 1-5 - build green groundwork, primitives from npm, sqlite pools + Worker Loader witness, mdxe CLI + @mdxe/cli-core leaf, @mdxe/tui seam + Ink 7 viewer, ai-evaluate in @mdxe/vitest, repo guards incl. lockfile-drift, RPC home in rpc.do, oauth.do wrapper integrate(mdx-8je): Cloudflare-native kernel round 1 — prune to workerd-only, mdxdb root, @mdxe/cli-core + @mdxe/tui seam, sqlite pools + $init, mdxld 1.9.2 alias release Sep 9, 2026
@nathanclevenger
nathanclevenger merged commit c00e323 into main Sep 9, 2026
1 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant