-
Notifications
You must be signed in to change notification settings - Fork 1.5k
chore: effect rpc and layer based startup #929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
68 commits
Select commit
Hold shift + click to select a range
8e16684
add reference
juliusmarminge 98289a2
remove test file for now
juliusmarminge 7b78c42
remove another test file that just trips the model up
juliusmarminge 61a365a
mirror setup
juliusmarminge ae2651f
setup http router
juliusmarminge 29fee97
wire in http routes
juliusmarminge 63c7cee
start wiring in rpc
juliusmarminge aa34e66
add test
juliusmarminge 75e8170
plan out remaining ports
juliusmarminge 9c3a40d
wire up keybindings
juliusmarminge a5ebd0c
searchEntries
juliusmarminge 70f7adb
finihs phase 2
juliusmarminge 89fc5c1
phase 3 - git - complete
juliusmarminge 0ca441f
phase 4 complete
juliusmarminge 9e3677e
phase 5
juliusmarminge d984557
prune unused stuff from wsServer.ts
juliusmarminge 84c6b51
add schemas for streaming rpcs
juliusmarminge 95650de
streaming server config
juliusmarminge c0788c0
remaining
juliusmarminge 7d73b72
type
juliusmarminge 8ea82bc
client
juliusmarminge 80b42f5
Derive server paths from base dir and unify platform layers
juliusmarminge 6295ae6
kewl
juliusmarminge 864c936
rm reference
juliusmarminge 35561a0
stale plan
juliusmarminge eb8ee3f
Merge origin/main into effect-http-router
juliusmarminge ee67778
fix stm and sqlite
juliusmarminge b6105c8
Merge origin/main into effect-http-router
juliusmarminge ec4226e
mv helper
juliusmarminge d190fdb
Merge origin/main into effect-http-router
juliusmarminge dbdc2bf
Use callback queue for terminal event streaming
juliusmarminge 6502a6c
Merge origin/main into effect-http-router
juliusmarminge b65e74d
Fix RPC browser test websocket mocks
juliusmarminge 0f48b4f
Use Effect RPC in browser test mocks
juliusmarminge 1cf79b5
bump
juliusmarminge d59a554
merge
juliusmarminge b6771ca
Move git error types to contracts
juliusmarminge 849a39c
rm reexport shim
juliusmarminge 1f1a3dd
Add bootstrap envelope config precedence
juliusmarminge f9b0f14
kewl
juliusmarminge 7c692d4
Refactor ServerSettings imports and remove unused error handling
juliusmarminge 0ba3f29
tidy up
juliusmarminge dd44ef0
rm
juliusmarminge 3656164
rev bun a bit
juliusmarminge fe8ba96
cool
juliusmarminge a3a4a22
Refactor websocket native API around typed RPC client
juliusmarminge 6cb183f
Move server config state to ws native atoms
juliusmarminge b636da5
runtime
juliusmarminge 5ea99a6
make dir
juliusmarminge 7d7c587
rm unnecessary test
juliusmarminge d7ec9d6
Unify project favicon routing and server setup
juliusmarminge f306805
Restore rich error message context in git error classes
cursoragent 6dcc05c
Merge origin/main into effect-http-router
juliusmarminge 6ee71f3
Merge remote-tracking branch 'origin/effect-http-router' into effect-…
juliusmarminge dfeb214
cleanup
juliusmarminge fe22173
rm more unused cruft
juliusmarminge 7b4bbd0
not that either
juliusmarminge 92f3f08
Normalize workspace paths and inline favicon fallback
juliusmarminge d628d39
Stream git stacked actions over RPC
juliusmarminge 8a403cc
move test helper
juliusmarminge 44adfc7
Format web tsconfig to match JSON style
juliusmarminge adc1619
Refactor WS contracts into rpc module
juliusmarminge cce11f0
Introduce AtomRpc client for websocket RPC
juliusmarminge 3142a92
Move server state handling into RPC layer
juliusmarminge b858ced
Merge origin/main into effect-http-router
juliusmarminge 0a353d1
Switch WebSocket RPC to secure URLs and await teardown
juliusmarminge 176a58b
Fix WsTransport dispose ordering test
juliusmarminge 0bb9550
log
juliusmarminge File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| # Replace React Query With AtomRpc + Atom State | ||
|
|
||
| ## Summary | ||
| - Use `effect/unstable/reactivity/AtomRpc` over the existing `WsRpcGroup`; stop wrapping RPC in promises via [wsRpcClient.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsRpcClient.ts) and [wsNativeApi.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApi.ts). | ||
| - Keep Zustand for orchestration read model and UI state. | ||
| - Keep a narrow `desktopBridge` adapter for dialogs, menus, external links, theme, and updater APIs. | ||
| - Do not introduce Suspense in this migration. Atom-backed hooks should keep returning `data`, `error`, `isLoading|isPending`, `refresh`, and `mutateAsync`-style surfaces so component churn stays low. | ||
|
|
||
| ## Target Architecture | ||
| - Extract the websocket `RpcClient.Protocol` layer from [wsTransport.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsTransport.ts) into `rpc/protocol.ts`. | ||
| - Define one `AtomRpc.Service` for `WsRpcGroup` in `rpc/client.ts`. | ||
| - Add `rpc/invalidation.ts` with explicit scoped invalidation keys: `git:${cwd}`, `project:${cwd}`, `checkpoint:${threadId}`, `server-config`. | ||
| - Add `platform/desktopBridge.ts` as the only browser/desktop facade. | ||
| - Remove from web by the end: [wsNativeApi.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApi.ts), [nativeApi.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/nativeApi.ts), [wsNativeApiState.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApiState.ts), [wsNativeApiAtoms.tsx](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApiAtoms.tsx), [wsRpcClient.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsRpcClient.ts), and all `*ReactQuery.ts` modules. | ||
|
|
||
| ## Phase 1: Infrastructure First | ||
| 1. Extract the shared websocket RPC protocol layer from [wsTransport.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsTransport.ts) without changing behavior. | ||
| 2. Build the AtomRpc client on top of that layer. | ||
| 3. Add one temporary `runRpc` helper for imperative handlers that still want `Promise` ergonomics; it must call the AtomRpc service directly and must not reintroduce a facade object. | ||
| 4. Replace manual registry wiring with one app-level registry provider based on `@effect/atom-react`. | ||
| 5. Land this as a no-behavior-change PR. | ||
|
|
||
| ## Phase 2: Replace `wsNativeApi`-Owned Push State | ||
| 1. Migrate welcome/config/provider/settings state first, because it is already atom-shaped and is the lowest-risk way to delete `wsNativeApi` responsibilities. | ||
| 2. Replace [wsNativeApiState.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApiState.ts) with `rpc/serverState.ts`, updated directly from `subscribeServerLifecycle` and `subscribeServerConfig`. | ||
| 3. Keep the current hook names for one PR: `useServerConfig`, `useServerSettings`, `useServerProviders`, `useServerKeybindings`, `useServerWelcomeSubscription`, `useServerConfigUpdatedSubscription`. | ||
| 4. Move bootstrap side effects out of [wsNativeApiAtoms.tsx](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApiAtoms.tsx) into a new root bootstrap component mounted from [__root.tsx](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/routes/__root.tsx). | ||
| 5. Delete the `server.getConfig()` fallback logic from [wsNativeApi.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApi.ts); snapshot fetch now lives beside the stream atoms. | ||
|
|
||
| ## Phase 3: Replace React Query Domain By Domain | ||
| 1. Replace [gitReactQuery.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/lib/gitReactQuery.ts) first. | ||
| 2. Add `rpc/gitAtoms.ts` and `rpc/useGit.ts` with `useGitStatus`, `useGitBranches`, `useResolvePullRequest`, and `useGitMutation`. | ||
| 3. Mutation settlement must invalidate scoped keys, not a global cache. `checkout`, `pull`, `init`, `createWorktree`, `removeWorktree`, `preparePullRequestThread`, and stacked actions invalidate `git:${cwd}`. Worktree create/remove also invalidates `project:${cwd}`. | ||
| 4. Replace [projectReactQuery.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/lib/projectReactQuery.ts) second. `useProjectSearchEntries` must preserve current “keep previous results while loading” behavior. | ||
| 5. Replace [providerReactQuery.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/lib/providerReactQuery.ts) third. Preserve current checkpoint error normalization and retry/backoff semantics inside the atom effect. Invalidate by `checkpoint:${threadId}`. | ||
| 6. Defer the desktop updater until the last phase. | ||
|
|
||
| ## Phase 4: Move Root Invalidation Off `queryClient` | ||
| 1. In [__root.tsx](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/routes/__root.tsx), remove `QueryClient` usage and replace the throttled `invalidateQueries` block with throttled invalidation helpers. | ||
| 2. Keep Zustand orchestration/event application unchanged. | ||
| 3. Map current effects exactly: | ||
| - git or checkpoint-affecting orchestration events touch `checkpoint:${threadId}` | ||
| - file creation/deletion/restoration touches `project:${cwd}` | ||
| - config-affecting server events touch `server-config` | ||
|
|
||
| ## Phase 5: Remove Imperative `NativeApi` Usage | ||
| 1. Create narrow modules instead of a replacement mega-facade: | ||
| - `rpc/orchestrationActions.ts` | ||
| - `rpc/terminalActions.ts` | ||
| - `rpc/gitActions.ts` | ||
| - `rpc/projectActions.ts` | ||
| - `platform/desktopBridge.ts` | ||
| 2. Migrate direct [nativeApi.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/nativeApi.ts) callers by domain, not file-by-file: git-heavy components first, then orchestration/thread actions, then shell/dialog helpers. | ||
| 3. After the last caller is gone, delete [nativeApi.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/nativeApi.ts) and the `window.nativeApi` fallback entirely. | ||
| 4. In the final cleanup PR, remove `NativeApi` from [ipc.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/packages/contracts/src/ipc.ts) if nothing outside web still needs it. | ||
|
|
||
| ## Phase 6: Remove React Query Completely | ||
| 1. Delete `@tanstack/react-query` from `apps/web/package.json`. | ||
| 2. Remove `QueryClientProvider` and router context from [router.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/router.ts) and [__root.tsx](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/routes/__root.tsx). | ||
| 3. Replace [desktopUpdateReactQuery.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/lib/desktopUpdateReactQuery.ts) with a writable atom plus `desktopBridge.onUpdateState`. | ||
| 4. Delete the old query-option tests. | ||
|
|
||
| ## Public Interfaces And Types | ||
| - Preserve the current server-state hook names during the transition. | ||
| - Add permanent domain hooks: `useGitStatus`, `useGitBranches`, `useResolvePullRequest`, `useProjectSearchEntries`, `useCheckpointDiff`, `useDesktopUpdateState`. | ||
| - Do not expose raw AtomRpc clients to components. | ||
| - Do not add Suspense as part of this migration. | ||
| - Final boundary is direct RPC for server features plus `desktopBridge` for local desktop features. | ||
|
|
||
| ## Test Plan | ||
| - Add unit tests for `rpc/serverState.ts`: snapshot bootstrapping, stream replay, provider/settings updates. | ||
| - Add unit tests for git/project/checkpoint hooks: loading, error mapping, retry behavior, invalidation, keep-previous-result behavior. | ||
| - Update the browser harness in [wsRpcHarness.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/test/wsRpcHarness.ts) to assert direct RPC + atom behavior instead of `__resetNativeApiForTests`. | ||
| - Replace [wsNativeApi.test.ts](/Users/julius/.t3/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApi.test.ts), `gitReactQuery.test.ts`, `providerReactQuery.test.ts`, and `desktopUpdateReactQuery.test.ts` with equivalent atom-backed coverage. | ||
| - Acceptance scenarios: | ||
| - welcome still bootstraps snapshot and navigation | ||
| - keybindings toast still responds to config stream updates | ||
| - git status/branches refresh after checkout/pull/worktree actions | ||
| - PR resolve dialog keeps cached result while typing | ||
| - `@` path search refreshes after file mutations and orchestration events | ||
| - diff panel refreshes when checkpoints arrive | ||
| - desktop updater still reflects push events and button actions | ||
|
|
||
| ## Assumptions And Defaults | ||
| - Zustand stays in scope; only `react-query` is being removed. | ||
| - `desktopBridge` remains the only non-RPC boundary. | ||
| - The migration lands as 5-6 small PRs, each green independently. | ||
| - Invalidations are explicit and scoped; do not recreate a global cache client abstraction. | ||
| - Orchestration recovery/order logic stays as-is; only the data-fetching and mutation layer changes. | ||
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
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
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import * as NodeRuntime from "@effect/platform-node/NodeRuntime"; | ||
| import * as NodeServices from "@effect/platform-node/NodeServices"; | ||
| import * as Effect from "effect/Effect"; | ||
| import * as Layer from "effect/Layer"; | ||
| import { Command } from "effect/unstable/cli"; | ||
|
|
||
| import { NetService } from "@t3tools/shared/Net"; | ||
| import { cli } from "./cli"; | ||
| import { version } from "../package.json" with { type: "json" }; | ||
|
|
||
| const CliRuntimeLayer = Layer.mergeAll(NodeServices.layer, NetService.layer); | ||
|
|
||
| Command.run(cli, { version }).pipe( | ||
| Effect.scoped, | ||
| Effect.provide(CliRuntimeLayer), | ||
| NodeRuntime.runMain, | ||
| ); |
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.