- Merge UI components, hooks, lib, styles from packages/ui - Merge API client, atoms, provider from packages/clients/react - Move shared pages and components from apps/local/src/web - Direct subpath exports: @executor/react/{api,plugins,pages,components,hooks,lib}/* - No barrel files, no backwards compat shims - Each app owns its own shell/router, imports pages from package - Delete packages/ui and packages/clients/react
Unified · Split
| @@ -26,8 +26,6 @@ · 25 unmodified lines | |||
| 26 | "@executor/plugin-keychain", | 26 | "@executor/plugin-keychain", |
| 27 | "@executor/plugin-mcp", | 27 | "@executor/plugin-mcp", |
| 28 | "@executor/plugin-onepassword", | 28 | "@executor/plugin-onepassword", |
| 29 | "@executor/plugin-openapi", | 29 | "@executor/plugin-openapi" |
| 30 | "@executor/ui", | ||
| 31 | "@executor/marketing" | ||
| 32 | ] | 30 | ] |
| 33 | } | 31 | } |
| @@ -15,7 +15,6 @@ · 14 unmodified lines | |||
| 15 | "@executor/react": "workspace:*", | 15 | "@executor/react": "workspace:*", |
| 16 | "@executor/sdk": "workspace:*", | 16 | "@executor/sdk": "workspace:*", |
| 17 | "@executor/storage-postgres": "workspace:*", | 17 | "@executor/storage-postgres": "workspace:*", |
| 18 | "@executor/ui": "workspace:*", | ||
| 19 | "@tanstack/react-router": "^1.168.10", | 18 | "@tanstack/react-router": "^1.168.10", |
| 20 | "@workos-inc/node": "^7.0.0", | 19 | "@workos-inc/node": "^7.0.0", |
| 21 | "drizzle-orm": "catalog:", | 20 | "drizzle-orm": "catalog:", |
| @@ -1,5 +1,5 @@ | |||
| 1 | // --------------------------------------------------------------------------- | 1 | // --------------------------------------------------------------------------- |
| 2 | // Cloud API — core handlers from @executor/api + cloud-specific plugins | 2 | // Cloud API — core handlers from @executor/api + cloud-specific plugins + auth |
| 3 | // --------------------------------------------------------------------------- | 3 | // --------------------------------------------------------------------------- |
| 4 | 4 | ||
| 5 | import { | 5 | import { |
| @@ -20,16 +20,20 @@ import { GraphqlGroup, GraphqlExtensionService, GraphqlHandlers } from "@executo · 14 unmodified lines | |||
| 20 | 20 | ||
| 21 | import { createTeamExecutor } from "./services/executor"; | 21 | import { createTeamExecutor } from "./services/executor"; |
| 22 | import { authenticateRequest } from "./auth/workos"; | 22 | import { authenticateRequest } from "./auth/workos"; |
| 23 | import { CloudAuthApi } from "./auth/api"; | ||
| 24 | import { CloudAuthHandlers } from "./auth/handlers"; | ||
| 25 | import { AuthContext, UserStoreService } from "./auth/context"; | ||
| 23 | import type { DrizzleDb } from "./services/db"; | 26 | import type { DrizzleDb } from "./services/db"; |
| 24 | 27 | ||
| 25 | // --------------------------------------------------------------------------- | 28 | // --------------------------------------------------------------------------- |
| 26 | // Cloud API — core + cloud plugins (no onepassword) | 29 | // Cloud API — core + cloud plugins + cloud auth (no onepassword) |
| 27 | // --------------------------------------------------------------------------- | 30 | // --------------------------------------------------------------------------- |
| 28 | 31 | ||
| 29 | const CloudApi = addGroup(OpenApiGroup) | 32 | const CloudApi = addGroup(OpenApiGroup) |
| 30 | .add(McpGroup) | 33 | .add(McpGroup) |
| 31 | .add(GoogleDiscoveryGroup) | 34 | .add(GoogleDiscoveryGroup) |
| 32 | .add(GraphqlGroup); | 35 | .add(GraphqlGroup) |
| 36 | .add(CloudAuthApi); | ||
| 33 | 37 | ||
| 34 | const CloudApiBase = HttpApiBuilder.api(CloudApi).pipe( | 38 | const CloudApiBase = HttpApiBuilder.api(CloudApi).pipe( |
| 35 | Layer.provide(CoreHandlers), | 39 | Layer.provide(CoreHandlers), |
| @@ -38,6 +42,7 @@ const CloudApiBase = HttpApiBuilder.api(CloudApi).pipe( · 2 unmodified lines | |||
| 38 | McpHandlers, | 42 | McpHandlers, |
| 39 | GoogleDiscoveryHandlers, | 43 | GoogleDiscoveryHandlers, |
| 40 | GraphqlHandlers, | 44 | GraphqlHandlers, |
| 45 | CloudAuthHandlers, | ||
| 41 | )), | 46 | )), |
| 42 | ); | 47 | ); |
| 43 | 48 | ||
| @@ -96,13 +101,29 @@ export const createCloudApiHandler = (db: DrizzleDb, encryptionKey: string) => { · 52 unmodified lines | |||
| 96 | Layer.provideMerge(pluginExtensions), | 101 | Layer.provideMerge(pluginExtensions), |
| 97 | Layer.provideMerge(Layer.succeed(ExecutorService, executor)), | 102 | Layer.provideMerge(Layer.succeed(ExecutorService, executor)), |
| 98 | Layer.provideMerge(Layer.succeed(ExecutionEngineService, engine)), | 103 | Layer.provideMerge(Layer.succeed(ExecutionEngineService, engine)), |
| 104 | Layer.provideMerge(Layer.succeed(AuthContext, { | ||
| 105 | userId: auth.userId, | ||
| 106 | email: auth.email, | ||
| 107 | teamId, | ||
| 108 | name: `${auth.firstName ?? ""} ${auth.lastName ?? ""}`.trim() || null, | ||
| 109 | avatarUrl: auth.avatarUrl, | ||
| 110 | })), | ||
| 111 | Layer.provideMerge(Layer.succeed(UserStoreService, userStore)), | ||
| 99 | Layer.provideMerge(HttpServer.layerContext), | 112 | Layer.provideMerge(HttpServer.layerContext), |
| 100 | ), | 113 | ), |
| 101 | { middleware: HttpMiddleware.logger }, | 114 | { middleware: HttpMiddleware.logger }, |
| 102 | ); | 115 | ); |
| 103 | 116 | ||
| 104 | try { | 117 | try { |
| 105 | return await handler.handler(request); | 118 | const response = await handler.handler(request); |
| 119 | |||
| 120 | if (auth.refreshedCookie) { | ||
| 121 | const newResponse = new Response(response.body, response); | ||
| 122 | newResponse.headers.append("Set-Cookie", auth.refreshedCookie); | ||
| 123 | return newResponse; | ||
| 124 | } | ||
| 125 | |||
| 126 | return response; | ||
| 106 | } finally { | 127 | } finally { |
| 107 | await Effect.runPromise(executor.close()).catch(() => undefined); | 128 | await Effect.runPromise(executor.close()).catch(() => undefined); |
| 108 | handler.dispose(); | 129 | handler.dispose(); |
| @@ -0,0 +1,25 @@ | |||
| 1 | import { HttpApiEndpoint, HttpApiGroup } from "@effect/platform"; | ||
| 2 | import { Schema } from "effect"; | ||
| 3 | |||
| 4 | const AuthUser = Schema.Struct({ | ||
| 5 | id: Schema.String, | ||
| 6 | email: Schema.String, | ||
| 7 | name: Schema.NullOr(Schema.String), | ||
| 8 | avatarUrl: Schema.NullOr(Schema.String), | ||
| 9 | }); | ||
| 10 | |||
| 11 | const AuthTeam = Schema.Struct({ | ||
| 12 | id: Schema.String, | ||
| 13 | name: Schema.String, | ||
| 14 | }); | ||
| 15 | |||
| 16 | const AuthMeResponse = Schema.Struct({ | ||
| 17 | user: AuthUser, | ||
| 18 | team: Schema.NullOr(AuthTeam), | ||
| 19 | }); | ||
| 20 | |||
| 21 | export class CloudAuthApi extends HttpApiGroup.make("cloudAuth") | ||
| 22 | .add( | ||
| 23 | HttpApiEndpoint.get("me")`/auth/me` | ||
| 24 | .addSuccess(AuthMeResponse), | ||
| 25 | ) {} | ||
| @@ -1,4 +1,5 @@ | |||
| 1 | import { Context } from "effect"; | 1 | import { Context } from "effect"; |
| 2 | import type { makeUserStore } from "@executor/storage-postgres"; | ||
| 2 | 3 | ||
| 3 | export class AuthContext extends Context.Tag("@executor/cloud/AuthContext")< | 4 | export class AuthContext extends Context.Tag("@executor/cloud/AuthContext")< |
| 4 | AuthContext, | 5 | AuthContext, |
| @@ -6,5 +7,12 @@ export class AuthContext extends Context.Tag("@executor/cloud/AuthContext")< · 1 unmodified line | |||
| 6 | readonly userId: string; | 7 | readonly userId: string; |
| 7 | readonly teamId: string; | 8 | readonly teamId: string; |
| 8 | readonly email: string; | 9 | readonly email: string; |
| 10 | readonly name: string | null; | ||
| 11 | readonly avatarUrl: string | null; | ||
| 9 | } | 12 | } |
| 10 | >() {} | 13 | >() {} |
| 14 | |||
| 15 | export class UserStoreService extends Context.Tag("@executor/cloud/UserStoreService")< | ||
| 16 | UserStoreService, | ||
| 17 | ReturnType<typeof makeUserStore> | ||
| 18 | >() {} | ||
| @@ -0,0 +1,34 @@ | |||
| 1 | import { HttpApiBuilder } from "@effect/platform"; | ||
| 2 | import { Effect } from "effect"; | ||
| 3 | |||
| 4 | import { addGroup } from "@executor/api"; | ||
| 5 | import { CloudAuthApi } from "./api"; | ||
| 6 | import { AuthContext, UserStoreService } from "./context"; | ||
| 7 | |||
| 8 | const ApiWithCloudAuth = addGroup(CloudAuthApi); | ||
| 9 | |||
| 10 | export const CloudAuthHandlers = HttpApiBuilder.group( | ||
| 11 | ApiWithCloudAuth, | ||
| 12 | "cloudAuth", | ||
| 13 | (handlers) => | ||
| 14 | handlers.handle("me", () => | ||
| 15 | Effect.gen(function* () { | ||
| 16 | const auth = yield* AuthContext; | ||
| 17 | const userStore = yield* UserStoreService; | ||
| 18 | |||
| 19 | const team = yield* Effect.tryPromise(() => | ||
| 20 | userStore.getTeam(auth.teamId), | ||
| 21 | ).pipe(Effect.orDie); | ||
| 22 | |||
| 23 | return { | ||
| 24 | user: { | ||
| 25 | id: auth.userId, | ||
| 26 | email: auth.email, | ||
| 27 | name: auth.name, | ||
| 28 | avatarUrl: auth.avatarUrl, | ||
| 29 | }, | ||
| 30 | team: team ? { id: team.id, name: team.name } : null, | ||
| 31 | }; | ||
| 32 | }), | ||
| 33 | ), | ||
| 34 | ); | ||
| @@ -48,6 +48,10 @@ export const authenticateWithCode = async (code: string) => { · 47 unmodified lines | |||
| 48 | * Authenticate a request using the sealed session cookie. | 48 | * Authenticate a request using the sealed session cookie. |
| 49 | * Returns user info or null if not authenticated. | 49 | * Returns user info or null if not authenticated. |
| 50 | */ | 50 | */ |
| 51 | /** | ||
| 52 | * Authenticate a request using the sealed session cookie. | ||
| 53 | * Automatically refreshes expired tokens and returns a new cookie if needed. | ||
| 54 | */ | ||
| 51 | export const authenticateRequest = async (request: Request) => { | 55 | export const authenticateRequest = async (request: Request) => { |
| 52 | const cookieHeader = request.headers.get("cookie"); | 56 | const cookieHeader = request.headers.get("cookie"); |
| 53 | const sessionData = parseCookie(cookieHeader, COOKIE_NAME); | 57 | const sessionData = parseCookie(cookieHeader, COOKIE_NAME); |
| @@ -60,39 +64,38 @@ export const authenticateRequest = async (request: Request) => { · 6 unmodified lines | |||
| 60 | }); | 64 | }); |
| 61 | 65 | ||
| 62 | const result = await session.authenticate(); | 66 | const result = await session.authenticate(); |
| 63 | if (!result.authenticated) return null; | ||
| 64 | |||
| 65 | return { | ||
| 66 | userId: result.user.id, | ||
| 67 | email: result.user.email, | ||
| 68 | firstName: result.user.firstName, | ||
| 69 | lastName: result.user.lastName, | ||
| 70 | avatarUrl: result.user.profilePictureUrl, | ||
| 71 | sessionId: result.sessionId, | ||
| 72 | }; | ||
| 73 | }; | ||
| 74 | |||
| 75 | /** | ||
| 76 | * Refresh the sealed session cookie. Returns new cookie value or null. | ||
| 77 | */ | ||
| 78 | export const refreshSession = async (request: Request) => { | ||
| 79 | const cookieHeader = request.headers.get("cookie"); | ||
| 80 | const sessionData = parseCookie(cookieHeader, COOKIE_NAME); | ||
| 81 | if (!sessionData) return null; | ||
| 82 | 67 | ||
| 83 | const wos = getWorkOS(); | 68 | if (result.authenticated) { |
| 84 | const session = wos.userManagement.loadSealedSession({ | 69 | return { |
| 85 | sessionData, | 70 | userId: result.user.id, |
| 86 | cookiePassword: getCookiePassword(), | 71 | email: result.user.email, |
| 87 | }); | 72 | firstName: result.user.firstName, |
| 88 | 73 | lastName: result.user.lastName, | |
| 89 | const result = await session.refresh(); | 74 | avatarUrl: result.user.profilePictureUrl, |
| 90 | if (!result.authenticated || !result.sealedSession) return null; | 75 | sessionId: result.sessionId, |
| 76 | refreshedCookie: undefined as string | undefined, | ||
| 77 | }; | ||
| 78 | } | ||
| 91 | 79 | ||
| 92 | return { | 80 | // Token expired — try refreshing |
| 93 | sealedSession: result.sealedSession, | 81 | if (result.reason === "no_session_cookie_provided") return null; |
| 94 | cookie: makeSessionCookie(result.sealedSession), | 82 | |
| 95 | }; | 83 | try { |
| 84 | const refreshed = await session.refresh(); | ||
| 85 | if (!refreshed.authenticated || !refreshed.sealedSession) return null; | ||
| 86 | |||
| 87 | return { | ||
| 88 | userId: refreshed.user.id, | ||
| 89 | email: refreshed.user.email, | ||
| 90 | firstName: refreshed.user.firstName, | ||
| 91 | lastName: refreshed.user.lastName, | ||
| 92 | avatarUrl: refreshed.user.profilePictureUrl, | ||
| 93 | sessionId: refreshed.sessionId, | ||
| 94 | refreshedCookie: makeSessionCookie(refreshed.sealedSession), | ||
| 95 | }; | ||
| 96 | } catch { | ||
| 97 | return null; | ||
| 98 | } | ||
| 96 | }; | 99 | }; |
| 97 | 100 | ||
| 98 | /** | 101 | /** |
| @@ -1,4 +1,11 @@ | |||
| 1 | import React, { createContext, useContext, useEffect, useState } from "react"; | 1 | import React, { createContext, useContext } from "react"; |
| 2 | import { useAtomValue, Result } from "@effect-atom/atom-react"; | ||
| 3 | |||
| 4 | import { CloudApiClient } from "./client"; | ||
| 5 | |||
| 6 | // --------------------------------------------------------------------------- | ||
| 7 | // Types (from CloudAuthApi response schema) | ||
| 8 | // --------------------------------------------------------------------------- | ||
| 2 | 9 | ||
| 3 | type AuthUser = { | 10 | type AuthUser = { |
| 4 | id: string; | 11 | id: string; |
| @@ -12,40 +19,39 @@ type AuthTeam = { · 7 unmodified lines | |||
| 12 | name: string; | 19 | name: string; |
| 13 | }; | 20 | }; |
| 14 | 21 | ||
| 22 | // --------------------------------------------------------------------------- | ||
| 23 | // Auth atom — typed query against CloudAuthApi | ||
| 24 | // --------------------------------------------------------------------------- | ||
| 25 | |||
| 26 | export const authAtom = CloudApiClient.query("cloudAuth", "me", { | ||
| 27 | timeToLive: "5 minutes", | ||
| 28 | }); | ||
| 29 | |||
| 30 | // --------------------------------------------------------------------------- | ||
| 31 | // Provider + hook | ||
| 32 | // --------------------------------------------------------------------------- | ||
| 33 | |||
| 15 | type AuthState = | 34 | type AuthState = |
| 16 | | { status: "loading" } | 35 | | { status: "loading" } |
| 17 | | { status: "unauthenticated" } | 36 | | { status: "unauthenticated" } |
| 18 | | { status: "authenticated"; user: AuthUser; team: AuthTeam }; | 37 | | { status: "authenticated"; user: AuthUser; team: AuthTeam | null }; |
| 19 | 38 | ||
| 20 | const AuthContext = createContext<AuthState>({ status: "loading" }); | 39 | const AuthContext = createContext<AuthState>({ status: "loading" }); |
| 21 | 40 | ||
| 22 | export const useAuth = () => useContext(AuthContext); | 41 | export const useAuth = () => useContext(AuthContext); |
| 23 | 42 | ||
| 24 | export const AuthProvider = ({ children }: { children: React.ReactNode }) => { | 43 | export const AuthProvider = ({ children }: { children: React.ReactNode }) => { |
| 25 | const [state, setState] = useState<AuthState>({ status: "loading" }); | 44 | const result = useAtomValue(authAtom); |
| 26 | 45 | ||
| 27 | useEffect(() => { | 46 | const state: AuthState = Result.match(result, { |
| 28 | fetch("/auth/me") | 47 | onInitial: () => ({ status: "loading" as const }), |
| 29 | .then((res) => { | 48 | onSuccess: ({ value }) => ({ |
| 30 | if (!res.ok) { | 49 | status: "authenticated" as const, |
| 31 | setState({ status: "unauthenticated" }); | 50 | user: value.user, |
| 32 | return; | 51 | team: value.team, |
| 33 | } | 52 | }), |
| 34 | return res.json(); | 53 | onFailure: () => ({ status: "unauthenticated" as const }), |
| 35 | }) | 54 | }); |
| 36 | .then((data) => { | ||
| 37 | if (data?.user) { | ||
| 38 | setState({ | ||
| 39 | status: "authenticated", | ||
| 40 | user: data.user, | ||
| 41 | team: data.team, | ||
| 42 | }); | ||
| 43 | } | ||
| 44 | }) | ||
| 45 | .catch(() => { | ||
| 46 | setState({ status: "unauthenticated" }); | ||
| 47 | }); | ||
| 48 | }, []); | ||
| 49 | 55 | ||
| 50 | return <AuthContext.Provider value={state}>{children}</AuthContext.Provider>; | 56 | return <AuthContext.Provider value={state}>{children}</AuthContext.Provider>; |
| 51 | }; | 57 | }; |
| @@ -0,0 +1,22 @@ | |||
| 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; | ||
| 2 | import { FetchHttpClient } from "@effect/platform"; | ||
| 3 | import { addGroup } from "@executor/api"; | ||
| 4 | import { getBaseUrl } from "@executor/react/api/base-url"; | ||
| 5 | import { CloudAuthApi } from "../auth/api"; | ||
| 6 | |||
| 7 | // --------------------------------------------------------------------------- | ||
| 8 | // Cloud API client — core API + cloud auth | ||
| 9 | // --------------------------------------------------------------------------- | ||
| 10 | |||
| 11 | const CloudApi = addGroup(CloudAuthApi); | ||
| 12 | |||
| 13 | class CloudApiClient extends AtomHttpApi.Tag<CloudApiClient>()( | ||
| 14 | "CloudApiClient", | ||
| 15 | { | ||
| 16 | api: CloudApi, | ||
| 17 | httpClient: FetchHttpClient.layer, | ||
| 18 | baseUrl: getBaseUrl(), | ||
| 19 | }, | ||
| 20 | ) {} | ||
| 21 | |||
| 22 | export { CloudApiClient }; | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | import React from "react"; | 1 | import React from "react"; |
| 2 | import { createRoot } from "react-dom/client"; | 2 | import { createRoot } from "react-dom/client"; |
| 3 | import "@executor/ui/globals.css"; | 3 | import "@executor/react/globals.css"; |
| 4 | import { App } from "./App"; | 4 | import { App } from "./App"; |
| 5 | 5 | ||
| 6 | const root = createRoot(document.getElementById("root")!); | 6 | const root = createRoot(document.getElementById("root")!); |
| @@ -3,13 +3,13 @@ import { · 2 unmodified lines | |||
| 3 | createRootRoute, | 3 | createRootRoute, |
| 4 | createRoute, | 4 | createRoute, |
| 5 | } from "@tanstack/react-router"; | 5 | } from "@tanstack/react-router"; |
| 6 | import { ExecutorProvider } from "@executor/react"; | 6 | import { ExecutorProvider } from "@executor/react/api/provider"; |
| 7 | import { ToolsPage } from "@web/pages/tools"; | 7 | import { ToolsPage } from "@executor/react/pages/tools"; |
| 8 | import { SourcesPage } from "@web/pages/sources"; | 8 | import { SourcesPage } from "@executor/react/pages/sources"; |
| 9 | import { SourcesAddPage } from "@web/pages/sources-add"; | 9 | import { SourcesAddPage } from "@executor/react/pages/sources-add"; |
| 10 | import { SourceDetailPage } from "@web/pages/source-detail"; | 10 | import { SourceDetailPage } from "@executor/react/pages/source-detail"; |
| 11 | import { SecretsPage } from "@web/pages/secrets"; | 11 | import { SecretsPage } from "@executor/react/pages/secrets"; |
| 12 | import { Shell } from "@web/shell"; | 12 | import { Shell } from "./shell"; |
| 13 | 13 | ||
| 14 | // --------------------------------------------------------------------------- | 14 | // --------------------------------------------------------------------------- |
| 15 | // Root layout — Shell renders <Outlet /> directly | 15 | // Root layout — Shell renders <Outlet /> directly |
| @@ -0,0 +1,483 @@ | |||
| 1 | import { Link, Outlet, useLocation } from "@tanstack/react-router"; | ||
| 2 | import { useCallback, useEffect, useRef, useState } from "react"; | ||
| 3 | import { useAtomRefresh, useAtomValue, Result } from "@effect-atom/atom-react"; | ||
| 4 | import { sourcesAtom, toolsAtom } from "@executor/react/api/atoms"; | ||
| 5 | import { useScope, useScopeInfo } from "@executor/react/api/scope-context"; | ||
| 6 | import { Button } from "@executor/react/components/button"; | ||
| 7 | import { useAuth } from "./auth"; | ||
| 8 | |||
| 9 | // ── Env ───────────────────────────────────────────────────────────────── | ||
| 10 | |||
| 11 | type AppMetaEnv = { | ||
| 12 | readonly VITE_APP_VERSION: string; | ||
| 13 | readonly VITE_GITHUB_URL: string; | ||
| 14 | }; | ||
| 15 | |||
| 16 | const { VITE_APP_VERSION, VITE_GITHUB_URL } = (import.meta as ImportMeta & { | ||
| 17 | readonly env: AppMetaEnv; | ||
| 18 | }).env; | ||
| 19 | |||
| 20 | // ── Version helpers ───────────────────────────────────────────────────── | ||
| 21 | |||
| 22 | type UpdateChannel = "latest" | "beta"; | ||
| 23 | |||
| 24 | const EXECUTOR_DIST_TAGS_PATH = "/v1/app/npm/dist-tags"; | ||
| 25 | |||
| 26 | type ParsedVersion = { | ||
| 27 | readonly major: number; | ||
| 28 | readonly minor: number; | ||
| 29 | readonly patch: number; | ||
| 30 | readonly prerelease: ReadonlyArray<string | number> | null; | ||
| 31 | }; | ||
| 32 | |||
| 33 | const semverPattern = | ||
| 34 | /^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?:-(?<prerelease>[0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/; | ||
| 35 | |||
| 36 | const resolveUpdateChannel = (version: string): UpdateChannel => | ||
| 37 | version.includes("-beta.") ? "beta" : "latest"; | ||
| 38 | |||
| 39 | const parseVersion = (version: string): ParsedVersion | null => { | ||
| 40 | const match = version.trim().match(semverPattern); | ||
| 41 | if (!match?.groups) return null; | ||
| 42 | return { | ||
| 43 | major: Number(match.groups.major), | ||
| 44 | minor: Number(match.groups.minor), | ||
| 45 | patch: Number(match.groups.patch), | ||
| 46 | prerelease: match.groups.prerelease | ||
| 47 | ? match.groups.prerelease.split(".").map((id) => | ||
| 48 | /^\d+$/.test(id) ? Number(id) : id, | ||
| 49 | ) | ||
| 50 | : null, | ||
| 51 | }; | ||
| 52 | }; | ||
| 53 | |||
| 54 | const comparePrereleaseIdentifiers = ( | ||
| 55 | left: ReadonlyArray<string | number> | null, | ||
| 56 | right: ReadonlyArray<string | number> | null, | ||
| 57 | ): number => { | ||
| 58 | if (left === null && right === null) return 0; | ||
| 59 | if (left === null) return 1; | ||
| 60 | if (right === null) return -1; | ||
| 61 | const max = Math.max(left.length, right.length); | ||
| 62 | for (let i = 0; i < max; i++) { | ||
| 63 | const l = left[i]; | ||
| 64 | const r = right[i]; | ||
| 65 | if (l === undefined) return -1; | ||
| 66 | if (r === undefined) return 1; | ||
| 67 | if (l === r) continue; | ||
| 68 | if (typeof l === "number" && typeof r === "number") return l < r ? -1 : 1; | ||
| 69 | if (typeof l === "number") return -1; | ||
| 70 | if (typeof r === "number") return 1; | ||
| 71 | return l < r ? -1 : 1; | ||
| 72 | } | ||
| 73 | return 0; | ||
| 74 | }; | ||
| 75 | |||
| 76 | const compareVersions = (left: string, right: string): number | null => { | ||
| 77 | const lv = parseVersion(left); | ||
| 78 | const rv = parseVersion(right); | ||
| 79 | if (!lv || !rv) return null; | ||
| 80 | if (lv.major !== rv.major) return lv.major < rv.major ? -1 : 1; | ||
| 81 | if (lv.minor !== rv.minor) return lv.minor < rv.minor ? -1 : 1; | ||
| 82 | if (lv.patch !== rv.patch) return lv.patch < rv.patch ? -1 : 1; | ||
| 83 | return comparePrereleaseIdentifiers(lv.prerelease, rv.prerelease); | ||
| 84 | }; | ||
| 85 | |||
| 86 | // ── useLatestVersion ──────────────────────────────────────────────────── | ||
| 87 | |||
| 88 | function useLatestVersion(currentVersion: string) { | ||
| 89 | const channel = resolveUpdateChannel(currentVersion); | ||
| 90 | const [latestVersion, setLatestVersion] = useState<string | null>(null); | ||
| 91 | |||
| 92 | useEffect(() => { | ||
| 93 | let cancelled = false; | ||
| 94 | fetch(EXECUTOR_DIST_TAGS_PATH) | ||
| 95 | .then(async (res) => { | ||
| 96 | if (!res.ok) throw new Error(`Failed to load dist tags: ${res.status}`); | ||
| 97 | return res.json() as Promise<Partial<Record<UpdateChannel, string>>>; | ||
| 98 | }) | ||
| 99 | .then((data) => { | ||
| 100 | if (!cancelled) setLatestVersion(data[channel] ?? null); | ||
| 101 | }) | ||
| 102 | .catch(() => {}); | ||
| 103 | return () => { cancelled = true; }; | ||
| 104 | }, [channel]); | ||
| 105 | |||
| 106 | const updateAvailable = | ||
| 107 | latestVersion !== null && compareVersions(currentVersion, latestVersion) === -1; | ||
| 108 | |||
| 109 | return { latestVersion, updateAvailable, channel }; | ||
| 110 | } | ||
| 111 | |||
| 112 | // ── UpdateCard ────────────────────────────────────────────────────────── | ||
| 113 | |||
| 114 | function UpdateCard(props: { latestVersion: string; channel: UpdateChannel }) { | ||
| 115 | const command = `npm i -g executor@${props.channel}`; | ||
| 116 | const [copied, setCopied] = useState(false); | ||
| 117 | |||
| 118 | const handleCopy = useCallback(() => { | ||
| 119 | void navigator.clipboard.writeText(command).then(() => { | ||
| 120 | setCopied(true); | ||
| 121 | setTimeout(() => setCopied(false), 1500); | ||
| 122 | }); | ||
| 123 | }, [command]); | ||
| 124 | |||
| 125 | return ( | ||
| 126 | <div className="mx-2 mb-2 rounded-xl border border-primary/25 bg-primary/[0.06] p-3"> | ||
| 127 | <div className="flex items-center gap-2"> | ||
| 128 | <div className="flex size-5 shrink-0 items-center justify-center rounded-full bg-primary/15"> | ||
| 129 | <svg viewBox="0 0 16 16" fill="none" className="size-3 text-primary"> | ||
| 130 | <path d="M8 3v7M5 7l3 3 3-3" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" /> | ||
| 131 | <path d="M3 12h10" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" /> | ||
| 132 | </svg> | ||
| 133 | </div> | ||
| 134 | <div className="min-w-0"> | ||
| 135 | <p className="text-[11px] font-semibold text-foreground">Update available</p> | ||
| 136 | <p className="text-[10px] text-muted-foreground"> | ||
| 137 | v{props.latestVersion} | ||
| 138 | </p> | ||
| 139 | </div> | ||
| 140 | </div> | ||
| 141 | <Button | ||
| 142 | type="button" | ||
| 143 | variant="outline" | ||
| 144 | onClick={handleCopy} | ||
| 145 | className="mt-2.5 flex w-full items-center justify-between gap-2 rounded-lg border-border/60 bg-background/50 px-2.5 py-1.5 text-left hover:bg-background/80" | ||
| 146 | > | ||
| 147 | <code className="truncate font-mono text-[10px] text-sidebar-foreground"> | ||
| 148 | {command} | ||
| 149 | </code> | ||
| 150 | <span className="shrink-0 text-muted-foreground transition-colors group-hover:text-foreground"> | ||
| 151 | {copied ? ( | ||
| 152 | <svg viewBox="0 0 16 16" fill="none" className="size-3 text-primary"> | ||
| 153 | <path d="M3 8.5l3.5 3.5L13 4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" /> | ||
| 154 | </svg> | ||
| 155 | ) : ( | ||
| 156 | <svg viewBox="0 0 16 16" fill="none" className="size-3"> | ||
| 157 | <rect x="5" y="5" width="8" height="8" rx="1.5" stroke="currentColor" strokeWidth="1.2" /> | ||
| 158 | <path d="M3 11V3.5A.5.5 0 013.5 3H11" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" /> | ||
| 159 | </svg> | ||
| 160 | )} | ||
| 161 | </span> | ||
| 162 | </Button> | ||
| 163 | </div> | ||
| 164 | ); | ||
| 165 | } | ||
| 166 | |||
| 167 | // ── NavItem ────────────────────────────────────────────────────────────── | ||
| 168 | |||
| 169 | function NavItem(props: { to: string; label: string; active: boolean; onNavigate?: () => void }) { | ||
| 170 | return ( | ||
| 171 | <Link | ||
| 172 | to={props.to} | ||
| 173 | onClick={props.onNavigate} | ||
| 174 | className={[ | ||
| 175 | "flex items-center gap-2.5 rounded-md px-2.5 py-1.5 text-[13px] transition-colors", | ||
| 176 | props.active | ||
| 177 | ? "bg-sidebar-active text-foreground font-medium" | ||
| 178 | : "text-sidebar-foreground hover:bg-sidebar-active/60 hover:text-foreground", | ||
| 179 | ].join(" ")} | ||
| 180 | > | ||
| 181 | {props.label} | ||
| 182 | </Link> | ||
| 183 | ); | ||
| 184 | } | ||
| 185 | |||
| 186 | // ── SourceList ─────────────────────────────────────────────────────────── | ||
| 187 | |||
| 188 | function SourceList(props: { pathname: string; onNavigate?: () => void }) { | ||
| 189 | const scopeId = useScope(); | ||
| 190 | const sources = useAtomValue(sourcesAtom(scopeId)); | ||
| 191 | |||
| 192 | return Result.match(sources, { | ||
| 193 | onInitial: () => ( | ||
| 194 | <div className="px-2.5 py-2 text-[11px] text-muted-foreground/40">Loading…</div> | ||
| 195 | ), | ||
| 196 | onFailure: () => ( | ||
| 197 | <div className="px-2.5 py-2 text-[11px] text-muted-foreground/40">No sources yet</div> | ||
| 198 | ), | ||
| 199 | onSuccess: ({ value }) => | ||
| 200 | value.length === 0 ? ( | ||
| 201 | <div className="px-2.5 py-2 text-[11px] leading-relaxed text-muted-foreground/40"> | ||
| 202 | No sources yet | ||
| 203 | </div> | ||
| 204 | ) : ( | ||
| 205 | <div className="flex flex-col gap-px"> | ||
| 206 | {value.map((s) => { | ||
| 207 | const detailPath = `/sources/${s.id}`; | ||
| 208 | const active = | ||
| 209 | props.pathname === detailPath || | ||
| 210 | props.pathname.startsWith(`${detailPath}/`); | ||
| 211 | return ( | ||
| 212 | <Link | ||
| 213 | key={s.id} | ||
| 214 | to="/sources/$namespace" | ||
| 215 | params={{ namespace: s.id }} | ||
| 216 | onClick={props.onNavigate} | ||
| 217 | className={[ | ||
| 218 | "group flex items-center gap-2 rounded-md px-2.5 py-1.5 text-[13px] transition-colors", | ||
| 219 | active | ||
| 220 | ? "bg-sidebar-active text-foreground font-medium" | ||
| 221 | : "text-sidebar-foreground hover:bg-sidebar-active/60 hover:text-foreground", | ||
| 222 | ].join(" ")} | ||
| 223 | > | ||
| 224 | <span className="flex-1 truncate">{s.name}</span> | ||
| 225 | <span className="rounded bg-secondary/50 px-1 py-px text-[9px] font-medium text-muted-foreground/50"> | ||
| 226 | {s.kind} | ||
| 227 | </span> | ||
| 228 | </Link> | ||
| 229 | ); | ||
| 230 | })} | ||
| 231 | </div> | ||
| 232 | ), | ||
| 233 | }); | ||
| 234 | } | ||
| 235 | |||
| 236 | // ── ScopeLabel ─────────────────────────────────────────────────────────── | ||
| 237 | |||
| 238 | function ScopeLabel() { | ||
| 239 | const { name } = useScopeInfo(); | ||
| 240 | // Show just the last folder name, with full path as tooltip | ||
| 241 | const parts = name.replace(/\/+$/, "").split("/"); | ||
| 242 | const folder = parts[parts.length - 1] || name; | ||
| 243 | |||
| 244 | return ( | ||
| 245 | <div className="mb-1.5 flex items-center gap-1.5 rounded-md px-2.5 py-1.5" title={name}> | ||
| 246 | <svg viewBox="0 0 16 16" fill="none" className="size-3.5 shrink-0 text-muted-foreground/50"> | ||
| 247 | <path | ||
| 248 | d="M2 4.5C2 3.67 2.67 3 3.5 3h3.09a1 1 0 0 1 .7.29l1.42 1.42a1 1 0 0 0 .7.29H12.5c.83 0 1.5.67 1.5 1.5v5.5c0 .83-.67 1.5-1.5 1.5h-9A1.5 1.5 0 0 1 2 12V4.5z" | ||
| 249 | stroke="currentColor" | ||
| 250 | strokeWidth="1.2" | ||
| 251 | /> | ||
| 252 | </svg> | ||
| 253 | <span className="truncate text-[12px] font-medium text-foreground/80"> | ||
| 254 | {folder} | ||
| 255 | </span> | ||
| 256 | </div> | ||
| 257 | ); | ||
| 258 | } | ||
| 259 | |||
| 260 | // ── UserFooter ────────────────────────────────────────────────────────── | ||
| 261 | |||
| 262 | function UserFooter() { | ||
| 263 | const auth = useAuth(); | ||
| 264 | if (auth.status !== "authenticated") return null; | ||
| 265 | |||
| 266 | const initials = auth.user.name | ||
| 267 | ? auth.user.name.split(" ").map((n) => n[0]).join("").slice(0, 2).toUpperCase() | ||
| 268 | : auth.user.email[0]!.toUpperCase(); | ||
| 269 | |||
| 270 | return ( | ||
| 271 | <div className="shrink-0 border-t border-sidebar-border px-3 py-2.5"> | ||
| 272 | <div className="flex items-center gap-2.5"> | ||
| 273 | {auth.user.avatarUrl ? ( | ||
| 274 | <img | ||
| 275 | src={auth.user.avatarUrl} | ||
| 276 | alt="" | ||
| 277 | className="size-7 shrink-0 rounded-full" | ||
| 278 | /> | ||
| 279 | ) : ( | ||
| 280 | <div className="flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-[10px] font-semibold text-primary"> | ||
| 281 | {initials} | ||
| 282 | </div> | ||
| 283 | )} | ||
| 284 | <div className="min-w-0 flex-1"> | ||
| 285 | <p className="truncate text-[12px] font-medium text-foreground"> | ||
| 286 | {auth.user.name ?? auth.user.email} | ||
| 287 | </p> | ||
| 288 | {auth.team && ( | ||
| 289 | <p className="truncate text-[10px] text-muted-foreground"> | ||
| 290 | {auth.team.name} | ||
| 291 | </p> | ||
| 292 | )} | ||
| 293 | </div> | ||
| 294 | <a | ||
| 295 | href="/auth/logout" | ||
| 296 | className="shrink-0 rounded-md p-1 text-muted-foreground/50 transition-colors hover:bg-sidebar-active hover:text-foreground" | ||
| 297 | title="Sign out" | ||
| 298 | > | ||
| 299 | <svg viewBox="0 0 16 16" fill="none" className="size-3.5"> | ||
| 300 | <path d="M6 2H3.5A1.5 1.5 0 002 3.5v9A1.5 1.5 0 003.5 14H6M10.5 11.5L14 8l-3.5-3.5M14 8H6" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round" /> | ||
| 301 | </svg> | ||
| 302 | </a> | ||
| 303 | </div> | ||
| 304 | </div> | ||
| 305 | ); | ||
| 306 | } | ||
| 307 | |||
| 308 | // ── SidebarContent ─────────────────────────────────────────────────────── | ||
| 309 | |||
| 310 | function SidebarContent(props: { | ||
| 311 | pathname: string; | ||
| 312 | onNavigate?: () => void; | ||
| 313 | showBrand?: boolean; | ||
| 314 | updateAvailable: boolean; | ||
| 315 | latestVersion: string | null; | ||
| 316 | channel: UpdateChannel; | ||
| 317 | }) { | ||
| 318 | const isHome = props.pathname === "/"; | ||
| 319 | const isSecrets = props.pathname === "/secrets"; | ||
| 320 | |||
| 321 | return ( | ||
| 322 | <> | ||
| 323 | {props.showBrand !== false && ( | ||
| 324 | <div className="flex h-12 shrink-0 items-center border-b border-sidebar-border px-4"> | ||
| 325 | <Link to="/" className="flex items-center gap-1.5"> | ||
| 326 | <span className="font-display text-base tracking-tight text-foreground"> | ||
| 327 | executor | ||
| 328 | </span> | ||
| 329 | </Link> | ||
| 330 | </div> | ||
| 331 | )} | ||
| 332 | |||
| 333 | <nav className="flex flex-1 flex-col overflow-y-auto p-2"> | ||
| 334 | <ScopeLabel /> | ||
| 335 | <NavItem | ||
| 336 | to="/" | ||
| 337 | label="Sources" | ||
| 338 | active={isHome} | ||
| 339 | onNavigate={props.onNavigate} | ||
| 340 | /> | ||
| 341 | <NavItem | ||
| 342 | to="/secrets" | ||
| 343 | label="Secrets" | ||
| 344 | active={isSecrets} | ||
| 345 | onNavigate={props.onNavigate} | ||
| 346 | /> | ||
| 347 | |||
| 348 | {/* Sources list */} | ||
| 349 | <div className="mt-5 mb-1 px-2.5 text-[10px] font-medium uppercase tracking-widest text-muted-foreground/50"> | ||
| 350 | <span>Configured</span> | ||
| 351 | </div> | ||
| 352 | |||
| 353 | <SourceList pathname={props.pathname} onNavigate={props.onNavigate} /> | ||
| 354 | </nav> | ||
| 355 | |||
| 356 | {/* User */} | ||
| 357 | <UserFooter /> | ||
| 358 | </> | ||
| 359 | ); | ||
| 360 | } | ||
| 361 | |||
| 362 | // ── Shell ───────────────────────────────────────────────────────────────── | ||
| 363 | |||
| 364 | export function Shell() { | ||
| 365 | const location = useLocation(); | ||
| 366 | const pathname = location.pathname; | ||
| 367 | const scopeId = useScope(); | ||
| 368 | const refreshSources = useAtomRefresh(sourcesAtom(scopeId)); | ||
| 369 | const refreshTools = useAtomRefresh(toolsAtom(scopeId)); | ||
| 370 | const { latestVersion, updateAvailable, channel } = useLatestVersion(VITE_APP_VERSION); | ||
| 371 | const lastPathname = useRef(pathname); | ||
| 372 | const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false); | ||
| 373 | if (lastPathname.current !== pathname) { | ||
| 374 | lastPathname.current = pathname; | ||
| 375 | if (mobileSidebarOpen) setMobileSidebarOpen(false); | ||
| 376 | } | ||
| 377 | |||
| 378 | // Lock scroll when mobile sidebar open | ||
| 379 | useEffect(() => { | ||
| 380 | if (!mobileSidebarOpen) return; | ||
| 381 | const prev = document.body.style.overflow; | ||
| 382 | document.body.style.overflow = "hidden"; | ||
| 383 | return () => { | ||
| 384 | document.body.style.overflow = prev; | ||
| 385 | }; | ||
| 386 | }, [mobileSidebarOpen]); | ||
| 387 | |||
| 388 | useEffect(() => { | ||
| 389 | if (!import.meta.hot) { | ||
| 390 | return; | ||
| 391 | } | ||
| 392 | |||
| 393 | const refreshBackendData = () => { | ||
| 394 | refreshSources(); | ||
| 395 | refreshTools(); | ||
| 396 | }; | ||
| 397 | |||
| 398 | import.meta.hot.on("executor:backend-updated", refreshBackendData); | ||
| 399 | |||
| 400 | return () => { | ||
| 401 | import.meta.hot?.off("executor:backend-updated", refreshBackendData); | ||
| 402 | }; | ||
| 403 | }, [refreshSources, refreshTools]); | ||
| 404 | |||
| 405 | return ( | ||
| 406 | <div className="flex h-screen overflow-hidden"> | ||
| 407 | {/* Desktop sidebar */} | ||
| 408 | <aside className="hidden w-52 shrink-0 border-r border-sidebar-border bg-sidebar md:flex md:flex-col lg:w-56"> | ||
| 409 | <SidebarContent | ||
| 410 | pathname={pathname} | ||
| 411 | updateAvailable={updateAvailable} | ||
| 412 | latestVersion={latestVersion} | ||
| 413 | channel={channel} | ||
| 414 | /> | ||
| 415 | </aside> | ||
| 416 | |||
| 417 | {/* Mobile sidebar overlay */} | ||
| 418 | {mobileSidebarOpen && ( | ||
| 419 | <div className="fixed inset-0 z-50 flex md:hidden"> | ||
| 420 | <button | ||
| 421 | type="button" | ||
| 422 | aria-label="Close navigation" | ||
| 423 | className="absolute inset-0 bg-black/45 backdrop-blur-[1px]" | ||
| 424 | onClick={() => setMobileSidebarOpen(false)} | ||
| 425 | /> | ||
| 426 | <div className="relative flex h-full w-[84vw] max-w-xs flex-col border-r border-sidebar-border bg-sidebar shadow-2xl"> | ||
| 427 | <div className="flex h-12 shrink-0 items-center justify-between border-b border-sidebar-border px-4"> | ||
| 428 | <Link to="/" className="flex items-center gap-1.5"> | ||
| 429 | <span className="font-display text-base tracking-tight text-foreground"> | ||
| 430 | executor | ||
| 431 | </span> | ||
| 432 | </Link> | ||
| 433 | <button | ||
| 434 | type="button" | ||
| 435 | aria-label="Close navigation" | ||
| 436 | onClick={() => setMobileSidebarOpen(false)} | ||
| 437 | className="size-8 flex items-center justify-center rounded-md text-sidebar-foreground hover:bg-sidebar-active hover:text-foreground" | ||
| 438 | > | ||
| 439 | <svg viewBox="0 0 16 16" className="size-3.5"> | ||
| 440 | <path d="M3 3l10 10M13 3L3 13" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" /> | ||
| 441 | </svg> | ||
| 442 | </button> | ||
| 443 | </div> | ||
| 444 | <SidebarContent | ||
| 445 | pathname={pathname} | ||
| 446 | onNavigate={() => setMobileSidebarOpen(false)} | ||
| 447 | showBrand={false} | ||
| 448 | updateAvailable={updateAvailable} | ||
| 449 | latestVersion={latestVersion} | ||
| 450 | channel={channel} | ||
| 451 | /> | ||
| 452 | </div> | ||
| 453 | </div> | ||
| 454 | )} | ||
| 455 | |||
| 456 | {/* Main content */} | ||
| 457 | <main className="flex min-h-0 flex-1 flex-col min-w-0 overflow-hidden"> | ||
| 458 | {/* Mobile top bar */} | ||
| 459 | <div className="flex h-12 shrink-0 items-center justify-between border-b border-border bg-background px-4 md:hidden"> | ||
| 460 | <button | ||
| 461 | type="button" | ||
| 462 | aria-label="Open navigation" | ||
| 463 | onClick={() => setMobileSidebarOpen(true)} | ||
| 464 | className="size-8 flex items-center justify-center rounded-md border border-border bg-card hover:bg-accent/50" | ||
| 465 | > | ||
| 466 | <svg viewBox="0 0 16 16" className="size-4"> | ||
| 467 | <path d="M2 4h12M2 8h12M2 12h12" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" /> | ||
| 468 | </svg> | ||
| 469 | </button> | ||
| 470 | <Link to="/" className="flex items-center gap-1.5"> | ||
| 471 | <span className="font-display text-base tracking-tight text-foreground"> | ||
| 472 | executor | ||
| 473 | </span> | ||
| 474 | </Link> | ||
| 475 | <div className="w-8 shrink-0" /> | ||
| 476 | </div> | ||
| 477 | |||
| 478 | {/* Outlet — pages control their own padding/scroll */} | ||
| 479 | <Outlet /> | ||
| 480 | </main> | ||
| 481 | </div> | ||
| 482 | ); | ||
| 483 | } | ||
| @@ -12,9 +12,6 @@ · 11 unmodified lines | |||
| 12 | "declarationMap": true, | 12 | "declarationMap": true, |
| 13 | "sourceMap": true, | 13 | "sourceMap": true, |
| 14 | "jsx": "react-jsx", | 14 | "jsx": "react-jsx", |
| 15 | "paths": { | ||
| 16 | "@web/*": ["../local/src/web/*"] | ||
| 17 | }, | ||
| 18 | "plugins": [ | 15 | "plugins": [ |
| 19 | { | 16 | { |
| 20 | "name": "@effect/language-service", | 17 | "name": "@effect/language-service", |
| @@ -1,4 +1,3 @@ | |||
| 1 | import { resolve } from "node:path"; | ||
| 2 | import { defineConfig } from "vite"; | 1 | import { defineConfig } from "vite"; |
| 3 | import react from "@vitejs/plugin-react"; | 2 | import react from "@vitejs/plugin-react"; |
| 4 | import tailwindcss from "@tailwindcss/vite"; | 3 | import tailwindcss from "@tailwindcss/vite"; |
| @@ -11,11 +10,6 @@ export default defineConfig({ · 6 unmodified lines | |||
| 11 | "import.meta.env.VITE_APP_VERSION": JSON.stringify("0.0.0"), | 10 | "import.meta.env.VITE_APP_VERSION": JSON.stringify("0.0.0"), |
| 12 | "import.meta.env.VITE_GITHUB_URL": JSON.stringify("https://github.com/RhysSullivan/executor"), | 11 | "import.meta.env.VITE_GITHUB_URL": JSON.stringify("https://github.com/RhysSullivan/executor"), |
| 13 | }, | 12 | }, |
| 14 | resolve: { | ||
| 15 | alias: { | ||
| 16 | "@web": resolve(__dirname, "../local/src/web"), | ||
| 17 | }, | ||
| 18 | }, | ||
| 19 | server: { | 13 | server: { |
| 20 | proxy: { | 14 | proxy: { |
| 21 | "/v1": `http://localhost:${API_PORT}`, | 15 | "/v1": `http://localhost:${API_PORT}`, |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | |||
| 25 | "@executor/react": "workspace:*", | 25 | "@executor/react": "workspace:*", |
| 26 | "@executor/sdk": "workspace:*", | 26 | "@executor/sdk": "workspace:*", |
| 27 | "@executor/storage-file": "workspace:*", | 27 | "@executor/storage-file": "workspace:*", |
| 28 | "@executor/ui": "workspace:*", | ||
| 29 | "@modelcontextprotocol/sdk": "^1.12.1", | 28 | "@modelcontextprotocol/sdk": "^1.12.1", |
| 30 | "@shikijs/langs": "^4.0.2", | 29 | "@shikijs/langs": "^4.0.2", |
| 31 | "@shikijs/themes": "^4.0.2", | 30 | "@shikijs/themes": "^4.0.2", |
| @@ -1 +0,0 @@ | |||
| 1 | export { useScope } from "@executor/react"; | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | import React from "react"; | 1 | import React from "react"; |
| 2 | import { createRoot } from "react-dom/client"; | 2 | import { createRoot } from "react-dom/client"; |
| 3 | import "@executor/ui/globals.css"; | 3 | import "@executor/react/globals.css"; |
| 4 | import { App } from "./App"; | 4 | import { App } from "./App"; |
| 5 | 5 | ||
| 6 | const root = createRoot(document.getElementById("root")!); | 6 | const root = createRoot(document.getElementById("root")!); |
| @@ -3,12 +3,12 @@ import { · 2 unmodified lines | |||
| 3 | createRootRoute, | 3 | createRootRoute, |
| 4 | createRoute, | 4 | createRoute, |
| 5 | } from "@tanstack/react-router"; | 5 | } from "@tanstack/react-router"; |
| 6 | import { ExecutorProvider } from "@executor/react"; | 6 | import { ExecutorProvider } from "@executor/react/api/provider"; |
| 7 | import { ToolsPage } from "./pages/tools"; | 7 | import { ToolsPage } from "@executor/react/pages/tools"; |
| 8 | import { SourcesPage } from "./pages/sources"; | 8 | import { SourcesPage } from "@executor/react/pages/sources"; |
| 9 | import { SourcesAddPage } from "./pages/sources-add"; | 9 | import { SourcesAddPage } from "@executor/react/pages/sources-add"; |
| 10 | import { SourceDetailPage } from "./pages/source-detail"; | 10 | import { SourceDetailPage } from "@executor/react/pages/source-detail"; |
| 11 | import { SecretsPage } from "./pages/secrets"; | 11 | import { SecretsPage } from "@executor/react/pages/secrets"; |
| 12 | import { Shell } from "./shell"; | 12 | import { Shell } from "./shell"; |
| 13 | 13 | ||
| 14 | // --------------------------------------------------------------------------- | 14 | // --------------------------------------------------------------------------- |
| @@ -1,15 +1,9 @@ | |||
| 1 | import { Link, Outlet, useLocation } from "@tanstack/react-router"; | 1 | import { Link, Outlet, useLocation } from "@tanstack/react-router"; |
| 2 | import { useCallback, useEffect, useRef, useState } from "react"; | 2 | import { useCallback, useEffect, useRef, useState } from "react"; |
| 3 | import { | 3 | import { useAtomRefresh, useAtomValue, Result } from "@effect-atom/atom-react"; |
| 4 | useAtomRefresh, | 4 | import { sourcesAtom, toolsAtom } from "@executor/react/api/atoms"; |
| 5 | useAtomValue, | 5 | import { useScope, useScopeInfo } from "@executor/react/api/scope-context"; |
| 6 | Result, | 6 | import { Button } from "@executor/react/components/button"; |
| 7 | sourcesAtom, | ||
| 8 | toolsAtom, | ||
| 9 | useScope, | ||
| 10 | useScopeInfo, | ||
| 11 | } from "@executor/react"; | ||
| 12 | import { Button } from "@executor/ui/components/button"; | ||
| 13 | 7 | ||
| 14 | // ── Env ───────────────────────────────────────────────────────────────── | 8 | // ── Env ───────────────────────────────────────────────────────────────── |
| 15 | 9 | ||
| @@ -53,7 +53,6 @@ · 52 unmodified lines | |||
| 53 | "@executor/react": "workspace:*", | 53 | "@executor/react": "workspace:*", |
| 54 | "@executor/sdk": "workspace:*", | 54 | "@executor/sdk": "workspace:*", |
| 55 | "@executor/storage-postgres": "workspace:*", | 55 | "@executor/storage-postgres": "workspace:*", |
| 56 | "@executor/ui": "workspace:*", | ||
| 57 | "@tanstack/react-router": "^1.168.10", | 56 | "@tanstack/react-router": "^1.168.10", |
| 58 | "@workos-inc/node": "^7.0.0", | 57 | "@workos-inc/node": "^7.0.0", |
| 59 | "drizzle-orm": "catalog:", | 58 | "drizzle-orm": "catalog:", |
| @@ -106,7 +105,6 @@ · 46 unmodified lines | |||
| 106 | "@executor/react": "workspace:*", | 105 | "@executor/react": "workspace:*", |
| 107 | "@executor/sdk": "workspace:*", | 106 | "@executor/sdk": "workspace:*", |
| 108 | "@executor/storage-file": "workspace:*", | 107 | "@executor/storage-file": "workspace:*", |
| 109 | "@executor/ui": "workspace:*", | ||
| 110 | "@modelcontextprotocol/sdk": "^1.12.1", | 108 | "@modelcontextprotocol/sdk": "^1.12.1", |
| 111 | "@shikijs/langs": "^4.0.2", | 109 | "@shikijs/langs": "^4.0.2", |
| 112 | "@shikijs/themes": "^4.0.2", | 110 | "@shikijs/themes": "^4.0.2", |
| @@ -140,25 +138,6 @@ · 27 unmodified lines | |||
| 140 | "tailwindcss": "^4.2.2", | 138 | "tailwindcss": "^4.2.2", |
| 141 | }, | 139 | }, |
| 142 | }, | 140 | }, |
| 143 | "packages/clients/react": { | ||
| 144 | "name": "@executor/react", | ||
| 145 | "version": "1.4.0", | ||
| 146 | "dependencies": { | ||
| 147 | "@effect-atom/atom": "^0.5.3", | ||
| 148 | "@effect-atom/atom-react": "^0.5.0", | ||
| 149 | "@effect/platform": "catalog:", | ||
| 150 | "@executor/api": "workspace:*", | ||
| 151 | "@executor/sdk": "workspace:*", | ||
| 152 | "@executor/ui": "workspace:*", | ||
| 153 | "effect": "catalog:", | ||
| 154 | "react": "^19.1.0", | ||
| 155 | }, | ||
| 156 | "devDependencies": { | ||
| 157 | "@types/node": "catalog:", | ||
| 158 | "@types/react": "^19.1.0", | ||
| 159 | "typescript": "^5.9.3", | ||
| 160 | }, | ||
| 161 | }, | ||
| 162 | "packages/core/api": { | 141 | "packages/core/api": { |
| 163 | "name": "@executor/api", | 142 | "name": "@executor/api", |
| 164 | "version": "1.4.0", | 143 | "version": "1.4.0", |
| @@ -357,7 +336,6 @@ · 192 unmodified lines | |||
| 357 | "@effect-atom/atom-react": "^0.5.0", | 336 | "@effect-atom/atom-react": "^0.5.0", |
| 358 | "@effect/vitest": "catalog:", | 337 | "@effect/vitest": "catalog:", |
| 359 | "@executor/react": "workspace:*", | 338 | "@executor/react": "workspace:*", |
| 360 | "@executor/ui": "workspace:*", | ||
| 361 | "@types/node": "catalog:", | 339 | "@types/node": "catalog:", |
| 362 | "@types/react": "^19.1.0", | 340 | "@types/react": "^19.1.0", |
| 363 | "bun-types": "catalog:", | 341 | "bun-types": "catalog:", |
| @@ -367,14 +345,12 @@ · 3 unmodified lines | |||
| 367 | "peerDependencies": { | 345 | "peerDependencies": { |
| 368 | "@effect-atom/atom-react": "^0.5.0", | 346 | "@effect-atom/atom-react": "^0.5.0", |
| 369 | "@executor/react": "workspace:*", | 347 | "@executor/react": "workspace:*", |
| 370 | "@executor/ui": "workspace:*", | ||
| 371 | "@tanstack/react-router": "^1.168.10", | 348 | "@tanstack/react-router": "^1.168.10", |
| 372 | "react": "^19.1.0", | 349 | "react": "^19.1.0", |
| 373 | }, | 350 | }, |
| 374 | "optionalPeers": [ | 351 | "optionalPeers": [ |
| 375 | "@effect-atom/atom-react", | 352 | "@effect-atom/atom-react", |
| 376 | "@executor/react", | 353 | "@executor/react", |
| 377 | "@executor/ui", | ||
| 378 | "@tanstack/react-router", | 354 | "@tanstack/react-router", |
| 379 | "react", | 355 | "react", |
| 380 | ], | 356 | ], |
| @@ -393,7 +369,6 @@ · 12 unmodified lines | |||
| 393 | "@effect/vitest": "catalog:", | 369 | "@effect/vitest": "catalog:", |
| 394 | "@executor/api": "workspace:*", | 370 | "@executor/api": "workspace:*", |
| 395 | "@executor/react": "workspace:*", | 371 | "@executor/react": "workspace:*", |
| 396 | "@executor/ui": "workspace:*", | ||
| 397 | "@types/node": "catalog:", | 372 | "@types/node": "catalog:", |
| 398 | "@types/react": "^19.1.0", | 373 | "@types/react": "^19.1.0", |
| 399 | "bun-types": "catalog:", | 374 | "bun-types": "catalog:", |
| @@ -404,7 +379,6 @@ · 4 unmodified lines | |||
| 404 | "@effect-atom/atom-react": "^0.5.0", | 379 | "@effect-atom/atom-react": "^0.5.0", |
| 405 | "@executor/api": "workspace:*", | 380 | "@executor/api": "workspace:*", |
| 406 | "@executor/react": "workspace:*", | 381 | "@executor/react": "workspace:*", |
| 407 | "@executor/ui": "workspace:*", | ||
| 408 | "@tanstack/react-router": "^1.168.10", | 382 | "@tanstack/react-router": "^1.168.10", |
| 409 | "react": "^19.1.0", | 383 | "react": "^19.1.0", |
| 410 | }, | 384 | }, |
| @@ -412,7 +386,6 @@ · 1 unmodified line | |||
| 412 | "@effect-atom/atom-react", | 386 | "@effect-atom/atom-react", |
| 413 | "@executor/api", | 387 | "@executor/api", |
| 414 | "@executor/react", | 388 | "@executor/react", |
| 415 | "@executor/ui", | ||
| 416 | "@tanstack/react-router", | 389 | "@tanstack/react-router", |
| 417 | "react", | 390 | "react", |
| 418 | ], | 391 | ], |
| @@ -447,7 +420,6 @@ · 28 unmodified lines | |||
| 447 | "@effect/vitest": "catalog:", | 420 | "@effect/vitest": "catalog:", |
| 448 | "@executor/api": "workspace:*", | 421 | "@executor/api": "workspace:*", |
| 449 | "@executor/react": "workspace:*", | 422 | "@executor/react": "workspace:*", |
| 450 | "@executor/ui": "workspace:*", | ||
| 451 | "@types/node": "catalog:", | 423 | "@types/node": "catalog:", |
| 452 | "@types/react": "^19.1.0", | 424 | "@types/react": "^19.1.0", |
| 453 | "bun-types": "catalog:", | 425 | "bun-types": "catalog:", |
| @@ -459,7 +431,6 @@ · 5 unmodified lines | |||
| 459 | "@effect-atom/atom-react": "^0.5.0", | 431 | "@effect-atom/atom-react": "^0.5.0", |
| 460 | "@executor/api": "workspace:*", | 432 | "@executor/api": "workspace:*", |
| 461 | "@executor/react": "workspace:*", | 433 | "@executor/react": "workspace:*", |
| 462 | "@executor/ui": "workspace:*", | ||
| 463 | "@tanstack/react-router": "^1.168.10", | 434 | "@tanstack/react-router": "^1.168.10", |
| 464 | "react": "^19.1.0", | 435 | "react": "^19.1.0", |
| 465 | }, | 436 | }, |
| @@ -467,7 +438,6 @@ · 1 unmodified line | |||
| 467 | "@effect-atom/atom-react", | 438 | "@effect-atom/atom-react", |
| 468 | "@executor/api", | 439 | "@executor/api", |
| 469 | "@executor/react", | 440 | "@executor/react", |
| 470 | "@executor/ui", | ||
| 471 | "@tanstack/react-router", | 441 | "@tanstack/react-router", |
| 472 | "react", | 442 | "react", |
| 473 | ], | 443 | ], |
| @@ -495,13 +465,11 @@ · 21 unmodified lines | |||
| 495 | "peerDependencies": { | 465 | "peerDependencies": { |
| 496 | "@effect-atom/atom-react": "^0.5.0", | 466 | "@effect-atom/atom-react": "^0.5.0", |
| 497 | "@executor/react": "workspace:*", | 467 | "@executor/react": "workspace:*", |
| 498 | "@executor/ui": "workspace:*", | ||
| 499 | "react": ">=18", | 468 | "react": ">=18", |
| 500 | }, | 469 | }, |
| 501 | "optionalPeers": [ | 470 | "optionalPeers": [ |
| 502 | "@effect-atom/atom-react", | 471 | "@effect-atom/atom-react", |
| 503 | "@executor/react", | 472 | "@executor/react", |
| 504 | "@executor/ui", | ||
| 505 | "react", | 473 | "react", |
| 506 | ], | 474 | ], |
| 507 | }, | 475 | }, |
| @@ -522,7 +490,6 @@ · 14 unmodified lines | |||
| 522 | "@effect/vitest": "catalog:", | 490 | "@effect/vitest": "catalog:", |
| 523 | "@executor/api": "workspace:*", | 491 | "@executor/api": "workspace:*", |
| 524 | "@executor/react": "workspace:*", | 492 | "@executor/react": "workspace:*", |
| 525 | "@executor/ui": "workspace:*", | ||
| 526 | "@types/node": "catalog:", | 493 | "@types/node": "catalog:", |
| 527 | "@types/react": "^19.1.0", | 494 | "@types/react": "^19.1.0", |
| 528 | "bun-types": "catalog:", | 495 | "bun-types": "catalog:", |
| @@ -533,7 +500,6 @@ · 4 unmodified lines | |||
| 533 | "@effect-atom/atom-react": "^0.5.0", | 500 | "@effect-atom/atom-react": "^0.5.0", |
| 534 | "@executor/api": "workspace:*", | 501 | "@executor/api": "workspace:*", |
| 535 | "@executor/react": "workspace:*", | 502 | "@executor/react": "workspace:*", |
| 536 | "@executor/ui": "workspace:*", | ||
| 537 | "@tanstack/react-router": "^1.168.10", | 503 | "@tanstack/react-router": "^1.168.10", |
| 538 | "react": "^19.1.0", | 504 | "react": "^19.1.0", |
| 539 | }, | 505 | }, |
| @@ -541,16 +507,20 @@ · 1 unmodified line | |||
| 541 | "@effect-atom/atom-react", | 507 | "@effect-atom/atom-react", |
| 542 | "@executor/api", | 508 | "@executor/api", |
| 543 | "@executor/react", | 509 | "@executor/react", |
| 544 | "@executor/ui", | ||
| 545 | "@tanstack/react-router", | 510 | "@tanstack/react-router", |
| 546 | "react", | 511 | "react", |
| 547 | ], | 512 | ], |
| 548 | }, | 513 | }, |
| 549 | "packages/ui": { | 514 | "packages/react": { |
| 550 | "name": "@executor/ui", | 515 | "name": "@executor/react", |
| 551 | "version": "1.4.0", | 516 | "version": "1.4.0", |
| 552 | "dependencies": { | 517 | "dependencies": { |
| 553 | "@base-ui/react": "^1.3.0", | 518 | "@base-ui/react": "^1.3.0", |
| 519 | "@effect-atom/atom": "^0.5.3", | ||
| 520 | "@effect-atom/atom-react": "^0.5.0", | ||
| 521 | "@effect/platform": "catalog:", | ||
| 522 | "@executor/api": "workspace:*", | ||
| 523 | "@executor/sdk": "workspace:*", | ||
| 554 | "@hookform/resolvers": "^5.2.2", | 524 | "@hookform/resolvers": "^5.2.2", |
| 555 | "@shikijs/langs": "^4.0.2", | 525 | "@shikijs/langs": "^4.0.2", |
| 556 | "@shikijs/themes": "^4.0.2", | 526 | "@shikijs/themes": "^4.0.2", |
| @@ -558,6 +528,7 @@ · 1 unmodified line | |||
| 558 | "clsx": "^2.1.1", | 528 | "clsx": "^2.1.1", |
| 559 | "cmdk": "^1.1.1", | 529 | "cmdk": "^1.1.1", |
| 560 | "date-fns": "^4.1.0", | 530 | "date-fns": "^4.1.0", |
| 531 | "effect": "catalog:", | ||
| 561 | "embla-carousel-react": "^8.6.0", | 532 | "embla-carousel-react": "^8.6.0", |
| 562 | "input-otp": "^1.4.2", | 533 | "input-otp": "^1.4.2", |
| 563 | "lucide-react": "^1.7.0", | 534 | "lucide-react": "^1.7.0", |
| @@ -576,6 +547,7 @@ · 12 unmodified lines | |||
| 576 | "zod": "^4.3.6", | 547 | "zod": "^4.3.6", |
| 577 | }, | 548 | }, |
| 578 | "devDependencies": { | 549 | "devDependencies": { |
| 550 | "@types/node": "catalog:", | ||
| 579 | "@types/react": "^19.1.0", | 551 | "@types/react": "^19.1.0", |
| 580 | "hast-util-to-jsx-runtime": "^2.3.6", | 552 | "hast-util-to-jsx-runtime": "^2.3.6", |
| 581 | "tailwindcss": "^4.1.10", | 553 | "tailwindcss": "^4.1.10", |
| @@ -885,7 +857,7 @@ · 303 unmodified lines | |||
| 885 | 857 | ||
| 886 | "@executor/plugin-openapi": ["@executor/plugin-openapi@workspace:packages/plugins/openapi"], | 858 | "@executor/plugin-openapi": ["@executor/plugin-openapi@workspace:packages/plugins/openapi"], |
| 887 | 859 | ||
| 888 | "@executor/react": ["@executor/react@workspace:packages/clients/react"], | 860 | "@executor/react": ["@executor/react@workspace:packages/react"], |
| 889 | 861 | ||
| 890 | "@executor/runtime-deno-subprocess": ["@executor/runtime-deno-subprocess@workspace:packages/kernel/runtime-deno-subprocess"], | 862 | "@executor/runtime-deno-subprocess": ["@executor/runtime-deno-subprocess@workspace:packages/kernel/runtime-deno-subprocess"], |
| 891 | 863 | ||
| @@ -897,8 +869,6 @@ · 5 unmodified lines | |||
| 897 | 869 | ||
| 898 | "@executor/storage-postgres": ["@executor/storage-postgres@workspace:packages/core/storage-postgres"], | 870 | "@executor/storage-postgres": ["@executor/storage-postgres@workspace:packages/core/storage-postgres"], |
| 899 | 871 | ||
| 900 | "@executor/ui": ["@executor/ui@workspace:packages/ui"], | ||
| 901 | |||
| 902 | "@floating-ui/core": ["@floating-ui/core@1.7.5", "", { "dependencies": { "@floating-ui/utils": "^0.2.11" } }, "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ=="], | 872 | "@floating-ui/core": ["@floating-ui/core@1.7.5", "", { "dependencies": { "@floating-ui/utils": "^0.2.11" } }, "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ=="], |
| 903 | 873 | ||
| 904 | "@floating-ui/dom": ["@floating-ui/dom@1.7.6", "", { "dependencies": { "@floating-ui/core": "^1.7.5", "@floating-ui/utils": "^0.2.11" } }, "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ=="], | 874 | "@floating-ui/dom": ["@floating-ui/dom@1.7.6", "", { "dependencies": { "@floating-ui/core": "^1.7.5", "@floating-ui/utils": "^0.2.11" } }, "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ=="], |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | |||
| 24 | "packageManager": "bun@1.3.11", | 24 | "packageManager": "bun@1.3.11", |
| 25 | "workspaces": [ | 25 | "workspaces": [ |
| 26 | "packages/*/*", | 26 | "packages/*/*", |
| 27 | "packages/ui", | 27 | "packages/react", |
| 28 | "apps/*" | 28 | "apps/*" |
| 29 | ], | 29 | ], |
| 30 | "catalog": { | 30 | "catalog": { |
| @@ -1,4 +0,0 @@ | |||
| 1 | # @executor/react changelog | ||
| 2 | |||
| 3 | This file exists for Changesets release workflow compatibility. | ||
| 4 | Canonical user-facing release notes are published on GitHub Releases. | ||
| @@ -1,27 +0,0 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor/react", | ||
| 3 | "version": "1.4.0", | ||
| 4 | "private": true, | ||
| 5 | "type": "module", | ||
| 6 | "exports": { | ||
| 7 | ".": "./src/index.ts" | ||
| 8 | }, | ||
| 9 | "dependencies": { | ||
| 10 | "@effect/platform": "catalog:", | ||
| 11 | "@effect-atom/atom": "^0.5.3", | ||
| 12 | "@effect-atom/atom-react": "^0.5.0", | ||
| 13 | "@executor/api": "workspace:*", | ||
| 14 | "@executor/ui": "workspace:*", | ||
| 15 | "@executor/sdk": "workspace:*", | ||
| 16 | "effect": "catalog:", | ||
| 17 | "react": "^19.1.0" | ||
| 18 | }, | ||
| 19 | "devDependencies": { | ||
| 20 | "@types/react": "^19.1.0", | ||
| 21 | "@types/node": "catalog:", | ||
| 22 | "typescript": "^5.9.3" | ||
| 23 | }, | ||
| 24 | "scripts": { | ||
| 25 | "typecheck": "tsc --noEmit" | ||
| 26 | } | ||
| 27 | } | ||
| @@ -1,54 +0,0 @@ | |||
| 1 | // Re-export effect-atom essentials so consumers don't need direct deps | ||
| 2 | export { | ||
| 3 | Atom, | ||
| 4 | AtomHttpApi, | ||
| 5 | Result, | ||
| 6 | RegistryContext, | ||
| 7 | RegistryProvider, | ||
| 8 | useAtom, | ||
| 9 | useAtomMount, | ||
| 10 | useAtomRefresh, | ||
| 11 | useAtomSet, | ||
| 12 | useAtomSuspense, | ||
| 13 | useAtomValue, | ||
| 14 | } from "@effect-atom/atom-react"; | ||
| 15 | |||
| 16 | // Base URL management | ||
| 17 | export { getBaseUrl, setBaseUrl } from "./base-url"; | ||
| 18 | |||
| 19 | // Typed API client | ||
| 20 | export { ExecutorApiClient } from "./client"; | ||
| 21 | |||
| 22 | // Query & mutation atoms | ||
| 23 | export { | ||
| 24 | toolsAtom, | ||
| 25 | sourceToolsAtom, | ||
| 26 | toolSchemaAtom, | ||
| 27 | sourcesAtom, | ||
| 28 | sourceAtom, | ||
| 29 | secretsAtom, | ||
| 30 | secretStatusAtom, | ||
| 31 | setSecret, | ||
| 32 | resolveSecret, | ||
| 33 | removeSecret, | ||
| 34 | removeSource, | ||
| 35 | refreshSource, | ||
| 36 | detectSource, | ||
| 37 | } from "./atoms"; | ||
| 38 | |||
| 39 | // Scope hook | ||
| 40 | export { useScope, useScopeInfo } from "./use-scope"; | ||
| 41 | export type { ScopeInfo } from "./use-scope"; | ||
| 42 | |||
| 43 | // Provider | ||
| 44 | export { ExecutorProvider } from "./provider"; | ||
| 45 | export { SecretPicker } from "./secret-picker"; | ||
| 46 | export type { SecretPickerSecret } from "./secret-picker"; | ||
| 47 | |||
| 48 | // Re-export commonly needed SDK types | ||
| 49 | export { ScopeId, ToolId } from "@executor/sdk"; | ||
| 50 | export type { ScopeId as ScopeIdType, ToolId as ToolIdType } from "@executor/sdk"; | ||
| 51 | |||
| 52 | // Plugin contracts | ||
| 53 | export type { SourcePlugin, SourcePreset } from "./source-plugin"; | ||
| 54 | export type { SecretProviderPlugin } from "./secret-provider-plugin"; | ||
| @@ -1,2 +0,0 @@ | |||
| 1 | export { useScope, useScopeInfo } from "./scope-context"; | ||
| 2 | export type { ScopeInfo } from "./scope-context"; | ||
| @@ -24,8 +24,7 @@ · 23 unmodified lines | |||
| 24 | "react": "^19.1.0", | 24 | "react": "^19.1.0", |
| 25 | "@effect-atom/atom-react": "^0.5.0", | 25 | "@effect-atom/atom-react": "^0.5.0", |
| 26 | "@tanstack/react-router": "^1.168.10", | 26 | "@tanstack/react-router": "^1.168.10", |
| 27 | "@executor/react": "workspace:*", | 27 | "@executor/react": "workspace:*" |
| 28 | "@executor/ui": "workspace:*" | ||
| 29 | }, | 28 | }, |
| 30 | "peerDependenciesMeta": { | 29 | "peerDependenciesMeta": { |
| 31 | "react": { | 30 | "react": { |
| @@ -39,16 +38,12 @@ · 7 unmodified lines | |||
| 39 | }, | 38 | }, |
| 40 | "@executor/react": { | 39 | "@executor/react": { |
| 41 | "optional": true | 40 | "optional": true |
| 42 | }, | ||
| 43 | "@executor/ui": { | ||
| 44 | "optional": true | ||
| 45 | } | 41 | } |
| 46 | }, | 42 | }, |
| 47 | "devDependencies": { | 43 | "devDependencies": { |
| 48 | "@effect-atom/atom-react": "^0.5.0", | 44 | "@effect-atom/atom-react": "^0.5.0", |
| 49 | "@effect/vitest": "catalog:", | 45 | "@effect/vitest": "catalog:", |
| 50 | "@executor/react": "workspace:*", | 46 | "@executor/react": "workspace:*", |
| 51 | "@executor/ui": "workspace:*", | ||
| 52 | "@types/node": "catalog:", | 47 | "@types/node": "catalog:", |
| 53 | "@types/react": "^19.1.0", | 48 | "@types/react": "^19.1.0", |
| 54 | "bun-types": "catalog:", | 49 | "bun-types": "catalog:", |
| @@ -1,25 +1,21 @@ | |||
| 1 | import { useCallback, useEffect, useMemo, useRef, useState } from "react"; | 1 | import { useCallback, useEffect, useMemo, useRef, useState } from "react"; |
| 2 | import { useAtomSet, useAtomValue, useAtomRefresh, Result } from "@effect-atom/atom-react"; | 2 | import { useAtomSet, useAtomValue, useAtomRefresh, Result } from "@effect-atom/atom-react"; |
| 3 | 3 | ||
| 4 | import { | 4 | import { secretsAtom, setSecret } from "@executor/react/api/atoms"; |
| 5 | useScope, | 5 | import { useScope } from "@executor/react/api/scope-context"; |
| 6 | SecretPicker, | 6 | import { SecretPicker, type SecretPickerSecret } from "@executor/react/plugins/secret-picker"; |
| 7 | secretsAtom, | ||
| 8 | setSecret, | ||
| 9 | type SecretPickerSecret, | ||
| 10 | } from "@executor/react"; | ||
| 11 | import { SecretId } from "@executor/sdk"; | 7 | import { SecretId } from "@executor/sdk"; |
| 12 | import { Badge } from "@executor/ui/components/badge"; | 8 | import { Badge } from "@executor/react/components/badge"; |
| 13 | import { Button } from "@executor/ui/components/button"; | 9 | import { Button } from "@executor/react/components/button"; |
| 14 | import { | 10 | import { |
| 15 | Collapsible, | 11 | Collapsible, |
| 16 | CollapsibleContent, | 12 | CollapsibleContent, |
| 17 | CollapsibleTrigger, | 13 | CollapsibleTrigger, |
| 18 | } from "@executor/ui/components/collapsible"; | 14 | } from "@executor/react/components/collapsible"; |
| 19 | import { Input } from "@executor/ui/components/input"; | 15 | import { Input } from "@executor/react/components/input"; |
| 20 | import { Label } from "@executor/ui/components/label"; | 16 | import { Label } from "@executor/react/components/label"; |
| 21 | import { RadioGroup, RadioGroupItem } from "@executor/ui/components/radio-group"; | 17 | import { RadioGroup, RadioGroupItem } from "@executor/react/components/radio-group"; |
| 22 | import { Spinner } from "@executor/ui/components/spinner"; | 18 | import { Spinner } from "@executor/react/components/spinner"; |
| 23 | import { | 19 | import { |
| 24 | addGoogleDiscoverySource, | 20 | addGoogleDiscoverySource, |
| 25 | probeGoogleDiscovery, | 21 | probeGoogleDiscovery, |
| @@ -1,5 +1,5 @@ | |||
| 1 | import { Badge } from "@executor/ui/components/badge"; | 1 | import { Badge } from "@executor/react/components/badge"; |
| 2 | import { Button } from "@executor/ui/components/button"; | 2 | import { Button } from "@executor/react/components/button"; |
| 3 | 3 | ||
| 4 | export default function EditGoogleDiscoverySource({ | 4 | export default function EditGoogleDiscoverySource({ |
| 5 | sourceId, | 5 | sourceId, |
| @@ -1,4 +1,4 @@ | |||
| 1 | import { Badge } from "@executor/ui/components/badge"; | 1 | import { Badge } from "@executor/react/components/badge"; |
| 2 | 2 | ||
| 3 | export default function GoogleDiscoverySourceSummary({ | 3 | export default function GoogleDiscoverySourceSummary({ |
| 4 | sourceId, | 4 | sourceId, |
| @@ -1,7 +1,7 @@ | |||
| 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; | 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; |
| 2 | import { FetchHttpClient } from "@effect/platform"; | 2 | import { FetchHttpClient } from "@effect/platform"; |
| 3 | import { addGroup } from "@executor/api"; | 3 | import { addGroup } from "@executor/api"; |
| 4 | import { getBaseUrl } from "@executor/react"; | 4 | import { getBaseUrl } from "@executor/react/api/base-url"; |
| 5 | import { GoogleDiscoveryGroup } from "../api/group"; | 5 | import { GoogleDiscoveryGroup } from "../api/group"; |
| 6 | 6 | ||
| 7 | const GoogleDiscoveryApi = addGroup(GoogleDiscoveryGroup); | 7 | const GoogleDiscoveryApi = addGroup(GoogleDiscoveryGroup); |
| @@ -1,5 +1,5 @@ | |||
| 1 | import { lazy } from "react"; | 1 | import { lazy } from "react"; |
| 2 | import type { SourcePlugin } from "@executor/react"; | 2 | import type { SourcePlugin } from "@executor/react/plugins/source-plugin"; |
| 3 | import { googleDiscoveryPresets } from "../sdk/presets"; | 3 | import { googleDiscoveryPresets } from "../sdk/presets"; |
| 4 | 4 | ||
| 5 | export const googleDiscoverySourcePlugin: SourcePlugin = { | 5 | export const googleDiscoverySourcePlugin: SourcePlugin = { |
| @@ -25,8 +25,7 @@ · 24 unmodified lines | |||
| 25 | "@effect-atom/atom-react": "^0.5.0", | 25 | "@effect-atom/atom-react": "^0.5.0", |
| 26 | "@tanstack/react-router": "^1.168.10", | 26 | "@tanstack/react-router": "^1.168.10", |
| 27 | "@executor/api": "workspace:*", | 27 | "@executor/api": "workspace:*", |
| 28 | "@executor/react": "workspace:*", | 28 | "@executor/react": "workspace:*" |
| 29 | "@executor/ui": "workspace:*" | ||
| 30 | }, | 29 | }, |
| 31 | "peerDependenciesMeta": { | 30 | "peerDependenciesMeta": { |
| 32 | "react": { | 31 | "react": { |
| @@ -43,9 +42,6 @@ · 10 unmodified lines | |||
| 43 | }, | 42 | }, |
| 44 | "@executor/react": { | 43 | "@executor/react": { |
| 45 | "optional": true | 44 | "optional": true |
| 46 | }, | ||
| 47 | "@executor/ui": { | ||
| 48 | "optional": true | ||
| 49 | } | 45 | } |
| 50 | }, | 46 | }, |
| 51 | "devDependencies": { | 47 | "devDependencies": { |
| @@ -53,7 +49,6 @@ · 1 unmodified line | |||
| 53 | "@effect-atom/atom-react": "^0.5.0", | 49 | "@effect-atom/atom-react": "^0.5.0", |
| 54 | "@executor/api": "workspace:*", | 50 | "@executor/api": "workspace:*", |
| 55 | "@executor/react": "workspace:*", | 51 | "@executor/react": "workspace:*", |
| 56 | "@executor/ui": "workspace:*", | ||
| 57 | "@types/react": "^19.1.0", | 52 | "@types/react": "^19.1.0", |
| 58 | "@effect/vitest": "catalog:", | 53 | "@effect/vitest": "catalog:", |
| 59 | "@types/node": "catalog:", | 54 | "@types/node": "catalog:", |
| @@ -1,18 +1,14 @@ | |||
| 1 | import { useState } from "react"; | 1 | import { useState } from "react"; |
| 2 | import { useAtomSet, useAtomValue, useAtomRefresh, Result } from "@effect-atom/atom-react"; | 2 | import { useAtomSet, useAtomValue, useAtomRefresh, Result } from "@effect-atom/atom-react"; |
| 3 | 3 | ||
| 4 | import { | 4 | import { secretsAtom, setSecret } from "@executor/react/api/atoms"; |
| 5 | secretsAtom, | 5 | import { useScope } from "@executor/react/api/scope-context"; |
| 6 | setSecret, | 6 | import { SecretPicker, type SecretPickerSecret } from "@executor/react/plugins/secret-picker"; |
| 7 | useScope, | ||
| 8 | SecretPicker, | ||
| 9 | type SecretPickerSecret, | ||
| 10 | } from "@executor/react"; | ||
| 11 | import { SecretId } from "@executor/sdk"; | 7 | import { SecretId } from "@executor/sdk"; |
| 12 | import { Button } from "@executor/ui/components/button"; | 8 | import { Button } from "@executor/react/components/button"; |
| 13 | import { Input } from "@executor/ui/components/input"; | 9 | import { Input } from "@executor/react/components/input"; |
| 14 | import { Label } from "@executor/ui/components/label"; | 10 | import { Label } from "@executor/react/components/label"; |
| 15 | import { Spinner } from "@executor/ui/components/spinner"; | 11 | import { Spinner } from "@executor/react/components/spinner"; |
| 16 | import { addGraphqlSource } from "./atoms"; | 12 | import { addGraphqlSource } from "./atoms"; |
| 17 | import type { HeaderValue } from "../sdk/types"; | 13 | import type { HeaderValue } from "../sdk/types"; |
| 18 | 14 | ||
| @@ -1,7 +1,7 @@ | |||
| 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; | 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; |
| 2 | import { FetchHttpClient } from "@effect/platform"; | 2 | import { FetchHttpClient } from "@effect/platform"; |
| 3 | import { addGroup } from "@executor/api"; | 3 | import { addGroup } from "@executor/api"; |
| 4 | import { getBaseUrl } from "@executor/react"; | 4 | import { getBaseUrl } from "@executor/react/api/base-url"; |
| 5 | import { GraphqlGroup } from "../api/group"; | 5 | import { GraphqlGroup } from "../api/group"; |
| 6 | 6 | ||
| 7 | // --------------------------------------------------------------------------- | 7 | // --------------------------------------------------------------------------- |
| @@ -1,5 +1,5 @@ | |||
| 1 | import { lazy } from "react"; | 1 | import { lazy } from "react"; |
| 2 | import type { SourcePlugin } from "@executor/react"; | 2 | import type { SourcePlugin } from "@executor/react/plugins/source-plugin"; |
| 3 | import { graphqlPresets } from "../sdk/presets"; | 3 | import { graphqlPresets } from "../sdk/presets"; |
| 4 | 4 | ||
| 5 | export const graphqlSourcePlugin: SourcePlugin = { | 5 | export const graphqlSourcePlugin: SourcePlugin = { |
| @@ -26,8 +26,7 @@ · 25 unmodified lines | |||
| 26 | "@effect-atom/atom-react": "^0.5.0", | 26 | "@effect-atom/atom-react": "^0.5.0", |
| 27 | "@tanstack/react-router": "^1.168.10", | 27 | "@tanstack/react-router": "^1.168.10", |
| 28 | "@executor/api": "workspace:*", | 28 | "@executor/api": "workspace:*", |
| 29 | "@executor/react": "workspace:*", | 29 | "@executor/react": "workspace:*" |
| 30 | "@executor/ui": "workspace:*" | ||
| 31 | }, | 30 | }, |
| 32 | "peerDependenciesMeta": { | 31 | "peerDependenciesMeta": { |
| 33 | "react": { | 32 | "react": { |
| @@ -44,9 +43,6 @@ · 10 unmodified lines | |||
| 44 | }, | 43 | }, |
| 45 | "@executor/react": { | 44 | "@executor/react": { |
| 46 | "optional": true | 45 | "optional": true |
| 47 | }, | ||
| 48 | "@executor/ui": { | ||
| 49 | "optional": true | ||
| 50 | } | 46 | } |
| 51 | }, | 47 | }, |
| 52 | "devDependencies": { | 48 | "devDependencies": { |
| @@ -54,7 +50,6 @@ · 1 unmodified line | |||
| 54 | "@effect-atom/atom-react": "^0.5.0", | 50 | "@effect-atom/atom-react": "^0.5.0", |
| 55 | "@executor/api": "workspace:*", | 51 | "@executor/api": "workspace:*", |
| 56 | "@executor/react": "workspace:*", | 52 | "@executor/react": "workspace:*", |
| 57 | "@executor/ui": "workspace:*", | ||
| 58 | "@types/react": "^19.1.0", | 53 | "@types/react": "^19.1.0", |
| 59 | "@effect/vitest": "catalog:", | 54 | "@effect/vitest": "catalog:", |
| 60 | "@types/node": "catalog:", | 55 | "@types/node": "catalog:", |
| @@ -1,12 +1,12 @@ | |||
| 1 | import { useReducer, useCallback, useEffect, useRef, useState } from "react"; | 1 | import { useReducer, useCallback, useEffect, useRef, useState } from "react"; |
| 2 | import { useAtomSet } from "@effect-atom/atom-react"; | 2 | import { useAtomSet } from "@effect-atom/atom-react"; |
| 3 | 3 | ||
| 4 | import { useScope } from "@executor/react"; | 4 | import { useScope } from "@executor/react/api/scope-context"; |
| 5 | import { Button } from "@executor/ui/components/button"; | 5 | import { Button } from "@executor/react/components/button"; |
| 6 | import { Input } from "@executor/ui/components/input"; | 6 | import { Input } from "@executor/react/components/input"; |
| 7 | import { Label } from "@executor/ui/components/label"; | 7 | import { Label } from "@executor/react/components/label"; |
| 8 | import { Badge } from "@executor/ui/components/badge"; | 8 | import { Badge } from "@executor/react/components/badge"; |
| 9 | import { Spinner } from "@executor/ui/components/spinner"; | 9 | import { Spinner } from "@executor/react/components/spinner"; |
| 10 | import { probeMcpEndpoint, addMcpSource, startMcpOAuth } from "./atoms"; | 10 | import { probeMcpEndpoint, addMcpSource, startMcpOAuth } from "./atoms"; |
| 11 | import { mcpPresets, type McpPreset } from "../sdk/presets"; | 11 | import { mcpPresets, type McpPreset } from "../sdk/presets"; |
| 12 | 12 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | import { Button } from "@executor/ui/components/button"; | 1 | import { Button } from "@executor/react/components/button"; |
| 2 | import { Badge } from "@executor/ui/components/badge"; | 2 | import { Badge } from "@executor/react/components/badge"; |
| 3 | 3 | ||
| 4 | // --------------------------------------------------------------------------- | 4 | // --------------------------------------------------------------------------- |
| 5 | // Edit MCP Source — config view for an existing MCP source | 5 | // Edit MCP Source — config view for an existing MCP source |
| @@ -1,4 +1,4 @@ | |||
| 1 | import { Badge } from "@executor/ui/components/badge"; | 1 | import { Badge } from "@executor/react/components/badge"; |
| 2 | 2 | ||
| 3 | // --------------------------------------------------------------------------- | 3 | // --------------------------------------------------------------------------- |
| 4 | // MCP Source Summary — shown in the source list | 4 | // MCP Source Summary — shown in the source list |
| @@ -1,7 +1,7 @@ | |||
| 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; | 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; |
| 2 | import { FetchHttpClient } from "@effect/platform"; | 2 | import { FetchHttpClient } from "@effect/platform"; |
| 3 | import { addGroup } from "@executor/api"; | 3 | import { addGroup } from "@executor/api"; |
| 4 | import { getBaseUrl } from "@executor/react"; | 4 | import { getBaseUrl } from "@executor/react/api/base-url"; |
| 5 | import { McpGroup } from "../api/group"; | 5 | import { McpGroup } from "../api/group"; |
| 6 | 6 | ||
| 7 | // --------------------------------------------------------------------------- | 7 | // --------------------------------------------------------------------------- |
| @@ -1,5 +1,5 @@ | |||
| 1 | import { lazy } from "react"; | 1 | import { lazy } from "react"; |
| 2 | import type { SourcePlugin } from "@executor/react"; | 2 | import type { SourcePlugin } from "@executor/react/plugins/source-plugin"; |
| 3 | import { mcpPresets } from "../sdk/presets"; | 3 | import { mcpPresets } from "../sdk/presets"; |
| 4 | 4 | ||
| 5 | export const mcpSourcePlugin: SourcePlugin = { | 5 | export const mcpSourcePlugin: SourcePlugin = { |
| @@ -33,8 +33,7 @@ · 32 unmodified lines | |||
| 33 | "peerDependencies": { | 33 | "peerDependencies": { |
| 34 | "react": ">=18", | 34 | "react": ">=18", |
| 35 | "@effect-atom/atom-react": "^0.5.0", | 35 | "@effect-atom/atom-react": "^0.5.0", |
| 36 | "@executor/react": "workspace:*", | 36 | "@executor/react": "workspace:*" |
| 37 | "@executor/ui": "workspace:*" | ||
| 38 | }, | 37 | }, |
| 39 | "peerDependenciesMeta": { | 38 | "peerDependenciesMeta": { |
| 40 | "react": { | 39 | "react": { |
| @@ -45,9 +44,6 @@ · 4 unmodified lines | |||
| 45 | }, | 44 | }, |
| 46 | "@executor/react": { | 45 | "@executor/react": { |
| 47 | "optional": true | 46 | "optional": true |
| 48 | }, | ||
| 49 | "@executor/ui": { | ||
| 50 | "optional": true | ||
| 51 | } | 47 | } |
| 52 | } | 48 | } |
| 53 | } | 49 | } |
| @@ -1,17 +1,17 @@ | |||
| 1 | import { useState } from "react"; | 1 | import { useState } from "react"; |
| 2 | import { useAtomSet, useAtomValue, useAtomRefresh } from "@effect-atom/atom-react"; | 2 | import { useAtomSet, useAtomValue, useAtomRefresh } from "@effect-atom/atom-react"; |
| 3 | import { Result } from "@effect-atom/atom-react"; | 3 | import { Result } from "@effect-atom/atom-react"; |
| 4 | import { useScope } from "@executor/react"; | 4 | import { useScope } from "@executor/react/api/scope-context"; |
| 5 | import { Button } from "@executor/ui/components/button"; | 5 | import { Button } from "@executor/react/components/button"; |
| 6 | import { Input } from "@executor/ui/components/input"; | 6 | import { Input } from "@executor/react/components/input"; |
| 7 | import { Label } from "@executor/ui/components/label"; | 7 | import { Label } from "@executor/react/components/label"; |
| 8 | import { | 8 | import { |
| 9 | Select, | 9 | Select, |
| 10 | SelectContent, | 10 | SelectContent, |
| 11 | SelectItem, | 11 | SelectItem, |
| 12 | SelectTrigger, | 12 | SelectTrigger, |
| 13 | SelectValue, | 13 | SelectValue, |
| 14 | } from "@executor/ui/components/select"; | 14 | } from "@executor/react/components/select"; |
| 15 | import { | 15 | import { |
| 16 | Dialog, | 16 | Dialog, |
| 17 | DialogContent, | 17 | DialogContent, |
| @@ -20,7 +20,7 @@ import { · 2 unmodified lines | |||
| 20 | DialogDescription, | 20 | DialogDescription, |
| 21 | DialogFooter, | 21 | DialogFooter, |
| 22 | DialogClose, | 22 | DialogClose, |
| 23 | } from "@executor/ui/components/dialog"; | 23 | } from "@executor/react/components/dialog"; |
| 24 | 24 | ||
| 25 | import { | 25 | import { |
| 26 | onepasswordConfigAtom, | 26 | onepasswordConfigAtom, |
| @@ -1,7 +1,7 @@ | |||
| 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; | 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; |
| 2 | import { FetchHttpClient } from "@effect/platform"; | 2 | import { FetchHttpClient } from "@effect/platform"; |
| 3 | import { addGroup } from "@executor/api"; | 3 | import { addGroup } from "@executor/api"; |
| 4 | import { getBaseUrl } from "@executor/react"; | 4 | import { getBaseUrl } from "@executor/react/api/base-url"; |
| 5 | import { OnePasswordGroup } from "../api/group"; | 5 | import { OnePasswordGroup } from "../api/group"; |
| 6 | 6 | ||
| 7 | // --------------------------------------------------------------------------- | 7 | // --------------------------------------------------------------------------- |
| @@ -1,5 +1,5 @@ | |||
| 1 | import { lazy } from "react"; | 1 | import { lazy } from "react"; |
| 2 | import type { SecretProviderPlugin } from "@executor/react"; | 2 | import type { SecretProviderPlugin } from "@executor/react/plugins/secret-provider-plugin"; |
| 3 | 3 | ||
| 4 | export const onePasswordSecretProviderPlugin: SecretProviderPlugin = { | 4 | export const onePasswordSecretProviderPlugin: SecretProviderPlugin = { |
| 5 | key: "onepassword", | 5 | key: "onepassword", |
| @@ -28,8 +28,7 @@ · 27 unmodified lines | |||
| 28 | "@effect-atom/atom-react": "^0.5.0", | 28 | "@effect-atom/atom-react": "^0.5.0", |
| 29 | "@tanstack/react-router": "^1.168.10", | 29 | "@tanstack/react-router": "^1.168.10", |
| 30 | "@executor/api": "workspace:*", | 30 | "@executor/api": "workspace:*", |
| 31 | "@executor/react": "workspace:*", | 31 | "@executor/react": "workspace:*" |
| 32 | "@executor/ui": "workspace:*" | ||
| 33 | }, | 32 | }, |
| 34 | "peerDependenciesMeta": { | 33 | "peerDependenciesMeta": { |
| 35 | "react": { | 34 | "react": { |
| @@ -46,9 +45,6 @@ · 10 unmodified lines | |||
| 46 | }, | 45 | }, |
| 47 | "@executor/react": { | 46 | "@executor/react": { |
| 48 | "optional": true | 47 | "optional": true |
| 49 | }, | ||
| 50 | "@executor/ui": { | ||
| 51 | "optional": true | ||
| 52 | } | 48 | } |
| 53 | }, | 49 | }, |
| 54 | "devDependencies": { | 50 | "devDependencies": { |
| @@ -56,7 +52,6 @@ · 1 unmodified line | |||
| 56 | "@effect-atom/atom-react": "^0.5.0", | 52 | "@effect-atom/atom-react": "^0.5.0", |
| 57 | "@executor/api": "workspace:*", | 53 | "@executor/api": "workspace:*", |
| 58 | "@executor/react": "workspace:*", | 54 | "@executor/react": "workspace:*", |
| 59 | "@executor/ui": "workspace:*", | ||
| 60 | "@types/react": "^19.1.0", | 55 | "@types/react": "^19.1.0", |
| 61 | "@effect/vitest": "catalog:", | 56 | "@effect/vitest": "catalog:", |
| 62 | "@types/node": "catalog:", | 57 | "@types/node": "catalog:", |
| @@ -2,22 +2,17 @@ import { useState, useEffect, useRef } from "react"; · 1 unmodified line | |||
| 2 | import { useAtomSet, useAtomValue, useAtomRefresh, Result } from "@effect-atom/atom-react"; | 2 | import { useAtomSet, useAtomValue, useAtomRefresh, Result } from "@effect-atom/atom-react"; |
| 3 | import { Option } from "effect"; | 3 | import { Option } from "effect"; |
| 4 | 4 | ||
| 5 | import { | 5 | import { secretsAtom, setSecret, resolveSecret } from "@executor/react/api/atoms"; |
| 6 | secretsAtom, | 6 | import { useScope } from "@executor/react/api/scope-context"; |
| 7 | setSecret, | 7 | import { SecretPicker, type SecretPickerSecret } from "@executor/react/plugins/secret-picker"; |
| 8 | resolveSecret, | ||
| 9 | useScope, | ||
| 10 | SecretPicker, | ||
| 11 | type SecretPickerSecret, | ||
| 12 | } from "@executor/react"; | ||
| 13 | import { SecretId } from "@executor/sdk"; | 8 | import { SecretId } from "@executor/sdk"; |
| 14 | import { Button } from "@executor/ui/components/button"; | 9 | import { Button } from "@executor/react/components/button"; |
| 15 | import { Input } from "@executor/ui/components/input"; | 10 | import { Input } from "@executor/react/components/input"; |
| 16 | import { Label } from "@executor/ui/components/label"; | 11 | import { Label } from "@executor/react/components/label"; |
| 17 | import { Textarea } from "@executor/ui/components/textarea"; | 12 | import { Textarea } from "@executor/react/components/textarea"; |
| 18 | import { Badge } from "@executor/ui/components/badge"; | 13 | import { Badge } from "@executor/react/components/badge"; |
| 19 | import { RadioGroup, RadioGroupItem } from "@executor/ui/components/radio-group"; | 14 | import { RadioGroup, RadioGroupItem } from "@executor/react/components/radio-group"; |
| 20 | import { Spinner } from "@executor/ui/components/spinner"; | 15 | import { Spinner } from "@executor/react/components/spinner"; |
| 21 | import { previewOpenApiSpec, addOpenApiSpec } from "./atoms"; | 16 | import { previewOpenApiSpec, addOpenApiSpec } from "./atoms"; |
| 22 | import type { SpecPreview, HeaderPreset } from "../sdk/preview"; | 17 | import type { SpecPreview, HeaderPreset } from "../sdk/preview"; |
| 23 | import type { HeaderValue } from "../sdk/types"; | 18 | import type { HeaderValue } from "../sdk/types"; |
| @@ -1,7 +1,7 @@ | |||
| 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; | 1 | import { AtomHttpApi } from "@effect-atom/atom-react"; |
| 2 | import { FetchHttpClient } from "@effect/platform"; | 2 | import { FetchHttpClient } from "@effect/platform"; |
| 3 | import { addGroup } from "@executor/api"; | 3 | import { addGroup } from "@executor/api"; |
| 4 | import { getBaseUrl } from "@executor/react"; | 4 | import { getBaseUrl } from "@executor/react/api/base-url"; |
| 5 | import { OpenApiGroup } from "../api/group"; | 5 | import { OpenApiGroup } from "../api/group"; |
| 6 | 6 | ||
| 7 | // --------------------------------------------------------------------------- | 7 | // --------------------------------------------------------------------------- |
| @@ -1,5 +1,5 @@ | |||
| 1 | import { lazy } from "react"; | 1 | import { lazy } from "react"; |
| 2 | import type { SourcePlugin } from "@executor/react"; | 2 | import type { SourcePlugin } from "@executor/react/plugins/source-plugin"; |
| 3 | import { openApiPresets } from "../sdk/presets"; | 3 | import { openApiPresets } from "../sdk/presets"; |
| 4 | 4 | ||
| 5 | export const openApiSourcePlugin: SourcePlugin = { | 5 | export const openApiSourcePlugin: SourcePlugin = { |
| @@ -1,9 +1,12 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "@executor/ui", | 2 | "name": "@executor/react", |
| 3 | "version": "1.4.0", | 3 | "version": "1.4.0", |
| 4 | "private": true, | 4 | "private": true, |
| 5 | "type": "module", | 5 | "type": "module", |
| 6 | "exports": { | 6 | "exports": { |
| 7 | "./api/*": "./src/api/*.tsx", | ||
| 8 | "./plugins/*": "./src/plugins/*.tsx", | ||
| 9 | "./pages/*": "./src/pages/*.tsx", | ||
| 7 | "./components/*": "./src/components/*.tsx", | 10 | "./components/*": "./src/components/*.tsx", |
| 8 | "./hooks/*": "./src/hooks/*.ts", | 11 | "./hooks/*": "./src/hooks/*.ts", |
| 9 | "./lib/*": "./src/lib/*.ts", | 12 | "./lib/*": "./src/lib/*.ts", |
| @@ -11,6 +14,11 @@ · 1 unmodified line | |||
| 11 | }, | 14 | }, |
| 12 | "dependencies": { | 15 | "dependencies": { |
| 13 | "@base-ui/react": "^1.3.0", | 16 | "@base-ui/react": "^1.3.0", |
| 17 | "@effect/platform": "catalog:", | ||
| 18 | "@effect-atom/atom": "^0.5.3", | ||
| 19 | "@effect-atom/atom-react": "^0.5.0", | ||
| 20 | "@executor/api": "workspace:*", | ||
| 21 | "@executor/sdk": "workspace:*", | ||
| 14 | "@hookform/resolvers": "^5.2.2", | 22 | "@hookform/resolvers": "^5.2.2", |
| 15 | "@shikijs/langs": "^4.0.2", | 23 | "@shikijs/langs": "^4.0.2", |
| 16 | "@shikijs/themes": "^4.0.2", | 24 | "@shikijs/themes": "^4.0.2", |
| @@ -18,6 +26,7 @@ · 1 unmodified line | |||
| 18 | "clsx": "^2.1.1", | 26 | "clsx": "^2.1.1", |
| 19 | "cmdk": "^1.1.1", | 27 | "cmdk": "^1.1.1", |
| 20 | "date-fns": "^4.1.0", | 28 | "date-fns": "^4.1.0", |
| 29 | "effect": "catalog:", | ||
| 21 | "embla-carousel-react": "^8.6.0", | 30 | "embla-carousel-react": "^8.6.0", |
| 22 | "input-otp": "^1.4.2", | 31 | "input-otp": "^1.4.2", |
| 23 | "lucide-react": "^1.7.0", | 32 | "lucide-react": "^1.7.0", |
| @@ -37,6 +46,7 @@ · 13 unmodified lines | |||
| 37 | }, | 46 | }, |
| 38 | "devDependencies": { | 47 | "devDependencies": { |
| 39 | "@types/react": "^19.1.0", | 48 | "@types/react": "^19.1.0", |
| 49 | "@types/node": "catalog:", | ||
| 40 | "hast-util-to-jsx-runtime": "^2.3.6", | 50 | "hast-util-to-jsx-runtime": "^2.3.6", |
| 41 | "tailwindcss": "^4.1.10", | 51 | "tailwindcss": "^4.1.10", |
| 42 | "typescript": "^5.9.3" | 52 | "typescript": "^5.9.3" |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -2,7 +2,7 @@ import * as React from "react" · 1 unmodified line | |||
| 2 | import { ChevronDownIcon } from "lucide-react" | 2 | import { ChevronDownIcon } from "lucide-react" |
| 3 | import { Accordion as AccordionPrimitive } from "radix-ui" | 3 | import { Accordion as AccordionPrimitive } from "radix-ui" |
| 4 | 4 | ||
| 5 | import { cn } from "@executor/ui/lib/utils" | 5 | import { cn } from "../lib/utils" |
| 6 | 6 | ||
| 7 | function Accordion({ | 7 | function Accordion({ |
| 8 | ...props | 8 | ...props |
| @@ -3,8 +3,8 @@ · 2 unmodified lines | |||
| 3 | import * as React from "react" | 3 | import * as React from "react" |
| 4 | import { AlertDialog as AlertDialogPrimitive } from "radix-ui" | 4 | import { AlertDialog as AlertDialogPrimitive } from "radix-ui" |
| 5 | 5 | ||
| 6 | import { cn } from "@executor/ui/lib/utils" | 6 | import { cn } from "../lib/utils" |
| 7 | import { Button } from "@executor/ui/components/button" | 7 | import { Button } from "./button" |
| 8 | 8 | ||
| 9 | function AlertDialog({ | 9 | function AlertDialog({ |
| 10 | ...props | 10 | ...props |
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { cva, type VariantProps } from "class-variance-authority" | 2 | import { cva, type VariantProps } from "class-variance-authority" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | const alertVariants = cva( | 6 | const alertVariants = cva( |
| 7 | "relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", | 7 | "relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", |
File renamed without changes.
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { Avatar as AvatarPrimitive } from "radix-ui" | 2 | import { Avatar as AvatarPrimitive } from "radix-ui" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function Avatar({ | 6 | function Avatar({ |
| 7 | className, | 7 | className, |
| @@ -2,7 +2,7 @@ import * as React from "react" · 1 unmodified line | |||
| 2 | import { cva, type VariantProps } from "class-variance-authority" | 2 | import { cva, type VariantProps } from "class-variance-authority" |
| 3 | import { Slot } from "radix-ui" | 3 | import { Slot } from "radix-ui" |
| 4 | 4 | ||
| 5 | import { cn } from "@executor/ui/lib/utils" | 5 | import { cn } from "../lib/utils" |
| 6 | 6 | ||
| 7 | const badgeVariants = cva( | 7 | const badgeVariants = cva( |
| 8 | "inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3", | 8 | "inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3", |
| @@ -2,7 +2,7 @@ import * as React from "react" · 1 unmodified line | |||
| 2 | import { ChevronRight, MoreHorizontal } from "lucide-react" | 2 | import { ChevronRight, MoreHorizontal } from "lucide-react" |
| 3 | import { Slot } from "radix-ui" | 3 | import { Slot } from "radix-ui" |
| 4 | 4 | ||
| 5 | import { cn } from "@executor/ui/lib/utils" | 5 | import { cn } from "../lib/utils" |
| 6 | 6 | ||
| 7 | function Breadcrumb({ ...props }: React.ComponentProps<"nav">) { | 7 | function Breadcrumb({ ...props }: React.ComponentProps<"nav">) { |
| 8 | return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} /> | 8 | return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} /> |
| @@ -1,8 +1,8 @@ | |||
| 1 | import { cva, type VariantProps } from "class-variance-authority" | 1 | import { cva, type VariantProps } from "class-variance-authority" |
| 2 | import { Slot } from "radix-ui" | 2 | import { Slot } from "radix-ui" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | import { Separator } from "@executor/ui/components/separator" | 5 | import { Separator } from "./separator" |
| 6 | 6 | ||
| 7 | const buttonGroupVariants = cva( | 7 | const buttonGroupVariants = cva( |
| 8 | "flex w-fit items-stretch has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1", | 8 | "flex w-fit items-stretch has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1", |
| @@ -2,7 +2,7 @@ import * as React from "react" · 1 unmodified line | |||
| 2 | import { cva, type VariantProps } from "class-variance-authority" | 2 | import { cva, type VariantProps } from "class-variance-authority" |
| 3 | import { Slot } from "radix-ui" | 3 | import { Slot } from "radix-ui" |
| 4 | 4 | ||
| 5 | import { cn } from "@executor/ui/lib/utils" | 5 | import { cn } from "../lib/utils" |
| 6 | 6 | ||
| 7 | const buttonVariants = cva( | 7 | const buttonVariants = cva( |
| 8 | "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", | 8 | "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", |
| @@ -10,8 +10,8 @@ import { · 9 unmodified lines | |||
| 10 | type DayButton, | 10 | type DayButton, |
| 11 | } from "react-day-picker" | 11 | } from "react-day-picker" |
| 12 | 12 | ||
| 13 | import { cn } from "@executor/ui/lib/utils" | 13 | import { cn } from "../lib/utils" |
| 14 | import { Button, buttonVariants } from "@executor/ui/components/button" | 14 | import { Button, buttonVariants } from "./button" |
| 15 | 15 | ||
| 16 | function Calendar({ | 16 | function Calendar({ |
| 17 | className, | 17 | className, |
| @@ -1,6 +1,6 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | 2 | ||
| 3 | import { cn } from "@executor/ui/lib/utils" | 3 | import { cn } from "../lib/utils" |
| 4 | 4 | ||
| 5 | function Card({ className, ...props }: React.ComponentProps<"div">) { | 5 | function Card({ className, ...props }: React.ComponentProps<"div">) { |
| 6 | return ( | 6 | return ( |
| @@ -6,8 +6,8 @@ import useEmblaCarousel, { · 5 unmodified lines | |||
| 6 | } from "embla-carousel-react" | 6 | } from "embla-carousel-react" |
| 7 | import { ArrowLeft, ArrowRight } from "lucide-react" | 7 | import { ArrowLeft, ArrowRight } from "lucide-react" |
| 8 | 8 | ||
| 9 | import { cn } from "@executor/ui/lib/utils" | 9 | import { cn } from "../lib/utils" |
| 10 | import { Button } from "@executor/ui/components/button" | 10 | import { Button } from "./button" |
| 11 | 11 | ||
| 12 | type CarouselApi = UseEmblaCarouselType[1] | 12 | type CarouselApi = UseEmblaCarouselType[1] |
| 13 | type UseCarouselParameters = Parameters<typeof useEmblaCarousel> | 13 | type UseCarouselParameters = Parameters<typeof useEmblaCarousel> |
| @@ -2,7 +2,7 @@ import * as React from "react" · 1 unmodified line | |||
| 2 | import * as RechartsPrimitive from "recharts" | 2 | import * as RechartsPrimitive from "recharts" |
| 3 | import type { TooltipValueType } from "recharts" | 3 | import type { TooltipValueType } from "recharts" |
| 4 | 4 | ||
| 5 | import { cn } from "@executor/ui/lib/utils" | 5 | import { cn } from "../lib/utils" |
| 6 | 6 | ||
| 7 | // Format: { THEME_NAME: CSS_SELECTOR } | 7 | // Format: { THEME_NAME: CSS_SELECTOR } |
| 8 | const THEMES = { light: "", dark: ".dark" } as const | 8 | const THEMES = { light: "", dark: ".dark" } as const |
| @@ -4,7 +4,7 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { CheckIcon } from "lucide-react" | 4 | import { CheckIcon } from "lucide-react" |
| 5 | import { Checkbox as CheckboxPrimitive } from "radix-ui" | 5 | import { Checkbox as CheckboxPrimitive } from "radix-ui" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | 8 | ||
| 9 | function Checkbox({ | 9 | function Checkbox({ |
| 10 | className, | 10 | className, |
File renamed without changes.
File renamed without changes.
| @@ -4,14 +4,14 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { Combobox as ComboboxPrimitive } from "@base-ui/react" | 4 | import { Combobox as ComboboxPrimitive } from "@base-ui/react" |
| 5 | import { CheckIcon, ChevronDownIcon, XIcon } from "lucide-react" | 5 | import { CheckIcon, ChevronDownIcon, XIcon } from "lucide-react" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | import { Button } from "@executor/ui/components/button" | 8 | import { Button } from "./button" |
| 9 | import { | 9 | import { |
| 10 | InputGroup, | 10 | InputGroup, |
| 11 | InputGroupAddon, | 11 | InputGroupAddon, |
| 12 | InputGroupButton, | 12 | InputGroupButton, |
| 13 | InputGroupInput, | 13 | InputGroupInput, |
| 14 | } from "@executor/ui/components/input-group" | 14 | } from "./input-group" |
| 15 | 15 | ||
| 16 | const Combobox = ComboboxPrimitive.Root | 16 | const Combobox = ComboboxPrimitive.Root |
| 17 | 17 | ||
| @@ -4,14 +4,14 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { Command as CommandPrimitive } from "cmdk" | 4 | import { Command as CommandPrimitive } from "cmdk" |
| 5 | import { SearchIcon } from "lucide-react" | 5 | import { SearchIcon } from "lucide-react" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | import { | 8 | import { |
| 9 | Dialog, | 9 | Dialog, |
| 10 | DialogContent, | 10 | DialogContent, |
| 11 | DialogDescription, | 11 | DialogDescription, |
| 12 | DialogHeader, | 12 | DialogHeader, |
| 13 | DialogTitle, | 13 | DialogTitle, |
| 14 | } from "@executor/ui/components/dialog" | 14 | } from "./dialog" |
| 15 | 15 | ||
| 16 | function Command({ | 16 | function Command({ |
| 17 | className, | 17 | className, |
| @@ -4,7 +4,7 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" | 4 | import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" |
| 5 | import { ContextMenu as ContextMenuPrimitive } from "radix-ui" | 5 | import { ContextMenu as ContextMenuPrimitive } from "radix-ui" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | 8 | ||
| 9 | function ContextMenu({ | 9 | function ContextMenu({ |
| 10 | ...props | 10 | ...props |
| @@ -2,8 +2,8 @@ import * as React from "react" · 1 unmodified line | |||
| 2 | import { XIcon } from "lucide-react" | 2 | import { XIcon } from "lucide-react" |
| 3 | import { Dialog as DialogPrimitive } from "radix-ui" | 3 | import { Dialog as DialogPrimitive } from "radix-ui" |
| 4 | 4 | ||
| 5 | import { cn } from "@executor/ui/lib/utils" | 5 | import { cn } from "../lib/utils" |
| 6 | import { Button } from "@executor/ui/components/button" | 6 | import { Button } from "./button" |
| 7 | 7 | ||
| 8 | function Dialog({ | 8 | function Dialog({ |
| 9 | ...props | 9 | ...props |
File renamed without changes.
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { Drawer as DrawerPrimitive } from "vaul" | 2 | import { Drawer as DrawerPrimitive } from "vaul" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function Drawer({ | 6 | function Drawer({ |
| 7 | ...props | 7 | ...props |
| @@ -4,7 +4,7 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" | 4 | import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" |
| 5 | import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui" | 5 | import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | 8 | ||
| 9 | function DropdownMenu({ | 9 | function DropdownMenu({ |
| 10 | ...props | 10 | ...props |
| @@ -1,6 +1,6 @@ | |||
| 1 | import { cva, type VariantProps } from "class-variance-authority" | 1 | import { cva, type VariantProps } from "class-variance-authority" |
| 2 | 2 | ||
| 3 | import { cn } from "@executor/ui/lib/utils" | 3 | import { cn } from "../lib/utils" |
| 4 | 4 | ||
| 5 | function Empty({ className, ...props }: React.ComponentProps<"div">) { | 5 | function Empty({ className, ...props }: React.ComponentProps<"div">) { |
| 6 | return ( | 6 | return ( |
| @@ -3,9 +3,9 @@ · 2 unmodified lines | |||
| 3 | import { useMemo } from "react" | 3 | import { useMemo } from "react" |
| 4 | import { cva, type VariantProps } from "class-variance-authority" | 4 | import { cva, type VariantProps } from "class-variance-authority" |
| 5 | 5 | ||
| 6 | import { cn } from "@executor/ui/lib/utils" | 6 | import { cn } from "../lib/utils" |
| 7 | import { Label } from "@executor/ui/components/label" | 7 | import { Label } from "./label" |
| 8 | import { Separator } from "@executor/ui/components/separator" | 8 | import { Separator } from "./separator" |
| 9 | 9 | ||
| 10 | function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) { | 10 | function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) { |
| 11 | return ( | 11 | return ( |
| @@ -11,8 +11,8 @@ import { · 10 unmodified lines | |||
| 11 | type FieldValues, | 11 | type FieldValues, |
| 12 | } from "react-hook-form" | 12 | } from "react-hook-form" |
| 13 | 13 | ||
| 14 | import { cn } from "@executor/ui/lib/utils" | 14 | import { cn } from "../lib/utils" |
| 15 | import { Label } from "@executor/ui/components/label" | 15 | import { Label } from "./label" |
| 16 | 16 | ||
| 17 | const Form = FormProvider | 17 | const Form = FormProvider |
| 18 | 18 | ||
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { HoverCard as HoverCardPrimitive } from "radix-ui" | 2 | import { HoverCard as HoverCardPrimitive } from "radix-ui" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function HoverCard({ | 6 | function HoverCard({ |
| 7 | ...props | 7 | ...props |
| @@ -1,10 +1,10 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { cva, type VariantProps } from "class-variance-authority" | 2 | import { cva, type VariantProps } from "class-variance-authority" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | import { Button } from "@executor/ui/components/button" | 5 | import { Button } from "./button" |
| 6 | import { Input } from "@executor/ui/components/input" | 6 | import { Input } from "./input" |
| 7 | import { Textarea } from "@executor/ui/components/textarea" | 7 | import { Textarea } from "./textarea" |
| 8 | 8 | ||
| 9 | function InputGroup({ className, ...props }: React.ComponentProps<"div">) { | 9 | function InputGroup({ className, ...props }: React.ComponentProps<"div">) { |
| 10 | return ( | 10 | return ( |
| @@ -4,7 +4,7 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { OTPInput, OTPInputContext } from "input-otp" | 4 | import { OTPInput, OTPInputContext } from "input-otp" |
| 5 | import { MinusIcon } from "lucide-react" | 5 | import { MinusIcon } from "lucide-react" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | 8 | ||
| 9 | function InputOTP({ | 9 | function InputOTP({ |
| 10 | className, | 10 | className, |
| @@ -1,6 +1,6 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | 2 | ||
| 3 | import { cn } from "@executor/ui/lib/utils" | 3 | import { cn } from "../lib/utils" |
| 4 | 4 | ||
| 5 | function Input({ className, type, ...props }: React.ComponentProps<"input">) { | 5 | function Input({ className, type, ...props }: React.ComponentProps<"input">) { |
| 6 | return ( | 6 | return ( |
| @@ -2,8 +2,8 @@ import * as React from "react" · 1 unmodified line | |||
| 2 | import { cva, type VariantProps } from "class-variance-authority" | 2 | import { cva, type VariantProps } from "class-variance-authority" |
| 3 | import { Slot } from "radix-ui" | 3 | import { Slot } from "radix-ui" |
| 4 | 4 | ||
| 5 | import { cn } from "@executor/ui/lib/utils" | 5 | import { cn } from "../lib/utils" |
| 6 | import { Separator } from "@executor/ui/components/separator" | 6 | import { Separator } from "./separator" |
| 7 | 7 | ||
| 8 | function ItemGroup({ className, ...props }: React.ComponentProps<"div">) { | 8 | function ItemGroup({ className, ...props }: React.ComponentProps<"div">) { |
| 9 | return ( | 9 | return ( |
| @@ -1,4 +1,4 @@ | |||
| 1 | import { cn } from "@executor/ui/lib/utils" | 1 | import { cn } from "../lib/utils" |
| 2 | 2 | ||
| 3 | function Kbd({ className, ...props }: React.ComponentProps<"kbd">) { | 3 | function Kbd({ className, ...props }: React.ComponentProps<"kbd">) { |
| 4 | return ( | 4 | return ( |
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { Label as LabelPrimitive } from "radix-ui" | 2 | import { Label as LabelPrimitive } from "radix-ui" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function Label({ | 6 | function Label({ |
| 7 | className, | 7 | className, |
File renamed without changes.
File renamed without changes.
| @@ -4,7 +4,7 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" | 4 | import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" |
| 5 | import { Menubar as MenubarPrimitive } from "radix-ui" | 5 | import { Menubar as MenubarPrimitive } from "radix-ui" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | 8 | ||
| 9 | function Menubar({ | 9 | function Menubar({ |
| 10 | className, | 10 | className, |
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { ChevronDownIcon } from "lucide-react" | 2 | import { ChevronDownIcon } from "lucide-react" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function NativeSelect({ | 6 | function NativeSelect({ |
| 7 | className, | 7 | className, |
| @@ -3,7 +3,7 @@ import { cva } from "class-variance-authority" · 2 unmodified lines | |||
| 3 | import { ChevronDownIcon } from "lucide-react" | 3 | import { ChevronDownIcon } from "lucide-react" |
| 4 | import { NavigationMenu as NavigationMenuPrimitive } from "radix-ui" | 4 | import { NavigationMenu as NavigationMenuPrimitive } from "radix-ui" |
| 5 | 5 | ||
| 6 | import { cn } from "@executor/ui/lib/utils" | 6 | import { cn } from "../lib/utils" |
| 7 | 7 | ||
| 8 | function NavigationMenu({ | 8 | function NavigationMenu({ |
| 9 | className, | 9 | className, |
| @@ -5,8 +5,8 @@ import { · 4 unmodified lines | |||
| 5 | MoreHorizontalIcon, | 5 | MoreHorizontalIcon, |
| 6 | } from "lucide-react" | 6 | } from "lucide-react" |
| 7 | 7 | ||
| 8 | import { cn } from "@executor/ui/lib/utils" | 8 | import { cn } from "../lib/utils" |
| 9 | import { buttonVariants, type Button } from "@executor/ui/components/button" | 9 | import { buttonVariants, type Button } from "./button" |
| 10 | 10 | ||
| 11 | function Pagination({ className, ...props }: React.ComponentProps<"nav">) { | 11 | function Pagination({ className, ...props }: React.ComponentProps<"nav">) { |
| 12 | return ( | 12 | return ( |
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { Popover as PopoverPrimitive } from "radix-ui" | 2 | import { Popover as PopoverPrimitive } from "radix-ui" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function Popover({ | 6 | function Popover({ |
| 7 | ...props | 7 | ...props |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | |||
| 3 | import * as React from "react" | 3 | import * as React from "react" |
| 4 | import { Progress as ProgressPrimitive } from "radix-ui" | 4 | import { Progress as ProgressPrimitive } from "radix-ui" |
| 5 | 5 | ||
| 6 | import { cn } from "@executor/ui/lib/utils" | 6 | import { cn } from "../lib/utils" |
| 7 | 7 | ||
| 8 | function Progress({ | 8 | function Progress({ |
| 9 | className, | 9 | className, |
| @@ -2,7 +2,7 @@ import * as React from "react" · 1 unmodified line | |||
| 2 | import { CircleIcon } from "lucide-react" | 2 | import { CircleIcon } from "lucide-react" |
| 3 | import { RadioGroup as RadioGroupPrimitive } from "radix-ui" | 3 | import { RadioGroup as RadioGroupPrimitive } from "radix-ui" |
| 4 | 4 | ||
| 5 | import { cn } from "@executor/ui/lib/utils" | 5 | import { cn } from "../lib/utils" |
| 6 | 6 | ||
| 7 | function RadioGroup({ | 7 | function RadioGroup({ |
| 8 | className, | 8 | className, |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | |||
| 3 | import { GripVerticalIcon } from "lucide-react" | 3 | import { GripVerticalIcon } from "lucide-react" |
| 4 | import * as ResizablePrimitive from "react-resizable-panels" | 4 | import * as ResizablePrimitive from "react-resizable-panels" |
| 5 | 5 | ||
| 6 | import { cn } from "@executor/ui/lib/utils" | 6 | import { cn } from "../lib/utils" |
| 7 | 7 | ||
| 8 | function ResizablePanelGroup({ | 8 | function ResizablePanelGroup({ |
| 9 | className, | 9 | className, |
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { ScrollArea as ScrollAreaPrimitive } from "radix-ui" | 2 | import { ScrollArea as ScrollAreaPrimitive } from "radix-ui" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function ScrollArea({ | 6 | function ScrollArea({ |
| 7 | className, | 7 | className, |
| @@ -4,7 +4,7 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react" | 4 | import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react" |
| 5 | import { Select as SelectPrimitive } from "radix-ui" | 5 | import { Select as SelectPrimitive } from "radix-ui" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | 8 | ||
| 9 | function Select({ | 9 | function Select({ |
| 10 | ...props | 10 | ...props |
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { Separator as SeparatorPrimitive } from "radix-ui" | 2 | import { Separator as SeparatorPrimitive } from "radix-ui" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function Separator({ | 6 | function Separator({ |
| 7 | className, | 7 | className, |
| @@ -4,7 +4,7 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { XIcon } from "lucide-react" | 4 | import { XIcon } from "lucide-react" |
| 5 | import { Dialog as SheetPrimitive } from "radix-ui" | 5 | import { Dialog as SheetPrimitive } from "radix-ui" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | 8 | ||
| 9 | function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) { | 9 | function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) { |
| 10 | return <SheetPrimitive.Root data-slot="sheet" {...props} /> | 10 | return <SheetPrimitive.Root data-slot="sheet" {...props} /> |
| @@ -3,25 +3,25 @@ import { cva, type VariantProps } from "class-variance-authority" · 2 unmodified lines | |||
| 3 | import { PanelLeftIcon } from "lucide-react" | 3 | import { PanelLeftIcon } from "lucide-react" |
| 4 | import { Slot } from "radix-ui" | 4 | import { Slot } from "radix-ui" |
| 5 | 5 | ||
| 6 | import { useIsMobile } from "@executor/ui/hooks/use-mobile" | 6 | import { useIsMobile } from "../hooks/use-mobile" |
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | import { Button } from "@executor/ui/components/button" | 8 | import { Button } from "./button" |
| 9 | import { Input } from "@executor/ui/components/input" | 9 | import { Input } from "./input" |
| 10 | import { Separator } from "@executor/ui/components/separator" | 10 | import { Separator } from "./separator" |
| 11 | import { | 11 | import { |
| 12 | Sheet, | 12 | Sheet, |
| 13 | SheetContent, | 13 | SheetContent, |
| 14 | SheetDescription, | 14 | SheetDescription, |
| 15 | SheetHeader, | 15 | SheetHeader, |
| 16 | SheetTitle, | 16 | SheetTitle, |
| 17 | } from "@executor/ui/components/sheet" | 17 | } from "./sheet" |
| 18 | import { Skeleton } from "@executor/ui/components/skeleton" | 18 | import { Skeleton } from "./skeleton" |
| 19 | import { | 19 | import { |
| 20 | Tooltip, | 20 | Tooltip, |
| 21 | TooltipContent, | 21 | TooltipContent, |
| 22 | TooltipProvider, | 22 | TooltipProvider, |
| 23 | TooltipTrigger, | 23 | TooltipTrigger, |
| 24 | } from "@executor/ui/components/tooltip" | 24 | } from "./tooltip" |
| 25 | 25 | ||
| 26 | const SIDEBAR_COOKIE_NAME = "sidebar_state" | 26 | const SIDEBAR_COOKIE_NAME = "sidebar_state" |
| 27 | const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 | 27 | const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 |
| @@ -1,4 +1,4 @@ | |||
| 1 | import { cn } from "@executor/ui/lib/utils" | 1 | import { cn } from "../lib/utils" |
| 2 | 2 | ||
| 3 | function Skeleton({ className, ...props }: React.ComponentProps<"div">) { | 3 | function Skeleton({ className, ...props }: React.ComponentProps<"div">) { |
| 4 | return ( | 4 | return ( |
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { Slider as SliderPrimitive } from "radix-ui" | 2 | import { Slider as SliderPrimitive } from "radix-ui" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function Slider({ | 6 | function Slider({ |
| 7 | className, | 7 | className, |
File renamed without changes.
| @@ -1,6 +1,6 @@ | |||
| 1 | import { Loader2Icon } from "lucide-react" | 1 | import { Loader2Icon } from "lucide-react" |
| 2 | 2 | ||
| 3 | import { cn } from "@executor/ui/lib/utils" | 3 | import { cn } from "../lib/utils" |
| 4 | 4 | ||
| 5 | function Spinner({ className, ...props }: React.ComponentProps<"svg">) { | 5 | function Spinner({ className, ...props }: React.ComponentProps<"svg">) { |
| 6 | return ( | 6 | return ( |
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { Switch as SwitchPrimitive } from "radix-ui" | 2 | import { Switch as SwitchPrimitive } from "radix-ui" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function Switch({ | 6 | function Switch({ |
| 7 | className, | 7 | className, |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | import * as React from "react" | 3 | import * as React from "react" |
| 4 | 4 | ||
| 5 | import { cn } from "@executor/ui/lib/utils" | 5 | import { cn } from "../lib/utils" |
| 6 | 6 | ||
| 7 | function Table({ className, ...props }: React.ComponentProps<"table">) { | 7 | function Table({ className, ...props }: React.ComponentProps<"table">) { |
| 8 | return ( | 8 | return ( |
| @@ -2,7 +2,7 @@ import * as React from "react" · 1 unmodified line | |||
| 2 | import { cva, type VariantProps } from "class-variance-authority" | 2 | import { cva, type VariantProps } from "class-variance-authority" |
| 3 | import { Tabs as TabsPrimitive } from "radix-ui" | 3 | import { Tabs as TabsPrimitive } from "radix-ui" |
| 4 | 4 | ||
| 5 | import { cn } from "@executor/ui/lib/utils" | 5 | import { cn } from "../lib/utils" |
| 6 | 6 | ||
| 7 | function Tabs({ | 7 | function Tabs({ |
| 8 | className, | 8 | className, |
| @@ -1,6 +1,6 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | 2 | ||
| 3 | import { cn } from "@executor/ui/lib/utils" | 3 | import { cn } from "../lib/utils" |
| 4 | 4 | ||
| 5 | function Textarea({ className, ...props }: React.ComponentProps<"textarea">) { | 5 | function Textarea({ className, ...props }: React.ComponentProps<"textarea">) { |
| 6 | return ( | 6 | return ( |
| @@ -4,8 +4,8 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { type VariantProps } from "class-variance-authority" | 4 | import { type VariantProps } from "class-variance-authority" |
| 5 | import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui" | 5 | import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | import { toggleVariants } from "@executor/ui/components/toggle" | 8 | import { toggleVariants } from "./toggle" |
| 9 | 9 | ||
| 10 | const ToggleGroupContext = React.createContext< | 10 | const ToggleGroupContext = React.createContext< |
| 11 | VariantProps<typeof toggleVariants> & { | 11 | VariantProps<typeof toggleVariants> & { |
| @@ -4,7 +4,7 @@ import * as React from "react" · 3 unmodified lines | |||
| 4 | import { cva, type VariantProps } from "class-variance-authority" | 4 | import { cva, type VariantProps } from "class-variance-authority" |
| 5 | import { Toggle as TogglePrimitive } from "radix-ui" | 5 | import { Toggle as TogglePrimitive } from "radix-ui" |
| 6 | 6 | ||
| 7 | import { cn } from "@executor/ui/lib/utils" | 7 | import { cn } from "../lib/utils" |
| 8 | 8 | ||
| 9 | const toggleVariants = cva( | 9 | const toggleVariants = cva( |
| 10 | "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", | 10 | "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", |
| @@ -1,9 +1,11 @@ | |||
| 1 | import { useMemo, useState } from "react"; | 1 | import { useMemo, useState } from "react"; |
| 2 | import { useAtomValue, toolSchemaAtom, Result, ScopeId, ToolId } from "@executor/react"; | 2 | import { useAtomValue, Result } from "@effect-atom/atom-react"; |
| 3 | import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@executor/ui/components/accordion"; | 3 | import { toolSchemaAtom } from "../api/atoms"; |
| 4 | import { Badge } from "@executor/ui/components/badge"; | 4 | import { ScopeId, ToolId } from "@executor/sdk"; |
| 5 | import { CodeBlock } from "@executor/ui/components/code-block"; | 5 | import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./accordion"; |
| 6 | import { Markdown } from "@executor/ui/components/markdown"; | 6 | import { Badge } from "./badge"; |
| 7 | import { CodeBlock } from "./code-block"; | ||
| 8 | import { Markdown } from "./markdown"; | ||
| 7 | 9 | ||
| 8 | // --------------------------------------------------------------------------- | 10 | // --------------------------------------------------------------------------- |
| 9 | // Copy button | 11 | // Copy button |
File renamed without changes.
| @@ -1,7 +1,7 @@ | |||
| 1 | import * as React from "react" | 1 | import * as React from "react" |
| 2 | import { Tooltip as TooltipPrimitive } from "radix-ui" | 2 | import { Tooltip as TooltipPrimitive } from "radix-ui" |
| 3 | 3 | ||
| 4 | import { cn } from "@executor/ui/lib/utils" | 4 | import { cn } from "../lib/utils" |
| 5 | 5 | ||
| 6 | function TooltipProvider({ | 6 | function TooltipProvider({ |
| 7 | delayDuration = 0, | 7 | delayDuration = 0, |
File renamed without changes.
| @@ -0,0 +1 @@ | |||
| 1 | export { useScope } from "../api/scope-context"; | ||
File renamed without changes.
File renamed without changes.
| @@ -1,16 +1,9 @@ | |||
| 1 | import { useState, Suspense } from "react"; | 1 | import { useState, Suspense } from "react"; |
| 2 | import { | 2 | import { useAtomValue, useAtomSet, useAtomRefresh, Result } from "@effect-atom/atom-react"; |
| 3 | useAtomValue, | 3 | import { secretsAtom, setSecret, removeSecret } from "../api/atoms"; |
| 4 | useAtomSet, | 4 | import type { SecretProviderPlugin } from "../plugins/secret-provider-plugin"; |
| 5 | useAtomRefresh, | ||
| 6 | Result, | ||
| 7 | secretsAtom, | ||
| 8 | setSecret, | ||
| 9 | removeSecret, | ||
| 10 | } from "@executor/react"; | ||
| 11 | import type { SecretProviderPlugin } from "@executor/react"; | ||
| 12 | import { SecretId } from "@executor/sdk"; | 5 | import { SecretId } from "@executor/sdk"; |
| 13 | import { useScope } from "../lib/use-scope"; | 6 | import { useScope } from "../hooks/use-scope"; |
| 14 | import { onePasswordSecretProviderPlugin } from "@executor/plugin-onepassword/react"; | 7 | import { onePasswordSecretProviderPlugin } from "@executor/plugin-onepassword/react"; |
| 15 | import { | 8 | import { |
| 16 | Dialog, | 9 | Dialog, |
| @@ -20,24 +13,24 @@ import { · 3 unmodified lines | |||
| 20 | DialogDescription, | 13 | DialogDescription, |
| 21 | DialogFooter, | 14 | DialogFooter, |
| 22 | DialogClose, | 15 | DialogClose, |
| 23 | } from "@executor/ui/components/dialog"; | 16 | } from "../components/dialog"; |
| 24 | import { Button } from "@executor/ui/components/button"; | 17 | import { Button } from "../components/button"; |
| 25 | import { Input } from "@executor/ui/components/input"; | 18 | import { Input } from "../components/input"; |
| 26 | import { Label } from "@executor/ui/components/label"; | 19 | import { Label } from "../components/label"; |
| 27 | import { Badge } from "@executor/ui/components/badge"; | 20 | import { Badge } from "../components/badge"; |
| 28 | import { | 21 | import { |
| 29 | DropdownMenu, | 22 | DropdownMenu, |
| 30 | DropdownMenuContent, | 23 | DropdownMenuContent, |
| 31 | DropdownMenuItem, | 24 | DropdownMenuItem, |
| 32 | DropdownMenuTrigger, | 25 | DropdownMenuTrigger, |
| 33 | } from "@executor/ui/components/dropdown-menu"; | 26 | } from "../components/dropdown-menu"; |
| 34 | import { | 27 | import { |
| 35 | Select, | 28 | Select, |
| 36 | SelectContent, | 29 | SelectContent, |
| 37 | SelectItem, | 30 | SelectItem, |
| 38 | SelectTrigger, | 31 | SelectTrigger, |
| 39 | SelectValue, | 32 | SelectValue, |
| 40 | } from "@executor/ui/components/select"; | 33 | } from "../components/select"; |
| 41 | 34 | ||
| 42 | // --------------------------------------------------------------------------- | 35 | // --------------------------------------------------------------------------- |
| 43 | // Add secret dialog | 36 | // Add secret dialog |
| @@ -1,20 +1,11 @@ | |||
| 1 | import { useEffect, useMemo, useState } from "react"; | 1 | import { useEffect, useMemo, useState } from "react"; |
| 2 | import { useNavigate } from "@tanstack/react-router"; | 2 | import { useNavigate } from "@tanstack/react-router"; |
| 3 | import { | 3 | import { useAtomValue, useAtomSet, useAtomRefresh, Result } from "@effect-atom/atom-react"; |
| 4 | useAtomValue, | 4 | import { sourceToolsAtom, sourcesAtom, sourceAtom, removeSource, refreshSource } from "../api/atoms"; |
| 5 | useAtomSet, | ||
| 6 | useAtomRefresh, | ||
| 7 | sourceToolsAtom, | ||
| 8 | sourcesAtom, | ||
| 9 | sourceAtom, | ||
| 10 | removeSource, | ||
| 11 | refreshSource, | ||
| 12 | Result, | ||
| 13 | } from "@executor/react"; | ||
| 14 | import { ToolTree } from "../components/tool-tree"; | 5 | import { ToolTree } from "../components/tool-tree"; |
| 15 | import { ToolDetail, ToolDetailEmpty } from "../components/tool-detail"; | 6 | import { ToolDetail, ToolDetailEmpty } from "../components/tool-detail"; |
| 16 | import type { ToolSummary } from "../components/tool-tree"; | 7 | import type { ToolSummary } from "../components/tool-tree"; |
| 17 | import { useScope } from "../lib/use-scope"; | 8 | import { useScope } from "../hooks/use-scope"; |
| 18 | 9 | ||
| 19 | export function SourceDetailPage(props: { namespace: string }) { | 10 | export function SourceDetailPage(props: { namespace: string }) { |
| 20 | const { namespace } = props; | 11 | const { namespace } = props; |
| @@ -1,8 +1,9 @@ | |||
| 1 | import { Suspense } from "react"; | 1 | import { Suspense } from "react"; |
| 2 | import { Link, useNavigate } from "@tanstack/react-router"; | 2 | import { Link, useNavigate } from "@tanstack/react-router"; |
| 3 | import type { SourcePlugin } from "@executor/react"; | 3 | import type { SourcePlugin } from "../plugins/source-plugin"; |
| 4 | import { useAtomRefresh, sourcesAtom } from "@executor/react"; | 4 | import { useAtomRefresh } from "@effect-atom/atom-react"; |
| 5 | import { useScope } from "../lib/use-scope"; | 5 | import { sourcesAtom } from "../api/atoms"; |
| 6 | import { useScope } from "../hooks/use-scope"; | ||
| 6 | import { openApiSourcePlugin } from "@executor/plugin-openapi/react"; | 7 | import { openApiSourcePlugin } from "@executor/plugin-openapi/react"; |
| 7 | import { mcpSourcePlugin } from "@executor/plugin-mcp/react"; | 8 | import { mcpSourcePlugin } from "@executor/plugin-mcp/react"; |
| 8 | import { googleDiscoverySourcePlugin } from "@executor/plugin-google-discovery/react"; | 9 | import { googleDiscoverySourcePlugin } from "@executor/plugin-google-discovery/react"; |
| @@ -1,8 +1,9 @@ | |||
| 1 | import { useState, useCallback, useMemo } from "react"; | 1 | import { useState, useCallback, useMemo } from "react"; |
| 2 | import { Link, useNavigate } from "@tanstack/react-router"; | 2 | import { Link, useNavigate } from "@tanstack/react-router"; |
| 3 | import { Result, useAtomValue, useAtomSet, sourcesAtom, detectSource } from "@executor/react"; | 3 | import { Result, useAtomValue, useAtomSet } from "@effect-atom/atom-react"; |
| 4 | import { useScope } from "../lib/use-scope"; | 4 | import { sourcesAtom, detectSource } from "../api/atoms"; |
| 5 | import type { SourcePlugin, SourcePreset } from "@executor/react"; | 5 | import { useScope } from "../hooks/use-scope"; |
| 6 | import type { SourcePlugin, SourcePreset } from "../plugins/source-plugin"; | ||
| 6 | import { openApiSourcePlugin } from "@executor/plugin-openapi/react"; | 7 | import { openApiSourcePlugin } from "@executor/plugin-openapi/react"; |
| 7 | import { mcpSourcePlugin } from "@executor/plugin-mcp/react"; | 8 | import { mcpSourcePlugin } from "@executor/plugin-mcp/react"; |
| 8 | import { googleDiscoverySourcePlugin } from "@executor/plugin-google-discovery/react"; | 9 | import { googleDiscoverySourcePlugin } from "@executor/plugin-google-discovery/react"; |
| @@ -1,5 +1,6 @@ | |||
| 1 | import { useAtomValue, Result, toolsAtom } from "@executor/react"; | 1 | import { useAtomValue, Result } from "@effect-atom/atom-react"; |
| 2 | import { useScope } from "../lib/use-scope"; | 2 | import { toolsAtom } from "../api/atoms"; |
| 3 | import { useScope } from "../hooks/use-scope"; | ||
| 3 | 4 | ||
| 4 | export function ToolsPage() { | 5 | export function ToolsPage() { |
| 5 | const scopeId = useScope(); | 6 | const scopeId = useScope(); |
| @@ -1,18 +1,18 @@ | |||
| 1 | import { useState, type ChangeEvent, type FocusEvent } from "react"; | 1 | import { useState, type ChangeEvent, type FocusEvent } from "react"; |
| 2 | 2 | ||
| 3 | import { Input } from "@executor/ui/components/input"; | 3 | import { Input } from "../components/input"; |
| 4 | import { | 4 | import { |
| 5 | Command, | 5 | Command, |
| 6 | CommandEmpty, | 6 | CommandEmpty, |
| 7 | CommandGroup, | 7 | CommandGroup, |
| 8 | CommandItem, | 8 | CommandItem, |
| 9 | CommandList, | 9 | CommandList, |
| 10 | } from "@executor/ui/components/command"; | 10 | } from "../components/command"; |
| 11 | import { | 11 | import { |
| 12 | Popover, | 12 | Popover, |
| 13 | PopoverAnchor, | 13 | PopoverAnchor, |
| 14 | PopoverContent, | 14 | PopoverContent, |
| 15 | } from "@executor/ui/components/popover"; | 15 | } from "../components/popover"; |
| 16 | 16 | ||
| 17 | export interface SecretPickerSecret { | 17 | export interface SecretPickerSecret { |
| 18 | readonly id: string; | 18 | readonly id: string; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -1,4 +0,0 @@ | |||
| 1 | # @executor/ui changelog | ||
| 2 | |||
| 3 | This file exists for Changesets release workflow compatibility. | ||
| 4 | Canonical user-facing release notes are published on GitHub Releases. | ||
| @@ -1,20 +0,0 @@ | |||
| 1 | { | ||
| 2 | "$schema": "https://ui.shadcn.com/schema.json", | ||
| 3 | "style": "new-york", | ||
| 4 | "rsc": false, | ||
| 5 | "tsx": true, | ||
| 6 | "tailwind": { | ||
| 7 | "config": "", | ||
| 8 | "css": "src/styles/globals.css", | ||
| 9 | "baseColor": "neutral", | ||
| 10 | "cssVariables": true | ||
| 11 | }, | ||
| 12 | "iconLibrary": "lucide", | ||
| 13 | "aliases": { | ||
| 14 | "components": "@executor/ui/components", | ||
| 15 | "utils": "@executor/ui/lib/utils", | ||
| 16 | "hooks": "@executor/ui/hooks", | ||
| 17 | "lib": "@executor/ui/lib", | ||
| 18 | "ui": "@executor/ui/components" | ||
| 19 | } | ||
| 20 | } | ||
| @@ -1,25 +0,0 @@ | |||
| 1 | { | ||
| 2 | "compilerOptions": { | ||
| 3 | "target": "ESNext", | ||
| 4 | "module": "ESNext", | ||
| 5 | "moduleResolution": "bundler", | ||
| 6 | "strict": true, | ||
| 7 | "esModuleInterop": true, | ||
| 8 | "skipLibCheck": true, | ||
| 9 | "outDir": "dist", | ||
| 10 | "rootDir": "src", | ||
| 11 | "declaration": true, | ||
| 12 | "declarationMap": true, | ||
| 13 | "sourceMap": true, | ||
| 14 | "jsx": "react-jsx", | ||
| 15 | "paths": { | ||
| 16 | "@executor/ui/*": ["./src/*"] | ||
| 17 | }, | ||
| 18 | "plugins": [ | ||
| 19 | { | ||
| 20 | "name": "@effect/language-service" | ||
| 21 | } | ||
| 22 | ] | ||
| 23 | }, | ||
| 24 | "include": ["src"] | ||
| 25 | } | ||