diff --git a/.cursor/rules/cursor-cloud.mdc b/.cursor/rules/cursor-cloud.mdc index 98fcb1d5766..d3dd3ee7f21 100644 --- a/.cursor/rules/cursor-cloud.mdc +++ b/.cursor/rules/cursor-cloud.mdc @@ -1,11 +1,11 @@ --- -description: Cursor Cloud environment setup and run notes for T3 Code (Cursor-specific; not for other editors/CI) +description: Cursor Cloud environment setup and run notes for V12 (Cursor-specific; not for other editors/CI) alwaysApply: true --- # Cursor Cloud specific instructions -These notes apply only to Cursor Cloud agents (kept out of the shared `AGENTS.md` since T3 Code is +These notes apply only to Cursor Cloud agents (kept out of the shared `AGENTS.md` since V12 is developed in many places). They cover the pre-provisioned VM environment and non-obvious run caveats. ## Toolchain @@ -28,7 +28,7 @@ Pre-installed and wired into login shells (`~/.bashrc`/`~/.profile`): Node 24 (v the next free pair, so read the actual ports from stdout. Avoid production `build`/`start` in dev. - Auth/pairing: the server is unauthenticated by default and prints a pairing URL to stdout on startup (e.g. `http://localhost:5733/pair#token=XXXX`). Open that URL in the browser to pair before the web - UI can talk to the server. Server state (SQLite, auth, projects) lives under `~/.t3` + UI can talk to the server. Server state (SQLite, auth, projects) lives under `~/.v12` (`T3CODE_HOME`); multiple `npm run dev` instances bind different ports but share that same DB. - Agent providers are external CLIs (`codex`, `claude`, `cursor-agent`, `opencode`) probed on `PATH`. Without one installed the UI loads but no agent can run. Claude Code diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index cc1f11cd8ba..627a88025b9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "T3 Code Dev", + "name": "V12 Dev", "image": "debian:bookworm", "features": { "ghcr.io/devcontainers/features/git:1": {}, diff --git a/.env.example b/.env.example index 79b2adaf0c8..2d5c8fc877d 100644 --- a/.env.example +++ b/.env.example @@ -1,24 +1,24 @@ -# Optional: T3 Connect source builds -# Leave these unset to disable optional T3 Connect features in local source builds. +# Optional: V12 Connect source builds +# Leave these unset to disable optional V12 Connect features in local source builds. # Release builds inject their public values at build time. Do not add server-side # secrets to this file. # Get these from the Clerk Dashboard under API keys, JWT templates, and OAuth applications. -# T3CODE_CLERK_PUBLISHABLE_KEY=pk_test_... -# T3CODE_CLERK_JWT_TEMPLATE=t3-relay -# T3CODE_CLERK_CLI_OAUTH_CLIENT_ID=oauthapp_... +# V12_CLERK_PUBLISHABLE_KEY=pk_test_... +# V12_CLERK_JWT_TEMPLATE=v12-relay +# V12_CLERK_CLI_OAUTH_CLIENT_ID=oauthapp_... # Optional: signed macOS passkey builds. The RP domain defaults to the Frontend API -# hostname encoded in T3CODE_CLERK_PUBLISHABLE_KEY. Set the override only when Clerk +# hostname encoded in V12_CLERK_PUBLISHABLE_KEY. Set the override only when Clerk # returns a different RP ID or when multiple domains must be entitled. -# T3CODE_APPLE_TEAM_ID=ABC1234567 -# T3CODE_MACOS_PROVISIONING_PROFILE=/absolute/path/to/t3code.provisionprofile -# T3CODE_CLERK_PASSKEY_RP_DOMAINS=example.clerk.accounts.dev,clerk.example.com +# V12_APPLE_TEAM_ID=ABC1234567 +# V12_MACOS_PROVISIONING_PROFILE=/absolute/path/to/v12.provisionprofile +# V12_CLERK_PASSKEY_RP_DOMAINS=example.clerk.accounts.dev,clerk.example.com # Get this from your relay deployment. `infra/relay` deploys update it automatically. -# T3CODE_RELAY_URL=https://relay.example.com +# V12_RELAY_URL=https://relay.example.com # Public, ingest-only mobile OpenTelemetry configuration. -# T3CODE_MOBILE_OTLP_TRACES_URL=https://api.axiom.co/v1/traces -# T3CODE_MOBILE_OTLP_TRACES_DATASET=t3-code-mobile-traces-dev -# T3CODE_MOBILE_OTLP_TRACES_TOKEN=xaat-... +# V12_MOBILE_OTLP_TRACES_URL=https://api.axiom.co/v1/traces +# V12_MOBILE_OTLP_TRACES_DATASET=v12-mobile-traces-dev +# V12_MOBILE_OTLP_TRACES_TOKEN=xaat-... diff --git a/.github/VOUCHED.td b/.github/VOUCHED.td index 73376110d9a..8866c94dd18 100644 --- a/.github/VOUCHED.td +++ b/.github/VOUCHED.td @@ -8,28 +8,5 @@ # github:username # -github:username reason for denouncement # -# Keep entries sorted alphabetically. -github:adityavardhansharma -github:binbandit -github:chuks-qua -github:cursoragent -github:gbarros-dev -github:github-actions[bot] -github:hwanseoc -github:jamesx0416 -github:jasonLaster -github:JoeEverest -github:maria-rcks -github:nmggithub -github:Noojuno -github:notkainoa -github:PatrickBauer -github:realAhmedRoach -github:shiroyasha9 -github:Yash-Singh1 -github:eggfriedrice24 -github:Ymit24 -github:shivamhwp -github:jappyjan -github:justsomelegs -github:UtkarshUsername +# Keep entries sorted alphabetically. This fork intentionally starts with no +# inherited external trust entries; collaborators are trusted automatically. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 76aac7e4d85..9085d7765e3 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,16 +1,3 @@ - - ## What Changed @@ -19,6 +6,10 @@ we may close it without merging it, or never review it. +## Validation + + + ## UI Changes Frontend : websocket accepted ``` -### `npx t3` user +### `npx v12` user This is the standalone local server flow. @@ -579,7 +579,7 @@ There is no trusted desktop shell here, so pairing should be explicit. ```text Participants: - UserShell = npx t3 launcher + UserShell = npx v12 launcher T3Server = standalone local server Browser = browser tab @@ -619,12 +619,12 @@ Participants: DesktopUser = user at the host machine DesktopMain = desktop app Tunnel = tunnel provider - T3Server = T3 server + T3Server = V12 server PhoneBrowser = mobile browser DesktopUser -> DesktopMain : enable remote access via tunnel DesktopMain -> T3Server : switch policy to RemoteReachablePolicy -DesktopMain -> Tunnel : publish local T3 endpoint +DesktopMain -> Tunnel : publish local V12 endpoint Tunnel --> DesktopMain : public https/wss URL DesktopMain -> T3Server : issue one-time pairing token @@ -653,7 +653,7 @@ The auth flow should stay the same. ```text Participants: DesktopUser = user at the host machine - T3Server = T3 server + T3Server = V12 server PrivateNet = tailscale / private LAN PhoneBrowser = mobile browser @@ -687,14 +687,14 @@ Participants: DesktopMain = desktop app SSH = ssh transport/session RemoteHost = remote machine - RemoteT3 = remote T3 server + RemoteT3 = remote V12 server Frontend = desktop renderer DesktopUser -> DesktopMain : add SSH host DesktopMain -> SSH : connect to remote host -SSH -> RemoteHost : probe environment / verify t3 availability +SSH -> RemoteHost : probe environment / verify v12 availability DesktopMain -> SSH : run remote launch command -SSH -> RemoteHost : t3 remote launch --json +SSH -> RemoteHost : v12 remote launch --json RemoteHost -> RemoteT3 : start or reuse server RemoteT3 --> RemoteHost : port + environment metadata RemoteHost --> SSH : launch result JSON @@ -779,7 +779,7 @@ Remote access is one reason this auth model matters, but the auth model should n Keep the design focused on: -- one T3 server +- one V12 server - one auth policy - multiple credential types - multiple future access methods diff --git a/.plans/19-remote-endpoints-hosted-static.md b/.plans/19-remote-endpoints-hosted-static.md index ada2f681ce4..5d04d416bbb 100644 --- a/.plans/19-remote-endpoints-hosted-static.md +++ b/.plans/19-remote-endpoints-hosted-static.md @@ -6,12 +6,12 @@ Make remote access feel first-class while keeping the free DIY path open. The immediate product goal is: -- users can expose a backend through LAN, their own Tailscale, MagicDNS, a manual HTTPS endpoint, or later T3 Tunnel -- users can generate a hosted pairing link for `app.t3.codes` +- users can expose a backend through LAN, their own Tailscale, MagicDNS, a manual HTTPS endpoint, or later V12 Tunnel +- users can generate a hosted pairing link for `app.v12.codes` - the hosted app can pair, persist, reconnect, and operate against saved environments without requiring a backend at the hosted app origin - all transports reuse the same backend auth, WebSocket runtime, saved environment registry, and pairing UX -This plan intentionally leaves the paid T3 cloud tunnel fabric out of scope. It defines the OSS foundation that T3 Tunnel should later plug into. +This plan intentionally leaves the paid V12 cloud tunnel fabric out of scope. It defines the OSS foundation that V12 Tunnel should later plug into. ## Current State @@ -58,7 +58,7 @@ Examples: - Tailscale IP URL - MagicDNS/Serve URL - manual URL -- future T3 Tunnel URL +- future V12 Tunnel URL - browser compatibility and exposure level Those are different lifecycles. One environment can have many endpoints, endpoints can appear/disappear as network interfaces change, and the same descriptor is returned regardless of which endpoint the client used. Extending the descriptor would blur environment identity with transport reachability and make saved environments harder to reason about. @@ -74,7 +74,7 @@ type AdvertisedEndpointProvider = | "tailscale-ip" | "tailscale-magicdns" | "manual" - | "t3-tunnel"; + | "v12-tunnel"; type AdvertisedEndpointVisibility = "local" | "private-network" | "tailnet" | "public"; @@ -113,7 +113,7 @@ What is ready: What is not solved by code alone: -- `https://app.t3.codes` cannot reliably call `http://...` or `ws://...` endpoints because browsers block mixed content. +- `https://app.v12.codes` cannot reliably call `http://...` or `ws://...` endpoints because browsers block mixed content. - `wss://100.x.y.z:3773` needs a certificate the browser trusts. A raw Tailscale IP does not solve certificate trust. - LAN `http://192.168.x.y:3773` is usable from another desktop/native context but not from the hosted HTTPS app. - The UI needs to explain why an endpoint is copyable for desktop pairing but not hosted-app compatible. @@ -122,7 +122,7 @@ Policy: - Support both HTTP/WS and HTTPS/WSS at the runtime layer. - Mark endpoint compatibility at the product layer. -- Generate `app.t3.codes` links only from endpoints that are likely hosted-browser compatible, or show a warning with an explicit fallback. +- Generate `app.v12.codes` links only from endpoints that are likely hosted-browser compatible, or show a warning with an explicit fallback. ## Architecture @@ -146,7 +146,7 @@ Endpoint records can come from several providers: - hidden/disabled endpoints 4. **Future cloud provider** - - T3 Tunnel endpoint + - V12 Tunnel endpoint - billing/account status - tunnel lifecycle state @@ -176,7 +176,7 @@ buildHostedPairingUrl({ Generated URL: ```text -https://app.t3.codes/pair?host=#token= +https://app.v12.codes/pair?host=#token= ``` Use fragment tokens by default. Continue accepting `?token=` for compatibility. @@ -218,7 +218,7 @@ Use fragment tokens by default. Continue accepting `?token=` for compatibility. - Existing LAN/network access UI still works. - Pairing links are generated from endpoint records. - Loopback endpoints never produce hosted pairing links silently. -- HTTP private-network endpoints are marked incompatible with `app.t3.codes`. +- HTTP private-network endpoints are marked incompatible with `app.v12.codes`. - No remote environment runtime changes are required for existing saved environments. ## Phase 2: BYO Tailscale/MagicDNS @@ -262,7 +262,7 @@ Use fragment tokens by default. Continue accepting `?token=` for compatibility. ### Goals -- `app.t3.codes` works as a real client shell. +- `app.v12.codes` works as a real client shell. - It can pair, persist, reconnect, and clearly explain offline/incompatible states. ### Tasks @@ -306,25 +306,25 @@ Use fragment tokens by default. Continue accepting `?token=` for compatibility. ### Acceptance Criteria -- `app.t3.codes` can pair a reachable HTTPS backend and reconnect after reload. -- A saved environment can be used without any backend at `app.t3.codes`. +- `app.v12.codes` can pair a reachable HTTPS backend and reconnect after reload. +- A saved environment can be used without any backend at `app.v12.codes`. - Offline machines show a useful state instead of a generic boot error. - HTTP endpoints are still supported in desktop/native/local contexts. - Hosted HTTPS app only promises compatibility for HTTPS/WSS endpoints. -## Phase 4: Future T3 Tunnel Provider +## Phase 4: Future V12 Tunnel Provider Not part of the current implementation, but the endpoint abstraction should make it straightforward. Future tunnel provider responsibilities: -- create endpoint with `provider: "t3-tunnel"` +- create endpoint with `provider: "v12-tunnel"` - surface tunnel status - provide stable HTTPS URL - use existing backend pairing/session auth - never bypass server auth -The tunnel fabric can later be Pipenet-derived, Tailscale-derived, or another reverse tunnel implementation. The rest of T3 Code should only see an `AdvertisedEndpoint`. +The tunnel fabric can later be Pipenet-derived, Tailscale-derived, or another reverse tunnel implementation. The rest of V12 should only see an `AdvertisedEndpoint`. ## Security Checklist diff --git a/.plans/19-version-control-phase-1-vcs-driver-foundation.md b/.plans/19-version-control-phase-1-vcs-driver-foundation.md index e71c22d0ce3..f6fe84fb6bd 100644 --- a/.plans/19-version-control-phase-1-vcs-driver-foundation.md +++ b/.plans/19-version-control-phase-1-vcs-driver-foundation.md @@ -24,7 +24,7 @@ The existing `GitCore` implementation is a behavior reference and source of regr - No GitLab, Azure DevOps, or GitHub provider rewrite yet. - No Jujutsu driver yet, but every interface must be designed so a Jujutsu driver does not have to pretend to be Git. -- No T3 Review implementation yet. +- No V12 Review implementation yet. - No broad UI redesign. ## Driver Model diff --git a/.plans/20-version-control-phase-2-source-control-provider-foundation.md b/.plans/20-version-control-phase-2-source-control-provider-foundation.md index ac1186ba5f9..78903048e86 100644 --- a/.plans/20-version-control-phase-2-source-control-provider-foundation.md +++ b/.plans/20-version-control-phase-2-source-control-provider-foundation.md @@ -123,7 +123,7 @@ Use Effect `Cache` for provider data: - repository metadata/default branch: key by provider repository stable ID or normalized remote URL; TTL around tens of minutes - change-request summary lists: key by provider repository, state/filter, source ref, target ref; short TTL with stale-while-revalidate - individual change-request summaries: key by provider repository and provider CR ID; short TTL, invalidated after create/update/comment operations -- review threads/comments/diffs: key by provider CR ID and head SHA/version when available; fetch on demand for T3 Review +- review threads/comments/diffs: key by provider CR ID and head SHA/version when available; fetch on demand for V12 Review Provider drivers should surface rate-limit signals when available: @@ -210,7 +210,7 @@ The abstraction should let Phase 3 add: No provider should need to edit GitHub code to join the registry. -## T3 Review Design Constraint +## V12 Review Design Constraint Do not optimize only for creation/checkout. The provider layer must be able to support a future in-app review surface. @@ -264,5 +264,5 @@ Required cases: - GitHub command execution does not depend on `processRunner.ts`. - Background provider reads are cached/coalesced and do not consume provider API quota on every status refresh. - Rate-limit responses become typed errors with retry/reset metadata where available. -- The provider API includes the review operations needed by future T3 Review work, even if they are capability-gated. +- The provider API includes the review operations needed by future V12 Review work, even if they are capability-gated. - `bun fmt`, `bun lint`, and `bun typecheck` pass. diff --git a/.plans/effect-atom.md b/.plans/effect-atom.md index ff6894f5637..5f12cd5663c 100644 --- a/.plans/effect-atom.md +++ b/.plans/effect-atom.md @@ -1,20 +1,20 @@ # 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). +- Use `effect/unstable/reactivity/AtomRpc` over the existing `WsRpcGroup`; stop wrapping RPC in promises via [wsRpcClient.ts](/Users/julius/.v12/worktrees/codething-mvp/effect-http-router/apps/web/src/wsRpcClient.ts) and [wsNativeApi.ts](/Users/julius/.v12/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`. +- Extract the websocket `RpcClient.Protocol` layer from [wsTransport.ts](/Users/julius/.v12/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. +- Remove from web by the end: [wsNativeApi.ts](/Users/julius/.v12/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApi.ts), [nativeApi.ts](/Users/julius/.v12/worktrees/codething-mvp/effect-http-router/apps/web/src/nativeApi.ts), [wsNativeApiState.ts](/Users/julius/.v12/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApiState.ts), [wsNativeApiAtoms.tsx](/Users/julius/.v12/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApiAtoms.tsx), [wsRpcClient.ts](/Users/julius/.v12/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. +1. Extract the shared websocket RPC protocol layer from [wsTransport.ts](/Users/julius/.v12/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`. @@ -22,21 +22,21 @@ ## 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`. +2. Replace [wsNativeApiState.ts](/Users/julius/.v12/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. +4. Move bootstrap side effects out of [wsNativeApiAtoms.tsx](/Users/julius/.v12/worktrees/codething-mvp/effect-http-router/apps/web/src/wsNativeApiAtoms.tsx) into a new root bootstrap component mounted from [__root.tsx](/Users/julius/.v12/worktrees/codething-mvp/effect-http-router/apps/web/src/routes/__root.tsx). +5. Delete the `server.getConfig()` fallback logic from [wsNativeApi.ts](/Users/julius/.v12/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. +1. Replace [gitReactQuery.ts](/Users/julius/.v12/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}`. +4. Replace [projectReactQuery.ts](/Users/julius/.v12/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/.v12/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. +1. In [__root.tsx](/Users/julius/.v12/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}` @@ -50,14 +50,14 @@ - `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. +2. Migrate direct [nativeApi.ts](/Users/julius/.v12/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/.v12/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/.v12/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`. +2. Remove `QueryClientProvider` and router context from [router.ts](/Users/julius/.v12/worktrees/codething-mvp/effect-http-router/apps/web/src/router.ts) and [__root.tsx](/Users/julius/.v12/worktrees/codething-mvp/effect-http-router/apps/web/src/routes/__root.tsx). +3. Replace [desktopUpdateReactQuery.ts](/Users/julius/.v12/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 @@ -70,8 +70,8 @@ ## 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. +- Update the browser harness in [wsRpcHarness.ts](/Users/julius/.v12/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/.v12/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 diff --git a/AGENTS.md b/AGENTS.md index 380a9202683..74ba73a0c6b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,7 +8,7 @@ ## Project Snapshot -T3 Code is a minimal web GUI for using coding agents like Codex and Claude. +V12 is a minimal web GUI for using coding agents like Codex and Claude. This repository is a VERY EARLY WIP. Proposing sweeping changes that improve long-term maintainability is encouraged. @@ -29,7 +29,7 @@ Long term maintainability is a core priority. If you add new functionality, firs - `apps/server`: Node.js WebSocket server. Wraps Codex app-server (JSON-RPC over stdio), serves the React web app, and manages provider sessions. - `apps/web`: React/Vite UI. Owns session UX, conversation/event rendering, and client-side state. Connects to the server via WebSocket. - `packages/contracts`: Shared effect/Schema schemas and TypeScript contracts for provider events, WebSocket protocol, and model/session types. Keep this package schema-only — no runtime logic. -- `packages/shared`: Shared runtime utilities consumed by both server and client applications. Uses explicit subpath exports (e.g. `@t3tools/shared/git`) — no barrel index. +- `packages/shared`: Shared runtime utilities consumed by both server and client applications. Uses explicit subpath exports (e.g. `@v12/shared/git`) — no barrel index. - `packages/client-runtime`: Shared runtime package for sharing client code across web and mobile. ## Reference Repos diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..c8d0ea9a0cd --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,27 @@ +# Code of Conduct + +## Our Standards + +We want V12 to be a welcoming, practical, and technically focused community. + +Participants are expected to: + +- Be respectful and constructive +- Focus feedback on the work, not the person +- Welcome people with different backgrounds and experience levels +- Accept correction and resolve disagreements in good faith +- Protect private information shared during support or security work + +Harassment, discrimination, threats, deliberate intimidation, sexualized conduct, doxxing, and sustained personal attacks are not acceptable. + +## Scope + +This policy applies to project repositories, issues, pull requests, discussions, and other spaces where someone represents the project. + +## Enforcement + +Maintainers may edit or remove content and may warn, temporarily restrict, or permanently ban participants whose behavior violates this policy. + +Report conduct concerns privately to a maintainer through their GitHub profile. Do not post sensitive reports publicly. GitHub-hosted abuse can also be reported through GitHub's reporting tools. + +Enforcement decisions should protect affected people, respect privacy, and be based on the behavior and context rather than a contributor's status. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8b734a99bbb..64ca76364dd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,65 +1,50 @@ # Contributing -## Read This First +Thanks for helping improve V12. Bug fixes, reliability improvements, performance work, documentation, and focused features are welcome. -We are not actively accepting contributions right now. +## Before You Start -You can still open an issue or PR, but please do so knowing there is a high chance we close it, defer it forever, or never look at it. +- Search existing issues and pull requests first. +- Open an issue before starting a significant feature or architectural change. +- Keep pull requests focused on one problem. +- Report security vulnerabilities privately according to [SECURITY.md](./SECURITY.md). -If that sounds annoying, that is because it is. This project is still early and we are trying to keep scope, quality, and direction under control. +Small fixes can be submitted directly when the problem and solution are clear. -PRs are automatically labeled with a `vouch:*` trust status and a `size:*` diff size based on changed lines. +## Development Setup -If you are an external contributor, expect `vouch:unvouched` until we explicitly add you to [.github/VOUCHED.td](.github/VOUCHED.td). +Install [Vite+](https://viteplus.dev/guide/), then install dependencies: -## What We Are Most Likely To Accept +```bash +vp i +``` -Small, focused bug fixes. +Before submitting a change, run: -Small reliability fixes. +```bash +vp check +vp run typecheck +``` -Small performance improvements. +For native mobile changes, also run: -Tightly scoped maintenance work that clearly improves the project without changing its direction. +```bash +vp run lint:mobile +``` -## What We Are Least Likely To Accept +Use `vp test` for the built-in Vite+ test command. Use `vp run test` when you specifically need the repository's `test` package script. -Large PRs. +## Pull Requests -Drive-by feature work. +- Explain the problem, the solution, and any important tradeoffs. +- Include tests for behavior changes when practical. +- Include before-and-after images for visual changes. +- Include a short recording for motion or interaction changes. +- Avoid unrelated refactors, generated files, and dependency churn. +- Confirm that no secrets, private data, or machine-specific files are included. -Opinionated rewrites. +Maintainers may ask for changes or decline work that does not fit the project's direction. Reviews will stay focused on the contribution and its technical merits. -Anything that expands product scope without us asking for it first. +## Community -If you open a 1,000+ line PR full of new features, we will probably close it quickly and remember that you ignored the clearly written instructions. - -## If You Still Want To Open A PR - -Keep it small. - -Explain exactly what changed. - -Explain exactly why the change should exist. - -Do not mix unrelated fixes together. - -If the PR makes anything resembling a UI change, include clear before/after images. - -If the change depends on motion, timing, transitions, or interaction details, include a short video. - -If we have to guess what changed, we are much less likely to review it. - -## Issues First - -If you are thinking about a non-trivial change, open an issue first. - -That still does not mean we will want the PR, but it gives you a chance to avoid wasting your time. - -## Be Realistic - -Opening a PR does not create an obligation on our side. - -We may close it. We may ignore it. We may ask you to shrink it. We may reimplement the idea ourselves later. - -If you are fine with that, proceed. +Participation in this project is governed by our [Code of Conduct](./CODE_OF_CONDUCT.md). diff --git a/README.md b/README.md index 6aebfc7e8b8..0730a0080a9 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,22 @@ -# T3 Code +Built on the goated [T3 Code](https://github.com/pingdotgg/t3code) by T3 Tools. -T3 Code is a minimal web GUI for coding agents (currently Codex, Claude, Cursor, and OpenCode, more coming soon). +# V12 + +V12 is a minimal web GUI for coding agents (currently Codex, Claude, Cursor, and OpenCode, more coming soon). + +## What is V12? + +V12 brings the best coding-agent workflows into one fast, open-source app: + +- **Cursor-like chat drafts:** Start a chat, switch away, and come back without losing what you wrote. +- **Codex-like tasks:** Follow agent work as clear tasks instead of digging through a wall of output. +- **Richer tool-call details:** See commands, file changes, results, and failures in useful, readable cards. +- **Chat pinning:** Keep important chats at the top of the sidebar so they stay easy to find. ## Installation > [!WARNING] -> T3 Code currently supports Codex, Claude, Cursor, and OpenCode. +> V12 currently supports Codex, Claude, Cursor, and OpenCode. > Install and authenticate at least one provider before use: > > - Codex: install [Codex CLI](https://developers.openai.com/codex/cli) and run `codex login` @@ -16,54 +27,55 @@ T3 Code is a minimal web GUI for coding agents (currently Codex, Claude, Cursor, ### Run without installing ```bash -npx t3@latest +npx v12@latest ``` -Tip: Use `npx t3@latest --help` for the full CLI reference. +Tip: Use `npx v12@latest --help` for the full CLI reference. ### Desktop app -Install the latest version of the desktop app from [GitHub Releases](https://github.com/pingdotgg/t3code/releases), or from your favorite package registry: +Install the latest version of the desktop app from [GitHub Releases](https://github.com/12ya/v12/releases), or from your favorite package registry: #### Windows (`winget`) ```bash -winget install T3Tools.T3Code +winget install V12.V12 ``` #### macOS (Homebrew) ```bash -brew install --cask t3-code +brew install --cask 12ya/tap/v12-code ``` #### Arch Linux (AUR) ```bash -yay -S t3code-bin +yay -S v12-bin ``` ## Some notes We are very very early in this project. Expect bugs. -We are not accepting contributions yet. - There's no public docs site yet, checkout the miscellaneous markdown files in [docs](./docs). ## Documentation +- [V12 roadmap](./docs/project/roadmap.md) - [Getting started](./docs/getting-started/quick-start.md) - [Architecture overview](./docs/architecture/overview.md) - [Provider guides](./docs/providers/codex.md) - [Operations](./docs/operations/ci.md) - [Reference](./docs/reference/encyclopedia.md) -## If you REALLY want to contribute still.... read this first +## Contributing + +Contributions are welcome. Read [CONTRIBUTING.md](./CONTRIBUTING.md) before opening an issue or PR. ### Install `vp` -T3 Code uses Vite+ so you'll need to install the global `vp` command-line tool. +V12 uses Vite+ so you'll need to install the global `vp` command-line tool. #### macOS / Linux @@ -85,6 +97,4 @@ Checkout their getting started guide for more information: https://viteplus.dev/ vp i ``` -Read [CONTRIBUTING.md](./CONTRIBUTING.md) before opening an issue or PR. - -Need support? Join the [Discord](https://discord.gg/jn4EGJjrvv). +Need support? [Open an issue](https://github.com/12ya/v12/issues). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000..1a36838c9f9 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ +# Security Policy + +## Reporting a Vulnerability + +Please do not open a public issue for a suspected security vulnerability. + +Use [GitHub private vulnerability reporting](https://github.com/12ya/v12/security/advisories/new) to send the maintainers: + +- A description of the vulnerability and its impact +- A minimal reproduction or proof of concept +- Affected versions or commits, if known +- Any suggested mitigation + +Do not include real credentials, customer data, or other sensitive information in a report. Use synthetic test data and revoke any credential that may have been exposed. + +The maintainers will investigate the report and coordinate disclosure after a fix or mitigation is available. Please keep vulnerability details private until that process is complete. + +## Supported Versions + +Security fixes target the latest release and the current default branch. Older releases may not receive patches. diff --git a/apps/desktop/package.json b/apps/desktop/package.json index ceac5792bbb..5aba48cfcc8 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,5 +1,5 @@ { - "name": "@t3tools/desktop", + "name": "@v12/desktop", "version": "0.0.28", "private": true, "type": "module", @@ -15,11 +15,11 @@ "@clerk/electron": "catalog:", "@clerk/electron-passkeys": "catalog:", "@effect/platform-node": "catalog:", - "@t3tools/client-runtime": "workspace:*", - "@t3tools/contracts": "workspace:*", - "@t3tools/shared": "workspace:*", - "@t3tools/ssh": "workspace:*", - "@t3tools/tailscale": "workspace:*", + "@v12/client-runtime": "workspace:*", + "@v12/contracts": "workspace:*", + "@v12/shared": "workspace:*", + "@v12/ssh": "workspace:*", + "@v12/tailscale": "workspace:*", "effect": "catalog:", "electron": "41.5.0", "electron-store": "^8.2.0", @@ -35,5 +35,5 @@ "tailwindcss": "^4.0.0", "vite-plus": "catalog:" }, - "productName": "T3 Code (Alpha)" + "productName": "V12" } diff --git a/apps/desktop/resources/icon.icns b/apps/desktop/resources/icon.icns index da16d12a0c7..112a31d3c12 100644 Binary files a/apps/desktop/resources/icon.icns and b/apps/desktop/resources/icon.icns differ diff --git a/apps/desktop/resources/icon.ico b/apps/desktop/resources/icon.ico index 8298f70d8b3..73dbbc7315b 100644 Binary files a/apps/desktop/resources/icon.ico and b/apps/desktop/resources/icon.ico differ diff --git a/apps/desktop/resources/icon.png b/apps/desktop/resources/icon.png index 37f3f756a55..fcf2a6a4b24 100644 Binary files a/apps/desktop/resources/icon.png and b/apps/desktop/resources/icon.png differ diff --git a/apps/desktop/scripts/dev-electron.mjs b/apps/desktop/scripts/dev-electron.mjs index c28d5ec358b..5334de47690 100644 --- a/apps/desktop/scripts/dev-electron.mjs +++ b/apps/desktop/scripts/dev-electron.mjs @@ -33,8 +33,8 @@ const watchedDirectories = [ const forcedShutdownTimeoutMs = 1_500; const restartDebounceMs = 120; const childTreeGracePeriodMs = 1_200; -const remoteDebuggingPort = process.env.T3CODE_DESKTOP_REMOTE_DEBUGGING_PORT?.trim(); -// oxlint-disable-next-line t3code/no-global-process-runtime -- Standalone dev script has no Effect runtime. +const remoteDebuggingPort = process.env.V12_DESKTOP_REMOTE_DEBUGGING_PORT?.trim(); +// oxlint-disable-next-line v12/no-global-process-runtime -- Standalone dev script has no Effect runtime. const hostPlatform = NodeOS.platform(); await waitForResources({ @@ -48,8 +48,8 @@ const childEnv = { ...process.env }; delete childEnv.ELECTRON_RUN_AS_NODE; const devProtocolClient = resolveDevProtocolClient(); if (devProtocolClient) { - childEnv.T3CODE_DESKTOP_APP_USER_MODEL_ID = devProtocolClient.appBundleId; - childEnv.T3CODE_DESKTOP_PROTOCOL_REGISTRATION_MANAGED = "1"; + childEnv.V12_DESKTOP_APP_USER_MODEL_ID = devProtocolClient.appBundleId; + childEnv.V12_DESKTOP_PROTOCOL_REGISTRATION_MANAGED = "1"; } let shuttingDown = false; @@ -72,7 +72,7 @@ function cleanupStaleDevApps() { return; } - NodeChildProcess.spawnSync("pkill", ["-f", "--", `--t3code-dev-root=${desktopDir}`], { + NodeChildProcess.spawnSync("pkill", ["-f", "--", `--v12-dev-root=${desktopDir}`], { stdio: "ignore", }); } @@ -87,7 +87,7 @@ function startApp() { : []; const launchArgs = devProtocolClient ? electronArgs - : [...electronArgs, `--t3code-dev-root=${desktopDir}`, "dist-electron/main.cjs"]; + : [...electronArgs, `--v12-dev-root=${desktopDir}`, "dist-electron/main.cjs"]; const electronCommand = resolveElectronLaunchCommand(launchArgs); const app = NodeChildProcess.spawn(electronCommand.electronPath, electronCommand.args, { cwd: desktopDir, diff --git a/apps/desktop/scripts/electron-launcher.mjs b/apps/desktop/scripts/electron-launcher.mjs index 081ef903a06..683d15fabda 100644 --- a/apps/desktop/scripts/electron-launcher.mjs +++ b/apps/desktop/scripts/electron-launcher.mjs @@ -1,4 +1,4 @@ -// This file mostly exists because we want dev mode to say "T3 Code (Dev)" instead of "electron" +// This file mostly exists because we want dev mode to say "V12 (Dev)" instead of "electron" import * as NodeChildProcess from "node:child_process"; import * as NodeFS from "node:fs"; @@ -15,11 +15,11 @@ const repoRoot = NodePath.resolve(desktopDir, "..", ".."); const devBundleIdSuffix = NodePath.basename(repoRoot) .toLowerCase() .replaceAll(/[^a-z0-9]+/g, ""); -export const APP_DISPLAY_NAME = isDevelopment ? "T3 Code (Dev)" : "T3 Code (Alpha)"; +export const APP_DISPLAY_NAME = isDevelopment ? "V12 (Dev)" : "V12 (Alpha)"; export const APP_BUNDLE_ID = isDevelopment - ? `com.t3tools.t3code.dev.${devBundleIdSuffix || "local"}` - : "com.t3tools.t3code"; -const APP_PROTOCOL_SCHEMES = isDevelopment ? ["t3code-dev"] : ["t3code"]; + ? `com.v12.v12.dev.${devBundleIdSuffix || "local"}` + : "com.v12.v12"; +const APP_PROTOCOL_SCHEMES = isDevelopment ? ["v12-dev"] : ["v12"]; const LAUNCHER_VERSION = 12; const defaultIconPath = NodePath.join(desktopDir, "resources", "icon.icns"); const developmentMacIconPngPath = NodePath.join( @@ -28,7 +28,7 @@ const developmentMacIconPngPath = NodePath.join( "dev", "blueprint-macos-1024.png", ); -// oxlint-disable-next-line t3code/no-global-process-runtime -- Standalone launcher script has no Effect runtime. +// oxlint-disable-next-line v12/no-global-process-runtime -- Standalone launcher script has no Effect runtime. const hostPlatform = NodeOS.platform(); function setPlistString(plistPath, key, value) { @@ -108,12 +108,12 @@ export function makeDevelopmentLauncherScript({ }) { const envEntries = [ ["VITE_DEV_SERVER_URL", environment.VITE_DEV_SERVER_URL], - ["T3CODE_PORT", environment.T3CODE_PORT], - ["T3CODE_HOME", environment.T3CODE_HOME], - ["T3CODE_COMMIT_HASH", environment.T3CODE_COMMIT_HASH], - ["T3CODE_OTLP_TRACES_URL", environment.T3CODE_OTLP_TRACES_URL], - ["T3CODE_OTLP_EXPORT_INTERVAL_MS", environment.T3CODE_OTLP_EXPORT_INTERVAL_MS], - ["T3CODE_DESKTOP_APP_USER_MODEL_ID", APP_BUNDLE_ID], + ["V12_PORT", environment.V12_PORT], + ["V12_HOME", environment.V12_HOME], + ["V12_COMMIT_HASH", environment.V12_COMMIT_HASH], + ["V12_OTLP_TRACES_URL", environment.V12_OTLP_TRACES_URL], + ["V12_OTLP_EXPORT_INTERVAL_MS", environment.V12_OTLP_EXPORT_INTERVAL_MS], + ["V12_DESKTOP_APP_USER_MODEL_ID", APP_BUNDLE_ID], ].filter((entry) => typeof entry[1] === "string" && entry[1].trim().length > 0); return [ "#!/bin/sh", @@ -121,7 +121,7 @@ export function makeDevelopmentLauncherScript({ ([name, value]) => `if [ -z "\${${name}:-}" ]; then export ${name}=${shellSingleQuote(value)}; fi`, ), - `exec ${shellSingleQuote(electronBinaryPath)} --t3code-dev-root=${shellSingleQuote(desktopRoot)} ${shellSingleQuote(mainEntryPath)} "$@"`, + `exec ${shellSingleQuote(electronBinaryPath)} --v12-dev-root=${shellSingleQuote(desktopRoot)} ${shellSingleQuote(mainEntryPath)} "$@"`, "", ].join("\n"); } diff --git a/apps/desktop/scripts/electron-launcher.test.mjs b/apps/desktop/scripts/electron-launcher.test.mjs index 36e9429e444..5455788b772 100644 --- a/apps/desktop/scripts/electron-launcher.test.mjs +++ b/apps/desktop/scripts/electron-launcher.test.mjs @@ -10,8 +10,8 @@ describe("electron development launcher", () => { desktopRoot: "/repo/apps/desktop", environment: { VITE_DEV_SERVER_URL: "http://127.0.0.1:8526", - T3CODE_PORT: "16566", - T3CODE_HOME: "/tmp/t3", + V12_PORT: "16566", + V12_HOME: "/tmp/v12", }, }); @@ -22,7 +22,7 @@ describe("electron development launcher", () => { assert.notInclude(script, "\nexport VITE_DEV_SERVER_URL="); assert.include( script, - "exec '/repo/node_modules/electron/Electron' --t3code-dev-root='/repo/apps/desktop' '/repo/apps/desktop/dist-electron/main.cjs' \"$@\"", + "exec '/repo/node_modules/electron/Electron' --v12-dev-root='/repo/apps/desktop' '/repo/apps/desktop/dist-electron/main.cjs' \"$@\"", ); }); diff --git a/apps/desktop/scripts/ensure-electron-runtime.mjs b/apps/desktop/scripts/ensure-electron-runtime.mjs index c37838ab183..5bdf16ecea7 100644 --- a/apps/desktop/scripts/ensure-electron-runtime.mjs +++ b/apps/desktop/scripts/ensure-electron-runtime.mjs @@ -5,9 +5,9 @@ import * as NodePath from "node:path"; import * as NodeChildProcess from "node:child_process"; const require = NodeModule.createRequire(import.meta.url); -// oxlint-disable-next-line t3code/no-global-process-runtime -- Standalone repair script has no Effect runtime. +// oxlint-disable-next-line v12/no-global-process-runtime -- Standalone repair script has no Effect runtime. const hostPlatform = NodeOS.platform(); -// oxlint-disable-next-line t3code/no-global-process-runtime -- Standalone repair script has no Effect runtime. +// oxlint-disable-next-line v12/no-global-process-runtime -- Standalone repair script has no Effect runtime. const hostArch = NodeOS.arch(); function getPlatformPath() { @@ -116,7 +116,7 @@ function runChecked(command, args) { } function installElectronRuntime(electronDir, version) { - const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-electron-")); + const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "v12-electron-")); const zipPath = NodePath.join(tempDir, `electron-v${version}-${hostPlatform}-${hostArch}.zip`); try { diff --git a/apps/desktop/src/app/DesktopApp.ts b/apps/desktop/src/app/DesktopApp.ts index fd86c5f05d2..c51c0d33637 100644 --- a/apps/desktop/src/app/DesktopApp.ts +++ b/apps/desktop/src/app/DesktopApp.ts @@ -4,7 +4,7 @@ import * as Option from "effect/Option"; import * as Ref from "effect/Ref"; import * as Schema from "effect/Schema"; -import * as NetService from "@t3tools/shared/Net"; +import * as NetService from "@v12/shared/Net"; import * as Crypto from "effect/Crypto"; import * as ElectronApp from "../electron/ElectronApp.ts"; import * as ElectronDialog from "../electron/ElectronDialog.ts"; @@ -53,7 +53,7 @@ export class DesktopDevelopmentBackendPortRequiredError extends Schema.TaggedErr {}, ) { override get message(): string { - return "T3CODE_PORT is required in desktop development."; + return "V12_PORT is required in desktop development."; } } @@ -125,7 +125,7 @@ const handleFatalStartupError = Effect.fn("desktop.startup.handleFatalStartupErr const wasQuitting = yield* Ref.getAndSet(state.quitting, true); if (!wasQuitting) { yield* electronDialog.showErrorBox( - "T3 Code failed to start", + "V12 failed to start", `Stage: ${stage}\n${message}${detail}`, ); } diff --git a/apps/desktop/src/app/DesktopAppErrors.test.ts b/apps/desktop/src/app/DesktopAppErrors.test.ts index 666c36d391d..4526e9bc4c7 100644 --- a/apps/desktop/src/app/DesktopAppErrors.test.ts +++ b/apps/desktop/src/app/DesktopAppErrors.test.ts @@ -25,6 +25,6 @@ describe("DesktopApp errors", () => { it("reports the required development port", () => { const error = new DesktopDevelopmentBackendPortRequiredError(); - assert.equal(error.message, "T3CODE_PORT is required in desktop development."); + assert.equal(error.message, "V12_PORT is required in desktop development."); }); }); diff --git a/apps/desktop/src/app/DesktopAppIdentity.test.ts b/apps/desktop/src/app/DesktopAppIdentity.test.ts index 3c95b266bc1..7ad4642c2ca 100644 --- a/apps/desktop/src/app/DesktopAppIdentity.test.ts +++ b/apps/desktop/src/app/DesktopAppIdentity.test.ts @@ -20,9 +20,9 @@ const defaultEnvironmentInput = { platform: "darwin", processArch: "arm64", appVersion: "1.2.3", - appPath: "/Applications/T3 Code.app/Contents/Resources/app.asar", + appPath: "/Applications/V12.app/Contents/Resources/app.asar", isPackaged: true, - resourcesPath: "/Applications/T3 Code.app/Contents/Resources", + resourcesPath: "/Applications/V12.app/Contents/Resources", runningUnderArm64Translation: false, } satisfies DesktopEnvironment.MakeDesktopEnvironmentInput; @@ -39,7 +39,7 @@ interface ElectronAppCalls { const makeElectronAppLayer = (calls: ElectronAppCalls) => Layer.succeed(ElectronApp.ElectronApp, { metadata: Effect.die("unexpected metadata read"), - name: Effect.succeed("T3 Code"), + name: Effect.succeed("V12"), whenReady: Effect.void, quit: Effect.void, exit: () => Effect.void, @@ -125,11 +125,9 @@ const withIdentity = ( exists: (path) => input.legacyPathProbeError ? Effect.fail(input.legacyPathProbeError) - : Effect.succeed( - input.legacyPathExists === true && path.includes("T3 Code (Alpha)"), - ), + : Effect.succeed(input.legacyPathExists === true && path.includes("V12 (Alpha)")), readFileString: () => - Effect.succeed(input.packageJson ?? '{"t3codeCommitHash":"abcdef1234567890"}'), + Effect.succeed(input.packageJson ?? '{"v12CommitHash":"abcdef1234567890"}'), }), ), Layer.provideMerge(makeAssetsLayer(input.pngIconPath ?? Option.none())), @@ -147,14 +145,14 @@ describe("DesktopAppIdentity", () => { const identity = yield* DesktopAppIdentity.DesktopAppIdentity; const userDataPath = yield* identity.resolveUserDataPath; - assert.equal(userDataPath, "/Users/alice/Library/Application Support/T3 Code (Alpha)"); + assert.equal(userDataPath, "/Users/alice/Library/Application Support/V12 (Alpha)"); }), { legacyPathExists: true }, ), ); it.effect("preserves failures while inspecting the legacy userData path", () => { - const legacyPath = "/Users/alice/Library/Application Support/T3 Code (Alpha)"; + const legacyPath = "/Users/alice/Library/Application Support/V12 (Alpha)"; const cause = PlatformError.systemError({ _tag: "PermissionDenied", module: "FileSystem", @@ -192,8 +190,8 @@ describe("DesktopAppIdentity", () => { const identity = yield* DesktopAppIdentity.DesktopAppIdentity; yield* identity.configure; - assert.deepEqual(calls.setName, ["T3 Code (Alpha)"]); - assert.equal(calls.setAboutPanelOptions[0]?.applicationName, "T3 Code (Alpha)"); + assert.deepEqual(calls.setName, ["V12 (Alpha)"]); + assert.equal(calls.setAboutPanelOptions[0]?.applicationName, "V12 (Alpha)"); assert.equal(calls.setAboutPanelOptions[0]?.applicationVersion, "1.2.3"); assert.equal(calls.setAboutPanelOptions[0]?.version, "0123456789ab"); assert.deepEqual(calls.setDockIcon, ["/icon.png"]); @@ -202,7 +200,7 @@ describe("DesktopAppIdentity", () => { calls, environment: { env: { - T3CODE_COMMIT_HASH: "0123456789abcdef", + V12_COMMIT_HASH: "0123456789abcdef", }, }, pngIconPath: Option.some("/icon.png"), diff --git a/apps/desktop/src/app/DesktopAppIdentity.ts b/apps/desktop/src/app/DesktopAppIdentity.ts index 385e694338d..8bf59de6359 100644 --- a/apps/desktop/src/app/DesktopAppIdentity.ts +++ b/apps/desktop/src/app/DesktopAppIdentity.ts @@ -14,7 +14,7 @@ const COMMIT_HASH_PATTERN = /^[0-9a-f]{7,40}$/i; const COMMIT_HASH_DISPLAY_LENGTH = 12; const AppPackageMetadata = Schema.Struct({ - t3codeCommitHash: Schema.optional(Schema.String), + v12CommitHash: Schema.optional(Schema.String), }); const decodeAppPackageMetadata = Schema.decodeEffect(Schema.fromJsonString(AppPackageMetadata)); @@ -36,7 +36,7 @@ export class DesktopAppIdentity extends Context.Service< readonly resolveUserDataPath: Effect.Effect; readonly configure: Effect.Effect; } ->()("@t3tools/desktop/app/DesktopAppIdentity") {} +>()("@v12/desktop/app/DesktopAppIdentity") {} const normalizeCommitHash = (value: string): Option.Option => { const trimmed = value.trim(); @@ -60,7 +60,7 @@ export const make = Effect.gen(function* () { onSome: (value) => decodeAppPackageMetadata(value).pipe( Effect.map((parsed) => - Option.fromNullishOr(parsed.t3codeCommitHash).pipe(Option.flatMap(normalizeCommitHash)), + Option.fromNullishOr(parsed.v12CommitHash).pipe(Option.flatMap(normalizeCommitHash)), ), Effect.orElseSucceed(() => Option.none()), ), diff --git a/apps/desktop/src/app/DesktopAssets.test.ts b/apps/desktop/src/app/DesktopAssets.test.ts index 2eb55c72057..7a7e0b3fd38 100644 --- a/apps/desktop/src/app/DesktopAssets.test.ts +++ b/apps/desktop/src/app/DesktopAssets.test.ts @@ -15,9 +15,9 @@ const environmentLayer = DesktopEnvironment.layer({ platform: "darwin", processArch: "arm64", appVersion: "1.2.3", - appPath: "/Applications/T3 Code.app/Contents/Resources/app.asar", + appPath: "/Applications/V12.app/Contents/Resources/app.asar", isPackaged: true, - resourcesPath: "/Applications/T3 Code.app/Contents/Resources", + resourcesPath: "/Applications/V12.app/Contents/Resources", runningUnderArm64Translation: false, }).pipe(Layer.provide(Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({})))); diff --git a/apps/desktop/src/app/DesktopAssets.ts b/apps/desktop/src/app/DesktopAssets.ts index 95585acab74..c281e709cf1 100644 --- a/apps/desktop/src/app/DesktopAssets.ts +++ b/apps/desktop/src/app/DesktopAssets.ts @@ -34,7 +34,7 @@ export class DesktopAssets extends Context.Service< fileName: string, ) => Effect.Effect, DesktopAssetProbeError>; } ->()("@t3tools/desktop/app/DesktopAssets") {} +>()("@v12/desktop/app/DesktopAssets") {} const resolveResourcePath = Effect.fn("desktop.assets.resolveResourcePath")(function* ( fileName: string, diff --git a/apps/desktop/src/app/DesktopClerk.test.ts b/apps/desktop/src/app/DesktopClerk.test.ts index 9b5ed56d1f3..914b95f0dee 100644 --- a/apps/desktop/src/app/DesktopClerk.test.ts +++ b/apps/desktop/src/app/DesktopClerk.test.ts @@ -27,7 +27,7 @@ import * as DesktopEnvironment from "./DesktopEnvironment.ts"; const makeDesktopClerkLayer = (isDevelopment = true) => { const environment = DesktopEnvironment.DesktopEnvironment.of({ - stateDir: "/tmp/t3-state", + stateDir: "/tmp/v12-state", isDevelopment, } as unknown as DesktopEnvironment.DesktopEnvironment["Service"]); @@ -43,11 +43,11 @@ describe("DesktopClerk", () => { }); it("derives the Clerk Frontend API hostname used by the desktop CSP", () => { - const publishableKey = `pk_test_${btoa("clerk.t3.codes$")}`; + const publishableKey = `pk_test_${btoa("clerk.v12.codes$")}`; assert.equal( DesktopClerk.resolveDesktopClerkFrontendApiHostname(publishableKey), - "clerk.t3.codes", + "clerk.v12.codes", ); assert.equal(DesktopClerk.resolveDesktopClerkFrontendApiHostname(""), undefined); assert.equal(DesktopClerk.resolveDesktopClerkFrontendApiHostname("invalid"), undefined); @@ -66,7 +66,7 @@ describe("DesktopClerk", () => { { storage: storageAdapter, passkeys: true, - renderer: { scheme: "t3code-dev", host: "app" }, + renderer: { scheme: "v12-dev", host: "app" }, }, ], ]); @@ -87,12 +87,12 @@ describe("DesktopClerk", () => { const error = yield* Effect.scoped(Layer.build(makeDesktopClerkLayer())).pipe(Effect.flip); assert.instanceOf(error, DesktopClerk.DesktopClerkBridgeInitializationError); - assert.equal(error.stateDir, "/tmp/t3-state"); + assert.equal(error.stateDir, "/tmp/v12-state"); assert.equal(error.isDevelopment, true); assert.strictEqual(error.cause, cause); assert.equal( error.message, - 'Failed to initialize the desktop Clerk bridge for state directory "/tmp/t3-state" (development: true).', + 'Failed to initialize the desktop Clerk bridge for state directory "/tmp/v12-state" (development: true).', ); }); }); @@ -113,27 +113,27 @@ describe("DesktopClerk", () => { if (exit._tag === "Failure") { const error = Cause.squash(exit.cause); assert.instanceOf(error, DesktopClerk.DesktopClerkBridgeCleanupError); - assert.equal(error.stateDir, "/tmp/t3-state"); + assert.equal(error.stateDir, "/tmp/v12-state"); assert.equal(error.isDevelopment, false); assert.strictEqual(error.cause, cause); assert.equal( error.message, - 'Failed to clean up the desktop Clerk bridge for state directory "/tmp/t3-state" (development: false).', + 'Failed to clean up the desktop Clerk bridge for state directory "/tmp/v12-state" (development: false).', ); } }); }); it.each([ - { isDevelopment: true, scheme: "t3code-dev" }, - { isDevelopment: false, scheme: "t3code" }, + { isDevelopment: true, scheme: "v12-dev" }, + { isDevelopment: false, scheme: "v12" }, ])("configures the SDK with the $scheme renderer origin", ({ isDevelopment, scheme }) => { const bridge = { cleanup: vi.fn() }; storageMock.mockReturnValue(storageAdapter); createClerkBridgeMock.mockReturnValue(bridge); - assert.equal(DesktopClerk.createDesktopClerkBridge("/tmp/t3-state", isDevelopment), bridge); - assert.deepEqual(storageMock.mock.calls, [[{ path: "/tmp/t3-state" }]]); + assert.equal(DesktopClerk.createDesktopClerkBridge("/tmp/v12-state", isDevelopment), bridge); + assert.deepEqual(storageMock.mock.calls, [[{ path: "/tmp/v12-state" }]]); assert.deepEqual(createClerkBridgeMock.mock.calls, [ [ { diff --git a/apps/desktop/src/app/DesktopClerk.ts b/apps/desktop/src/app/DesktopClerk.ts index 0e283f8dd0c..65a734dadee 100644 --- a/apps/desktop/src/app/DesktopClerk.ts +++ b/apps/desktop/src/app/DesktopClerk.ts @@ -7,13 +7,13 @@ import * as Option from "effect/Option"; import * as Schema from "effect/Schema"; import * as Scope from "effect/Scope"; -import { clerkFrontendApiHostnameFromPublishableKey } from "@t3tools/shared/relayAuth"; +import { clerkFrontendApiHostnameFromPublishableKey } from "@v12/shared/relayAuth"; import * as ElectronApp from "../electron/ElectronApp.ts"; import * as ElectronProtocol from "../electron/ElectronProtocol.ts"; import * as ElectronWindow from "../electron/ElectronWindow.ts"; import * as DesktopEnvironment from "./DesktopEnvironment.ts"; -declare const __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__: string | undefined; +declare const __V12_BUILD_CLERK_PUBLISHABLE_KEY__: string | undefined; export class DesktopClerkBridgeInitializationError extends Schema.TaggedErrorClass()( "DesktopClerkBridgeInitializationError", @@ -50,7 +50,7 @@ export class DesktopClerk extends Context.Service< ElectronApp.ElectronApp | ElectronWindow.ElectronWindow | Scope.Scope >; } ->()("@t3tools/desktop/app/DesktopClerk") {} +>()("@v12/desktop/app/DesktopClerk") {} export function resolveDesktopClerkFrontendApiHostname( publishableKey: string | undefined, @@ -66,9 +66,9 @@ export function resolveDesktopClerkFrontendApiHostname( } export const desktopClerkFrontendApiHostname = resolveDesktopClerkFrontendApiHostname( - typeof __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__ === "undefined" + typeof __V12_BUILD_CLERK_PUBLISHABLE_KEY__ === "undefined" ? undefined - : __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__, + : __V12_BUILD_CLERK_PUBLISHABLE_KEY__, ); export function createDesktopClerkBridge(stateDir: string, isDevelopment: boolean) { diff --git a/apps/desktop/src/app/DesktopConfig.ts b/apps/desktop/src/app/DesktopConfig.ts index 4bf6b513306..fc9ec050d78 100644 --- a/apps/desktop/src/app/DesktopConfig.ts +++ b/apps/desktop/src/app/DesktopConfig.ts @@ -35,22 +35,20 @@ const compactEnv = (env: Readonly>): Record( Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-connection-catalog-test-", + prefix: "v12-desktop-connection-catalog-test-", }); return yield* effect.pipe(Effect.provide(makeLayer(baseDir, encryptionAvailable))); }).pipe(Effect.provide(NodeServices.layer), Effect.scoped); @@ -248,7 +248,7 @@ describe("DesktopConnectionCatalogStore", () => { Effect.gen(function* () { const baseFileSystem = yield* FileSystem.FileSystem; const baseDir = yield* baseFileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-connection-catalog-test-", + prefix: "v12-desktop-connection-catalog-test-", }); const permissionError = PlatformError.systemError({ _tag: "PermissionDenied", @@ -285,7 +285,7 @@ describe("DesktopConnectionCatalogStore", () => { Effect.gen(function* () { const baseFileSystem = yield* FileSystem.FileSystem; const baseDir = yield* baseFileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-connection-catalog-test-", + prefix: "v12-desktop-connection-catalog-test-", }); const permissionError = PlatformError.systemError({ _tag: "PermissionDenied", @@ -382,7 +382,7 @@ describe("DesktopConnectionCatalogStore", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-connection-catalog-test-", + prefix: "v12-desktop-connection-catalog-test-", }); const failDecrypt = yield* Ref.make(false); const layer = makeLayer(baseDir, true, failDecrypt); diff --git a/apps/desktop/src/app/DesktopConnectionCatalogStore.ts b/apps/desktop/src/app/DesktopConnectionCatalogStore.ts index 5ec2edb595f..b9dd7fcf0b2 100644 --- a/apps/desktop/src/app/DesktopConnectionCatalogStore.ts +++ b/apps/desktop/src/app/DesktopConnectionCatalogStore.ts @@ -5,13 +5,13 @@ import { RelayConnectionTarget, SshConnectionProfile, SshConnectionTarget, -} from "@t3tools/client-runtime/connection"; +} from "@v12/client-runtime/connection"; import { ConnectionCatalogDocument as RuntimeConnectionCatalogDocument, type ConnectionCatalogDocument as RuntimeConnectionCatalogDocumentType, -} from "@t3tools/client-runtime/platform"; -import type { PersistedSavedEnvironmentRecord } from "@t3tools/contracts"; -import { fromLenientJson } from "@t3tools/shared/schemaJson"; +} from "@v12/client-runtime/platform"; +import type { PersistedSavedEnvironmentRecord } from "@v12/contracts"; +import { fromLenientJson } from "@v12/shared/schemaJson"; import * as Context from "effect/Context"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; @@ -165,7 +165,7 @@ export class DesktopConnectionCatalogStore extends Context.Service< >; readonly clear: Effect.Effect; } ->()("@t3tools/desktop/app/DesktopConnectionCatalogStore") {} +>()("@v12/desktop/app/DesktopConnectionCatalogStore") {} function decodeSecretBytes( catalogPath: string, diff --git a/apps/desktop/src/app/DesktopEnvironment.test.ts b/apps/desktop/src/app/DesktopEnvironment.test.ts index 92da3f887ac..158d65a8cd4 100644 --- a/apps/desktop/src/app/DesktopEnvironment.test.ts +++ b/apps/desktop/src/app/DesktopEnvironment.test.ts @@ -13,9 +13,9 @@ const defaultInput = { platform: "darwin", processArch: "arm64", appVersion: "0.0.22", - appPath: "/Applications/T3 Code.app/Contents/Resources/app.asar", + appPath: "/Applications/V12.app/Contents/Resources/app.asar", isPackaged: false, - resourcesPath: "/Applications/T3 Code.app/Contents/Resources", + resourcesPath: "/Applications/V12.app/Contents/Resources", runningUnderArm64Translation: false, } satisfies DesktopEnvironment.MakeDesktopEnvironmentInput; @@ -40,37 +40,40 @@ describe("DesktopEnvironment", () => { const environment = yield* makeEnvironment( {}, { - T3CODE_HOME: " /tmp/t3 ", - T3CODE_COMMIT_HASH: " 0123456789abcdef ", - T3CODE_PORT: "4949", + V12_HOME: " /tmp/v12 ", + V12_COMMIT_HASH: " 0123456789abcdef ", + V12_PORT: "4949", VITE_DEV_SERVER_URL: "http://localhost:5173", - T3CODE_DEV_REMOTE_T3_SERVER_ENTRY_PATH: " /remote/server.mjs ", - T3CODE_OTLP_TRACES_URL: " http://127.0.0.1:4318/v1/traces ", - T3CODE_OTLP_EXPORT_INTERVAL_MS: "2500", + V12_DEV_REMOTE_V12_SERVER_ENTRY_PATH: " /remote/server.mjs ", + V12_OTLP_TRACES_URL: " http://127.0.0.1:4318/v1/traces ", + V12_OTLP_EXPORT_INTERVAL_MS: "2500", }, ); assert.equal(environment.isDevelopment, true); assert.equal(environment.appDataDirectory, "/Users/alice/Library/Application Support"); - assert.equal(environment.baseDir, "/tmp/t3"); - assert.equal(environment.stateDir, "/tmp/t3/dev"); - assert.equal(environment.desktopSettingsPath, "/tmp/t3/dev/desktop-settings.json"); - assert.equal(environment.clientSettingsPath, "/tmp/t3/dev/client-settings.json"); - assert.equal(environment.savedEnvironmentRegistryPath, "/tmp/t3/dev/saved-environments.json"); - assert.equal(environment.serverSettingsPath, "/tmp/t3/dev/settings.json"); - assert.equal(environment.logDir, "/tmp/t3/dev/logs"); - assert.equal(environment.browserArtifactsDir, "/tmp/t3/dev/browser-artifacts"); + assert.equal(environment.baseDir, "/tmp/v12"); + assert.equal(environment.stateDir, "/tmp/v12/dev"); + assert.equal(environment.desktopSettingsPath, "/tmp/v12/dev/desktop-settings.json"); + assert.equal(environment.clientSettingsPath, "/tmp/v12/dev/client-settings.json"); + assert.equal( + environment.savedEnvironmentRegistryPath, + "/tmp/v12/dev/saved-environments.json", + ); + assert.equal(environment.serverSettingsPath, "/tmp/v12/dev/settings.json"); + assert.equal(environment.logDir, "/tmp/v12/dev/logs"); + assert.equal(environment.browserArtifactsDir, "/tmp/v12/dev/browser-artifacts"); assert.equal(environment.rootDir, "/repo"); assert.equal(environment.appRoot, "/repo"); assert.equal(environment.backendEntryPath, "/repo/apps/server/dist/bin.mjs"); assert.equal(environment.backendCwd, "/repo"); - assert.equal(environment.appUserModelId, "com.t3tools.t3code.dev"); - assert.equal(environment.linuxWmClass, "t3code-dev"); + assert.equal(environment.appUserModelId, "com.v12.v12.dev"); + assert.equal(environment.linuxWmClass, "v12-dev"); assert.deepEqual( Option.map(environment.devServerUrl, (url) => url.href), Option.some("http://localhost:5173/"), ); - assert.deepEqual(environment.devRemoteT3ServerEntryPath, Option.some("/remote/server.mjs")); + assert.deepEqual(environment.devRemoteV12ServerEntryPath, Option.some("/remote/server.mjs")); assert.deepEqual(environment.configuredBackendPort, Option.some(4949)); assert.deepEqual(environment.commitHashOverride, Option.some("0123456789abcdef")); assert.deepEqual(environment.otlpTracesUrl, Option.some("http://127.0.0.1:4318/v1/traces")); @@ -83,15 +86,15 @@ describe("DesktopEnvironment", () => { const environment = yield* makeEnvironment( {}, { - T3CODE_HOME: "/tmp/t3", + V12_HOME: "/tmp/v12", }, ); assert.equal(environment.isDevelopment, false); - assert.equal(environment.stateDir, "/tmp/t3/userdata"); - assert.equal(environment.logDir, "/tmp/t3/userdata/logs"); - assert.equal(environment.browserArtifactsDir, "/tmp/t3/userdata/browser-artifacts"); - assert.equal(environment.serverSettingsPath, "/tmp/t3/userdata/settings.json"); + assert.equal(environment.stateDir, "/tmp/v12/userdata"); + assert.equal(environment.logDir, "/tmp/v12/userdata/logs"); + assert.equal(environment.browserArtifactsDir, "/tmp/v12/userdata/browser-artifacts"); + assert.equal(environment.serverSettingsPath, "/tmp/v12/userdata/settings.json"); }), ); @@ -100,12 +103,12 @@ describe("DesktopEnvironment", () => { const environment = yield* makeEnvironment( {}, { - T3CODE_DESKTOP_APP_USER_MODEL_ID: " com.t3tools.t3code.dev.local ", + V12_DESKTOP_APP_USER_MODEL_ID: " com.v12.v12.dev.local ", VITE_DEV_SERVER_URL: "http://localhost:5173", }, ); - assert.equal(environment.appUserModelId, "com.t3tools.t3code.dev.local"); + assert.equal(environment.appUserModelId, "com.v12.v12.dev.local"); }), ); diff --git a/apps/desktop/src/app/DesktopEnvironment.ts b/apps/desktop/src/app/DesktopEnvironment.ts index 061a9368c53..5de6265f784 100644 --- a/apps/desktop/src/app/DesktopEnvironment.ts +++ b/apps/desktop/src/app/DesktopEnvironment.ts @@ -3,7 +3,7 @@ import type { DesktopAppStageLabel, DesktopRuntimeArch, DesktopRuntimeInfo, -} from "@t3tools/contracts"; +} from "@v12/contracts"; import * as Config from "effect/Config"; import * as Context from "effect/Context"; import * as Effect from "effect/Effect"; @@ -56,7 +56,7 @@ export class DesktopEnvironment extends Context.Service< readonly preloadPath: string; readonly appUpdateYmlPath: string; readonly devServerUrl: Option.Option; - readonly devRemoteT3ServerEntryPath: Option.Option; + readonly devRemoteV12ServerEntryPath: Option.Option; readonly configuredBackendPort: Option.Option; readonly commitHashOverride: Option.Option; readonly otlpTracesUrl: Option.Option; @@ -74,9 +74,9 @@ export class DesktopEnvironment extends Context.Service< readonly resolveResourcePathCandidates: (fileName: string) => readonly string[]; readonly developmentDockIconPath: string; } ->()("@t3tools/desktop/app/DesktopEnvironment") {} +>()("@v12/desktop/app/DesktopEnvironment") {} -const APP_BASE_NAME = "T3 Code"; +const APP_BASE_NAME = "V12"; function resolveDesktopAppStageLabel(input: { readonly isDevelopment: boolean; @@ -147,7 +147,7 @@ const make = Effect.fn("desktop.environment.make")(function* ( : input.platform === "darwin" ? path.join(homeDirectory, "Library", "Application Support") : Option.getOrElse(config.xdgConfigHome, () => path.join(homeDirectory, ".config")); - const baseDir = Option.getOrElse(config.t3Home, () => path.join(homeDirectory, ".t3")); + const baseDir = Option.getOrElse(config.v12Home, () => path.join(homeDirectory, ".v12")); const rootDir = path.resolve(input.dirname, "../../.."); const appRoot = input.isPackaged ? input.appPath : rootDir; const branding = resolveDesktopAppBranding({ @@ -156,8 +156,8 @@ const make = Effect.fn("desktop.environment.make")(function* ( }); const displayName = branding.displayName; const stateDir = path.join(baseDir, isDevelopment ? "dev" : "userdata"); - const userDataDirName = isDevelopment ? "t3code-dev" : "t3code"; - const legacyUserDataDirName = isDevelopment ? "T3 Code (Dev)" : "T3 Code (Alpha)"; + const userDataDirName = isDevelopment ? "v12-dev" : "v12"; + const legacyUserDataDirName = isDevelopment ? "V12 (Dev)" : "V12 (Alpha)"; const resourcesPath = input.resourcesPath; return DesktopEnvironment.of({ @@ -189,7 +189,7 @@ const make = Effect.fn("desktop.environment.make")(function* ( ? path.join(resourcesPath, "app-update.yml") : path.join(input.appPath, "dev-app-update.yml"), devServerUrl, - devRemoteT3ServerEntryPath: config.devRemoteT3ServerEntryPath, + devRemoteV12ServerEntryPath: config.devRemoteV12ServerEntryPath, configuredBackendPort: config.configuredBackendPort, commitHashOverride: config.commitHashOverride, otlpTracesUrl: config.otlpTracesUrl, @@ -197,10 +197,10 @@ const make = Effect.fn("desktop.environment.make")(function* ( branding, displayName, appUserModelId: Option.getOrElse(config.appUserModelIdOverride, () => - isDevelopment ? "com.t3tools.t3code.dev" : "com.t3tools.t3code", + isDevelopment ? "com.v12.v12.dev" : "com.v12.v12", ), - linuxDesktopEntryName: isDevelopment ? "t3code-dev.desktop" : "t3code.desktop", - linuxWmClass: isDevelopment ? "t3code-dev" : "t3code", + linuxDesktopEntryName: isDevelopment ? "v12-dev.desktop" : "v12.desktop", + linuxWmClass: isDevelopment ? "v12-dev" : "v12", userDataDirName, legacyUserDataDirName, defaultDesktopSettings: DesktopAppSettings.resolveDefaultDesktopSettings(input.appVersion), diff --git a/apps/desktop/src/app/DesktopLifecycle.ts b/apps/desktop/src/app/DesktopLifecycle.ts index c5264332b66..afcb69e626c 100644 --- a/apps/desktop/src/app/DesktopLifecycle.ts +++ b/apps/desktop/src/app/DesktopLifecycle.ts @@ -46,7 +46,7 @@ export class DesktopLifecycle extends Context.Service< ) => Effect.Effect; readonly register: Effect.Effect; } ->()("@t3tools/desktop/app/DesktopLifecycle") {} +>()("@v12/desktop/app/DesktopLifecycle") {} const { logInfo: logLifecycleInfo, logError: logLifecycleError } = makeComponentLogger("desktop-lifecycle"); diff --git a/apps/desktop/src/app/DesktopObservability.test.ts b/apps/desktop/src/app/DesktopObservability.test.ts index 9438175f602..4310ba2d833 100644 --- a/apps/desktop/src/app/DesktopObservability.test.ts +++ b/apps/desktop/src/app/DesktopObservability.test.ts @@ -55,7 +55,7 @@ const makeEnvironmentLayer = (baseDir: string) => Layer.mergeAll( NodeServices.layer, DesktopConfig.layerTest({ - T3CODE_HOME: baseDir, + V12_HOME: baseDir, VITE_DEV_SERVER_URL: "http://127.0.0.1:5733", }), ), @@ -67,7 +67,7 @@ describe("DesktopObservability", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-observability-test-", + prefix: "v12-desktop-observability-test-", }); const environmentLayer = makeEnvironmentLayer(baseDir); const tracePath = yield* Effect.gen(function* () { @@ -116,7 +116,7 @@ describe("DesktopObservability", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-output-log-test-", + prefix: "v12-desktop-backend-output-log-test-", }); const environmentLayer = makeEnvironmentLayer(baseDir); const logPath = yield* Effect.gen(function* () { diff --git a/apps/desktop/src/app/DesktopObservability.ts b/apps/desktop/src/app/DesktopObservability.ts index 42451e45ded..e49632692bf 100644 --- a/apps/desktop/src/app/DesktopObservability.ts +++ b/apps/desktop/src/app/DesktopObservability.ts @@ -1,6 +1,6 @@ -import { PRIMARY_LOCAL_ENVIRONMENT_ID } from "@t3tools/contracts"; -import { makeLocalFileTracer, makeTraceSink } from "@t3tools/shared/observability"; -import { parsePersistedServerObservabilitySettings } from "@t3tools/shared/serverSettings"; +import { PRIMARY_LOCAL_ENVIRONMENT_ID } from "@v12/contracts"; +import { makeLocalFileTracer, makeTraceSink } from "@v12/shared/observability"; +import { parsePersistedServerObservabilitySettings } from "@v12/shared/serverSettings"; import * as Context from "effect/Context"; import * as DateTime from "effect/DateTime"; import * as Effect from "effect/Effect"; @@ -56,7 +56,7 @@ export class DesktopBackendOutputLogFactory extends Context.Service< { readonly forInstance: (id: string) => Effect.Effect; } ->()("@t3tools/desktop/app/DesktopObservability/DesktopBackendOutputLogFactory") {} +>()("@v12/desktop/app/DesktopObservability/DesktopBackendOutputLogFactory") {} const textEncoder = new TextEncoder(); const textDecoder = new TextDecoder(); diff --git a/apps/desktop/src/app/DesktopShutdown.ts b/apps/desktop/src/app/DesktopShutdown.ts index 78b77b565b9..898709231ca 100644 --- a/apps/desktop/src/app/DesktopShutdown.ts +++ b/apps/desktop/src/app/DesktopShutdown.ts @@ -13,7 +13,7 @@ export class DesktopShutdown extends Context.Service< readonly awaitComplete: Effect.Effect; readonly isComplete: Effect.Effect; } ->()("@t3tools/desktop/app/DesktopShutdown") {} +>()("@v12/desktop/app/DesktopShutdown") {} const make = Effect.gen(function* () { const requested = yield* Deferred.make(); diff --git a/apps/desktop/src/app/DesktopState.ts b/apps/desktop/src/app/DesktopState.ts index cd2abe91065..12617c44fee 100644 --- a/apps/desktop/src/app/DesktopState.ts +++ b/apps/desktop/src/app/DesktopState.ts @@ -9,7 +9,7 @@ export class DesktopState extends Context.Service< readonly backendReady: Ref.Ref; readonly quitting: Ref.Ref; } ->()("@t3tools/desktop/app/DesktopState") {} +>()("@v12/desktop/app/DesktopState") {} const make = Effect.all({ backendReady: Ref.make(false), diff --git a/apps/desktop/src/backend/DesktopBackendConfiguration.test.ts b/apps/desktop/src/backend/DesktopBackendConfiguration.test.ts index 24c90943ec3..99b7e96842d 100644 --- a/apps/desktop/src/backend/DesktopBackendConfiguration.test.ts +++ b/apps/desktop/src/backend/DesktopBackendConfiguration.test.ts @@ -73,10 +73,10 @@ function makeEnvironmentLayer( Layer.mergeAll( NodeServices.layer, DesktopConfig.layerTest({ - T3CODE_HOME: baseDir, - T3CODE_PORT: "9999", - T3CODE_MODE: "desktop", - T3CODE_DESKTOP_LAN_HOST: "192.168.1.50", + V12_HOME: baseDir, + V12_PORT: "9999", + V12_MODE: "desktop", + V12_DESKTOP_LAN_HOST: "192.168.1.50", VITE_DEV_SERVER_URL: options?.devServerUrl, }), ), @@ -105,7 +105,7 @@ const withHarness = ( Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); return yield* effect.pipe( @@ -135,15 +135,15 @@ describe("DesktopBackendConfiguration", () => { assert.equal(first.cwd, environment.backendCwd); assert.equal(first.captureOutput, true); assert.equal(first.env.ELECTRON_RUN_AS_NODE, "1"); - assert.isUndefined(first.env.T3CODE_PORT); - assert.isUndefined(first.env.T3CODE_MODE); - assert.isUndefined(first.env.T3CODE_DESKTOP_LAN_HOST); + assert.isUndefined(first.env.V12_PORT); + assert.isUndefined(first.env.V12_MODE); + assert.isUndefined(first.env.V12_DESKTOP_LAN_HOST); assert.equal(first.bootstrap.mode, "desktop"); assert.equal(first.bootstrap.noBrowser, true); assert.equal(first.bootstrap.port, 4888); assert.equal(first.bootstrap.host, "0.0.0.0"); - assert.equal(first.bootstrap.t3Home, environment.baseDir); + assert.equal(first.bootstrap.v12Home, environment.baseDir); assert.equal(first.bootstrap.tailscaleServeEnabled, true); assert.equal(first.bootstrap.tailscaleServePort, 8443); assert.match(first.bootstrap.desktopBootstrapToken, /^[0-9a-f]{48}$/i); @@ -170,7 +170,7 @@ describe("DesktopBackendConfiguration", () => { const fileSystem = yield* FileSystem.FileSystem; const path = yield* Path.Path; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); const entryPath = path.join(baseDir, "app.asar.unpacked/apps/server/dist/bin.mjs"); yield* fileSystem.makeDirectory(path.dirname(entryPath), { recursive: true }); @@ -231,14 +231,14 @@ describe("DesktopBackendConfiguration", () => { const fileSystem = yield* FileSystem.FileSystem; const path = yield* Path.Path; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); const entryPath = path.join(baseDir, "app.asar.unpacked/apps/server/dist/bin.mjs"); yield* fileSystem.makeDirectory(path.dirname(entryPath), { recursive: true }); yield* fileSystem.writeFileString(entryPath, ""); const nodePath = "/home/test user's/.nvm/versions/node/v22.0.0/bin/node"; - const linuxEntryPath = "/tmp/t3 code's launch/entry file.mjs"; + const linuxEntryPath = "/tmp/v12 code's launch/entry file.mjs"; const resolvedPath = "/home/test user/bin:/opt/test's tools/bin:/usr/bin:/bin"; const devServerUrl = "http://127.0.0.1:5733/dev%20assets/?label=hello%20world"; const config = yield* Effect.gen(function* () { @@ -356,7 +356,7 @@ describe("DesktopBackendConfiguration", () => { const fileSystem = yield* FileSystem.FileSystem; const path = yield* Path.Path; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); const settingsPath = path.join(baseDir, "userdata", "settings.json"); const cause = PlatformError.systemError({ @@ -414,7 +414,7 @@ describe("DesktopBackendConfiguration", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); yield* Effect.gen(function* () { @@ -443,7 +443,7 @@ describe("DesktopBackendConfiguration", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); const previousWslEnv = process.env.WSLENV; @@ -508,7 +508,7 @@ describe("DesktopBackendConfiguration", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); yield* Effect.gen(function* () { @@ -520,7 +520,7 @@ describe("DesktopBackendConfiguration", () => { // not spawn wsl.exe (which would loop on preflight failures while the // Connections backend control is hidden). Resolve the Windows primary. assert.equal(config.executablePath, process.execPath); - assert.equal(config.bootstrap.t3Home, environment.baseDir); + assert.equal(config.bootstrap.v12Home, environment.baseDir); assert.isTrue(Option.isNone(config.preflightFailure)); }).pipe( Effect.provide( @@ -547,7 +547,7 @@ describe("DesktopBackendConfiguration", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); yield* Effect.gen(function* () { @@ -587,7 +587,7 @@ describe("DesktopBackendConfiguration", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); yield* Effect.gen(function* () { @@ -622,7 +622,7 @@ describe("DesktopBackendConfiguration", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); yield* Effect.gen(function* () { @@ -654,7 +654,7 @@ describe("DesktopBackendConfiguration", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); yield* Effect.gen(function* () { @@ -686,7 +686,7 @@ describe("DesktopBackendConfiguration", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); yield* Effect.gen(function* () { @@ -727,7 +727,7 @@ describe("DesktopBackendConfiguration", () => { Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-backend-config-test-", + prefix: "v12-desktop-backend-config-test-", }); yield* Effect.gen(function* () { @@ -765,7 +765,7 @@ describe("DesktopBackendConfiguration", () => { // a live async effect — otherwise runSync throws in the handler. Build the // real WSL layer (not the sync test stub) and resolve the label with a // top-level runSync, exactly as the handler does. - // oxlint-disable-next-line t3code/no-manual-effect-runtime-in-tests -- This test intentionally replicates the sync IPC handler's runSync path to catch a regression to async-only resolution; it.effect would mask it. + // oxlint-disable-next-line v12/no-manual-effect-runtime-in-tests -- This test intentionally replicates the sync IPC handler's runSync path to catch a regression to async-only resolution; it.effect would mask it. const runtime = ManagedRuntime.make( DesktopBackendConfiguration.layer.pipe( Layer.provideMerge(serverExposureLayer), @@ -781,7 +781,7 @@ describe("DesktopBackendConfiguration", () => { ), ), ), - Layer.provideMerge(makeEnvironmentLayer("/tmp/t3-wsl-isavailable", { platform: "win32" })), + Layer.provideMerge(makeEnvironmentLayer("/tmp/v12-wsl-isavailable", { platform: "win32" })), Layer.provide(NodeServices.layer), ), ); @@ -789,7 +789,7 @@ describe("DesktopBackendConfiguration", () => { const configuration = await runtime.runPromise( DesktopBackendConfiguration.DesktopBackendConfiguration, ); - // oxlint-disable-next-line t3code/no-manual-effect-runtime-in-tests -- Same reason: this is the synchronous resolution the IPC handler performs. + // oxlint-disable-next-line v12/no-manual-effect-runtime-in-tests -- Same reason: this is the synchronous resolution the IPC handler performs. const label = Effect.runSync(configuration.resolvePrimaryLabel); assert.equal(typeof label, "string"); } finally { diff --git a/apps/desktop/src/backend/DesktopBackendConfiguration.ts b/apps/desktop/src/backend/DesktopBackendConfiguration.ts index 7ae3ad6c912..0642fe1f337 100644 --- a/apps/desktop/src/backend/DesktopBackendConfiguration.ts +++ b/apps/desktop/src/backend/DesktopBackendConfiguration.ts @@ -1,6 +1,6 @@ import * as NodeOS from "node:os"; -import { parsePersistedServerObservabilitySettings } from "@t3tools/shared/serverSettings"; +import { parsePersistedServerObservabilitySettings } from "@v12/shared/serverSettings"; import * as Context from "effect/Context"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; @@ -61,7 +61,7 @@ export class DesktopBackendConfiguration extends Context.Service< // backend that actually resolved to Windows. readonly resolvePrimaryLabel: Effect.Effect; } ->()("@t3tools/desktop/backend/DesktopBackendConfiguration") {} +>()("@v12/desktop/backend/DesktopBackendConfiguration") {} interface BackendObservabilitySettings { readonly otlpTracesUrl: Option.Option; @@ -74,16 +74,16 @@ const emptyBackendObservabilitySettings: BackendObservabilitySettings = { }; const DESKTOP_BACKEND_ENV_NAMES = [ - "T3CODE_PORT", - "T3CODE_MODE", - "T3CODE_NO_BROWSER", - "T3CODE_HOST", - "T3CODE_DESKTOP_WS_URL", - "T3CODE_DESKTOP_LAN_ACCESS", - "T3CODE_DESKTOP_LAN_HOST", - "T3CODE_DESKTOP_HTTPS_ENDPOINTS", - "T3CODE_TAILSCALE_SERVE", - "T3CODE_TAILSCALE_SERVE_PORT", + "V12_PORT", + "V12_MODE", + "V12_NO_BROWSER", + "V12_HOST", + "V12_DESKTOP_WS_URL", + "V12_DESKTOP_LAN_ACCESS", + "V12_DESKTOP_LAN_HOST", + "V12_DESKTOP_HTTPS_ENDPOINTS", + "V12_TAILSCALE_SERVE", + "V12_TAILSCALE_SERVE_PORT", ] as const; // Sensitive env vars that the WSL backend needs but Windows process.env won't @@ -340,7 +340,7 @@ const resolvePrimaryStartConfig = Effect.fn("desktop.backendConfiguration.resolv mode: "desktop" as const, noBrowser: true, port: backendExposure.port, - t3Home: environment.baseDir, + v12Home: environment.baseDir, host: backendExposure.bindHost, desktopBootstrapToken: input.bootstrapToken, tailscaleServeEnabled: backendExposure.tailscaleServeEnabled, @@ -357,7 +357,7 @@ const resolvePrimaryStartConfig = Effect.fn("desktop.backendConfiguration.resolv ...backendChildEnvPatch(), ELECTRON_RUN_AS_NODE: "1", }, - // Primary wants process.env (PATH, dev-runner's T3CODE_HOME, etc.). + // Primary wants process.env (PATH, dev-runner's V12_HOME, etc.). extendEnv: true, bootstrap, bootstrapDelivery: "fd3", @@ -400,7 +400,7 @@ const resolveWslStartConfig = Effect.fn("desktop.backendConfiguration.resolveWsl mode: "desktop" as const, noBrowser: true, port: input.port, - // Omit t3Home so the Linux backend uses its own home dir instead of + // Omit v12Home so the Linux backend uses its own home dir instead of // the Windows-side baseDir (which would be a /mnt/c path and share // the SQLite file with the primary). host: wslBindHost, @@ -470,29 +470,29 @@ const resolveWslStartConfig = Effect.fn("desktop.backendConfiguration.resolveWsl } } - // Build an explicit copy of process.env minus T3CODE_HOME (dev-runner + // Build an explicit copy of process.env minus V12_HOME (dev-runner // exports the Windows-side base dir for the primary; if it leaks into - // the WSL backend the Linux side ends up sharing C:\Users\...\.t3 via + // the WSL backend the Linux side ends up sharing C:\Users\...\.v12 via // /mnt/c, which means both backends read/write the same database and // their env-ids collide). - const parentEnvWithoutT3Home: Record = {}; + const parentEnvWithoutV12Home: Record = {}; for (const [key, value] of Object.entries(process.env)) { - if (key === "T3CODE_HOME") continue; - parentEnvWithoutT3Home[key] = value; + if (key === "V12_HOME") continue; + parentEnvWithoutV12Home[key] = value; } - const wslEnv = mergeWslEnv(parentEnvWithoutT3Home.WSLENV, forwardedEnvNames); + const wslEnv = mergeWslEnv(parentEnvWithoutV12Home.WSLENV, forwardedEnvNames); const baseConfig = { executablePath: "wsl.exe", entryPath: wslEntryPath, cwd: environment.backendCwd, env: { - ...parentEnvWithoutT3Home, + ...parentEnvWithoutV12Home, ...backendChildEnvPatch(), ...forwardedEnv, ...(wslEnv !== undefined ? { WSLENV: wslEnv } : {}), }, - // env is already a complete process.env minus T3CODE_HOME; pass it + // env is already a complete process.env minus V12_HOME; pass it // verbatim instead of letting the spawner re-merge process.env on top. extendEnv: false, bootstrap, diff --git a/apps/desktop/src/backend/DesktopBackendManager.test.ts b/apps/desktop/src/backend/DesktopBackendManager.test.ts index 858c9b0d560..a8bb8ee03ac 100644 --- a/apps/desktop/src/backend/DesktopBackendManager.test.ts +++ b/apps/desktop/src/backend/DesktopBackendManager.test.ts @@ -1,7 +1,7 @@ import { DesktopBackendBootstrap, type DesktopBackendBootstrap as DesktopBackendBootstrapValue, -} from "@t3tools/contracts"; +} from "@v12/contracts"; import { assert, describe, it } from "@effect/vitest"; import * as Deferred from "effect/Deferred"; import * as Duration from "effect/Duration"; @@ -36,7 +36,7 @@ const baseConfig: DesktopBackendManager.DesktopBackendStartConfig = { mode: "desktop", noBrowser: true, port: 3773, - t3Home: "/tmp/t3", + v12Home: "/tmp/v12", host: "127.0.0.1", desktopBootstrapToken: "token", tailscaleServeEnabled: false, @@ -265,15 +265,15 @@ describe("DesktopBackendManager", () => { yield* Deferred.await(firstRequest); assert.equal(readyCount, 0); - assert.deepEqual(requestUrls, ["http://127.0.0.1:3773/.well-known/t3/environment"]); + assert.deepEqual(requestUrls, ["http://127.0.0.1:3773/.well-known/v12/environment"]); yield* TestClock.adjust(Duration.millis(100)); yield* Queue.take(exited); assert.equal(readyCount, 1); assert.deepEqual(requestUrls, [ - "http://127.0.0.1:3773/.well-known/t3/environment", - "http://127.0.0.1:3773/.well-known/t3/environment", + "http://127.0.0.1:3773/.well-known/v12/environment", + "http://127.0.0.1:3773/.well-known/v12/environment", ]); }).pipe(Effect.provide(TestClock.layer())), ), diff --git a/apps/desktop/src/backend/DesktopBackendManager.ts b/apps/desktop/src/backend/DesktopBackendManager.ts index e3a4de661ac..a837a55ee08 100644 --- a/apps/desktop/src/backend/DesktopBackendManager.ts +++ b/apps/desktop/src/backend/DesktopBackendManager.ts @@ -46,8 +46,8 @@ import { DesktopBackendBootstrap, type DesktopBackendBootstrap as DesktopBackendBootstrapValue, PRIMARY_LOCAL_ENVIRONMENT_ID, -} from "@t3tools/contracts"; -import { waitForHttpReady as waitForHttpReadyShared } from "@t3tools/shared/httpReadiness"; +} from "@v12/contracts"; +import { waitForHttpReady as waitForHttpReadyShared } from "@v12/shared/httpReadiness"; import * as DesktopObservability from "../app/DesktopObservability.ts"; @@ -62,7 +62,7 @@ const DEFAULT_BACKEND_READINESS_TIMEOUT = Duration.minutes(1); const DEFAULT_BACKEND_READINESS_INTERVAL = Duration.millis(100); const DEFAULT_BACKEND_READINESS_REQUEST_TIMEOUT = Duration.seconds(1); const DEFAULT_BACKEND_TERMINATE_GRACE = Duration.seconds(2); -const BACKEND_READINESS_PATH = "/.well-known/t3/environment"; +const BACKEND_READINESS_PATH = "/.well-known/v12/environment"; type BackendProcessLayerServices = ChildProcessSpawner.ChildProcessSpawner | HttpClient.HttpClient; @@ -80,7 +80,7 @@ export interface DesktopBackendStartConfig { readonly env: Record; // When true the spawner merges the desktop process.env on top of `env`; // when false `env` is passed verbatim. WSL mode opts out so a leaking - // T3CODE_HOME can't pin the WSL backend to /mnt/c/...\.t3. + // V12_HOME can't pin the WSL backend to /mnt/c/...\.v12. readonly extendEnv: boolean; readonly bootstrap: DesktopBackendBootstrapValue; readonly bootstrapDelivery: DesktopBackendBootstrapDelivery; diff --git a/apps/desktop/src/backend/DesktopBackendPool.ts b/apps/desktop/src/backend/DesktopBackendPool.ts index 258f8731fa1..28e01dae086 100644 --- a/apps/desktop/src/backend/DesktopBackendPool.ts +++ b/apps/desktop/src/backend/DesktopBackendPool.ts @@ -55,7 +55,7 @@ // (server.log: 13773 primary, 13774 wsl). // - Per-instance log files: server-child.log + server-child-wsl_Ubuntu.log. // - Distinct environment ids reported by each backend's -// /.well-known/t3/environment (Windows vs Linux platform). +// /.well-known/v12/environment (Windows vs Linux platform). // - Renderer completes the bearer-token bootstrap against the WSL // backend (POST /api/auth/bootstrap/bearer 200), obtains a // ws-token (POST /api/auth/ws-token 200), and holds an @@ -167,7 +167,7 @@ export class DesktopBackendPool extends Context.Service< id: BackendInstanceId, ) => Effect.Effect; } ->()("@t3tools/desktop/backend/DesktopBackendPool") {} +>()("@v12/desktop/backend/DesktopBackendPool") {} // Services required by makeBackendInstance — exported so caller // orchestrators that build their own specs can confirm the layer graph @@ -239,7 +239,7 @@ export const layer = Layer.effect( ); yield* electronDialog.showErrorBox( "WSL backend is still unavailable", - `${reason}\n\nT3 Code will use the Windows backend for this launch and retry WSL the next time the app starts.`, + `${reason}\n\nV12 will use the Windows backend for this launch and retry WSL the next time the app starts.`, ); yield* appSettings.applyWslWindowsFallbackInMemory; return true; @@ -250,7 +250,7 @@ export const layer = Layer.effect( }); yield* electronDialog.showErrorBox( "WSL backend couldn't start", - `${reason}\n\nFalling back to the Windows backend so T3 Code can open. Re-enable the WSL backend from Settings > Connections once the WSL distro is fixed.`, + `${reason}\n\nFalling back to the Windows backend so V12 can open. Re-enable the WSL backend from Settings > Connections once the WSL distro is fixed.`, ); // Fully disable the WSL backend — both flags, matching the "Switch to // Windows" recovery path — so the manager's next restart re-resolves the diff --git a/apps/desktop/src/backend/DesktopLocalEnvironmentAuth.test.ts b/apps/desktop/src/backend/DesktopLocalEnvironmentAuth.test.ts index e7a58baef14..3bf951a3189 100644 --- a/apps/desktop/src/backend/DesktopLocalEnvironmentAuth.test.ts +++ b/apps/desktop/src/backend/DesktopLocalEnvironmentAuth.test.ts @@ -5,7 +5,7 @@ import * as Option from "effect/Option"; import * as Ref from "effect/Ref"; import * as HttpClient from "effect/unstable/http/HttpClient"; import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"; -import { PRIMARY_LOCAL_ENVIRONMENT_ID } from "@t3tools/contracts"; +import { PRIMARY_LOCAL_ENVIRONMENT_ID } from "@v12/contracts"; import * as DesktopBackendPool from "./DesktopBackendPool.ts"; import * as DesktopLocalEnvironmentAuth from "./DesktopLocalEnvironmentAuth.ts"; @@ -19,7 +19,7 @@ const config = { mode: "desktop", noBrowser: true, port: 3773, - t3Home: "/tmp/t3", + v12Home: "/tmp/v12", host: "127.0.0.1", desktopBootstrapToken: "desktop-bootstrap-token", tailscaleServeEnabled: false, diff --git a/apps/desktop/src/backend/DesktopLocalEnvironmentAuth.ts b/apps/desktop/src/backend/DesktopLocalEnvironmentAuth.ts index 201492f0e4c..3b94e7a436c 100644 --- a/apps/desktop/src/backend/DesktopLocalEnvironmentAuth.ts +++ b/apps/desktop/src/backend/DesktopLocalEnvironmentAuth.ts @@ -1,5 +1,5 @@ -import { bootstrapRemoteBearerSession } from "@t3tools/client-runtime/authorization"; -import { PRIMARY_LOCAL_ENVIRONMENT_ID } from "@t3tools/contracts"; +import { bootstrapRemoteBearerSession } from "@v12/client-runtime/authorization"; +import { PRIMARY_LOCAL_ENVIRONMENT_ID } from "@v12/contracts"; import * as Context from "effect/Context"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; @@ -40,7 +40,7 @@ export class DesktopLocalEnvironmentAuth extends Context.Service< { readonly getBearerToken: Effect.Effect; } ->()("@t3tools/desktop/backend/DesktopLocalEnvironmentAuth") {} +>()("@v12/desktop/backend/DesktopLocalEnvironmentAuth") {} export const make = Effect.gen(function* () { const pool = yield* DesktopBackendPool.DesktopBackendPool; @@ -71,7 +71,7 @@ export const make = Effect.gen(function* () { httpBaseUrl: config.httpBaseUrl.href, credential, clientMetadata: { - label: "T3 Code Desktop", + label: "V12 Desktop", deviceType: "desktop", }, }).pipe( diff --git a/apps/desktop/src/backend/DesktopNetworkInterfaces.test.ts b/apps/desktop/src/backend/DesktopNetworkInterfaces.test.ts index 411af7553f9..48085ccb489 100644 --- a/apps/desktop/src/backend/DesktopNetworkInterfaces.test.ts +++ b/apps/desktop/src/backend/DesktopNetworkInterfaces.test.ts @@ -1,5 +1,5 @@ import { assert, describe, it } from "@effect/vitest"; -import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; +import { HostProcessPlatform } from "@v12/shared/hostProcess"; import * as Cause from "effect/Cause"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; diff --git a/apps/desktop/src/backend/DesktopNetworkInterfaces.ts b/apps/desktop/src/backend/DesktopNetworkInterfaces.ts index 43f634c4491..287bd389559 100644 --- a/apps/desktop/src/backend/DesktopNetworkInterfaces.ts +++ b/apps/desktop/src/backend/DesktopNetworkInterfaces.ts @@ -1,6 +1,6 @@ import * as NodeOS from "node:os"; -import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; +import { HostProcessPlatform } from "@v12/shared/hostProcess"; import * as Context from "effect/Context"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; @@ -37,7 +37,7 @@ export class DesktopNetworkInterfaces extends Context.Service< { readonly read: Effect.Effect; } ->()("@t3tools/desktop/backend/DesktopNetworkInterfaces") {} +>()("@v12/desktop/backend/DesktopNetworkInterfaces") {} export const make = Effect.gen(function* () { const platform = yield* HostProcessPlatform; diff --git a/apps/desktop/src/backend/DesktopServerExposure.test.ts b/apps/desktop/src/backend/DesktopServerExposure.test.ts index 1a107c5c856..72341e096d1 100644 --- a/apps/desktop/src/backend/DesktopServerExposure.test.ts +++ b/apps/desktop/src/backend/DesktopServerExposure.test.ts @@ -81,7 +81,7 @@ function makeEnvironmentLayer(baseDir: string, env: Record; readonly desktopSettingsLayer?: Layer.Layer; }) { - const env = { T3CODE_HOME: input.baseDir, ...input.env }; + const env = { V12_HOME: input.baseDir, ...input.env }; const environmentLayer = makeEnvironmentLayer(input.baseDir, env); const networkLayer = Layer.succeed(DesktopNetworkInterfaces.DesktopNetworkInterfaces, { read: Effect.succeed(input.networkInterfaces ?? emptyNetworkInterfaces), @@ -128,7 +128,7 @@ const withHarness = ( Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-server-exposure-test-", + prefix: "v12-desktop-server-exposure-test-", }); return yield* effect.pipe( Effect.provide( @@ -362,8 +362,8 @@ describe("DesktopServerExposure", () => { ); }), { - T3CODE_DESKTOP_LAN_HOST: "10.0.0.7", - T3CODE_DESKTOP_HTTPS_ENDPOINTS: "https://public.example.test", + V12_DESKTOP_LAN_HOST: "10.0.0.7", + V12_DESKTOP_HTTPS_ENDPOINTS: "https://public.example.test", }, ), ); @@ -462,7 +462,7 @@ describe("DesktopServerExposure", () => { ]); }), { - T3CODE_DESKTOP_HTTPS_ENDPOINTS: + V12_DESKTOP_HTTPS_ENDPOINTS: "https://desktop.example.ts.net,http://desktop.example.test:3773,not-a-url", }, ), diff --git a/apps/desktop/src/backend/DesktopServerExposure.ts b/apps/desktop/src/backend/DesktopServerExposure.ts index f04d2af7b1f..3afa38fd7e0 100644 --- a/apps/desktop/src/backend/DesktopServerExposure.ts +++ b/apps/desktop/src/backend/DesktopServerExposure.ts @@ -1,15 +1,15 @@ import { createAdvertisedEndpoint, type CreateAdvertisedEndpointInput, -} from "@t3tools/shared/advertisedEndpoint"; +} from "@v12/shared/advertisedEndpoint"; import { DesktopServerExposureModeSchema, type AdvertisedEndpoint, type AdvertisedEndpointProvider, type DesktopServerExposureMode, type DesktopServerExposureState, -} from "@t3tools/contracts"; -import { readTailscaleStatus } from "@t3tools/tailscale"; +} from "@v12/contracts"; +import { readTailscaleStatus } from "@v12/tailscale"; import * as Context from "effect/Context"; import * as Duration from "effect/Duration"; import * as Effect from "effect/Effect"; @@ -284,7 +284,7 @@ export class DesktopServerExposure extends Context.Service< }) => Effect.Effect; readonly getAdvertisedEndpoints: Effect.Effect; } ->()("@t3tools/desktop/backend/DesktopServerExposure") {} +>()("@v12/desktop/backend/DesktopServerExposure") {} interface RuntimeState { readonly requestedMode: DesktopServerExposureMode; diff --git a/apps/desktop/src/backend/tailscaleEndpointProvider.ts b/apps/desktop/src/backend/tailscaleEndpointProvider.ts index 0b48adc308c..112ff87691a 100644 --- a/apps/desktop/src/backend/tailscaleEndpointProvider.ts +++ b/apps/desktop/src/backend/tailscaleEndpointProvider.ts @@ -1,12 +1,12 @@ -import { createAdvertisedEndpoint } from "@t3tools/shared/advertisedEndpoint"; -import type { AdvertisedEndpoint, AdvertisedEndpointProvider } from "@t3tools/contracts"; +import { createAdvertisedEndpoint } from "@v12/shared/advertisedEndpoint"; +import type { AdvertisedEndpoint, AdvertisedEndpointProvider } from "@v12/contracts"; import { buildTailscaleHttpsBaseUrl, isTailscaleIpv4Address, parseTailscaleMagicDnsName, probeTailscaleHttpsEndpoint, readTailscaleStatus, -} from "@t3tools/tailscale"; +} from "@v12/tailscale"; import * as Effect from "effect/Effect"; import * as Option from "effect/Option"; import * as HttpClient from "effect/unstable/http/HttpClient"; @@ -14,7 +14,7 @@ import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawne import type { NetworkInterfaces } from "./DesktopNetworkInterfaces.ts"; -export { isTailscaleIpv4Address, parseTailscaleMagicDnsName } from "@t3tools/tailscale"; +export { isTailscaleIpv4Address, parseTailscaleMagicDnsName } from "@v12/tailscale"; const TAILSCALE_ENDPOINT_PROVIDER: AdvertisedEndpointProvider = { id: "tailscale", diff --git a/apps/desktop/src/electron/ElectronApp.test.ts b/apps/desktop/src/electron/ElectronApp.test.ts index f3ce3b4b5f4..e694333cc77 100644 --- a/apps/desktop/src/electron/ElectronApp.test.ts +++ b/apps/desktop/src/electron/ElectronApp.test.ts @@ -54,7 +54,7 @@ vi.mock("electron", () => ({ getVersion: getVersionMock, isDefaultProtocolClient: isDefaultProtocolClientMock, isPackaged: true, - name: "T3 Code", + name: "V12", on: onMock, quit: quitMock, relaunch: relaunchMock, diff --git a/apps/desktop/src/electron/ElectronApp.ts b/apps/desktop/src/electron/ElectronApp.ts index 0af8691f6c4..9a16b9bc708 100644 --- a/apps/desktop/src/electron/ElectronApp.ts +++ b/apps/desktop/src/electron/ElectronApp.ts @@ -71,7 +71,7 @@ export class ElectronApp extends Context.Service< listener: (...args: Args) => void, ) => Effect.Effect; } ->()("@t3tools/desktop/electron/ElectronApp") {} +>()("@v12/desktop/electron/ElectronApp") {} const addScopedAppListener = >( eventName: string, diff --git a/apps/desktop/src/electron/ElectronDialog.ts b/apps/desktop/src/electron/ElectronDialog.ts index be633971bea..764f7ba2fbf 100644 --- a/apps/desktop/src/electron/ElectronDialog.ts +++ b/apps/desktop/src/electron/ElectronDialog.ts @@ -100,7 +100,7 @@ export class ElectronDialog extends Context.Service< ) => Effect.Effect; readonly showErrorBox: (title: string, content: string) => Effect.Effect; } ->()("@t3tools/desktop/electron/ElectronDialog") {} +>()("@v12/desktop/electron/ElectronDialog") {} export const make = ElectronDialog.of({ pickFolder: Effect.fn("desktop.electron.dialog.pickFolder")(function* (input) { diff --git a/apps/desktop/src/electron/ElectronMenu.test.ts b/apps/desktop/src/electron/ElectronMenu.test.ts index 3dc218d8252..cb3eb16dacd 100644 --- a/apps/desktop/src/electron/ElectronMenu.test.ts +++ b/apps/desktop/src/electron/ElectronMenu.test.ts @@ -1,5 +1,5 @@ import { assert, describe, it } from "@effect/vitest"; -import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; +import { HostProcessPlatform } from "@v12/shared/hostProcess"; import * as Cause from "effect/Cause"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; diff --git a/apps/desktop/src/electron/ElectronMenu.ts b/apps/desktop/src/electron/ElectronMenu.ts index 09fb5d1807d..5054f355e2e 100644 --- a/apps/desktop/src/electron/ElectronMenu.ts +++ b/apps/desktop/src/electron/ElectronMenu.ts @@ -1,5 +1,5 @@ -import type { ContextMenuItem } from "@t3tools/contracts"; -import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; +import type { ContextMenuItem } from "@v12/contracts"; +import { HostProcessPlatform } from "@v12/shared/hostProcess"; import * as Context from "effect/Context"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; @@ -57,7 +57,7 @@ export class ElectronMenu extends Context.Service< ) => Effect.Effect>; readonly popupTemplate: (input: ElectronMenuTemplateInput) => Effect.Effect; } ->()("@t3tools/desktop/electron/ElectronMenu") {} +>()("@v12/desktop/electron/ElectronMenu") {} function normalizeContextMenuItems(source: readonly ContextMenuItem[]): ContextMenuItem[] { const normalizedItems: ContextMenuItem[] = []; diff --git a/apps/desktop/src/electron/ElectronProtocol.test.ts b/apps/desktop/src/electron/ElectronProtocol.test.ts index 92e30000427..a0a5208f8b3 100644 --- a/apps/desktop/src/electron/ElectronProtocol.test.ts +++ b/apps/desktop/src/electron/ElectronProtocol.test.ts @@ -35,20 +35,20 @@ describe("ElectronProtocol", () => { Effect.gen(function* () { const protocol = yield* ElectronProtocol.ElectronProtocol; yield* protocol.registerDesktopProtocol({ - scheme: "t3code-dev", + scheme: "v12-dev", targetOrigin: new URL("http://127.0.0.1:3773/"), backendOrigin: new URL("http://127.0.0.1:3774/"), - clerkFrontendApiHostname: "clerk.t3.codes", + clerkFrontendApiHostname: "clerk.v12.codes", }); assert.isDefined(handler); const response = yield* Effect.promise(() => handler!( - new Request("t3code-dev://app/api/health?verbose=1", { + new Request("v12-dev://app/api/health?verbose=1", { headers: { accept: "application/json", - origin: "t3code-dev://app", - referer: "t3code-dev://app/", + origin: "v12-dev://app", + referer: "v12-dev://app/", "sec-fetch-site": "same-origin", }, }), @@ -57,7 +57,7 @@ describe("ElectronProtocol", () => { assert.equal(yield* Effect.promise(() => response.text()), "ok"); assert.include( response.headers.get("content-security-policy") ?? "", - "script-src 'self' 'unsafe-inline' https://clerk.t3.codes https://challenges.cloudflare.com", + "script-src 'self' 'unsafe-inline' https://clerk.v12.codes https://challenges.cloudflare.com", ); assert.include( response.headers.get("content-security-policy") ?? "", @@ -65,18 +65,18 @@ describe("ElectronProtocol", () => { ); assert.include( response.headers.get("content-security-policy") ?? "", - "img-src 'self' t3code-dev: blob: data: http: https:", + "img-src 'self' v12-dev: blob: data: http: https:", ); assert.include( response.headers.get("content-security-policy") ?? "", - "font-src 'self' t3code-dev: data:", + "font-src 'self' v12-dev: data:", ); }), ); assert.deepEqual( handleMock.mock.calls.map((call) => call[0]), - ["t3code-dev"], + ["v12-dev"], ); assert.equal(netFetchMock.mock.calls[0]?.[0], "http://127.0.0.1:3773/api/health?verbose=1"); const forwardedHeaders = new Headers(netFetchMock.mock.calls[0]?.[1]?.headers); @@ -84,7 +84,7 @@ describe("ElectronProtocol", () => { assert.isNull(forwardedHeaders.get("origin")); assert.isNull(forwardedHeaders.get("referer")); assert.isNull(forwardedHeaders.get("sec-fetch-site")); - assert.deepEqual(unhandleMock.mock.calls, [["t3code-dev"]]); + assert.deepEqual(unhandleMock.mock.calls, [["v12-dev"]]); }).pipe(Effect.provide(ElectronProtocol.layer)), ); @@ -99,12 +99,12 @@ describe("ElectronProtocol", () => { Effect.gen(function* () { const protocol = yield* ElectronProtocol.ElectronProtocol; yield* protocol.registerDesktopProtocol({ - scheme: "t3code", + scheme: "v12", targetOrigin: new URL("http://127.0.0.1:3773/"), backendOrigin: new URL("http://127.0.0.1:3773/"), clerkFrontendApiHostname: undefined, }); - return yield* Effect.promise(() => handler!(new Request("t3code://other/"))); + return yield* Effect.promise(() => handler!(new Request("v12://other/"))); }), ); @@ -127,12 +127,12 @@ describe("ElectronProtocol", () => { Effect.gen(function* () { const protocol = yield* ElectronProtocol.ElectronProtocol; yield* protocol.registerDesktopProtocol({ - scheme: "t3code-dev", + scheme: "v12-dev", targetOrigin: new URL("http://127.0.0.1:5733/"), backendOrigin: new URL("http://127.0.0.1:3773/"), clerkFrontendApiHostname: undefined, }); - return yield* Effect.promise(() => handler!(new Request("t3code-dev://app/"))); + return yield* Effect.promise(() => handler!(new Request("v12-dev://app/"))); }), ); @@ -151,7 +151,7 @@ describe("ElectronProtocol", () => { const protocol = yield* ElectronProtocol.ElectronProtocol; const error = yield* Effect.scoped( protocol.registerDesktopProtocol({ - scheme: "t3code-dev", + scheme: "v12-dev", targetOrigin: new URL("http://127.0.0.1:3773/"), backendOrigin: new URL("http://127.0.0.1:3774/"), clerkFrontendApiHostname: undefined, @@ -159,9 +159,9 @@ describe("ElectronProtocol", () => { ).pipe(Effect.flip); assert.instanceOf(error, ElectronProtocol.ElectronProtocolRegistrationError); - assert.equal(error.scheme, "t3code-dev"); + assert.equal(error.scheme, "v12-dev"); assert.strictEqual(error.cause, cause); - assert.equal(error.message, 'Failed to register Electron protocol scheme "t3code-dev".'); + assert.equal(error.message, 'Failed to register Electron protocol scheme "v12-dev".'); }).pipe(Effect.provide(ElectronProtocol.layer)), ); @@ -176,7 +176,7 @@ describe("ElectronProtocol", () => { const exit = yield* Effect.exit( Effect.scoped( protocol.registerDesktopProtocol({ - scheme: "t3code", + scheme: "v12", targetOrigin: new URL("http://127.0.0.1:3773/"), backendOrigin: new URL("http://127.0.0.1:3773/"), clerkFrontendApiHostname: undefined, @@ -188,19 +188,19 @@ describe("ElectronProtocol", () => { if (exit._tag === "Failure") { const error = Cause.squash(exit.cause); assert.instanceOf(error, ElectronProtocol.ElectronProtocolUnregistrationError); - assert.equal(error.scheme, "t3code"); + assert.equal(error.scheme, "v12"); assert.strictEqual(error.cause, cause); - assert.equal(error.message, 'Failed to unregister Electron protocol scheme "t3code".'); + assert.equal(error.message, 'Failed to unregister Electron protocol scheme "v12".'); } }).pipe(Effect.provide(ElectronProtocol.layer)), ); it("keeps executable sources host-restricted while allowing runtime network resources", () => { const policy = ElectronProtocol.makeDesktopContentSecurityPolicy({ - scheme: "t3code", + scheme: "v12", targetOrigin: new URL("http://127.0.0.1:3773/"), backendOrigin: new URL("http://127.0.0.1:3773/"), - clerkFrontendApiHostname: "clerk.t3.codes", + clerkFrontendApiHostname: "clerk.v12.codes", }); const directives = Object.fromEntries( policy.split("; ").map((directive) => { @@ -212,18 +212,18 @@ describe("ElectronProtocol", () => { assert.deepEqual(directives["script-src"], [ "'self'", "'unsafe-inline'", - "https://clerk.t3.codes", + "https://clerk.v12.codes", "https://challenges.cloudflare.com", ]); assert.deepEqual(directives["connect-src"], ["'self'", "http:", "https:", "ws:", "wss:"]); assert.deepEqual(directives["img-src"], [ "'self'", - "t3code:", + "v12:", "blob:", "data:", "http:", "https:", ]); - assert.deepEqual(directives["font-src"], ["'self'", "t3code:", "data:"]); + assert.deepEqual(directives["font-src"], ["'self'", "v12:", "data:"]); }); }); diff --git a/apps/desktop/src/electron/ElectronProtocol.ts b/apps/desktop/src/electron/ElectronProtocol.ts index 03c7ef64fd7..66d3b2a889f 100644 --- a/apps/desktop/src/electron/ElectronProtocol.ts +++ b/apps/desktop/src/electron/ElectronProtocol.ts @@ -9,8 +9,8 @@ import * as Scope from "effect/Scope"; import * as Electron from "electron"; export const DESKTOP_HOST = "app"; -export const DESKTOP_PRODUCTION_SCHEME = "t3code"; -export const DESKTOP_DEVELOPMENT_SCHEME = "t3code-dev"; +export const DESKTOP_PRODUCTION_SCHEME = "v12"; +export const DESKTOP_DEVELOPMENT_SCHEME = "v12-dev"; export function getDesktopScheme(isDevelopment: boolean): string { return isDevelopment ? DESKTOP_DEVELOPMENT_SCHEME : DESKTOP_PRODUCTION_SCHEME; @@ -62,7 +62,7 @@ export class ElectronProtocol extends Context.Service< input: DesktopProtocolRegistrationInput, ) => Effect.Effect; } ->()("@t3tools/desktop/electron/ElectronProtocol") {} +>()("@v12/desktop/electron/ElectronProtocol") {} export function makeDesktopContentSecurityPolicy(input: DesktopProtocolRegistrationInput): string { const clerkOrigin = input.clerkFrontendApiHostname diff --git a/apps/desktop/src/electron/ElectronSafeStorage.ts b/apps/desktop/src/electron/ElectronSafeStorage.ts index 76162c1647a..4a019fcc15f 100644 --- a/apps/desktop/src/electron/ElectronSafeStorage.ts +++ b/apps/desktop/src/electron/ElectronSafeStorage.ts @@ -61,7 +61,7 @@ export class ElectronSafeStorage extends Context.Service< value: Uint8Array, ) => Effect.Effect; } ->()("@t3tools/desktop/electron/ElectronSafeStorage") {} +>()("@v12/desktop/electron/ElectronSafeStorage") {} export const make = ElectronSafeStorage.of({ isEncryptionAvailable: Effect.try({ diff --git a/apps/desktop/src/electron/ElectronShell.ts b/apps/desktop/src/electron/ElectronShell.ts index 316d3138bfa..d9120ea98a3 100644 --- a/apps/desktop/src/electron/ElectronShell.ts +++ b/apps/desktop/src/electron/ElectronShell.ts @@ -26,7 +26,7 @@ export class ElectronShell extends Context.Service< readonly openExternal: (rawUrl: unknown) => Effect.Effect; readonly copyText: (text: string) => Effect.Effect; } ->()("@t3tools/desktop/electron/ElectronShell") {} +>()("@v12/desktop/electron/ElectronShell") {} export const make = ElectronShell.of({ openExternal: (rawUrl) => diff --git a/apps/desktop/src/electron/ElectronTheme.ts b/apps/desktop/src/electron/ElectronTheme.ts index ef47e3d0954..ea3228d0b70 100644 --- a/apps/desktop/src/electron/ElectronTheme.ts +++ b/apps/desktop/src/electron/ElectronTheme.ts @@ -1,4 +1,4 @@ -import { DesktopThemeSchema, type DesktopTheme } from "@t3tools/contracts"; +import { DesktopThemeSchema, type DesktopTheme } from "@v12/contracts"; import * as Context from "effect/Context"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; @@ -28,7 +28,7 @@ export class ElectronTheme extends Context.Service< readonly setSource: (theme: DesktopTheme) => Effect.Effect; readonly onUpdated: (listener: () => void) => Effect.Effect; } ->()("@t3tools/desktop/electron/ElectronTheme") {} +>()("@v12/desktop/electron/ElectronTheme") {} export const make = ElectronTheme.of({ shouldUseDarkColors: Effect.sync(() => Electron.nativeTheme.shouldUseDarkColors), diff --git a/apps/desktop/src/electron/ElectronUpdater.ts b/apps/desktop/src/electron/ElectronUpdater.ts index 435fbd00228..6d7aa71d39d 100644 --- a/apps/desktop/src/electron/ElectronUpdater.ts +++ b/apps/desktop/src/electron/ElectronUpdater.ts @@ -78,7 +78,7 @@ export class ElectronUpdater extends Context.Service< listener: (...args: Args) => void, ) => Effect.Effect; } ->()("@t3tools/desktop/electron/ElectronUpdater") {} +>()("@v12/desktop/electron/ElectronUpdater") {} export const make = ElectronUpdater.of({ setFeedURL: (options) => diff --git a/apps/desktop/src/electron/ElectronWindow.test.ts b/apps/desktop/src/electron/ElectronWindow.test.ts index b59f8572739..7dca65ca9b6 100644 --- a/apps/desktop/src/electron/ElectronWindow.test.ts +++ b/apps/desktop/src/electron/ElectronWindow.test.ts @@ -1,5 +1,5 @@ import { assert, describe, it } from "@effect/vitest"; -import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; +import { HostProcessPlatform } from "@v12/shared/hostProcess"; import * as Cause from "effect/Cause"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; @@ -53,7 +53,7 @@ describe("ElectronWindow", () => { throw cause; }); const options = { - title: "T3 Code", + title: "V12", width: 1100, height: 780, minWidth: 840, @@ -66,7 +66,7 @@ describe("ElectronWindow", () => { icon: {} as Electron.NativeImage, webPreferences: { preload: "/tmp/preload.js", - partition: "persist:t3code-preview-test", + partition: "persist:v12-preview-test", sandbox: true, contextIsolation: true, nodeIntegration: false, @@ -81,7 +81,7 @@ describe("ElectronWindow", () => { assert.instanceOf(error, ElectronWindow.ElectronWindowCreateError); assert.isTrue(ElectronWindow.isElectronWindowCreateError(error)); assert.deepEqual(error.options, { - title: "T3 Code", + title: "V12", width: 1100, height: 780, minWidth: 840, @@ -93,7 +93,7 @@ describe("ElectronWindow", () => { backgroundColor: "#101010", webPreferences: { preload: "/tmp/preload.js", - partition: "persist:t3code-preview-test", + partition: "persist:v12-preview-test", sandbox: true, contextIsolation: true, nodeIntegration: false, @@ -103,7 +103,7 @@ describe("ElectronWindow", () => { assert.isFalse("icon" in error.options); assert.isFalse("spellcheck" in error.options.webPreferences); assert.strictEqual(error.cause, cause); - assert.equal(error.message, 'Failed to create Electron BrowserWindow "T3 Code" (1100x780).'); + assert.equal(error.message, 'Failed to create Electron BrowserWindow "V12" (1100x780).'); assert.notInclude(error.message, cause.message); assert.deepEqual(browserWindowMock.mock.calls, [[options]]); }).pipe(Effect.provide(TestLayer)), diff --git a/apps/desktop/src/electron/ElectronWindow.ts b/apps/desktop/src/electron/ElectronWindow.ts index dacb2eebb47..c5fcabe1bcf 100644 --- a/apps/desktop/src/electron/ElectronWindow.ts +++ b/apps/desktop/src/electron/ElectronWindow.ts @@ -1,4 +1,4 @@ -import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; +import { HostProcessPlatform } from "@v12/shared/hostProcess"; import * as Context from "effect/Context"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; @@ -92,7 +92,7 @@ export class ElectronWindow extends Context.Service< sync: (window: Electron.BrowserWindow) => Effect.Effect, ) => Effect.Effect; } ->()("@t3tools/desktop/electron/ElectronWindow") {} +>()("@v12/desktop/electron/ElectronWindow") {} export const make = Effect.gen(function* () { const platform = yield* HostProcessPlatform; diff --git a/apps/desktop/src/ipc/DesktopIpc.ts b/apps/desktop/src/ipc/DesktopIpc.ts index e948571cc62..22ca05f1044 100644 --- a/apps/desktop/src/ipc/DesktopIpc.ts +++ b/apps/desktop/src/ipc/DesktopIpc.ts @@ -77,7 +77,7 @@ export class DesktopIpc extends Context.Service< input: DesktopSyncIpcMethod, ) => Effect.Effect; } ->()("@t3tools/desktop/ipc/DesktopIpc") {} +>()("@v12/desktop/ipc/DesktopIpc") {} export const make = (ipcMain: DesktopIpcMain): DesktopIpc["Service"] => DesktopIpc.of({ diff --git a/apps/desktop/src/ipc/methods/clientSettings.ts b/apps/desktop/src/ipc/methods/clientSettings.ts index dd0625759e9..c7ebfe4ce95 100644 --- a/apps/desktop/src/ipc/methods/clientSettings.ts +++ b/apps/desktop/src/ipc/methods/clientSettings.ts @@ -1,4 +1,4 @@ -import { ClientSettingsSchema } from "@t3tools/contracts"; +import { ClientSettingsSchema } from "@v12/contracts"; import * as Effect from "effect/Effect"; import * as Option from "effect/Option"; import * as Schema from "effect/Schema"; diff --git a/apps/desktop/src/ipc/methods/preview.ts b/apps/desktop/src/ipc/methods/preview.ts index 2abf53ac284..c51a07df8e3 100644 --- a/apps/desktop/src/ipc/methods/preview.ts +++ b/apps/desktop/src/ipc/methods/preview.ts @@ -18,7 +18,7 @@ import { PreviewAnnotationPayloadSchema, PreviewAutomationSnapshot, PreviewAutomationStatus, -} from "@t3tools/contracts"; +} from "@v12/contracts"; import * as Effect from "effect/Effect"; import * as Schema from "effect/Schema"; import * as NodeURL from "node:url"; diff --git a/apps/desktop/src/ipc/methods/serverExposure.ts b/apps/desktop/src/ipc/methods/serverExposure.ts index 9a9ce768973..8eccdb295f4 100644 --- a/apps/desktop/src/ipc/methods/serverExposure.ts +++ b/apps/desktop/src/ipc/methods/serverExposure.ts @@ -2,7 +2,7 @@ import { AdvertisedEndpoint, DesktopServerExposureModeSchema, DesktopServerExposureStateSchema, -} from "@t3tools/contracts"; +} from "@v12/contracts"; import * as Effect from "effect/Effect"; import * as Schema from "effect/Schema"; diff --git a/apps/desktop/src/ipc/methods/sshEnvironment.test.ts b/apps/desktop/src/ipc/methods/sshEnvironment.test.ts index fa53486d5e2..c3da3f36d1e 100644 --- a/apps/desktop/src/ipc/methods/sshEnvironment.test.ts +++ b/apps/desktop/src/ipc/methods/sshEnvironment.test.ts @@ -1,5 +1,5 @@ import { assert, describe, it } from "@effect/vitest"; -import { SshHttpBridgeError } from "@t3tools/ssh/errors"; +import { SshHttpBridgeError } from "@v12/ssh/errors"; import * as Cause from "effect/Cause"; import * as Effect from "effect/Effect"; import * as Exit from "effect/Exit"; @@ -61,7 +61,7 @@ describe("SSH environment IPC", () => { serverVersion: "1.2.3", capabilities: { repositoryIdentity: true }, }); - assert.deepEqual(requestUrls, ["http://127.0.0.1:41773/.well-known/t3/environment"]); + assert.deepEqual(requestUrls, ["http://127.0.0.1:41773/.well-known/v12/environment"]); }).pipe(Effect.provide(layer)); }); diff --git a/apps/desktop/src/ipc/methods/sshEnvironment.ts b/apps/desktop/src/ipc/methods/sshEnvironment.ts index 9c9af2a4e2b..b9f61cda5a5 100644 --- a/apps/desktop/src/ipc/methods/sshEnvironment.ts +++ b/apps/desktop/src/ipc/methods/sshEnvironment.ts @@ -4,8 +4,8 @@ import { issueRemoteWebSocketTicket, RemoteEnvironmentAuthUndeclaredStatusError, type RemoteEnvironmentAuthError, -} from "@t3tools/client-runtime/authorization"; -import { fetchRemoteEnvironmentDescriptor } from "@t3tools/client-runtime/environment"; +} from "@v12/client-runtime/authorization"; +import { fetchRemoteEnvironmentDescriptor } from "@v12/client-runtime/environment"; import { EnvironmentAuthInvalidError, DesktopDiscoveredSshHostSchema, @@ -25,9 +25,9 @@ import { AuthAccessTokenResult, AuthSessionState, AuthWebSocketTicketResult, -} from "@t3tools/contracts"; -import { SshHttpBridgeError } from "@t3tools/ssh/errors"; -import { resolveLoopbackSshHttpBaseUrl } from "@t3tools/ssh/tunnel"; +} from "@v12/contracts"; +import { SshHttpBridgeError } from "@v12/ssh/errors"; +import { resolveLoopbackSshHttpBaseUrl } from "@v12/ssh/tunnel"; import * as Data from "effect/Data"; import * as Effect from "effect/Effect"; import * as Schema from "effect/Schema"; diff --git a/apps/desktop/src/ipc/methods/updates.ts b/apps/desktop/src/ipc/methods/updates.ts index b2212609030..7c3454fbcb7 100644 --- a/apps/desktop/src/ipc/methods/updates.ts +++ b/apps/desktop/src/ipc/methods/updates.ts @@ -3,7 +3,7 @@ import { DesktopUpdateChannelSchema, DesktopUpdateCheckResultSchema, DesktopUpdateStateSchema, -} from "@t3tools/contracts"; +} from "@v12/contracts"; import * as Effect from "effect/Effect"; import * as Schema from "effect/Schema"; diff --git a/apps/desktop/src/ipc/methods/window.ts b/apps/desktop/src/ipc/methods/window.ts index a4e98aaabad..fa248b700d5 100644 --- a/apps/desktop/src/ipc/methods/window.ts +++ b/apps/desktop/src/ipc/methods/window.ts @@ -6,7 +6,7 @@ import { PickFolderOptionsSchema, PRIMARY_LOCAL_ENVIRONMENT_ID, type DesktopEnvironmentBootstrap, -} from "@t3tools/contracts"; +} from "@v12/contracts"; import * as Effect from "effect/Effect"; import * as Option from "effect/Option"; import * as Schema from "effect/Schema"; diff --git a/apps/desktop/src/ipc/methods/wsl.test.ts b/apps/desktop/src/ipc/methods/wsl.test.ts index 3e07ae7f39b..93528a93be2 100644 --- a/apps/desktop/src/ipc/methods/wsl.test.ts +++ b/apps/desktop/src/ipc/methods/wsl.test.ts @@ -1,4 +1,4 @@ -import { DesktopWslStateSchema } from "@t3tools/contracts"; +import { DesktopWslStateSchema } from "@v12/contracts"; import { assert, describe, it } from "@effect/vitest"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; diff --git a/apps/desktop/src/ipc/methods/wsl.ts b/apps/desktop/src/ipc/methods/wsl.ts index 1d0dc262bae..6a3a51505d8 100644 --- a/apps/desktop/src/ipc/methods/wsl.ts +++ b/apps/desktop/src/ipc/methods/wsl.ts @@ -1,4 +1,4 @@ -import { DesktopWslStateSchema, type DesktopWslState } from "@t3tools/contracts"; +import { DesktopWslStateSchema, type DesktopWslState } from "@v12/contracts"; import * as Effect from "effect/Effect"; import * as Option from "effect/Option"; import * as Schema from "effect/Schema"; diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 7a51700e0fd..97929fab79d 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -8,10 +8,10 @@ import * as Option from "effect/Option"; import * as Electron from "electron"; -import * as NetService from "@t3tools/shared/Net"; -import { HostProcessArchitecture, HostProcessPlatform } from "@t3tools/shared/hostProcess"; -import { resolveRemoteT3CliPackageSpec } from "@t3tools/ssh/command"; -import type { RemoteT3RunnerOptions } from "@t3tools/ssh/tunnel"; +import * as NetService from "@v12/shared/Net"; +import { HostProcessArchitecture, HostProcessPlatform } from "@v12/shared/hostProcess"; +import { resolveRemoteV12CliPackageSpec } from "@v12/ssh/command"; +import type { RemoteV12RunnerOptions } from "@v12/ssh/tunnel"; import serverPackageJson from "../../server/package.json" with { type: "json" }; import * as DesktopIpc from "./ipc/DesktopIpc.ts"; @@ -73,8 +73,8 @@ const desktopEnvironmentLayer = Layer.unwrap( const resolveDesktopSshCliRunner = ( environment: DesktopEnvironment.DesktopEnvironment["Service"], settings: DesktopAppSettings.DesktopSettings, -): RemoteT3RunnerOptions => { - const devRemoteEntryPath = Option.getOrUndefined(environment.devRemoteT3ServerEntryPath); +): RemoteV12RunnerOptions => { + const devRemoteEntryPath = Option.getOrUndefined(environment.devRemoteV12ServerEntryPath); if (environment.isDevelopment && devRemoteEntryPath !== undefined) { return { nodeScriptPath: devRemoteEntryPath, @@ -82,7 +82,7 @@ const resolveDesktopSshCliRunner = ( }; } return { - packageSpec: resolveRemoteT3CliPackageSpec({ + packageSpec: resolveRemoteV12CliPackageSpec({ appVersion: environment.appVersion, updateChannel: settings.updateChannel, isDevelopment: environment.isDevelopment, diff --git a/apps/desktop/src/preload.ts b/apps/desktop/src/preload.ts index 9f92cfcf2fa..6e8f75b92f1 100644 --- a/apps/desktop/src/preload.ts +++ b/apps/desktop/src/preload.ts @@ -3,7 +3,7 @@ import type { DesktopPreviewPointerEvent, DesktopPreviewRecordingFrame, DesktopPreviewTabState, -} from "@t3tools/contracts"; +} from "@v12/contracts"; import { exposeClerkBridge } from "@clerk/electron/preload"; import { contextBridge, ipcRenderer } from "electron"; diff --git a/apps/desktop/src/preview/Annotation.css b/apps/desktop/src/preview/Annotation.css index 89676a22d58..b24e25a710d 100644 --- a/apps/desktop/src/preview/Annotation.css +++ b/apps/desktop/src/preview/Annotation.css @@ -1,55 +1,55 @@ @import "tailwindcss"; @theme inline { - --font-sans: var(--t3-font-sans); - --font-mono: var(--t3-font-mono); - --color-background: var(--t3-background); - --color-foreground: var(--t3-foreground); - --color-popover: var(--t3-popover); - --color-popover-foreground: var(--t3-popover-foreground); - --color-primary: var(--t3-primary); - --color-primary-foreground: var(--t3-primary-foreground); - --color-muted: var(--t3-muted); - --color-muted-foreground: var(--t3-muted-foreground); - --color-accent: var(--t3-accent); - --color-accent-foreground: var(--t3-accent-foreground); - --color-border: var(--t3-border); - --color-input: var(--t3-input); - --color-ring: var(--t3-ring); - --radius-sm: calc(var(--t3-radius) - 4px); - --radius-md: calc(var(--t3-radius) - 2px); - --radius-lg: var(--t3-radius); - --radius-xl: calc(var(--t3-radius) + 4px); - --radius-2xl: calc(var(--t3-radius) + 8px); + --font-sans: var(--v12-font-sans); + --font-mono: var(--v12-font-mono); + --color-background: var(--v12-background); + --color-foreground: var(--v12-foreground); + --color-popover: var(--v12-popover); + --color-popover-foreground: var(--v12-popover-foreground); + --color-primary: var(--v12-primary); + --color-primary-foreground: var(--v12-primary-foreground); + --color-muted: var(--v12-muted); + --color-muted-foreground: var(--v12-muted-foreground); + --color-accent: var(--v12-accent); + --color-accent-foreground: var(--v12-accent-foreground); + --color-border: var(--v12-border); + --color-input: var(--v12-input); + --color-ring: var(--v12-ring); + --radius-sm: calc(var(--v12-radius) - 4px); + --radius-md: calc(var(--v12-radius) - 2px); + --radius-lg: var(--v12-radius); + --radius-xl: calc(var(--v12-radius) + 4px); + --radius-2xl: calc(var(--v12-radius) + 8px); } :host { - --t3-font-sans: + --v12-font-sans: "DM Sans Variable", "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif; - --t3-font-mono: + --v12-font-mono: "SF Mono", "SFMono-Regular", "JetBrains Mono", Consolas, "Liberation Mono", Menlo, monospace; - --t3-radius: 0.625rem; - --t3-background: white; - --t3-foreground: oklch(0.269 0 0); - --t3-popover: white; - --t3-popover-foreground: oklch(0.269 0 0); - --t3-primary: oklch(0.488 0.217 264); - --t3-primary-foreground: white; - --t3-muted: rgb(0 0 0 / 4%); - --t3-muted-foreground: oklch(0.556 0 0); - --t3-accent: rgb(0 0 0 / 4%); - --t3-accent-foreground: oklch(0.269 0 0); - --t3-border: rgb(0 0 0 / 8%); - --t3-input: rgb(0 0 0 / 10%); - --t3-ring: oklch(0.488 0.217 264); - color: var(--t3-foreground); - font-family: var(--t3-font-sans); + --v12-radius: 0.625rem; + --v12-background: white; + --v12-foreground: oklch(0.269 0 0); + --v12-popover: white; + --v12-popover-foreground: oklch(0.269 0 0); + --v12-primary: oklch(0.488 0.217 264); + --v12-primary-foreground: white; + --v12-muted: rgb(0 0 0 / 4%); + --v12-muted-foreground: oklch(0.556 0 0); + --v12-accent: rgb(0 0 0 / 4%); + --v12-accent-foreground: oklch(0.269 0 0); + --v12-border: rgb(0 0 0 / 8%); + --v12-input: rgb(0 0 0 / 10%); + --v12-ring: oklch(0.488 0.217 264); + color: var(--v12-foreground); + font-family: var(--v12-font-sans); } * { box-sizing: border-box; - border-color: var(--t3-border); + border-color: var(--v12-border); } button, @@ -63,6 +63,6 @@ button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { - outline: 2px solid color-mix(in srgb, var(--t3-ring) 72%, transparent); + outline: 2px solid color-mix(in srgb, var(--v12-ring) 72%, transparent); outline-offset: 1px; } diff --git a/apps/desktop/src/preview/AnnotationStyles.generated.ts b/apps/desktop/src/preview/AnnotationStyles.generated.ts index 5b6b73c8ba7..7b42a30b7f7 100644 --- a/apps/desktop/src/preview/AnnotationStyles.generated.ts +++ b/apps/desktop/src/preview/AnnotationStyles.generated.ts @@ -1,3 +1,3 @@ // Generated by scripts/build-preview-annotation-css.mjs. Do not edit. export const previewAnnotationStyles = - '/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */\n@layer properties;\n:root, :host {\n --spacing: 0.25rem;\n --text-xs: 0.75rem;\n --text-xs--line-height: calc(1 / 0.75);\n --text-sm: 0.875rem;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --blur-xl: 24px;\n --default-font-family: var(--t3-font-sans);\n --default-mono-font-family: var(--t3-font-mono);\n}\n*, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n}\nhtml, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, \'Apple Color Emoji\', \'Segoe UI Emoji\', \'Segoe UI Symbol\', \'Noto Color Emoji\');\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n}\nhr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n}\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\nh1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n}\na {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n}\nb, strong {\n font-weight: bolder;\n}\ncode, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \'Liberation Mono\', \'Courier New\', monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n}\nsmall {\n font-size: 80%;\n}\nsub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsub {\n bottom: -0.25em;\n}\nsup {\n top: -0.5em;\n}\ntable {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n}\n:-moz-focusring {\n outline: auto;\n}\nprogress {\n vertical-align: baseline;\n}\nsummary {\n display: list-item;\n}\nol, ul, menu {\n list-style: none;\n}\nimg, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n}\nimg, video {\n max-width: 100%;\n height: auto;\n}\nbutton, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n}\n:where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n}\n:where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n}\n::file-selector-button {\n margin-inline-end: 4px;\n}\n::placeholder {\n opacity: 1;\n}\n@supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n}\ntextarea {\n resize: vertical;\n}\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n}\n::-webkit-datetime-edit {\n display: inline-flex;\n}\n::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n}\n::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n}\n::-webkit-calendar-picker-indicator {\n line-height: 1;\n}\n:-moz-ui-invalid {\n box-shadow: none;\n}\nbutton, input:where([type=\'button\'], [type=\'reset\'], [type=\'submit\']), ::file-selector-button {\n appearance: button;\n}\n::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n}\n[hidden]:where(:not([hidden=\'until-found\'])) {\n display: none !important;\n}\n.pointer-events-auto {\n pointer-events: auto;\n}\n.pointer-events-none {\n pointer-events: none;\n}\n.absolute {\n position: absolute;\n}\n.fixed {\n position: fixed;\n}\n.inset-0 {\n inset: calc(var(--spacing) * 0);\n}\n.top-1\\/2 {\n top: calc(1 / 2 * 100%);\n}\n.top-2\\.5 {\n top: calc(var(--spacing) * 2.5);\n}\n.right-2 {\n right: calc(var(--spacing) * 2);\n}\n.left-1\\/2 {\n left: calc(1 / 2 * 100%);\n}\n.z-1 {\n z-index: 1;\n}\n.block {\n display: block;\n}\n.flex {\n display: flex;\n}\n.grid {\n display: grid;\n}\n.hidden {\n display: none;\n}\n.inline-flex {\n display: inline-flex;\n}\n.h-7 {\n height: calc(var(--spacing) * 7);\n}\n.h-8 {\n height: calc(var(--spacing) * 8);\n}\n.max-h-24 {\n max-height: calc(var(--spacing) * 24);\n}\n.max-h-\\[calc\\(100vh-16px\\)\\] {\n max-height: calc(100vh - 16px);\n}\n.max-h-\\[min\\(176px\\,calc\\(100vh-180px\\)\\)\\] {\n max-height: min(176px, calc(100vh - 180px));\n}\n.min-h-7 {\n min-height: calc(var(--spacing) * 7);\n}\n.min-h-8 {\n min-height: calc(var(--spacing) * 8);\n}\n.w-6 {\n width: calc(var(--spacing) * 6);\n}\n.w-8 {\n width: calc(var(--spacing) * 8);\n}\n.w-\\[min\\(360px\\,calc\\(100vw-16px\\)\\)\\] {\n width: min(360px, calc(100vw - 16px));\n}\n.w-full {\n width: 100%;\n}\n.max-w-70 {\n max-width: calc(var(--spacing) * 70);\n}\n.min-w-0 {\n min-width: calc(var(--spacing) * 0);\n}\n.flex-1 {\n flex: 1;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n}\n.-translate-y-1\\/2 {\n --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n}\n.cursor-grab {\n cursor: grab;\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.resize {\n resize: both;\n}\n.resize-none {\n resize: none;\n}\n.appearance-none {\n appearance: none;\n}\n.grid-cols-\\[22px_minmax\\(0\\,1fr\\)\\] {\n grid-template-columns: 22px minmax(0,1fr);\n}\n.grid-cols-\\[82px_minmax\\(0\\,1fr\\)\\] {\n grid-template-columns: 82px minmax(0,1fr);\n}\n.flex-col {\n flex-direction: column;\n}\n.items-center {\n align-items: center;\n}\n.items-start {\n align-items: flex-start;\n}\n.justify-center {\n justify-content: center;\n}\n.gap-0\\.5 {\n gap: calc(var(--spacing) * 0.5);\n}\n.gap-1 {\n gap: calc(var(--spacing) * 1);\n}\n.gap-2 {\n gap: calc(var(--spacing) * 2);\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-y-hidden {\n overflow-y: hidden;\n}\n.rounded-lg {\n border-radius: var(--t3-radius);\n}\n.rounded-md {\n border-radius: calc(var(--t3-radius) - 2px);\n}\n.rounded-xl {\n border-radius: calc(var(--t3-radius) + 4px);\n}\n.border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n}\n.border-0 {\n border-style: var(--tw-border-style);\n border-width: 0px;\n}\n.border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n}\n.border-b {\n border-bottom-style: var(--tw-border-style);\n border-bottom-width: 1px;\n}\n.border-border {\n border-color: var(--t3-border);\n}\n.border-input {\n border-color: var(--t3-input);\n}\n.border-primary {\n border-color: var(--t3-primary);\n}\n.border-transparent {\n border-color: transparent;\n}\n.border-b-transparent {\n border-bottom-color: transparent;\n}\n.bg-background {\n background-color: var(--t3-background);\n}\n.bg-muted {\n background-color: var(--t3-muted);\n}\n.bg-muted\\/40 {\n background-color: var(--t3-muted);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--t3-muted) 40%, transparent);\n }\n}\n.bg-popover\\/95 {\n background-color: var(--t3-popover);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--t3-popover) 95%, transparent);\n }\n}\n.bg-popover\\/96 {\n background-color: var(--t3-popover);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--t3-popover) 96%, transparent);\n }\n}\n.bg-primary {\n background-color: var(--t3-primary);\n}\n.bg-primary\\/10 {\n background-color: var(--t3-primary);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--t3-primary) 10%, transparent);\n }\n}\n.bg-transparent {\n background-color: transparent;\n}\n.p-0 {\n padding: calc(var(--spacing) * 0);\n}\n.p-1 {\n padding: calc(var(--spacing) * 1);\n}\n.p-2 {\n padding: calc(var(--spacing) * 2);\n}\n.px-0 {\n padding-inline: calc(var(--spacing) * 0);\n}\n.px-1 {\n padding-inline: calc(var(--spacing) * 1);\n}\n.px-2 {\n padding-inline: calc(var(--spacing) * 2);\n}\n.px-2\\.5 {\n padding-inline: calc(var(--spacing) * 2.5);\n}\n.px-3 {\n padding-inline: calc(var(--spacing) * 3);\n}\n.py-1 {\n padding-block: calc(var(--spacing) * 1);\n}\n.py-1\\.5 {\n padding-block: calc(var(--spacing) * 1.5);\n}\n.py-2 {\n padding-block: calc(var(--spacing) * 2);\n}\n.font-mono {\n font-family: var(--t3-font-mono);\n}\n.font-sans {\n font-family: var(--t3-font-sans);\n}\n.text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n}\n.text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n}\n.text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n}\n.leading-5 {\n --tw-leading: calc(var(--spacing) * 5);\n line-height: calc(var(--spacing) * 5);\n}\n.font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n}\n.font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n}\n.font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n}\n.text-foreground {\n color: var(--t3-foreground);\n}\n.text-muted-foreground {\n color: var(--t3-muted-foreground);\n}\n.text-popover-foreground {\n color: var(--t3-popover-foreground);\n}\n.text-primary {\n color: var(--t3-primary);\n}\n.text-primary-foreground {\n color: var(--t3-primary-foreground);\n}\n.shadow-2xl {\n --tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, rgb(0 0 0 / 0.25));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.shadow-lg {\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.shadow-md {\n --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.shadow-sm {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.shadow-xs {\n --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.ring-0 {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.blur {\n --tw-blur: blur(8px);\n filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);\n}\n.backdrop-blur-xl {\n --tw-backdrop-blur: blur(var(--blur-xl));\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n}\n.outline-none {\n --tw-outline-style: none;\n outline-style: none;\n}\n.select-none {\n -webkit-user-select: none;\n user-select: none;\n}\n.placeholder\\:text-muted-foreground {\n &::placeholder {\n color: var(--t3-muted-foreground);\n }\n}\n.hover\\:bg-accent {\n &:hover {\n @media (hover: hover) {\n background-color: var(--t3-accent);\n }\n }\n}\n.hover\\:bg-primary\\/90 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--t3-primary);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--t3-primary) 90%, transparent);\n }\n }\n }\n}\n.hover\\:text-accent-foreground {\n &:hover {\n @media (hover: hover) {\n color: var(--t3-accent-foreground);\n }\n }\n}\n.focus\\:border-b-primary {\n &:focus {\n border-bottom-color: var(--t3-primary);\n }\n}\n.focus\\:ring-0 {\n &:focus {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n}\n.focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n}\n.disabled\\:pointer-events-none {\n &:disabled {\n pointer-events: none;\n }\n}\n.disabled\\:opacity-60 {\n &:disabled {\n opacity: 60%;\n }\n}\n:host {\n --t3-font-sans: "DM Sans Variable", "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui,\n sans-serif;\n --t3-font-mono: "SF Mono", "SFMono-Regular", "JetBrains Mono", Consolas, "Liberation Mono", Menlo, monospace;\n --t3-radius: 0.625rem;\n --t3-background: white;\n --t3-foreground: oklch(0.269 0 0);\n --t3-popover: white;\n --t3-popover-foreground: oklch(0.269 0 0);\n --t3-primary: oklch(0.488 0.217 264);\n --t3-primary-foreground: white;\n --t3-muted: rgb(0 0 0 / 4%);\n --t3-muted-foreground: oklch(0.556 0 0);\n --t3-accent: rgb(0 0 0 / 4%);\n --t3-accent-foreground: oklch(0.269 0 0);\n --t3-border: rgb(0 0 0 / 8%);\n --t3-input: rgb(0 0 0 / 10%);\n --t3-ring: oklch(0.488 0.217 264);\n color: var(--t3-foreground);\n font-family: var(--t3-font-sans);\n}\n* {\n box-sizing: border-box;\n border-color: var(--t3-border);\n}\nbutton, input, select, textarea {\n font: inherit;\n}\nbutton:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {\n outline: 2px solid var(--t3-ring);\n @supports (color: color-mix(in lab, red, red)) {\n outline: 2px solid color-mix(in srgb, var(--t3-ring) 72%, transparent);\n }\n outline-offset: 1px;\n}\n@property --tw-translate-x {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-y {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-z {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-border-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-leading {\n syntax: "*";\n inherits: false;\n}\n@property --tw-font-weight {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: "";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: "*";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-blur {\n syntax: "*";\n inherits: false;\n}\n@property --tw-brightness {\n syntax: "*";\n inherits: false;\n}\n@property --tw-contrast {\n syntax: "*";\n inherits: false;\n}\n@property --tw-grayscale {\n syntax: "*";\n inherits: false;\n}\n@property --tw-hue-rotate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-invert {\n syntax: "*";\n inherits: false;\n}\n@property --tw-opacity {\n syntax: "*";\n inherits: false;\n}\n@property --tw-saturate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-sepia {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-drop-shadow-size {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-blur {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-brightness {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-contrast {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-grayscale {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-hue-rotate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-invert {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-opacity {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-saturate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-sepia {\n syntax: "*";\n inherits: false;\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-border-style: solid;\n --tw-leading: initial;\n --tw-font-weight: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-blur: initial;\n --tw-brightness: initial;\n --tw-contrast: initial;\n --tw-grayscale: initial;\n --tw-hue-rotate: initial;\n --tw-invert: initial;\n --tw-opacity: initial;\n --tw-saturate: initial;\n --tw-sepia: initial;\n --tw-drop-shadow: initial;\n --tw-drop-shadow-color: initial;\n --tw-drop-shadow-alpha: 100%;\n --tw-drop-shadow-size: initial;\n --tw-backdrop-blur: initial;\n --tw-backdrop-brightness: initial;\n --tw-backdrop-contrast: initial;\n --tw-backdrop-grayscale: initial;\n --tw-backdrop-hue-rotate: initial;\n --tw-backdrop-invert: initial;\n --tw-backdrop-opacity: initial;\n --tw-backdrop-saturate: initial;\n --tw-backdrop-sepia: initial;\n }\n }\n}\n'; + '/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */\n@layer properties;\n:root, :host {\n --spacing: 0.25rem;\n --text-xs: 0.75rem;\n --text-xs--line-height: calc(1 / 0.75);\n --text-sm: 0.875rem;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --blur-xl: 24px;\n --default-font-family: var(--v12-font-sans);\n --default-mono-font-family: var(--v12-font-mono);\n}\n*, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n}\nhtml, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, \'Apple Color Emoji\', \'Segoe UI Emoji\', \'Segoe UI Symbol\', \'Noto Color Emoji\');\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n}\nhr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n}\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\nh1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n}\na {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n}\nb, strong {\n font-weight: bolder;\n}\ncode, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \'Liberation Mono\', \'Courier New\', monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n}\nsmall {\n font-size: 80%;\n}\nsub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsub {\n bottom: -0.25em;\n}\nsup {\n top: -0.5em;\n}\ntable {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n}\n:-moz-focusring {\n outline: auto;\n}\nprogress {\n vertical-align: baseline;\n}\nsummary {\n display: list-item;\n}\nol, ul, menu {\n list-style: none;\n}\nimg, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n}\nimg, video {\n max-width: 100%;\n height: auto;\n}\nbutton, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n}\n:where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n}\n:where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n}\n::file-selector-button {\n margin-inline-end: 4px;\n}\n::placeholder {\n opacity: 1;\n}\n@supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n}\ntextarea {\n resize: vertical;\n}\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n}\n::-webkit-datetime-edit {\n display: inline-flex;\n}\n::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n}\n::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n}\n::-webkit-calendar-picker-indicator {\n line-height: 1;\n}\n:-moz-ui-invalid {\n box-shadow: none;\n}\nbutton, input:where([type=\'button\'], [type=\'reset\'], [type=\'submit\']), ::file-selector-button {\n appearance: button;\n}\n::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n}\n[hidden]:where(:not([hidden=\'until-found\'])) {\n display: none !important;\n}\n.pointer-events-auto {\n pointer-events: auto;\n}\n.pointer-events-none {\n pointer-events: none;\n}\n.absolute {\n position: absolute;\n}\n.fixed {\n position: fixed;\n}\n.inset-0 {\n inset: calc(var(--spacing) * 0);\n}\n.top-1\\/2 {\n top: calc(1 / 2 * 100%);\n}\n.top-2\\.5 {\n top: calc(var(--spacing) * 2.5);\n}\n.right-2 {\n right: calc(var(--spacing) * 2);\n}\n.left-1\\/2 {\n left: calc(1 / 2 * 100%);\n}\n.z-1 {\n z-index: 1;\n}\n.block {\n display: block;\n}\n.flex {\n display: flex;\n}\n.grid {\n display: grid;\n}\n.hidden {\n display: none;\n}\n.inline-flex {\n display: inline-flex;\n}\n.h-7 {\n height: calc(var(--spacing) * 7);\n}\n.h-8 {\n height: calc(var(--spacing) * 8);\n}\n.max-h-24 {\n max-height: calc(var(--spacing) * 24);\n}\n.max-h-\\[calc\\(100vh-16px\\)\\] {\n max-height: calc(100vh - 16px);\n}\n.max-h-\\[min\\(176px\\,calc\\(100vh-180px\\)\\)\\] {\n max-height: min(176px, calc(100vh - 180px));\n}\n.min-h-7 {\n min-height: calc(var(--spacing) * 7);\n}\n.min-h-8 {\n min-height: calc(var(--spacing) * 8);\n}\n.w-6 {\n width: calc(var(--spacing) * 6);\n}\n.w-8 {\n width: calc(var(--spacing) * 8);\n}\n.w-\\[min\\(360px\\,calc\\(100vw-16px\\)\\)\\] {\n width: min(360px, calc(100vw - 16px));\n}\n.w-full {\n width: 100%;\n}\n.max-w-70 {\n max-width: calc(var(--spacing) * 70);\n}\n.min-w-0 {\n min-width: calc(var(--spacing) * 0);\n}\n.flex-1 {\n flex: 1;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n}\n.-translate-y-1\\/2 {\n --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n}\n.cursor-grab {\n cursor: grab;\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.resize {\n resize: both;\n}\n.resize-none {\n resize: none;\n}\n.appearance-none {\n appearance: none;\n}\n.grid-cols-\\[22px_minmax\\(0\\,1fr\\)\\] {\n grid-template-columns: 22px minmax(0,1fr);\n}\n.grid-cols-\\[82px_minmax\\(0\\,1fr\\)\\] {\n grid-template-columns: 82px minmax(0,1fr);\n}\n.flex-col {\n flex-direction: column;\n}\n.items-center {\n align-items: center;\n}\n.items-start {\n align-items: flex-start;\n}\n.justify-center {\n justify-content: center;\n}\n.gap-0\\.5 {\n gap: calc(var(--spacing) * 0.5);\n}\n.gap-1 {\n gap: calc(var(--spacing) * 1);\n}\n.gap-2 {\n gap: calc(var(--spacing) * 2);\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-y-hidden {\n overflow-y: hidden;\n}\n.rounded-lg {\n border-radius: var(--v12-radius);\n}\n.rounded-md {\n border-radius: calc(var(--v12-radius) - 2px);\n}\n.rounded-xl {\n border-radius: calc(var(--v12-radius) + 4px);\n}\n.border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n}\n.border-0 {\n border-style: var(--tw-border-style);\n border-width: 0px;\n}\n.border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n}\n.border-b {\n border-bottom-style: var(--tw-border-style);\n border-bottom-width: 1px;\n}\n.border-border {\n border-color: var(--v12-border);\n}\n.border-input {\n border-color: var(--v12-input);\n}\n.border-primary {\n border-color: var(--v12-primary);\n}\n.border-transparent {\n border-color: transparent;\n}\n.border-b-transparent {\n border-bottom-color: transparent;\n}\n.bg-background {\n background-color: var(--v12-background);\n}\n.bg-muted {\n background-color: var(--v12-muted);\n}\n.bg-muted\\/40 {\n background-color: var(--v12-muted);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--v12-muted) 40%, transparent);\n }\n}\n.bg-popover\\/95 {\n background-color: var(--v12-popover);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--v12-popover) 95%, transparent);\n }\n}\n.bg-popover\\/96 {\n background-color: var(--v12-popover);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--v12-popover) 96%, transparent);\n }\n}\n.bg-primary {\n background-color: var(--v12-primary);\n}\n.bg-primary\\/10 {\n background-color: var(--v12-primary);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--v12-primary) 10%, transparent);\n }\n}\n.bg-transparent {\n background-color: transparent;\n}\n.p-0 {\n padding: calc(var(--spacing) * 0);\n}\n.p-1 {\n padding: calc(var(--spacing) * 1);\n}\n.p-2 {\n padding: calc(var(--spacing) * 2);\n}\n.px-0 {\n padding-inline: calc(var(--spacing) * 0);\n}\n.px-1 {\n padding-inline: calc(var(--spacing) * 1);\n}\n.px-2 {\n padding-inline: calc(var(--spacing) * 2);\n}\n.px-2\\.5 {\n padding-inline: calc(var(--spacing) * 2.5);\n}\n.px-3 {\n padding-inline: calc(var(--spacing) * 3);\n}\n.py-1 {\n padding-block: calc(var(--spacing) * 1);\n}\n.py-1\\.5 {\n padding-block: calc(var(--spacing) * 1.5);\n}\n.py-2 {\n padding-block: calc(var(--spacing) * 2);\n}\n.font-mono {\n font-family: var(--v12-font-mono);\n}\n.font-sans {\n font-family: var(--v12-font-sans);\n}\n.text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n}\n.text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n}\n.text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n}\n.leading-5 {\n --tw-leading: calc(var(--spacing) * 5);\n line-height: calc(var(--spacing) * 5);\n}\n.font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n}\n.font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n}\n.font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n}\n.text-foreground {\n color: var(--v12-foreground);\n}\n.text-muted-foreground {\n color: var(--v12-muted-foreground);\n}\n.text-popover-foreground {\n color: var(--v12-popover-foreground);\n}\n.text-primary {\n color: var(--v12-primary);\n}\n.text-primary-foreground {\n color: var(--v12-primary-foreground);\n}\n.shadow-2xl {\n --tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, rgb(0 0 0 / 0.25));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.shadow-lg {\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.shadow-md {\n --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.shadow-sm {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.shadow-xs {\n --tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.05));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.ring-0 {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\n.blur {\n --tw-blur: blur(8px);\n filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);\n}\n.backdrop-blur-xl {\n --tw-backdrop-blur: blur(var(--blur-xl));\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n}\n.outline-none {\n --tw-outline-style: none;\n outline-style: none;\n}\n.select-none {\n -webkit-user-select: none;\n user-select: none;\n}\n.placeholder\\:text-muted-foreground {\n &::placeholder {\n color: var(--v12-muted-foreground);\n }\n}\n.hover\\:bg-accent {\n &:hover {\n @media (hover: hover) {\n background-color: var(--v12-accent);\n }\n }\n}\n.hover\\:bg-primary\\/90 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--v12-primary);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--v12-primary) 90%, transparent);\n }\n }\n }\n}\n.hover\\:text-accent-foreground {\n &:hover {\n @media (hover: hover) {\n color: var(--v12-accent-foreground);\n }\n }\n}\n.focus\\:border-b-primary {\n &:focus {\n border-bottom-color: var(--v12-primary);\n }\n}\n.focus\\:ring-0 {\n &:focus {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n}\n.focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n}\n.disabled\\:pointer-events-none {\n &:disabled {\n pointer-events: none;\n }\n}\n.disabled\\:opacity-60 {\n &:disabled {\n opacity: 60%;\n }\n}\n:host {\n --v12-font-sans: "DM Sans Variable", "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui,\n sans-serif;\n --v12-font-mono: "SF Mono", "SFMono-Regular", "JetBrains Mono", Consolas, "Liberation Mono", Menlo, monospace;\n --v12-radius: 0.625rem;\n --v12-background: white;\n --v12-foreground: oklch(0.269 0 0);\n --v12-popover: white;\n --v12-popover-foreground: oklch(0.269 0 0);\n --v12-primary: oklch(0.488 0.217 264);\n --v12-primary-foreground: white;\n --v12-muted: rgb(0 0 0 / 4%);\n --v12-muted-foreground: oklch(0.556 0 0);\n --v12-accent: rgb(0 0 0 / 4%);\n --v12-accent-foreground: oklch(0.269 0 0);\n --v12-border: rgb(0 0 0 / 8%);\n --v12-input: rgb(0 0 0 / 10%);\n --v12-ring: oklch(0.488 0.217 264);\n color: var(--v12-foreground);\n font-family: var(--v12-font-sans);\n}\n* {\n box-sizing: border-box;\n border-color: var(--v12-border);\n}\nbutton, input, select, textarea {\n font: inherit;\n}\nbutton:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {\n outline: 2px solid var(--v12-ring);\n @supports (color: color-mix(in lab, red, red)) {\n outline: 2px solid color-mix(in srgb, var(--v12-ring) 72%, transparent);\n }\n outline-offset: 1px;\n}\n@property --tw-translate-x {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-y {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-z {\n syntax: "*";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-border-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-leading {\n syntax: "*";\n inherits: false;\n}\n@property --tw-font-weight {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: "";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: "*";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-blur {\n syntax: "*";\n inherits: false;\n}\n@property --tw-brightness {\n syntax: "*";\n inherits: false;\n}\n@property --tw-contrast {\n syntax: "*";\n inherits: false;\n}\n@property --tw-grayscale {\n syntax: "*";\n inherits: false;\n}\n@property --tw-hue-rotate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-invert {\n syntax: "*";\n inherits: false;\n}\n@property --tw-opacity {\n syntax: "*";\n inherits: false;\n}\n@property --tw-saturate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-sepia {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-drop-shadow-size {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-blur {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-brightness {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-contrast {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-grayscale {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-hue-rotate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-invert {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-opacity {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-saturate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-sepia {\n syntax: "*";\n inherits: false;\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-border-style: solid;\n --tw-leading: initial;\n --tw-font-weight: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-blur: initial;\n --tw-brightness: initial;\n --tw-contrast: initial;\n --tw-grayscale: initial;\n --tw-hue-rotate: initial;\n --tw-invert: initial;\n --tw-opacity: initial;\n --tw-saturate: initial;\n --tw-sepia: initial;\n --tw-drop-shadow: initial;\n --tw-drop-shadow-color: initial;\n --tw-drop-shadow-alpha: 100%;\n --tw-drop-shadow-size: initial;\n --tw-backdrop-blur: initial;\n --tw-backdrop-brightness: initial;\n --tw-backdrop-contrast: initial;\n --tw-backdrop-grayscale: initial;\n --tw-backdrop-hue-rotate: initial;\n --tw-backdrop-invert: initial;\n --tw-backdrop-opacity: initial;\n --tw-backdrop-saturate: initial;\n --tw-backdrop-sepia: initial;\n }\n }\n}\n'; diff --git a/apps/desktop/src/preview/BrowserSession.test.ts b/apps/desktop/src/preview/BrowserSession.test.ts index e258bb2dfc5..59a2a75991e 100644 --- a/apps/desktop/src/preview/BrowserSession.test.ts +++ b/apps/desktop/src/preview/BrowserSession.test.ts @@ -38,7 +38,7 @@ describe("BrowserSession", () => { const browserSession = { clearCache: vi.fn(() => Promise.resolve()), clearStorageData: vi.fn(() => Promise.resolve()), - getUserAgent: vi.fn(() => "Mozilla/5.0 Electron/41.5.0 t3code/0.0.27"), + getUserAgent: vi.fn(() => "Mozilla/5.0 Electron/41.5.0 v12/0.0.27"), setPermissionRequestHandler: vi.fn(), setUserAgent: vi.fn(), }; @@ -55,7 +55,7 @@ describe("BrowserSession", () => { const first = yield* browserSessions.getSession("scope-a"); const second = yield* browserSessions.getSession("scope-a"); - assert.strictEqual(partition, "persist:t3code-preview-f051bb2c68cb7b2fe969"); + assert.strictEqual(partition, "persist:v12-preview-f051bb2c68cb7b2fe969"); assert.strictEqual(first, second); assert.strictEqual(fromPartition.mock.calls.length, 1); }).pipe(Effect.provide(layer)), diff --git a/apps/desktop/src/preview/BrowserSession.ts b/apps/desktop/src/preview/BrowserSession.ts index afa8dafe976..243b164bb2e 100644 --- a/apps/desktop/src/preview/BrowserSession.ts +++ b/apps/desktop/src/preview/BrowserSession.ts @@ -9,7 +9,7 @@ import * as PlatformError from "effect/PlatformError"; import * as Schema from "effect/Schema"; import * as SynchronizedRef from "effect/SynchronizedRef"; -const PREVIEW_PARTITION_PREFIX = "persist:t3code-preview-"; +const PREVIEW_PARTITION_PREFIX = "persist:v12-preview-"; export class BrowserSessionPartitionDerivationError extends Schema.TaggedErrorClass()( "BrowserSessionPartitionDerivationError", @@ -87,7 +87,7 @@ export class BrowserSession extends Context.Service< readonly clearCookies: () => Effect.Effect; readonly clearCache: () => Effect.Effect; } ->()("@t3tools/desktop/preview/BrowserSession") {} +>()("@v12/desktop/preview/BrowserSession") {} export const make = Effect.gen(function* BrowserSessionMake() { const crypto = yield* Crypto.Crypto; @@ -117,7 +117,7 @@ export const make = Effect.gen(function* BrowserSessionMake() { const userAgent = browserSession .getUserAgent() .replace(/Electron\/[\d.]+ /, "") - .replace(/\s*t3code\/[\d.]+/, ""); + .replace(/\s*v12\/[\d.]+/, ""); browserSession.setUserAgent(userAgent); browserSession.setPermissionRequestHandler((_webContents, permission, callback) => { const allowed = ["clipboard-read", "clipboard-write", "notifications", "geolocation"]; diff --git a/apps/desktop/src/preview/Manager.test.ts b/apps/desktop/src/preview/Manager.test.ts index 6e2df118c34..e4c6a13bf97 100644 --- a/apps/desktop/src/preview/Manager.test.ts +++ b/apps/desktop/src/preview/Manager.test.ts @@ -1,5 +1,5 @@ import { it as effectIt } from "@effect/vitest"; -import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; +import { HostProcessPlatform } from "@v12/shared/hostProcess"; import * as Cause from "effect/Cause"; import * as Effect from "effect/Effect"; import * as Exit from "effect/Exit"; @@ -61,8 +61,8 @@ vi.mock("electron", () => ({ const browserSessionLayer = Layer.succeed( BrowserSession.BrowserSession, BrowserSession.BrowserSession.of({ - getPartition: () => Effect.succeed("persist:t3code-preview-test"), - isPartition: (partition) => partition.startsWith("persist:t3code-preview-"), + getPartition: () => Effect.succeed("persist:v12-preview-test"), + isPartition: (partition) => partition.startsWith("persist:v12-preview-"), getSession: () => Effect.die("unexpected getSession"), clearCookies: () => Effect.void, clearCache: () => Effect.void, @@ -72,7 +72,7 @@ const browserSessionLayer = Layer.succeed( const environmentLayer = Layer.succeed( DesktopEnvironment.DesktopEnvironment, DesktopEnvironment.DesktopEnvironment.of({ - browserArtifactsDir: "/tmp/t3/dev/browser-artifacts", + browserArtifactsDir: "/tmp/v12/dev/browser-artifacts", } as DesktopEnvironment.DesktopEnvironment["Service"]), ); @@ -502,7 +502,7 @@ describe("PreviewManager", () => { const artifact = yield* manager.captureScreenshot("tab_1"); expect(capturePage).toHaveBeenCalledOnce(); - expect(mkdir).toHaveBeenCalledWith("/tmp/t3/dev/browser-artifacts"); + expect(mkdir).toHaveBeenCalledWith("/tmp/v12/dev/browser-artifacts"); expect(writeFile).toHaveBeenCalledWith(artifact.path, png); expect(artifact).toMatchObject({ tabId: "tab_1", @@ -582,19 +582,19 @@ describe("PreviewManager", () => { effectIt.effect("reveals only files inside the configured browser artifact directory", () => withManager((manager) => Effect.gen(function* () { - yield* manager.revealArtifact("/tmp/t3/dev/browser-artifacts/browser-screenshot-test.png"); + yield* manager.revealArtifact("/tmp/v12/dev/browser-artifacts/browser-screenshot-test.png"); expect(showItemInFolder).toHaveBeenCalledWith( - "/tmp/t3/dev/browser-artifacts/browser-screenshot-test.png", + "/tmp/v12/dev/browser-artifacts/browser-screenshot-test.png", ); - const exit = yield* Effect.exit(manager.revealArtifact("/tmp/t3/dev/settings.json")); + const exit = yield* Effect.exit(manager.revealArtifact("/tmp/v12/dev/settings.json")); expect(Exit.isFailure(exit)).toBe(true); if (Exit.isSuccess(exit)) return; const error = Option.getOrThrow(Cause.findErrorOption(exit.cause)); expect(error).toMatchObject({ _tag: "PreviewArtifactPathOutsideDirectoryError", - artifactPath: "/tmp/t3/dev/settings.json", - artifactDirectory: "/tmp/t3/dev/browser-artifacts", + artifactPath: "/tmp/v12/dev/settings.json", + artifactDirectory: "/tmp/v12/dev/browser-artifacts", }); expect("cause" in error).toBe(false); }), @@ -604,22 +604,22 @@ describe("PreviewManager", () => { effectIt.effect("copies screenshot artifacts to the system clipboard", () => withManager((manager) => Effect.gen(function* () { - const artifactPath = "/tmp/t3/dev/browser-artifacts/browser-screenshot-test.png"; + const artifactPath = "/tmp/v12/dev/browser-artifacts/browser-screenshot-test.png"; yield* manager.copyArtifactToClipboard(artifactPath); expect(createFromPath).toHaveBeenCalledWith(artifactPath); expect(writeImage).toHaveBeenCalledOnce(); const exit = yield* Effect.exit( - manager.copyArtifactToClipboard("/tmp/t3/dev/settings.json"), + manager.copyArtifactToClipboard("/tmp/v12/dev/settings.json"), ); expect(Exit.isFailure(exit)).toBe(true); if (Exit.isSuccess(exit)) return; const error = Option.getOrThrow(Cause.findErrorOption(exit.cause)); expect(error).toMatchObject({ _tag: "PreviewArtifactPathOutsideDirectoryError", - artifactPath: "/tmp/t3/dev/settings.json", - artifactDirectory: "/tmp/t3/dev/browser-artifacts", + artifactPath: "/tmp/v12/dev/settings.json", + artifactDirectory: "/tmp/v12/dev/browser-artifacts", }); expect("cause" in error).toBe(false); diff --git a/apps/desktop/src/preview/Manager.ts b/apps/desktop/src/preview/Manager.ts index 2d0360ef72c..2010f71625c 100644 --- a/apps/desktop/src/preview/Manager.ts +++ b/apps/desktop/src/preview/Manager.ts @@ -24,9 +24,9 @@ import type { PreviewAutomationStatus, PreviewAutomationTypeInput, PreviewAutomationWaitForInput, -} from "@t3tools/contracts"; -import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; -import { normalizePreviewUrl } from "@t3tools/shared/preview"; +} from "@v12/contracts"; +import { HostProcessPlatform } from "@v12/shared/hostProcess"; +import { normalizePreviewUrl } from "@v12/shared/preview"; import { type BrowserWindow, type Session, @@ -1025,7 +1025,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function const installed = yield* evaluateWithDebugger( tabId, send, - "Boolean(globalThis.__t3PlaywrightInjected)", + "Boolean(globalThis.__v12PlaywrightInjected)", true, ); if (installed) return; @@ -1981,7 +1981,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function send, `(() => { try { - const injected = globalThis.__t3PlaywrightInjected; + const injected = globalThis.__v12PlaywrightInjected; const parsed = injected.parseSelector(${locatorJson}); const element = injected.querySelector(parsed, document, true); if (!element) return { notFound: true }; @@ -2118,7 +2118,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function send, `(() => { try { - const element = ${locatorJson ? `(() => { const injected = globalThis.__t3PlaywrightInjected; return injected.querySelector(injected.parseSelector(${locatorJson}), document, true); })()` : "document.activeElement"}; + const element = ${locatorJson ? `(() => { const injected = globalThis.__v12PlaywrightInjected; return injected.querySelector(injected.parseSelector(${locatorJson}), document, true); })()` : "document.activeElement"}; if (!element) return { notFound: true }; const textControl = element instanceof HTMLTextAreaElement || @@ -2300,7 +2300,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function send, `(() => { try { - const target = ${locatorJson ? `(() => { const injected = globalThis.__t3PlaywrightInjected; return injected.querySelector(injected.parseSelector(${locatorJson}), document, true); })()` : "window"}; + const target = ${locatorJson ? `(() => { const injected = globalThis.__v12PlaywrightInjected; return injected.querySelector(injected.parseSelector(${locatorJson}), document, true); })()` : "window"}; if (!target) return { notFound: true }; target.scrollBy({ left: ${input.deltaX ?? 0}, top: ${input.deltaY ?? 0}, behavior: "instant" }); return { ok: true }; @@ -2403,7 +2403,7 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function send, `(() => { try { - const selectorMatched = ${locatorJson ? `(() => { const injected = globalThis.__t3PlaywrightInjected; return injected.querySelector(injected.parseSelector(${locatorJson}), document, false) !== null; })()` : "true"}; + const selectorMatched = ${locatorJson ? `(() => { const injected = globalThis.__v12PlaywrightInjected; return injected.querySelector(injected.parseSelector(${locatorJson}), document, false) !== null; })()` : "true"}; const textMatched = ${ textJson ? `(document.body?.innerText || "").includes(${textJson})` : "true" }; @@ -2891,7 +2891,7 @@ export class PreviewManager extends Context.Service< listener: RecordingFrameListener, ) => Effect.Effect; } ->()("@t3tools/desktop/preview/Manager/PreviewManager") {} +>()("@v12/desktop/preview/Manager/PreviewManager") {} export const make = Effect.gen(function* PreviewManagerMake() { const environment = yield* DesktopEnvironment.DesktopEnvironment; diff --git a/apps/desktop/src/preview/PickPreload.ts b/apps/desktop/src/preview/PickPreload.ts index 2654b898102..c73c9b08d31 100644 --- a/apps/desktop/src/preview/PickPreload.ts +++ b/apps/desktop/src/preview/PickPreload.ts @@ -11,7 +11,7 @@ import type { PreviewAnnotationRegionTarget, PreviewAnnotationStrokeTarget, PreviewAnnotationStyleChange, -} from "@t3tools/contracts"; +} from "@v12/contracts"; import { previewAnnotationStyles } from "./AnnotationStyles.generated.ts"; import { @@ -22,10 +22,10 @@ import { HUMAN_INPUT_CHANNEL, START_PICK_CHANNEL, } from "./GuestProtocol.ts"; -const OVERLAY_ATTRIBUTE = "data-t3code-annotation-ui"; +const OVERLAY_ATTRIBUTE = "data-v12-annotation-ui"; const Z_INDEX_OVERLAY = 2147483646; -const PRIMARY = "var(--t3-primary)"; -const PRIMARY_FILL = "color-mix(in srgb, var(--t3-primary) 10%, transparent)"; +const PRIMARY = "var(--v12-primary)"; +const PRIMARY_FILL = "color-mix(in srgb, var(--v12-primary) 10%, transparent)"; const MAX_MARQUEE_ELEMENTS = 20; const CONTENT_LAYER_Z_INDEX = 1; const CHROME_LAYER_Z_INDEX = 10; @@ -56,22 +56,22 @@ const applyAnnotationTheme = ( if (!theme) return; host.style.colorScheme = theme.colorScheme; const variables = { - "--t3-radius": theme.radius, - "--t3-background": theme.background, - "--t3-foreground": theme.foreground, - "--t3-popover": theme.popover, - "--t3-popover-foreground": theme.popoverForeground, - "--t3-primary": theme.primary, - "--t3-primary-foreground": theme.primaryForeground, - "--t3-muted": theme.muted, - "--t3-muted-foreground": theme.mutedForeground, - "--t3-accent": theme.accent, - "--t3-accent-foreground": theme.accentForeground, - "--t3-border": theme.border, - "--t3-input": theme.input, - "--t3-ring": theme.ring, - "--t3-font-sans": theme.fontSans, - "--t3-font-mono": theme.fontMono, + "--v12-radius": theme.radius, + "--v12-background": theme.background, + "--v12-foreground": theme.foreground, + "--v12-popover": theme.popover, + "--v12-popover-foreground": theme.popoverForeground, + "--v12-primary": theme.primary, + "--v12-primary-foreground": theme.primaryForeground, + "--v12-muted": theme.muted, + "--v12-muted-foreground": theme.mutedForeground, + "--v12-accent": theme.accent, + "--v12-accent-foreground": theme.accentForeground, + "--v12-border": theme.border, + "--v12-input": theme.input, + "--v12-ring": theme.ring, + "--v12-font-sans": theme.fontSans, + "--v12-font-mono": theme.fontMono, }; for (const [name, value] of Object.entries(variables)) { host.style.setProperty(name, value); @@ -368,7 +368,7 @@ function startAnnotation(): void { root.style.cssText = "pointer-events:none"; const cursorStyle = document.createElement("style"); cursorStyle.setAttribute(OVERLAY_ATTRIBUTE, ""); - cursorStyle.textContent = `html[data-t3code-annotation-tool] body, html[data-t3code-annotation-tool] body * { cursor: crosshair !important; } [${OVERLAY_ATTRIBUTE}], [${OVERLAY_ATTRIBUTE}] * { cursor: default !important; } [${OVERLAY_ATTRIBUTE}] input[type=number]::-webkit-inner-spin-button, [${OVERLAY_ATTRIBUTE}] input[type=number]::-webkit-outer-spin-button { appearance:none; margin:0; }`; + cursorStyle.textContent = `html[data-v12-annotation-tool] body, html[data-v12-annotation-tool] body * { cursor: crosshair !important; } [${OVERLAY_ATTRIBUTE}], [${OVERLAY_ATTRIBUTE}] * { cursor: default !important; } [${OVERLAY_ATTRIBUTE}] input[type=number]::-webkit-inner-spin-button, [${OVERLAY_ATTRIBUTE}] input[type=number]::-webkit-outer-spin-button { appearance:none; margin:0; }`; document.documentElement.appendChild(cursorStyle); shadowRoot.appendChild(root); @@ -485,7 +485,7 @@ function startAnnotation(): void { } if (tool !== "select") hoverOutline.style.display = "none"; if (tool !== "marquee") marqueeBox.style.display = "none"; - document.documentElement.setAttribute("data-t3code-annotation-tool", tool); + document.documentElement.setAttribute("data-v12-annotation-tool", tool); }; const removeSelected = (target: SelectedElement): void => { @@ -1096,7 +1096,7 @@ function startAnnotation(): void { regions.push(region); const regionBox = createBox( PRIMARY, - "color-mix(in srgb, var(--t3-primary) 6%, transparent)", + "color-mix(in srgb, var(--v12-primary) 6%, transparent)", ); regionBox.setAttribute("data-region-id", region.id); positionBox(regionBox, rect); @@ -1157,7 +1157,7 @@ function startAnnotation(): void { if (editorLayoutFrame !== null) window.cancelAnimationFrame(editorLayoutFrame); ipcRenderer.off(CANCEL_PICK_CHANNEL, onCancel); ipcRenderer.off(ANNOTATION_CAPTURED_CHANNEL, onCaptured); - document.documentElement.removeAttribute("data-t3code-annotation-tool"); + document.documentElement.removeAttribute("data-v12-annotation-tool"); cursorStyle.remove(); host.remove(); activeSession = null; diff --git a/apps/desktop/src/preview/PickedElementPayload.ts b/apps/desktop/src/preview/PickedElementPayload.ts index e2d596120db..cb7160ae1d0 100644 --- a/apps/desktop/src/preview/PickedElementPayload.ts +++ b/apps/desktop/src/preview/PickedElementPayload.ts @@ -10,7 +10,7 @@ * channel via prototype pollution) would otherwise throw deep in the * renderer and the chip silently never appears. */ -import type { PickedElementPayload, PreviewAnnotationPayload } from "@t3tools/contracts"; +import type { PickedElementPayload, PreviewAnnotationPayload } from "@v12/contracts"; function isStringOrNull(value: unknown): value is string | null { return value === null || typeof value === "string"; diff --git a/apps/desktop/src/preview/PlaywrightInjectedRuntime.test.ts b/apps/desktop/src/preview/PlaywrightInjectedRuntime.test.ts index cd7fee1e3c7..53d3bd19e8a 100644 --- a/apps/desktop/src/preview/PlaywrightInjectedRuntime.test.ts +++ b/apps/desktop/src/preview/PlaywrightInjectedRuntime.test.ts @@ -23,7 +23,7 @@ describe("playwright injected runtime", () => { effectIt.effect("builds an idempotent install expression", () => Effect.gen(function* () { const expression = yield* playwrightInjectedRuntimeInstallExpression(); - expect(expression).toContain("__t3PlaywrightInjected"); + expect(expression).toContain("__v12PlaywrightInjected"); expect(expression).toContain('testIdAttributeName":"data-testid'); }), ); diff --git a/apps/desktop/src/preview/PlaywrightInjectedRuntime.ts b/apps/desktop/src/preview/PlaywrightInjectedRuntime.ts index ff1531f08f3..83d14ea3534 100644 --- a/apps/desktop/src/preview/PlaywrightInjectedRuntime.ts +++ b/apps/desktop/src/preview/PlaywrightInjectedRuntime.ts @@ -205,10 +205,10 @@ export const playwrightInjectedRuntimeInstallExpression = Effect.fn( ), ); return `(() => { - if (globalThis.__t3PlaywrightInjected) return true; + if (globalThis.__v12PlaywrightInjected) return true; const module = { exports: {} }; ${source} - globalThis.__t3PlaywrightInjected = new (module.exports.InjectedScript())(globalThis, ${options}); + globalThis.__v12PlaywrightInjected = new (module.exports.InjectedScript())(globalThis, ${options}); return true; })()`; }); diff --git a/apps/desktop/src/preview/PreviewKeyboard.ts b/apps/desktop/src/preview/PreviewKeyboard.ts index 0d231b86f4c..3526c52aafe 100644 --- a/apps/desktop/src/preview/PreviewKeyboard.ts +++ b/apps/desktop/src/preview/PreviewKeyboard.ts @@ -1,4 +1,4 @@ -import type { PreviewAutomationPressInput } from "@t3tools/contracts"; +import type { PreviewAutomationPressInput } from "@v12/contracts"; interface KeyDefinition { readonly code: string; diff --git a/apps/desktop/src/settings/DesktopAppSettings.test.ts b/apps/desktop/src/settings/DesktopAppSettings.test.ts index 70b26798266..cc7f8a0766d 100644 --- a/apps/desktop/src/settings/DesktopAppSettings.test.ts +++ b/apps/desktop/src/settings/DesktopAppSettings.test.ts @@ -38,7 +38,7 @@ function makeEnvironmentLayer(baseDir: string, appVersion = "0.0.17") { runningUnderArm64Translation: false, }).pipe( Layer.provide( - Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({ T3CODE_HOME: baseDir })), + Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({ V12_HOME: baseDir })), ), ); } @@ -54,7 +54,7 @@ const withSettings = ( Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-settings-test-", + prefix: "v12-desktop-settings-test-", }); return yield* effect.pipe( Effect.provide( diff --git a/apps/desktop/src/settings/DesktopAppSettings.ts b/apps/desktop/src/settings/DesktopAppSettings.ts index 6a26bf5a6e2..e5438c07760 100644 --- a/apps/desktop/src/settings/DesktopAppSettings.ts +++ b/apps/desktop/src/settings/DesktopAppSettings.ts @@ -3,8 +3,8 @@ import { DesktopUpdateChannelSchema, type DesktopServerExposureMode, type DesktopUpdateChannel, -} from "@t3tools/contracts"; -import { fromLenientJson } from "@t3tools/shared/schemaJson"; +} from "@v12/contracts"; +import { fromLenientJson } from "@v12/shared/schemaJson"; import * as Context from "effect/Context"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; @@ -139,7 +139,7 @@ export class DesktopAppSettings extends Context.Service< >; readonly applyWslWindowsFallbackInMemory: Effect.Effect; } ->()("@t3tools/desktop/settings/DesktopAppSettings") {} +>()("@v12/desktop/settings/DesktopAppSettings") {} export function resolveDefaultDesktopSettings(appVersion: string): DesktopSettings { return { diff --git a/apps/desktop/src/settings/DesktopClientSettings.diagnostics.test.ts b/apps/desktop/src/settings/DesktopClientSettings.diagnostics.test.ts index 5034df44cf7..f1a5fcac2d8 100644 --- a/apps/desktop/src/settings/DesktopClientSettings.diagnostics.test.ts +++ b/apps/desktop/src/settings/DesktopClientSettings.diagnostics.test.ts @@ -32,7 +32,7 @@ function makeLayer(fileSystemLayer: Layer.Layer) { runningUnderArm64Translation: false, }).pipe( Layer.provide( - Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({ T3CODE_HOME: baseDir })), + Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({ V12_HOME: baseDir })), ), ); diff --git a/apps/desktop/src/settings/DesktopClientSettings.test.ts b/apps/desktop/src/settings/DesktopClientSettings.test.ts index ea7ec6e1512..2fad85e818f 100644 --- a/apps/desktop/src/settings/DesktopClientSettings.test.ts +++ b/apps/desktop/src/settings/DesktopClientSettings.test.ts @@ -1,6 +1,6 @@ import * as NodeServices from "@effect/platform-node/NodeServices"; import { assert, describe, it } from "@effect/vitest"; -import { ClientSettingsSchema, type ClientSettings } from "@t3tools/contracts"; +import { ClientSettingsSchema, type ClientSettings } from "@v12/contracts"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; import * as Layer from "effect/Layer"; @@ -48,7 +48,7 @@ function makeLayer(baseDir: string) { runningUnderArm64Translation: false, }).pipe( Layer.provide( - Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({ T3CODE_HOME: baseDir })), + Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({ V12_HOME: baseDir })), ), ); @@ -64,7 +64,7 @@ const withClientSettings = ( Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-client-settings-test-", + prefix: "v12-desktop-client-settings-test-", }); return yield* effect.pipe(Effect.provide(makeLayer(baseDir))); }).pipe(Effect.provide(NodeServices.layer), Effect.scoped); diff --git a/apps/desktop/src/settings/DesktopClientSettings.ts b/apps/desktop/src/settings/DesktopClientSettings.ts index 4ff091e27a2..3fad851bd51 100644 --- a/apps/desktop/src/settings/DesktopClientSettings.ts +++ b/apps/desktop/src/settings/DesktopClientSettings.ts @@ -1,5 +1,5 @@ -import { ClientSettingsSchema, type ClientSettings } from "@t3tools/contracts"; -import { fromLenientJson } from "@t3tools/shared/schemaJson"; +import { ClientSettingsSchema, type ClientSettings } from "@v12/contracts"; +import { fromLenientJson } from "@v12/shared/schemaJson"; import * as Context from "effect/Context"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; @@ -60,7 +60,7 @@ export class DesktopClientSettings extends Context.Service< settings: ClientSettings, ) => Effect.Effect; } ->()("@t3tools/desktop/settings/DesktopClientSettings") {} +>()("@v12/desktop/settings/DesktopClientSettings") {} const readClientSettings = ( fileSystem: FileSystem.FileSystem, diff --git a/apps/desktop/src/settings/DesktopSavedEnvironments.test.ts b/apps/desktop/src/settings/DesktopSavedEnvironments.test.ts index ec70308b3d3..493b65d22fc 100644 --- a/apps/desktop/src/settings/DesktopSavedEnvironments.test.ts +++ b/apps/desktop/src/settings/DesktopSavedEnvironments.test.ts @@ -1,6 +1,6 @@ import * as NodeServices from "@effect/platform-node/NodeServices"; import { assert, describe, it } from "@effect/vitest"; -import { EnvironmentId, type PersistedSavedEnvironmentRecord } from "@t3tools/contracts"; +import { EnvironmentId, type PersistedSavedEnvironmentRecord } from "@v12/contracts"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; import * as Layer from "effect/Layer"; @@ -111,7 +111,7 @@ function makeLayer( runningUnderArm64Translation: false, }).pipe( Layer.provide( - Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({ T3CODE_HOME: baseDir })), + Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({ V12_HOME: baseDir })), ), ); @@ -143,7 +143,7 @@ const withSavedEnvironments = ( Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const baseDir = yield* fileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-saved-environments-test-", + prefix: "v12-desktop-saved-environments-test-", }); return yield* effect.pipe(Effect.provide(makeLayer(baseDir, options))); }).pipe(Effect.provide(NodeServices.layer), Effect.scoped); @@ -401,7 +401,7 @@ describe("DesktopSavedEnvironments", () => { Effect.gen(function* () { const baseFileSystem = yield* FileSystem.FileSystem; const baseDir = yield* baseFileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-saved-environments-test-", + prefix: "v12-desktop-saved-environments-test-", }); const registryPath = `${baseDir}/userdata/saved-environments.json`; const permissionError = PlatformError.systemError({ @@ -433,7 +433,7 @@ describe("DesktopSavedEnvironments", () => { Effect.gen(function* () { const baseFileSystem = yield* FileSystem.FileSystem; const baseDir = yield* baseFileSystem.makeTempDirectoryScoped({ - prefix: "t3-desktop-saved-environments-test-", + prefix: "v12-desktop-saved-environments-test-", }); const permissionError = PlatformError.systemError({ _tag: "PermissionDenied", diff --git a/apps/desktop/src/settings/DesktopSavedEnvironments.ts b/apps/desktop/src/settings/DesktopSavedEnvironments.ts index bdda7f9c738..f13f012d167 100644 --- a/apps/desktop/src/settings/DesktopSavedEnvironments.ts +++ b/apps/desktop/src/settings/DesktopSavedEnvironments.ts @@ -1,5 +1,5 @@ -import { EnvironmentId, type PersistedSavedEnvironmentRecord } from "@t3tools/contracts"; -import { fromLenientJson } from "@t3tools/shared/schemaJson"; +import { EnvironmentId, type PersistedSavedEnvironmentRecord } from "@v12/contracts"; +import { fromLenientJson } from "@v12/shared/schemaJson"; import * as Context from "effect/Context"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; @@ -190,7 +190,7 @@ export class DesktopSavedEnvironments extends Context.Service< environmentId: string, ) => Effect.Effect; } ->()("@t3tools/desktop/settings/DesktopSavedEnvironments") {} +>()("@v12/desktop/settings/DesktopSavedEnvironments") {} function toPersistedSavedEnvironmentRecord( record: PersistedSavedEnvironmentStorageRecord, diff --git a/apps/desktop/src/shell/DesktopShellEnvironment.test.ts b/apps/desktop/src/shell/DesktopShellEnvironment.test.ts index 7ec0ab80ae7..aa2774f02a3 100644 --- a/apps/desktop/src/shell/DesktopShellEnvironment.test.ts +++ b/apps/desktop/src/shell/DesktopShellEnvironment.test.ts @@ -20,11 +20,7 @@ const isDesktopShellEnvironmentCommandError = Schema.is( function envOutput(values: Readonly>): string { return Object.entries(values) - .flatMap(([name, value]) => [ - `__T3CODE_ENV_${name}_START__`, - value, - `__T3CODE_ENV_${name}_END__`, - ]) + .flatMap(([name, value]) => [`__V12_ENV_${name}_START__`, value, `__V12_ENV_${name}_END__`]) .join("\n"); } diff --git a/apps/desktop/src/shell/DesktopShellEnvironment.ts b/apps/desktop/src/shell/DesktopShellEnvironment.ts index 8219f18b7a5..5fca70defcc 100644 --- a/apps/desktop/src/shell/DesktopShellEnvironment.ts +++ b/apps/desktop/src/shell/DesktopShellEnvironment.ts @@ -64,7 +64,7 @@ export class DesktopShellEnvironment extends Context.Service< { readonly installIntoProcess: Effect.Effect; } ->()("@t3tools/desktop/shell/DesktopShellEnvironment") {} +>()("@v12/desktop/shell/DesktopShellEnvironment") {} const LOGIN_SHELL_ENV_NAMES = [ "PATH", @@ -163,8 +163,8 @@ const knownWindowsCliDirs = (env: NodeJS.ProcessEnv): ReadonlyArray => [ ), ]; -const startMarker = (name: string) => `__T3CODE_ENV_${name}_START__`; -const endMarker = (name: string) => `__T3CODE_ENV_${name}_END__`; +const startMarker = (name: string) => `__V12_ENV_${name}_START__`; +const endMarker = (name: string) => `__V12_ENV_${name}_END__`; const executableName = (command: string): string => command.split(/[\\/]/u).at(-1) ?? command; diff --git a/apps/desktop/src/ssh/DesktopSshEnvironment.test.ts b/apps/desktop/src/ssh/DesktopSshEnvironment.test.ts index 1fe2b86aae7..ec14dff8f5f 100644 --- a/apps/desktop/src/ssh/DesktopSshEnvironment.test.ts +++ b/apps/desktop/src/ssh/DesktopSshEnvironment.test.ts @@ -1,8 +1,8 @@ import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient"; import * as NodeServices from "@effect/platform-node/NodeServices"; import { assert, describe, it } from "@effect/vitest"; -import * as NetService from "@t3tools/shared/Net"; -import { SshPasswordPromptError } from "@t3tools/ssh/errors"; +import * as NetService from "@v12/shared/Net"; +import { SshPasswordPromptError } from "@v12/ssh/errors"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; import * as Layer from "effect/Layer"; @@ -14,7 +14,7 @@ import * as DesktopSshPasswordPrompts from "./DesktopSshPasswordPrompts.ts"; function makeTempHomeDir() { return Effect.gen(function* () { const fs = yield* FileSystem.FileSystem; - return yield* fs.makeTempDirectoryScoped({ prefix: "t3-ssh-env-test-" }); + return yield* fs.makeTempDirectoryScoped({ prefix: "v12-ssh-env-test-" }); }); } @@ -30,7 +30,7 @@ describe("sshEnvironment", () => { assert.equal(cause.message, "Failed to present SSH password prompt for devbox."); assert.equal( DesktopSshEnvironment.toSshPasswordPromptError(cause).message, - "T3 Code window is not available for SSH authentication.", + "V12 window is not available for SSH authentication.", ); }); diff --git a/apps/desktop/src/ssh/DesktopSshEnvironment.ts b/apps/desktop/src/ssh/DesktopSshEnvironment.ts index 31e84ae995e..aa0dc0f560c 100644 --- a/apps/desktop/src/ssh/DesktopSshEnvironment.ts +++ b/apps/desktop/src/ssh/DesktopSshEnvironment.ts @@ -2,10 +2,10 @@ import type { DesktopDiscoveredSshHost, DesktopSshEnvironmentBootstrap, DesktopSshEnvironmentTarget, -} from "@t3tools/contracts"; -import * as NetService from "@t3tools/shared/Net"; -import * as SshAuth from "@t3tools/ssh/auth"; -import { discoverSshHosts } from "@t3tools/ssh/config"; +} from "@v12/contracts"; +import * as NetService from "@v12/shared/Net"; +import * as SshAuth from "@v12/ssh/auth"; +import { discoverSshHosts } from "@v12/ssh/config"; import { SshCommandError, SshHostDiscoveryError, @@ -14,8 +14,8 @@ import { SshPairingError, SshPasswordPromptError, SshReadinessError, -} from "@t3tools/ssh/errors"; -import * as SshTunnel from "@t3tools/ssh/tunnel"; +} from "@v12/ssh/errors"; +import * as SshTunnel from "@v12/ssh/tunnel"; import * as Context from "effect/Context"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; @@ -62,11 +62,11 @@ export class DesktopSshEnvironment extends Context.Service< target: DesktopSshEnvironmentTarget, ) => Effect.Effect; } ->()("@t3tools/desktop/ssh/DesktopSshEnvironment") {} +>()("@v12/desktop/ssh/DesktopSshEnvironment") {} export interface DesktopSshEnvironmentLayerOptions { readonly resolveCliPackageSpec?: () => string; - readonly resolveCliRunner?: Effect.Effect; + readonly resolveCliRunner?: Effect.Effect; } function discoverDesktopSshHostsEffect(input?: { readonly homeDir?: string }) { @@ -96,7 +96,7 @@ export function toSshPasswordPromptError( break; case "DesktopSshPromptWindowUnavailableError": case "DesktopSshPromptPresentationError": - message = "T3 Code window is not available for SSH authentication."; + message = "V12 window is not available for SSH authentication."; break; case "DesktopSshPromptTimedOutError": message = `SSH authentication timed out for ${cause.destination}.`; diff --git a/apps/desktop/src/ssh/DesktopSshPasswordPrompts.ts b/apps/desktop/src/ssh/DesktopSshPasswordPrompts.ts index aa25d8135c7..69e76388348 100644 --- a/apps/desktop/src/ssh/DesktopSshPasswordPrompts.ts +++ b/apps/desktop/src/ssh/DesktopSshPasswordPrompts.ts @@ -1,6 +1,6 @@ -import type { DesktopSshPasswordPromptRequest } from "@t3tools/contracts"; -import { DesktopSshPasswordPromptResolutionInputSchema } from "@t3tools/contracts"; -import type { SshPasswordRequest } from "@t3tools/ssh/auth"; +import type { DesktopSshPasswordPromptRequest } from "@v12/contracts"; +import { DesktopSshPasswordPromptResolutionInputSchema } from "@v12/contracts"; +import type { SshPasswordRequest } from "@v12/ssh/auth"; import * as Context from "effect/Context"; import * as Crypto from "effect/Crypto"; import * as DateTime from "effect/DateTime"; @@ -63,7 +63,7 @@ export class DesktopSshPromptWindowUnavailableError extends Schema.TaggedErrorCl ) { override get message(): string { const request = this.requestId === null ? "before a request id was assigned" : this.requestId; - return `T3 Code window is unavailable during ${this.stage} for SSH authentication to ${this.destination} (request: ${request}).`; + return `V12 window is unavailable during ${this.stage} for SSH authentication to ${this.destination} (request: ${request}).`; } } @@ -190,7 +190,7 @@ export class DesktopSshPasswordPrompts extends Context.Service< input: DesktopSshPasswordPromptResolutionInput, ) => Effect.Effect; } ->()("@t3tools/desktop/ssh/DesktopSshPasswordPrompts") {} +>()("@v12/desktop/ssh/DesktopSshPasswordPrompts") {} interface PendingSshPasswordPrompt { readonly requestId: string; diff --git a/apps/desktop/src/updates/DesktopUpdates.test.ts b/apps/desktop/src/updates/DesktopUpdates.test.ts index 696bd755506..452234333de 100644 --- a/apps/desktop/src/updates/DesktopUpdates.test.ts +++ b/apps/desktop/src/updates/DesktopUpdates.test.ts @@ -1,6 +1,6 @@ import { assert, describe, it } from "@effect/vitest"; import * as NodeServices from "@effect/platform-node/NodeServices"; -import type { DesktopUpdateState } from "@t3tools/contracts"; +import type { DesktopUpdateState } from "@v12/contracts"; import * as Cause from "effect/Cause"; import * as Deferred from "effect/Deferred"; import * as Duration from "effect/Duration"; @@ -126,7 +126,7 @@ function makeHarness(options: UpdatesHarnessOptions = {}) { const environmentLayer = DesktopEnvironment.layer({ dirname: "/repo/apps/desktop/src", - homeDirectory: `/tmp/t3-desktop-updates-home-${process.pid}`, + homeDirectory: `/tmp/v12-desktop-updates-home-${process.pid}`, platform: "darwin", processArch: "x64", appVersion: "1.2.3", @@ -139,9 +139,9 @@ function makeHarness(options: UpdatesHarnessOptions = {}) { Layer.mergeAll( NodeServices.layer, DesktopConfig.layerTest({ - T3CODE_HOME: `/tmp/t3-desktop-updates-test-${process.pid}`, - T3CODE_DESKTOP_MOCK_UPDATES: "true", - T3CODE_DESKTOP_MOCK_UPDATE_SERVER_PORT: "4141", + V12_HOME: `/tmp/v12-desktop-updates-test-${process.pid}`, + V12_DESKTOP_MOCK_UPDATES: "true", + V12_DESKTOP_MOCK_UPDATE_SERVER_PORT: "4141", ...options.env, }), ), @@ -172,9 +172,9 @@ function makeHarness(options: UpdatesHarnessOptions = {}) { Layer.provideMerge(settingsLayer), Layer.provideMerge( DesktopConfig.layerTest({ - T3CODE_HOME: `/tmp/t3-desktop-updates-test-${process.pid}`, - T3CODE_DESKTOP_MOCK_UPDATES: "true", - T3CODE_DESKTOP_MOCK_UPDATE_SERVER_PORT: "4141", + V12_HOME: `/tmp/v12-desktop-updates-test-${process.pid}`, + V12_DESKTOP_MOCK_UPDATES: "true", + V12_DESKTOP_MOCK_UPDATE_SERVER_PORT: "4141", ...options.env, }), ), diff --git a/apps/desktop/src/updates/DesktopUpdates.ts b/apps/desktop/src/updates/DesktopUpdates.ts index aabb0830b0f..ee4f1c7427a 100644 --- a/apps/desktop/src/updates/DesktopUpdates.ts +++ b/apps/desktop/src/updates/DesktopUpdates.ts @@ -5,7 +5,7 @@ import { type DesktopUpdateChannel, type DesktopUpdateCheckResult, type DesktopUpdateState, -} from "@t3tools/contracts"; +} from "@v12/contracts"; import * as Cause from "effect/Cause"; import * as Context from "effect/Context"; import * as DateTime from "effect/DateTime"; @@ -155,7 +155,7 @@ export class DesktopUpdates extends Context.Service< readonly download: Effect.Effect; readonly install: Effect.Effect; } ->()("@t3tools/desktop/updates/DesktopUpdates") {} +>()("@v12/desktop/updates/DesktopUpdates") {} const { logInfo: logUpdaterInfo, @@ -227,7 +227,7 @@ function getAutoUpdateDisabledReason(args: { return "Automatic updates are only available in packaged production builds."; } if (args.disabledByEnv) { - return "Automatic updates are disabled by the T3CODE_DISABLE_AUTO_UPDATE setting."; + return "Automatic updates are disabled by the V12_DISABLE_AUTO_UPDATE setting."; } if (args.platform === "linux" && !args.appImage) { return "Automatic updates on Linux require running the AppImage build."; diff --git a/apps/desktop/src/updates/updateChannels.ts b/apps/desktop/src/updates/updateChannels.ts index 731910e441f..219c244599f 100644 --- a/apps/desktop/src/updates/updateChannels.ts +++ b/apps/desktop/src/updates/updateChannels.ts @@ -1,4 +1,4 @@ -import type { DesktopUpdateChannel } from "@t3tools/contracts"; +import type { DesktopUpdateChannel } from "@v12/contracts"; const NIGHTLY_VERSION_PATTERN = /-nightly\.\d{8}\.\d+$/; diff --git a/apps/desktop/src/updates/updateMachine.ts b/apps/desktop/src/updates/updateMachine.ts index b5037225774..3761b7ebb2c 100644 --- a/apps/desktop/src/updates/updateMachine.ts +++ b/apps/desktop/src/updates/updateMachine.ts @@ -1,8 +1,4 @@ -import type { - DesktopRuntimeInfo, - DesktopUpdateChannel, - DesktopUpdateState, -} from "@t3tools/contracts"; +import type { DesktopRuntimeInfo, DesktopUpdateChannel, DesktopUpdateState } from "@v12/contracts"; export function nextStatusAfterDownloadFailure( currentState: DesktopUpdateState, diff --git a/apps/desktop/src/window/DesktopApplicationMenu.test.ts b/apps/desktop/src/window/DesktopApplicationMenu.test.ts index ba77292fdc8..6d76d3ba52f 100644 --- a/apps/desktop/src/window/DesktopApplicationMenu.test.ts +++ b/apps/desktop/src/window/DesktopApplicationMenu.test.ts @@ -30,7 +30,7 @@ const environmentInput = { const electronAppLayer = Layer.succeed(ElectronApp.ElectronApp, { metadata: Effect.die("unexpected metadata read"), - name: Effect.succeed("T3 Code"), + name: Effect.succeed("V12"), whenReady: Effect.void, quit: Effect.void, exit: () => Effect.void, diff --git a/apps/desktop/src/window/DesktopApplicationMenu.ts b/apps/desktop/src/window/DesktopApplicationMenu.ts index a52707627b0..361f9438050 100644 --- a/apps/desktop/src/window/DesktopApplicationMenu.ts +++ b/apps/desktop/src/window/DesktopApplicationMenu.ts @@ -31,7 +31,7 @@ export class DesktopApplicationMenu extends Context.Service< { readonly configure: Effect.Effect; } ->()("@t3tools/desktop/window/DesktopApplicationMenu") {} +>()("@v12/desktop/window/DesktopApplicationMenu") {} type DesktopApplicationMenuRuntimeServices = | DesktopUpdates.DesktopUpdates @@ -59,7 +59,7 @@ const checkForUpdatesFromMenu = Effect.gen(function* () { yield* electronDialog.showMessageBox({ type: "info", title: "You're up to date!", - message: `T3 Code ${updateState.currentVersion} is currently the newest version available.`, + message: `V12 ${updateState.currentVersion} is currently the newest version available.`, buttons: ["OK"], }); } else if (updateState.status === "error") { diff --git a/apps/desktop/src/window/DesktopWindow.test.ts b/apps/desktop/src/window/DesktopWindow.test.ts index 492ef1ad577..f047459e7b6 100644 --- a/apps/desktop/src/window/DesktopWindow.test.ts +++ b/apps/desktop/src/window/DesktopWindow.test.ts @@ -13,7 +13,7 @@ vi.mock("electron", async (importOriginal) => ({ ...(await importOriginal()), session: { fromPartition: vi.fn(() => ({ - getUserAgent: vi.fn(() => "Mozilla/5.0 Electron/41.5.0 t3code/1.2.3"), + getUserAgent: vi.fn(() => "Mozilla/5.0 Electron/41.5.0 v12/1.2.3"), setPermissionRequestHandler: vi.fn(), setUserAgent: vi.fn(), })), @@ -50,7 +50,7 @@ function makeFakeBrowserWindow() { const webContentsListeners = new Map void>(); const webContents = { copyImageAt: vi.fn(), - getURL: vi.fn(() => "t3code-dev://app/"), + getURL: vi.fn(() => "v12-dev://app/"), isLoadingMainFrame: vi.fn(() => false), on: vi.fn((eventName: string, listener: (...args: readonly unknown[]) => void) => { webContentsListeners.set(eventName, listener); @@ -137,7 +137,7 @@ const desktopEnvironmentLayer = DesktopEnvironment.layer(environmentInput).pipe( Layer.mergeAll( NodeServices.layer, DesktopConfig.layerTest({ - T3CODE_PORT: "3773", + V12_PORT: "3773", VITE_DEV_SERVER_URL: "http://127.0.0.1:5733", }), ), @@ -191,8 +191,8 @@ function makeTestLayer(input: { Layer.mock(PreviewManager.PreviewManager)({ getBrowserSession: () => Effect.succeed({} as Electron.Session), setMainWindow: () => Effect.void, - isBrowserPartition: (partition) => partition.startsWith("persist:t3code-preview-"), - getBrowserPartition: () => Effect.succeed("persist:t3code-preview-test"), + isBrowserPartition: (partition) => partition.startsWith("persist:v12-preview-"), + getBrowserPartition: () => Effect.succeed("persist:v12-preview-test"), }), ), ), @@ -283,8 +283,8 @@ const makeSplashScenario = (createOutcomes: readonly (Electron.BrowserWindow | n Layer.mock(PreviewManager.PreviewManager)({ getBrowserSession: () => Effect.succeed({} as Electron.Session), setMainWindow: () => Effect.void, - isBrowserPartition: (partition) => partition.startsWith("persist:t3code-preview-"), - getBrowserPartition: () => Effect.succeed("persist:t3code-preview-test"), + isBrowserPartition: (partition) => partition.startsWith("persist:v12-preview-"), + getBrowserPartition: () => Effect.succeed("persist:v12-preview-test"), }), ), ), @@ -297,19 +297,19 @@ describe("DesktopWindow", () => { it("recognizes only same-origin renderer navigations", () => { assert.isTrue( DesktopWindow.isSameOriginRendererNavigation({ - applicationUrl: "t3code://app/", - navigationUrl: "t3code://app/settings/connections", + applicationUrl: "v12://app/", + navigationUrl: "v12://app/settings/connections", }), ); assert.isFalse( DesktopWindow.isSameOriginRendererNavigation({ - applicationUrl: "t3code://app/", + applicationUrl: "v12://app/", navigationUrl: "https://accounts.microsoft.com/oauth", }), ); assert.isFalse( DesktopWindow.isSameOriginRendererNavigation({ - applicationUrl: "t3code://app/", + applicationUrl: "v12://app/", navigationUrl: "not a url", }), ); @@ -337,7 +337,7 @@ describe("DesktopWindow", () => { assert.equal(yield* Ref.get(createCount), 1); assert.isTrue(createdWindowOptions[0]?.disableAutoHideCursor); assert.deepEqual(fakeWindow.setAutoHideCursor.mock.calls, [[false]]); - assert.deepEqual(fakeWindow.loadURL.mock.calls[0], ["t3code-dev://app/"]); + assert.deepEqual(fakeWindow.loadURL.mock.calls[0], ["v12-dev://app/"]); assert.equal(fakeWindow.openDevTools.mock.calls.length, 1); }).pipe(Effect.provide(layer)); }), @@ -395,17 +395,14 @@ describe("DesktopWindow", () => { return yield* Effect.die("renderer load listeners were not registered"); } - didFailLoad({}, -9, "ERR_UNEXPECTED", "t3code-dev://app/", true); + didFailLoad({}, -9, "ERR_UNEXPECTED", "v12-dev://app/", true); assert.equal(fakeWindow.loadURL.mock.calls.length, 1); yield* TestClock.adjust(100); - assert.deepEqual(fakeWindow.loadURL.mock.calls, [ - ["t3code-dev://app/"], - ["t3code-dev://app/"], - ]); + assert.deepEqual(fakeWindow.loadURL.mock.calls, [["v12-dev://app/"], ["v12-dev://app/"]]); assert.equal(fakeWindow.reload.mock.calls.length, 0); - didFailLoad({}, -9, "ERR_UNEXPECTED", "t3code-dev://app/", true); + didFailLoad({}, -9, "ERR_UNEXPECTED", "v12-dev://app/", true); didFinishLoad(); yield* TestClock.adjust(250); assert.equal(fakeWindow.loadURL.mock.calls.length, 2); @@ -417,23 +414,23 @@ describe("DesktopWindow", () => { it("retries only transient failures for the development renderer", () => { assert.isTrue( DesktopWindow.isRetryableDevelopmentRendererLoadFailure({ - applicationUrl: "t3code-dev://app/", + applicationUrl: "v12-dev://app/", errorCode: -102, isMainFrame: true, - validatedUrl: "t3code-dev://app/", + validatedUrl: "v12-dev://app/", }), ); assert.isFalse( DesktopWindow.isRetryableDevelopmentRendererLoadFailure({ - applicationUrl: "t3code-dev://app/", + applicationUrl: "v12-dev://app/", errorCode: -3, isMainFrame: true, - validatedUrl: "t3code-dev://app/", + validatedUrl: "v12-dev://app/", }), ); assert.isFalse( DesktopWindow.isRetryableDevelopmentRendererLoadFailure({ - applicationUrl: "t3code-dev://app/", + applicationUrl: "v12-dev://app/", errorCode: -102, isMainFrame: true, validatedUrl: "https://example.com/", diff --git a/apps/desktop/src/window/DesktopWindow.ts b/apps/desktop/src/window/DesktopWindow.ts index c808c77e51c..492dbb8ad34 100644 --- a/apps/desktop/src/window/DesktopWindow.ts +++ b/apps/desktop/src/window/DesktopWindow.ts @@ -78,7 +78,7 @@ export class DesktopWindow extends Context.Service< readonly dispatchMenuAction: (action: string) => Effect.Effect; readonly syncAppearance: Effect.Effect; } ->()("@t3tools/desktop/window/DesktopWindow") {} +>()("@v12/desktop/window/DesktopWindow") {} const { logInfo: logWindowInfo, logWarning: logWindowWarning } = makeComponentLogger("desktop-window"); diff --git a/apps/desktop/src/wsl/DesktopWslBackend.test.ts b/apps/desktop/src/wsl/DesktopWslBackend.test.ts index 2f58c6adcfb..44928d91dbe 100644 --- a/apps/desktop/src/wsl/DesktopWslBackend.test.ts +++ b/apps/desktop/src/wsl/DesktopWslBackend.test.ts @@ -4,7 +4,7 @@ import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import * as Option from "effect/Option"; -import * as NetService from "@t3tools/shared/Net"; +import * as NetService from "@v12/shared/Net"; import * as DesktopBackendConfiguration from "../backend/DesktopBackendConfiguration.ts"; import * as DesktopBackendPool from "../backend/DesktopBackendPool.ts"; diff --git a/apps/desktop/src/wsl/DesktopWslBackend.ts b/apps/desktop/src/wsl/DesktopWslBackend.ts index 605f4e7a477..48c207d14af 100644 --- a/apps/desktop/src/wsl/DesktopWslBackend.ts +++ b/apps/desktop/src/wsl/DesktopWslBackend.ts @@ -28,7 +28,7 @@ import * as Option from "effect/Option"; import * as Ref from "effect/Ref"; import * as Semaphore from "effect/Semaphore"; -import * as NetService from "@t3tools/shared/Net"; +import * as NetService from "@v12/shared/Net"; import * as DesktopObservability from "../app/DesktopObservability.ts"; import * as DesktopBackendConfiguration from "../backend/DesktopBackendConfiguration.ts"; @@ -58,7 +58,7 @@ export class DesktopWslBackend extends Context.Service< // surfaces via a dialog + Windows fallback). readonly lastPreflightError: Effect.Effect>; } ->()("@t3tools/desktop/wsl/DesktopWslBackend") {} +>()("@v12/desktop/wsl/DesktopWslBackend") {} const { logInfo: logWslBackendInfo, logWarning: logWslBackendWarning } = DesktopObservability.makeComponentLogger("desktop-wsl-backend"); diff --git a/apps/desktop/src/wsl/DesktopWslEnvironment.test.ts b/apps/desktop/src/wsl/DesktopWslEnvironment.test.ts index cdb3fc78286..6b1cab16fb3 100644 --- a/apps/desktop/src/wsl/DesktopWslEnvironment.test.ts +++ b/apps/desktop/src/wsl/DesktopWslEnvironment.test.ts @@ -113,14 +113,14 @@ describe("buildWslNodeEnvPreamble", () => { it("passes the required Node engine range into the shared resolver", () => { const preamble = buildWslNodeEnvPreamble("^22.16 || ^23.11 || >=24.10"); - expect(preamble).toContain("T3_NODE_ENGINE_RANGE='^22.16 || ^23.11 || >=24.10'"); - expect(preamble.indexOf("T3_NODE_ENGINE_RANGE=")).toBeLessThan( + expect(preamble).toContain("V12_NODE_ENGINE_RANGE='^22.16 || ^23.11 || >=24.10'"); + expect(preamble.indexOf("V12_NODE_ENGINE_RANGE=")).toBeLessThan( preamble.lastIndexOf("ensure_remote_node_path || true"), ); }); it("keeps the shared resolver permissive when no Node engine range is provided", () => { - expect(buildWslNodeEnvPreamble()).toContain("T3_NODE_ENGINE_RANGE=''"); + expect(buildWslNodeEnvPreamble()).toContain("V12_NODE_ENGINE_RANGE=''"); }); }); diff --git a/apps/desktop/src/wsl/DesktopWslEnvironment.ts b/apps/desktop/src/wsl/DesktopWslEnvironment.ts index b38675f0e1f..3142cc4497f 100644 --- a/apps/desktop/src/wsl/DesktopWslEnvironment.ts +++ b/apps/desktop/src/wsl/DesktopWslEnvironment.ts @@ -9,8 +9,8 @@ import * as Schema from "effect/Schema"; import * as Stream from "effect/Stream"; import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; -import { buildRemoteNodeEnvScript } from "@t3tools/ssh/tunnel"; -import { satisfiesSemverRange } from "@t3tools/shared/semver"; +import { buildRemoteNodeEnvScript } from "@v12/ssh/tunnel"; +import { satisfiesSemverRange } from "@v12/shared/semver"; import * as DesktopEnvironment from "../app/DesktopEnvironment.ts"; import { parseWslDistroList, type WslDistro } from "./wslPathParsing.ts"; @@ -81,7 +81,7 @@ export class DesktopWslEnvironment extends Context.Service< options?: EnsureWslNodePtyOptions, ) => Effect.Effect; } ->()("@t3tools/desktop/wsl/DesktopWslEnvironment") {} +>()("@v12/desktop/wsl/DesktopWslEnvironment") {} const buildDistroArgs = (distro: string | null): ReadonlyArray => distro ? ["-d", distro] : []; @@ -216,7 +216,7 @@ const NODE_PTY_PREBUILD_MISSING_EXIT_CODE = 4; export const formatNodePtyProbeFailureReason = (exitCode: number): string | null => exitCode === NODE_PTY_PREBUILD_MISSING_EXIT_CODE - ? "WSL support is missing from this T3 Code build: the packaged Linux node-pty binary was not included. Rebuild the Windows artifact with `--wsl-prebuild ` or install a build that includes WSL support." + ? "WSL support is missing from this V12 build: the packaged Linux node-pty binary was not included. Rebuild the Windows artifact with `--wsl-prebuild ` or install a build that includes WSL support." : null; const NODE_PTY_PROBE_SCRIPT = ( @@ -247,7 +247,7 @@ const expected = { nodePtyVersion: require("node-pty/package.json").version, }; const prebuildDir = path.join(pkgDir, "prebuilds", "linux-" + process.arch); -const marker = path.join(prebuildDir, "t3code-wsl-node-pty.json"); +const marker = path.join(prebuildDir, "v12-wsl-node-pty.json"); const binary = path.join(prebuildDir, "pty.node"); if (!fs.existsSync(marker) || !fs.existsSync(binary)) process.exit(${NODE_PTY_PREBUILD_MISSING_EXIT_CODE}); require("node-pty"); @@ -280,7 +280,7 @@ const NODE_PTY_BUILD_SCRIPT = (linuxServerDir: string) => `prebuild_dir="prebuilds/linux-$arch"`, `mkdir -p "$prebuild_dir"`, `cp build/Release/pty.node "$prebuild_dir/pty.node"`, - `printf '{"arch":"%s","modules":"%s","nodePtyVersion":"%s"}\\n' "$arch" "$modules" "$node_pty_version" > "$prebuild_dir/t3code-wsl-node-pty.json"`, + `printf '{"arch":"%s","modules":"%s","nodePtyVersion":"%s"}\\n' "$arch" "$modules" "$node_pty_version" > "$prebuild_dir/v12-wsl-node-pty.json"`, `node -e 'require("node-pty")'`, ].join("\n"); diff --git a/apps/desktop/vite.config.ts b/apps/desktop/vite.config.ts index 96e089b9183..20a6df974b7 100644 --- a/apps/desktop/vite.config.ts +++ b/apps/desktop/vite.config.ts @@ -3,10 +3,10 @@ import { defineConfig } from "vite-plus"; import { loadRepoEnv } from "../../scripts/lib/public-config.ts"; const repoEnv = loadRepoEnv(); -const shouldLaunchElectronAfterPack = process.env.T3CODE_DESKTOP_DEV === "1"; +const shouldLaunchElectronAfterPack = process.env.V12_DESKTOP_DEV === "1"; const publicConfigDefine = { - __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__: JSON.stringify( - repoEnv.T3CODE_CLERK_PUBLISHABLE_KEY?.trim() ?? "", + __V12_BUILD_CLERK_PUBLISHABLE_KEY__: JSON.stringify( + repoEnv.V12_CLERK_PUBLISHABLE_KEY?.trim() ?? "", ), }; @@ -15,13 +15,13 @@ export default defineConfig({ tasks: { build: { command: "node scripts/build-preview-annotation-css.mjs && vp pack", - dependsOn: ["t3#build"], + dependsOn: ["v12#build"], cache: false, }, dev: { command: - "node scripts/build-preview-annotation-css.mjs && cross-env T3CODE_DESKTOP_DEV=1 vp pack --watch", - dependsOn: ["t3#build"], + "node scripts/build-preview-annotation-css.mjs && cross-env V12_DESKTOP_DEV=1 vp pack --watch", + dependsOn: ["v12#build"], cache: false, }, "dev:bundle": { @@ -30,7 +30,7 @@ export default defineConfig({ }, "dev:electron": { command: "node scripts/dev-electron.mjs", - dependsOn: ["t3#build"], + dependsOn: ["v12#build"], cache: false, }, }, @@ -45,7 +45,7 @@ export default defineConfig({ entry: ["src/main.ts"], clean: true, deps: { - alwaysBundle: (id) => id.startsWith("@t3tools/"), + alwaysBundle: (id) => id.startsWith("@v12/"), }, ...(shouldLaunchElectronAfterPack ? { onSuccess: "node scripts/dev-electron.mjs" } : {}), }, diff --git a/apps/marketing/package.json b/apps/marketing/package.json index d122dac3c56..4e299e2a4b5 100644 --- a/apps/marketing/package.json +++ b/apps/marketing/package.json @@ -1,5 +1,5 @@ { - "name": "@t3tools/marketing", + "name": "@v12/marketing", "version": "0.0.0", "private": true, "type": "module", diff --git a/apps/marketing/public/apple-touch-icon.png b/apps/marketing/public/apple-touch-icon.png index 9c593ce352c..16ff2d5f8b4 100644 Binary files a/apps/marketing/public/apple-touch-icon.png and b/apps/marketing/public/apple-touch-icon.png differ diff --git a/apps/marketing/public/apple-touch-icon.webp b/apps/marketing/public/apple-touch-icon.webp index fc990561902..ca36493c0b9 100644 Binary files a/apps/marketing/public/apple-touch-icon.webp and b/apps/marketing/public/apple-touch-icon.webp differ diff --git a/apps/marketing/public/favicon-16x16.png b/apps/marketing/public/favicon-16x16.png index f85017caf75..3e378ed9629 100644 Binary files a/apps/marketing/public/favicon-16x16.png and b/apps/marketing/public/favicon-16x16.png differ diff --git a/apps/marketing/public/favicon-16x16.webp b/apps/marketing/public/favicon-16x16.webp index b09dc155aef..1468dd05eb5 100644 Binary files a/apps/marketing/public/favicon-16x16.webp and b/apps/marketing/public/favicon-16x16.webp differ diff --git a/apps/marketing/public/favicon-32x32.png b/apps/marketing/public/favicon-32x32.png index fae2d285b7a..15fd4edeab1 100644 Binary files a/apps/marketing/public/favicon-32x32.png and b/apps/marketing/public/favicon-32x32.png differ diff --git a/apps/marketing/public/favicon-32x32.webp b/apps/marketing/public/favicon-32x32.webp index 72c9243de42..ac5164ccab7 100644 Binary files a/apps/marketing/public/favicon-32x32.webp and b/apps/marketing/public/favicon-32x32.webp differ diff --git a/apps/marketing/public/favicon.ico b/apps/marketing/public/favicon.ico index e3ab4ae5e02..73dbbc7315b 100644 Binary files a/apps/marketing/public/favicon.ico and b/apps/marketing/public/favicon.ico differ diff --git a/apps/marketing/public/icon.png b/apps/marketing/public/icon.png index 0a6e1cbfcff..d2a715f6a5c 100644 Binary files a/apps/marketing/public/icon.png and b/apps/marketing/public/icon.png differ diff --git a/apps/marketing/public/icon.webp b/apps/marketing/public/icon.webp index aa6826dd36d..eeb21434868 100644 Binary files a/apps/marketing/public/icon.webp and b/apps/marketing/public/icon.webp differ diff --git a/apps/marketing/src/layouts/Layout.astro b/apps/marketing/src/layouts/Layout.astro index 9c454c4b78b..d488220a1b6 100644 --- a/apps/marketing/src/layouts/Layout.astro +++ b/apps/marketing/src/layouts/Layout.astro @@ -8,8 +8,8 @@ interface Props { } const { - title = "T3 Code", - description = "T3 Code — The open-source control plane for coding agents.", + title = "V12", + description = "V12 — The open-source control plane for coding agents.", pageClass, } = Astro.props; --- @@ -35,8 +35,8 @@ const {