| author | |
| committer | |
| log | 6b3050ee740f510ad06c12a91ecd7e338792dce0 |
| tree | 41c288ff5d92c343fc0685793eaac651ea7e19fb |
| parent | 83f0cc9e31b8c38cc3ecd3c394f882ce9ee3714f |
| signature | Signed by PGP key B5690EEEBB952194 |
102 files changed, 827 insertions(+), 831 deletions(-)
apps/desktop/package.json+1-3| ... | @@ -10,7 +10,7 @@ | ... | @@ -10,7 +10,7 @@ |
| 10 | "dev:electron": "node scripts/dev-electron.mjs", | 10 | "dev:electron": "node scripts/dev-electron.mjs", |
| 11 | "build": "tsdown", | 11 | "build": "tsdown", |
| 12 | "start": "node scripts/start-electron.mjs", | 12 | "start": "node scripts/start-electron.mjs", |
| 13 | "typecheck": "tsc --noEmit", | 13 | "typecheck": "tsgo --noEmit", |
| 14 | "test": "vitest run --passWithNoTests", | 14 | "test": "vitest run --passWithNoTests", |
| 15 | "smoke-test": "node scripts/smoke-test.mjs" | 15 | "smoke-test": "node scripts/smoke-test.mjs" |
| 16 | }, | 16 | }, |
| ... | @@ -25,11 +25,9 @@ | ... | @@ -25,11 +25,9 @@ |
| 25 | "electron-updater": "^6.6.2" | 25 | "electron-updater": "^6.6.2" |
| 26 | }, | 26 | }, |
| 27 | "devDependencies": { | 27 | "devDependencies": { |
| 28 | "@effect/language-service": "catalog:", | ||
| 29 | "@effect/vitest": "catalog:", | 28 | "@effect/vitest": "catalog:", |
| 30 | "@types/node": "catalog:", | 29 | "@types/node": "catalog:", |
| 31 | "tsdown": "catalog:", | 30 | "tsdown": "catalog:", |
| 32 | "typescript": "catalog:", | ||
| 33 | "vitest": "catalog:" | 31 | "vitest": "catalog:" |
| 34 | }, | 32 | }, |
| 35 | "productName": "T3 Code (Alpha)" | 33 | "productName": "T3 Code (Alpha)" |
apps/desktop/src/app/DesktopAppIdentity.ts+1-1| ... | @@ -26,7 +26,7 @@ export interface DesktopAppIdentityShape { | ... | @@ -26,7 +26,7 @@ export interface DesktopAppIdentityShape { |
| 26 | export class DesktopAppIdentity extends Context.Service< | 26 | export class DesktopAppIdentity extends Context.Service< |
| 27 | DesktopAppIdentity, | 27 | DesktopAppIdentity, |
| 28 | DesktopAppIdentityShape | 28 | DesktopAppIdentityShape |
| 29 | >()("t3/desktop/AppIdentity") {} | 29 | >()("@t3tools/desktop/app/DesktopAppIdentity") {} |
| 30 | 30 | ||
| 31 | const normalizeCommitHash = (value: string): Option.Option<string> => { | 31 | const normalizeCommitHash = (value: string): Option.Option<string> => { |
| 32 | const trimmed = value.trim(); | 32 | const trimmed = value.trim(); |
apps/desktop/src/app/DesktopAssets.ts+1-1| ... | @@ -18,7 +18,7 @@ export interface DesktopAssetsShape { | ... | @@ -18,7 +18,7 @@ export interface DesktopAssetsShape { |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | export class DesktopAssets extends Context.Service<DesktopAssets, DesktopAssetsShape>()( | 20 | export class DesktopAssets extends Context.Service<DesktopAssets, DesktopAssetsShape>()( |
| 21 | "t3/desktop/Assets", | 21 | "@t3tools/desktop/app/DesktopAssets", |
| 22 | ) {} | 22 | ) {} |
| 23 | 23 | ||
| 24 | const resolveResourcePath = Effect.fn("desktop.assets.resolveResourcePath")(function* ( | 24 | const resolveResourcePath = Effect.fn("desktop.assets.resolveResourcePath")(function* ( |
apps/desktop/src/app/DesktopEnvironment.test.ts+1-3| ... | @@ -32,9 +32,7 @@ const makeEnvironment = ( | ... | @@ -32,9 +32,7 @@ const makeEnvironment = ( |
| 32 | overrides: Partial<DesktopEnvironment.MakeDesktopEnvironmentInput> = {}, | 32 | overrides: Partial<DesktopEnvironment.MakeDesktopEnvironmentInput> = {}, |
| 33 | env: Record<string, string | undefined> = {}, | 33 | env: Record<string, string | undefined> = {}, |
| 34 | ) => | 34 | ) => |
| 35 | Effect.gen(function* () { | 35 | DesktopEnvironment.DesktopEnvironment.pipe(Effect.provide(makeEnvironmentLayer(overrides, env))); |
| 36 | return yield* DesktopEnvironment.DesktopEnvironment; | ||
| 37 | }).pipe(Effect.provide(makeEnvironmentLayer(overrides, env))); | ||
| 38 | 36 | ||
| 39 | describe("DesktopEnvironment", () => { | 37 | describe("DesktopEnvironment", () => { |
| 40 | it.effect("derives state paths and development identity inside Effect", () => | 38 | it.effect("derives state paths and development identity inside Effect", () => |
apps/desktop/src/app/DesktopEnvironment.ts+1-1| ... | @@ -78,7 +78,7 @@ export interface DesktopEnvironmentShape { | ... | @@ -78,7 +78,7 @@ export interface DesktopEnvironmentShape { |
| 78 | export class DesktopEnvironment extends Context.Service< | 78 | export class DesktopEnvironment extends Context.Service< |
| 79 | DesktopEnvironment, | 79 | DesktopEnvironment, |
| 80 | DesktopEnvironmentShape | 80 | DesktopEnvironmentShape |
| 81 | >()("t3/desktop/Environment") {} | 81 | >()("@t3tools/desktop/app/DesktopEnvironment") {} |
| 82 | 82 | ||
| 83 | const APP_BASE_NAME = "T3 Code"; | 83 | const APP_BASE_NAME = "T3 Code"; |
| 84 | 84 |
apps/desktop/src/app/DesktopLifecycle.ts+5-2| ... | @@ -24,7 +24,7 @@ export interface DesktopShutdownShape { | ... | @@ -24,7 +24,7 @@ export interface DesktopShutdownShape { |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | export class DesktopShutdown extends Context.Service<DesktopShutdown, DesktopShutdownShape>()( | 26 | export class DesktopShutdown extends Context.Service<DesktopShutdown, DesktopShutdownShape>()( |
| 27 | "t3/desktop/Shutdown", | 27 | "@t3tools/desktop/app/DesktopLifecycle/DesktopShutdown", |
| 28 | ) {} | 28 | ) {} |
| 29 | 29 | ||
| 30 | const makeShutdown = Effect.gen(function* () { | 30 | const makeShutdown = Effect.gen(function* () { |
| ... | @@ -61,8 +61,11 @@ export interface DesktopLifecycleShape { | ... | @@ -61,8 +61,11 @@ export interface DesktopLifecycleShape { |
| 61 | readonly register: Effect.Effect<void, never, Scope.Scope | DesktopLifecycleRuntimeServices>; | 61 | readonly register: Effect.Effect<void, never, Scope.Scope | DesktopLifecycleRuntimeServices>; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | /** | ||
| 65 | * @effect-expect-leaking DesktopEnvironment | DesktopShutdown | DesktopState | DesktopWindow | ElectronApp | ElectronTheme | ||
| 66 | */ | ||
| 64 | export class DesktopLifecycle extends Context.Service<DesktopLifecycle, DesktopLifecycleShape>()( | 67 | export class DesktopLifecycle extends Context.Service<DesktopLifecycle, DesktopLifecycleShape>()( |
| 65 | "t3/desktop/Lifecycle", | 68 | "@t3tools/desktop/app/DesktopLifecycle", |
| 66 | ) {} | 69 | ) {} |
| 67 | 70 | ||
| 68 | const { logInfo: logLifecycleInfo, logError: logLifecycleError } = | 71 | const { logInfo: logLifecycleInfo, logError: logLifecycleError } = |
apps/desktop/src/app/DesktopObservability.ts+1-1| ... | @@ -43,7 +43,7 @@ export interface DesktopBackendOutputLogShape { | ... | @@ -43,7 +43,7 @@ export interface DesktopBackendOutputLogShape { |
| 43 | export class DesktopBackendOutputLog extends Context.Service< | 43 | export class DesktopBackendOutputLog extends Context.Service< |
| 44 | DesktopBackendOutputLog, | 44 | DesktopBackendOutputLog, |
| 45 | DesktopBackendOutputLogShape | 45 | DesktopBackendOutputLogShape |
| 46 | >()("t3/desktop/BackendOutputLog") {} | 46 | >()("@t3tools/desktop/app/DesktopObservability/DesktopBackendOutputLog") {} |
| 47 | 47 | ||
| 48 | const textEncoder = new TextEncoder(); | 48 | const textEncoder = new TextEncoder(); |
| 49 | const textDecoder = new TextDecoder(); | 49 | const textDecoder = new TextDecoder(); |
apps/desktop/src/app/DesktopState.ts+1-1| ... | @@ -9,7 +9,7 @@ export interface DesktopStateShape { | ... | @@ -9,7 +9,7 @@ export interface DesktopStateShape { |
| 9 | } | 9 | } |
| 10 | 10 | ||
| 11 | export class DesktopState extends Context.Service<DesktopState, DesktopStateShape>()( | 11 | export class DesktopState extends Context.Service<DesktopState, DesktopStateShape>()( |
| 12 | "t3/desktop/State", | 12 | "@t3tools/desktop/app/DesktopState", |
| 13 | ) {} | 13 | ) {} |
| 14 | 14 | ||
| 15 | export const layer = Layer.effect( | 15 | export const layer = Layer.effect( |
apps/desktop/src/backend/DesktopBackendConfiguration.ts+1-1| ... | @@ -24,7 +24,7 @@ export interface DesktopBackendConfigurationShape { | ... | @@ -24,7 +24,7 @@ export interface DesktopBackendConfigurationShape { |
| 24 | export class DesktopBackendConfiguration extends Context.Service< | 24 | export class DesktopBackendConfiguration extends Context.Service< |
| 25 | DesktopBackendConfiguration, | 25 | DesktopBackendConfiguration, |
| 26 | DesktopBackendConfigurationShape | 26 | DesktopBackendConfigurationShape |
| 27 | >()("t3/desktop/BackendConfiguration") {} | 27 | >()("@t3tools/desktop/backend/DesktopBackendConfiguration") {} |
| 28 | 28 | ||
| 29 | interface BackendObservabilitySettings { | 29 | interface BackendObservabilitySettings { |
| 30 | readonly otlpTracesUrl: Option.Option<string>; | 30 | readonly otlpTracesUrl: Option.Option<string>; |
apps/desktop/src/backend/DesktopBackendManager.ts+1-1| ... | @@ -116,7 +116,7 @@ export interface DesktopBackendManagerShape { | ... | @@ -116,7 +116,7 @@ export interface DesktopBackendManagerShape { |
| 116 | export class DesktopBackendManager extends Context.Service< | 116 | export class DesktopBackendManager extends Context.Service< |
| 117 | DesktopBackendManager, | 117 | DesktopBackendManager, |
| 118 | DesktopBackendManagerShape | 118 | DesktopBackendManagerShape |
| 119 | >()("t3/desktop/BackendManager") {} | 119 | >()("@t3tools/desktop/backend/DesktopBackendManager") {} |
| 120 | 120 | ||
| 121 | const { logWarning: logBackendManagerWarning, logError: logBackendManagerError } = | 121 | const { logWarning: logBackendManagerWarning, logError: logBackendManagerError } = |
| 122 | DesktopObservability.makeComponentLogger("desktop-backend-manager"); | 122 | DesktopObservability.makeComponentLogger("desktop-backend-manager"); |
apps/desktop/src/backend/DesktopServerExposure.ts+2-2| ... | @@ -275,7 +275,7 @@ export interface DesktopServerExposureShape { | ... | @@ -275,7 +275,7 @@ export interface DesktopServerExposureShape { |
| 275 | export class DesktopServerExposure extends Context.Service< | 275 | export class DesktopServerExposure extends Context.Service< |
| 276 | DesktopServerExposure, | 276 | DesktopServerExposure, |
| 277 | DesktopServerExposureShape | 277 | DesktopServerExposureShape |
| 278 | >()("t3/desktop/ServerExposure") {} | 278 | >()("@t3tools/desktop/backend/DesktopServerExposure") {} |
| 279 | 279 | ||
| 280 | export interface DesktopNetworkInterfacesServiceShape { | 280 | export interface DesktopNetworkInterfacesServiceShape { |
| 281 | readonly read: Effect.Effect<DesktopNetworkInterfaces>; | 281 | readonly read: Effect.Effect<DesktopNetworkInterfaces>; |
| ... | @@ -284,7 +284,7 @@ export interface DesktopNetworkInterfacesServiceShape { | ... | @@ -284,7 +284,7 @@ export interface DesktopNetworkInterfacesServiceShape { |
| 284 | export class DesktopNetworkInterfacesService extends Context.Service< | 284 | export class DesktopNetworkInterfacesService extends Context.Service< |
| 285 | DesktopNetworkInterfacesService, | 285 | DesktopNetworkInterfacesService, |
| 286 | DesktopNetworkInterfacesServiceShape | 286 | DesktopNetworkInterfacesServiceShape |
| 287 | >()("t3/desktop/ServerExposure/NetworkInterfaces") {} | 287 | >()("@t3tools/desktop/backend/DesktopServerExposure/DesktopNetworkInterfacesService") {} |
| 288 | 288 | ||
| 289 | interface RuntimeState { | 289 | interface RuntimeState { |
| 290 | readonly requestedMode: DesktopServerExposureMode; | 290 | readonly requestedMode: DesktopServerExposureMode; |
apps/desktop/src/electron/ElectronApp.ts+1-1| ... | @@ -39,7 +39,7 @@ export interface ElectronAppShape { | ... | @@ -39,7 +39,7 @@ export interface ElectronAppShape { |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | export class ElectronApp extends Context.Service<ElectronApp, ElectronAppShape>()( | 41 | export class ElectronApp extends Context.Service<ElectronApp, ElectronAppShape>()( |
| 42 | "t3/desktop/electron/App", | 42 | "@t3tools/desktop/electron/ElectronApp", |
| 43 | ) {} | 43 | ) {} |
| 44 | 44 | ||
| 45 | const addScopedAppListener = <Args extends ReadonlyArray<unknown>>( | 45 | const addScopedAppListener = <Args extends ReadonlyArray<unknown>>( |
apps/desktop/src/electron/ElectronDialog.ts+1-1| ... | @@ -29,7 +29,7 @@ export interface ElectronDialogShape { | ... | @@ -29,7 +29,7 @@ export interface ElectronDialogShape { |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | export class ElectronDialog extends Context.Service<ElectronDialog, ElectronDialogShape>()( | 31 | export class ElectronDialog extends Context.Service<ElectronDialog, ElectronDialogShape>()( |
| 32 | "t3/desktop/electron/Dialog", | 32 | "@t3tools/desktop/electron/ElectronDialog", |
| 33 | ) {} | 33 | ) {} |
| 34 | 34 | ||
| 35 | const make = ElectronDialog.of({ | 35 | const make = ElectronDialog.of({ |
apps/desktop/src/electron/ElectronMenu.ts+1-1| ... | @@ -33,7 +33,7 @@ export interface ElectronMenuShape { | ... | @@ -33,7 +33,7 @@ export interface ElectronMenuShape { |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | export class ElectronMenu extends Context.Service<ElectronMenu, ElectronMenuShape>()( | 35 | export class ElectronMenu extends Context.Service<ElectronMenu, ElectronMenuShape>()( |
| 36 | "t3/desktop/electron/Menu", | 36 | "@t3tools/desktop/electron/ElectronMenu", |
| 37 | ) {} | 37 | ) {} |
| 38 | 38 | ||
| 39 | function normalizeContextMenuItems(source: readonly ContextMenuItem[]): ContextMenuItem[] { | 39 | function normalizeContextMenuItems(source: readonly ContextMenuItem[]): ContextMenuItem[] { |
apps/desktop/src/electron/ElectronProtocol.ts+1-1| ... | @@ -52,7 +52,7 @@ export interface ElectronProtocolShape { | ... | @@ -52,7 +52,7 @@ export interface ElectronProtocolShape { |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | export class ElectronProtocol extends Context.Service<ElectronProtocol, ElectronProtocolShape>()( | 54 | export class ElectronProtocol extends Context.Service<ElectronProtocol, ElectronProtocolShape>()( |
| 55 | "t3/desktop/electron/Protocol", | 55 | "@t3tools/desktop/electron/ElectronProtocol", |
| 56 | ) {} | 56 | ) {} |
| 57 | 57 | ||
| 58 | export function normalizeDesktopProtocolPathname(rawPath: string): Option.Option<string> { | 58 | export function normalizeDesktopProtocolPathname(rawPath: string): Option.Option<string> { |
apps/desktop/src/electron/ElectronSafeStorage.ts+1-1| ... | @@ -48,7 +48,7 @@ export interface ElectronSafeStorageShape { | ... | @@ -48,7 +48,7 @@ export interface ElectronSafeStorageShape { |
| 48 | export class ElectronSafeStorage extends Context.Service< | 48 | export class ElectronSafeStorage extends Context.Service< |
| 49 | ElectronSafeStorage, | 49 | ElectronSafeStorage, |
| 50 | ElectronSafeStorageShape | 50 | ElectronSafeStorageShape |
| 51 | >()("@t3tools/desktop/ElectronSafeStorage") {} | 51 | >()("@t3tools/desktop/electron/ElectronSafeStorage") {} |
| 52 | 52 | ||
| 53 | const make = ElectronSafeStorage.of({ | 53 | const make = ElectronSafeStorage.of({ |
| 54 | isEncryptionAvailable: Effect.try({ | 54 | isEncryptionAvailable: Effect.try({ |
apps/desktop/src/electron/ElectronShell.ts+1-1| ... | @@ -26,7 +26,7 @@ export interface ElectronShellShape { | ... | @@ -26,7 +26,7 @@ export interface ElectronShellShape { |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | export class ElectronShell extends Context.Service<ElectronShell, ElectronShellShape>()( | 28 | export class ElectronShell extends Context.Service<ElectronShell, ElectronShellShape>()( |
| 29 | "t3/desktop/electron/Shell", | 29 | "@t3tools/desktop/electron/ElectronShell", |
| 30 | ) {} | 30 | ) {} |
| 31 | 31 | ||
| 32 | const make = ElectronShell.of({ | 32 | const make = ElectronShell.of({ |
apps/desktop/src/electron/ElectronTheme.ts+1-1| ... | @@ -13,7 +13,7 @@ export interface ElectronThemeShape { | ... | @@ -13,7 +13,7 @@ export interface ElectronThemeShape { |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | export class ElectronTheme extends Context.Service<ElectronTheme, ElectronThemeShape>()( | 15 | export class ElectronTheme extends Context.Service<ElectronTheme, ElectronThemeShape>()( |
| 16 | "t3/desktop/electron/Theme", | 16 | "@t3tools/desktop/electron/ElectronTheme", |
| 17 | ) {} | 17 | ) {} |
| 18 | 18 | ||
| 19 | const make = ElectronTheme.of({ | 19 | const make = ElectronTheme.of({ |
apps/desktop/src/electron/ElectronUpdater.ts+1-1| ... | @@ -67,7 +67,7 @@ export interface ElectronUpdaterShape { | ... | @@ -67,7 +67,7 @@ export interface ElectronUpdaterShape { |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | export class ElectronUpdater extends Context.Service<ElectronUpdater, ElectronUpdaterShape>()( | 69 | export class ElectronUpdater extends Context.Service<ElectronUpdater, ElectronUpdaterShape>()( |
| 70 | "t3/desktop/electron/Updater", | 70 | "@t3tools/desktop/electron/ElectronUpdater", |
| 71 | ) {} | 71 | ) {} |
| 72 | 72 | ||
| 73 | export const layer = Layer.succeed(ElectronUpdater, { | 73 | export const layer = Layer.succeed(ElectronUpdater, { |
apps/desktop/src/electron/ElectronWindow.ts+1-1| ... | @@ -33,7 +33,7 @@ export interface ElectronWindowShape { | ... | @@ -33,7 +33,7 @@ export interface ElectronWindowShape { |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | export class ElectronWindow extends Context.Service<ElectronWindow, ElectronWindowShape>()( | 35 | export class ElectronWindow extends Context.Service<ElectronWindow, ElectronWindowShape>()( |
| 36 | "t3/desktop/electron/Window", | 36 | "@t3tools/desktop/electron/ElectronWindow", |
| 37 | ) {} | 37 | ) {} |
| 38 | 38 | ||
| 39 | const make = Effect.gen(function* () { | 39 | const make = Effect.gen(function* () { |
apps/desktop/src/ipc/DesktopIpc.ts+3-1| ... | @@ -42,7 +42,9 @@ export interface DesktopIpcShape { | ... | @@ -42,7 +42,9 @@ export interface DesktopIpcShape { |
| 42 | ) => Effect.Effect<void, never, R | Scope.Scope>; | 42 | ) => Effect.Effect<void, never, R | Scope.Scope>; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | export class DesktopIpc extends Context.Service<DesktopIpc, DesktopIpcShape>()("t3/desktop/Ipc") {} | 45 | export class DesktopIpc extends Context.Service<DesktopIpc, DesktopIpcShape>()( |
| 46 | "@t3tools/desktop/ipc/DesktopIpc", | ||
| 47 | ) {} | ||
| 46 | 48 | ||
| 47 | export const make = (ipcMain: DesktopIpcMain): DesktopIpcShape => | 49 | export const make = (ipcMain: DesktopIpcMain): DesktopIpcShape => |
| 48 | DesktopIpc.of({ | 50 | DesktopIpc.of({ |
apps/desktop/src/settings/DesktopAppSettings.ts+1-1| ... | @@ -89,7 +89,7 @@ export interface DesktopAppSettingsShape { | ... | @@ -89,7 +89,7 @@ export interface DesktopAppSettingsShape { |
| 89 | export class DesktopAppSettings extends Context.Service< | 89 | export class DesktopAppSettings extends Context.Service< |
| 90 | DesktopAppSettings, | 90 | DesktopAppSettings, |
| 91 | DesktopAppSettingsShape | 91 | DesktopAppSettingsShape |
| 92 | >()("t3/desktop/AppSettings") {} | 92 | >()("@t3tools/desktop/settings/DesktopAppSettings") {} |
| 93 | 93 | ||
| 94 | export function resolveDefaultDesktopSettings(appVersion: string): DesktopSettings { | 94 | export function resolveDefaultDesktopSettings(appVersion: string): DesktopSettings { |
| 95 | return { | 95 | return { |
apps/desktop/src/settings/DesktopClientSettings.ts+1-1| ... | @@ -49,7 +49,7 @@ export interface DesktopClientSettingsShape { | ... | @@ -49,7 +49,7 @@ export interface DesktopClientSettingsShape { |
| 49 | export class DesktopClientSettings extends Context.Service< | 49 | export class DesktopClientSettings extends Context.Service< |
| 50 | DesktopClientSettings, | 50 | DesktopClientSettings, |
| 51 | DesktopClientSettingsShape | 51 | DesktopClientSettingsShape |
| 52 | >()("t3/desktop/ClientSettings") {} | 52 | >()("@t3tools/desktop/settings/DesktopClientSettings") {} |
| 53 | 53 | ||
| 54 | const readClientSettings = ( | 54 | const readClientSettings = ( |
| 55 | fileSystem: FileSystem.FileSystem, | 55 | fileSystem: FileSystem.FileSystem, |
apps/desktop/src/settings/DesktopSavedEnvironments.ts+1-1| ... | @@ -121,7 +121,7 @@ export interface DesktopSavedEnvironmentsShape { | ... | @@ -121,7 +121,7 @@ export interface DesktopSavedEnvironmentsShape { |
| 121 | export class DesktopSavedEnvironments extends Context.Service< | 121 | export class DesktopSavedEnvironments extends Context.Service< |
| 122 | DesktopSavedEnvironments, | 122 | DesktopSavedEnvironments, |
| 123 | DesktopSavedEnvironmentsShape | 123 | DesktopSavedEnvironmentsShape |
| 124 | >()("t3/desktop/SavedEnvironments") {} | 124 | >()("@t3tools/desktop/settings/DesktopSavedEnvironments") {} |
| 125 | 125 | ||
| 126 | function toPersistedSavedEnvironmentRecord( | 126 | function toPersistedSavedEnvironmentRecord( |
| 127 | record: PersistedSavedEnvironmentStorageRecord, | 127 | record: PersistedSavedEnvironmentStorageRecord, |
apps/desktop/src/shell/DesktopShellEnvironment.ts+1-1| ... | @@ -26,7 +26,7 @@ export interface DesktopShellEnvironmentShape { | ... | @@ -26,7 +26,7 @@ export interface DesktopShellEnvironmentShape { |
| 26 | export class DesktopShellEnvironment extends Context.Service< | 26 | export class DesktopShellEnvironment extends Context.Service< |
| 27 | DesktopShellEnvironment, | 27 | DesktopShellEnvironment, |
| 28 | DesktopShellEnvironmentShape | 28 | DesktopShellEnvironmentShape |
| 29 | >()("t3/desktop/ShellEnvironment") {} | 29 | >()("@t3tools/desktop/shell/DesktopShellEnvironment") {} |
| 30 | 30 | ||
| 31 | const LOGIN_SHELL_ENV_NAMES = [ | 31 | const LOGIN_SHELL_ENV_NAMES = [ |
| 32 | "PATH", | 32 | "PATH", |
apps/desktop/src/ssh/DesktopSshEnvironment.ts+1-1| ... | @@ -68,7 +68,7 @@ export interface DesktopSshEnvironmentShape { | ... | @@ -68,7 +68,7 @@ export interface DesktopSshEnvironmentShape { |
| 68 | export class DesktopSshEnvironment extends Context.Service< | 68 | export class DesktopSshEnvironment extends Context.Service< |
| 69 | DesktopSshEnvironment, | 69 | DesktopSshEnvironment, |
| 70 | DesktopSshEnvironmentShape | 70 | DesktopSshEnvironmentShape |
| 71 | >()("t3/desktop/SshEnvironment") {} | 71 | >()("@t3tools/desktop/ssh/DesktopSshEnvironment") {} |
| 72 | 72 | ||
| 73 | export interface DesktopSshEnvironmentLayerOptions { | 73 | export interface DesktopSshEnvironmentLayerOptions { |
| 74 | readonly resolveCliPackageSpec?: () => string; | 74 | readonly resolveCliPackageSpec?: () => string; |
apps/desktop/src/ssh/DesktopSshPasswordPrompts.ts+1-1| ... | @@ -129,7 +129,7 @@ export interface DesktopSshPasswordPromptsShape { | ... | @@ -129,7 +129,7 @@ export interface DesktopSshPasswordPromptsShape { |
| 129 | export class DesktopSshPasswordPrompts extends Context.Service< | 129 | export class DesktopSshPasswordPrompts extends Context.Service< |
| 130 | DesktopSshPasswordPrompts, | 130 | DesktopSshPasswordPrompts, |
| 131 | DesktopSshPasswordPromptsShape | 131 | DesktopSshPasswordPromptsShape |
| 132 | >()("t3/desktop/SshPasswordPrompts") {} | 132 | >()("@t3tools/desktop/ssh/DesktopSshPasswordPrompts") {} |
| 133 | 133 | ||
| 134 | interface PendingSshPasswordPrompt { | 134 | interface PendingSshPasswordPrompt { |
| 135 | readonly requestId: string; | 135 | readonly requestId: string; |
apps/desktop/src/ssh/DesktopSshRemoteApi.ts+1-1| ... | @@ -53,7 +53,7 @@ export interface DesktopSshRemoteApiShape { | ... | @@ -53,7 +53,7 @@ export interface DesktopSshRemoteApiShape { |
| 53 | export class DesktopSshRemoteApi extends Context.Service< | 53 | export class DesktopSshRemoteApi extends Context.Service< |
| 54 | DesktopSshRemoteApi, | 54 | DesktopSshRemoteApi, |
| 55 | DesktopSshRemoteApiShape | 55 | DesktopSshRemoteApiShape |
| 56 | >()("t3/desktop/SshRemoteApi") {} | 56 | >()("@t3tools/desktop/ssh/DesktopSshRemoteApi") {} |
| 57 | 57 | ||
| 58 | const decodeExecutionEnvironmentDescriptor = Schema.decodeUnknownEffect( | 58 | const decodeExecutionEnvironmentDescriptor = Schema.decodeUnknownEffect( |
| 59 | ExecutionEnvironmentDescriptor, | 59 | ExecutionEnvironmentDescriptor, |
apps/desktop/src/updates/DesktopUpdates.ts+1-1| ... | @@ -100,7 +100,7 @@ export interface DesktopUpdatesShape { | ... | @@ -100,7 +100,7 @@ export interface DesktopUpdatesShape { |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | export class DesktopUpdates extends Context.Service<DesktopUpdates, DesktopUpdatesShape>()( | 102 | export class DesktopUpdates extends Context.Service<DesktopUpdates, DesktopUpdatesShape>()( |
| 103 | "t3/desktop/Updates", | 103 | "@t3tools/desktop/updates/DesktopUpdates", |
| 104 | ) {} | 104 | ) {} |
| 105 | 105 | ||
| 106 | const { | 106 | const { |
apps/desktop/src/window/DesktopApplicationMenu.ts+1-1| ... | @@ -21,7 +21,7 @@ export interface DesktopApplicationMenuShape { | ... | @@ -21,7 +21,7 @@ export interface DesktopApplicationMenuShape { |
| 21 | export class DesktopApplicationMenu extends Context.Service< | 21 | export class DesktopApplicationMenu extends Context.Service< |
| 22 | DesktopApplicationMenu, | 22 | DesktopApplicationMenu, |
| 23 | DesktopApplicationMenuShape | 23 | DesktopApplicationMenuShape |
| 24 | >()("t3/desktop/ApplicationMenu") {} | 24 | >()("@t3tools/desktop/window/DesktopApplicationMenu") {} |
| 25 | 25 | ||
| 26 | type DesktopApplicationMenuRuntimeServices = | 26 | type DesktopApplicationMenuRuntimeServices = |
| 27 | | DesktopUpdates.DesktopUpdates | 27 | | DesktopUpdates.DesktopUpdates |
apps/desktop/src/window/DesktopWindow.ts+1-1| ... | @@ -62,7 +62,7 @@ export interface DesktopWindowShape { | ... | @@ -62,7 +62,7 @@ export interface DesktopWindowShape { |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | export class DesktopWindow extends Context.Service<DesktopWindow, DesktopWindowShape>()( | 64 | export class DesktopWindow extends Context.Service<DesktopWindow, DesktopWindowShape>()( |
| 65 | "t3/desktop/Window", | 65 | "@t3tools/desktop/window/DesktopWindow", |
| 66 | ) {} | 66 | ) {} |
| 67 | 67 | ||
| 68 | const { logInfo: logWindowInfo, logWarning: logWindowWarning } = | 68 | const { logInfo: logWindowInfo, logWarning: logWindowWarning } = |
apps/server/package.json+1-3| ... | @@ -19,7 +19,7 @@ | ... | @@ -19,7 +19,7 @@ |
| 19 | "build": "node scripts/cli.ts build", | 19 | "build": "node scripts/cli.ts build", |
| 20 | "build:bundle": "tsdown", | 20 | "build:bundle": "tsdown", |
| 21 | "start": "node dist/bin.mjs", | 21 | "start": "node dist/bin.mjs", |
| 22 | "typecheck": "tsc --noEmit", | 22 | "typecheck": "tsgo --noEmit", |
| 23 | "test": "vitest run" | 23 | "test": "vitest run" |
| 24 | }, | 24 | }, |
| 25 | "dependencies": { | 25 | "dependencies": { |
| ... | @@ -34,7 +34,6 @@ | ... | @@ -34,7 +34,6 @@ |
| 34 | "node-pty": "^1.1.0" | 34 | "node-pty": "^1.1.0" |
| 35 | }, | 35 | }, |
| 36 | "devDependencies": { | 36 | "devDependencies": { |
| 37 | "@effect/language-service": "catalog:", | ||
| 38 | "@effect/vitest": "catalog:", | 37 | "@effect/vitest": "catalog:", |
| 39 | "@t3tools/contracts": "workspace:*", | 38 | "@t3tools/contracts": "workspace:*", |
| 40 | "@t3tools/shared": "workspace:*", | 39 | "@t3tools/shared": "workspace:*", |
| ... | @@ -45,7 +44,6 @@ | ... | @@ -45,7 +44,6 @@ |
| 45 | "effect-acp": "workspace:*", | 44 | "effect-acp": "workspace:*", |
| 46 | "effect-codex-app-server": "workspace:*", | 45 | "effect-codex-app-server": "workspace:*", |
| 47 | "tsdown": "catalog:", | 46 | "tsdown": "catalog:", |
| 48 | "typescript": "catalog:", | ||
| 49 | "vitest": "catalog:" | 47 | "vitest": "catalog:" |
| 50 | }, | 48 | }, |
| 51 | "engines": { | 49 | "engines": { |
apps/server/src/auth/Layers/BootstrapCredentialService.ts+3-1| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | import type { AuthPairingLink } from "@t3tools/contracts"; | 1 | import type { AuthPairingLink } from "@t3tools/contracts"; |
| 2 | import * as Crypto from "effect/Crypto"; | ||
| 2 | import * as DateTime from "effect/DateTime"; | 3 | import * as DateTime from "effect/DateTime"; |
| 3 | import * as Duration from "effect/Duration"; | 4 | import * as Duration from "effect/Duration"; |
| 4 | import * as Effect from "effect/Effect"; | 5 | import * as Effect from "effect/Effect"; |
| ... | @@ -46,6 +47,7 @@ const generatePairingToken = (): string => { | ... | @@ -46,6 +47,7 @@ const generatePairingToken = (): string => { |
| 46 | }; | 47 | }; |
| 47 | 48 | ||
| 48 | export const makeBootstrapCredentialService = Effect.gen(function* () { | 49 | export const makeBootstrapCredentialService = Effect.gen(function* () { |
| 50 | const crypto = yield* Crypto.Crypto; | ||
| 49 | const config = yield* ServerConfig; | 51 | const config = yield* ServerConfig; |
| 50 | const pairingLinks = yield* AuthPairingLinkRepository; | 52 | const pairingLinks = yield* AuthPairingLinkRepository; |
| 51 | const seededGrantsRef = yield* Ref.make(new Map<string, StoredBootstrapGrant>()); | 53 | const seededGrantsRef = yield* Ref.make(new Map<string, StoredBootstrapGrant>()); |
| ... | @@ -141,7 +143,7 @@ export const makeBootstrapCredentialService = Effect.gen(function* () { | ... | @@ -141,7 +143,7 @@ export const makeBootstrapCredentialService = Effect.gen(function* () { |
| 141 | 143 | ||
| 142 | const issueOneTimeToken: BootstrapCredentialServiceShape["issueOneTimeToken"] = (input) => | 144 | const issueOneTimeToken: BootstrapCredentialServiceShape["issueOneTimeToken"] = (input) => |
| 143 | Effect.gen(function* () { | 145 | Effect.gen(function* () { |
| 144 | const id = crypto.randomUUID(); | 146 | const id = yield* crypto.randomUUIDv4; |
| 145 | const credential = generatePairingToken(); | 147 | const credential = generatePairingToken(); |
| 146 | const ttl = input?.ttl ?? DEFAULT_ONE_TIME_TOKEN_TTL_MINUTES; | 148 | const ttl = input?.ttl ?? DEFAULT_ONE_TIME_TOKEN_TTL_MINUTES; |
| 147 | const now = yield* DateTime.now; | 149 | const now = yield* DateTime.now; |
apps/server/src/auth/Layers/SessionCredentialService.ts+3-1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | import { AuthSessionId, type AuthClientMetadata, type AuthClientSession } from "@t3tools/contracts"; | 1 | import { AuthSessionId, type AuthClientMetadata, type AuthClientSession } from "@t3tools/contracts"; |
| 2 | import * as Clock from "effect/Clock"; | 2 | import * as Clock from "effect/Clock"; |
| 3 | import * as Crypto from "effect/Crypto"; | ||
| 3 | import * as DateTime from "effect/DateTime"; | 4 | import * as DateTime from "effect/DateTime"; |
| 4 | import * as Duration from "effect/Duration"; | 5 | import * as Duration from "effect/Duration"; |
| 5 | import * as Effect from "effect/Effect"; | 6 | import * as Effect from "effect/Effect"; |
| ... | @@ -90,6 +91,7 @@ function toAuthClientSession(input: Omit<AuthClientSession, "current">): AuthCli | ... | @@ -90,6 +91,7 @@ function toAuthClientSession(input: Omit<AuthClientSession, "current">): AuthCli |
| 90 | } | 91 | } |
| 91 | 92 | ||
| 92 | export const makeSessionCredentialService = Effect.gen(function* () { | 93 | export const makeSessionCredentialService = Effect.gen(function* () { |
| 94 | const crypto = yield* Crypto.Crypto; | ||
| 93 | const serverConfig = yield* ServerConfig; | 95 | const serverConfig = yield* ServerConfig; |
| 94 | const secretStore = yield* ServerSecretStore; | 96 | const secretStore = yield* ServerSecretStore; |
| 95 | const authSessions = yield* AuthSessionRepository; | 97 | const authSessions = yield* AuthSessionRepository; |
| ... | @@ -203,7 +205,7 @@ export const makeSessionCredentialService = Effect.gen(function* () { | ... | @@ -203,7 +205,7 @@ export const makeSessionCredentialService = Effect.gen(function* () { |
| 203 | const encodeClaims = Schema.encodeEffect(Schema.fromJsonString(SessionClaims)); | 205 | const encodeClaims = Schema.encodeEffect(Schema.fromJsonString(SessionClaims)); |
| 204 | const issue: SessionCredentialServiceShape["issue"] = (input) => | 206 | const issue: SessionCredentialServiceShape["issue"] = (input) => |
| 205 | Effect.gen(function* () { | 207 | Effect.gen(function* () { |
| 206 | const sessionId = AuthSessionId.make(crypto.randomUUID()); | 208 | const sessionId = AuthSessionId.make(yield* crypto.randomUUIDv4); |
| 207 | const issuedAt = yield* DateTime.now; | 209 | const issuedAt = yield* DateTime.now; |
| 208 | const expiresAt = DateTime.add(issuedAt, { | 210 | const expiresAt = DateTime.add(issuedAt, { |
| 209 | milliseconds: Duration.toMillis(input?.ttl ?? DEFAULT_SESSION_TTL), | 211 | milliseconds: Duration.toMillis(input?.ttl ?? DEFAULT_SESSION_TTL), |
apps/server/src/auth/Services/AuthControlPlane.ts+1-1| ... | @@ -69,5 +69,5 @@ export interface AuthControlPlaneShape { | ... | @@ -69,5 +69,5 @@ export interface AuthControlPlaneShape { |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | export class AuthControlPlane extends Context.Service<AuthControlPlane, AuthControlPlaneShape>()( | 71 | export class AuthControlPlane extends Context.Service<AuthControlPlane, AuthControlPlaneShape>()( |
| 72 | "t3/AuthControlPlane", | 72 | "t3/auth/Services/AuthControlPlane", |
| 73 | ) {} | 73 | ) {} |
apps/server/src/bin.test.ts+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | // @effect-diagnostics-next-line nodeBuiltinImport:off - NodeHttpServer.layer takes `NodeHttp.createServer` as arg | 1 | // @effect-diagnostics nodeBuiltinImport:off - CLI integration exercises Node HTTP and filesystem boundaries. |
| 2 | import * as NodeHttp from "node:http"; | 2 | import * as NodeHttp from "node:http"; |
| 3 | import { mkdtempSync } from "node:fs"; | 3 | import { mkdtempSync } from "node:fs"; |
| 4 | import { tmpdir } from "node:os"; | 4 | import { tmpdir } from "node:os"; |
apps/server/src/orchestration/Layers/CheckpointReactor.ts+63-41| ... | @@ -9,10 +9,12 @@ import { | ... | @@ -9,10 +9,12 @@ import { |
| 9 | type ProviderRuntimeEvent, | 9 | type ProviderRuntimeEvent, |
| 10 | } from "@t3tools/contracts"; | 10 | } from "@t3tools/contracts"; |
| 11 | import * as Cause from "effect/Cause"; | 11 | import * as Cause from "effect/Cause"; |
| 12 | import * as Crypto from "effect/Crypto"; | ||
| 12 | import * as DateTime from "effect/DateTime"; | 13 | import * as DateTime from "effect/DateTime"; |
| 13 | import * as Effect from "effect/Effect"; | 14 | import * as Effect from "effect/Effect"; |
| 14 | import * as Layer from "effect/Layer"; | 15 | import * as Layer from "effect/Layer"; |
| 15 | import * as Option from "effect/Option"; | 16 | import * as Option from "effect/Option"; |
| 17 | import type * as PlatformError from "effect/PlatformError"; | ||
| 16 | import * as Stream from "effect/Stream"; | 18 | import * as Stream from "effect/Stream"; |
| 17 | import { makeDrainableWorker } from "@t3tools/shared/DrainableWorker"; | 19 | import { makeDrainableWorker } from "@t3tools/shared/DrainableWorker"; |
| 18 | 20 | ||
| ... | @@ -69,10 +71,12 @@ function checkpointStatusFromRuntime(status: string | undefined): "ready" | "mis | ... | @@ -69,10 +71,12 @@ function checkpointStatusFromRuntime(status: string | undefined): "ready" | "mis |
| 69 | } | 71 | } |
| 70 | } | 72 | } |
| 71 | 73 | ||
| 72 | const serverCommandId = (tag: string): CommandId => | ||
| 73 | CommandId.make(`server:${tag}:${crypto.randomUUID()}`); | ||
| 74 | |||
| 75 | const make = Effect.gen(function* () { | 74 | const make = Effect.gen(function* () { |
| 75 | const crypto = yield* Crypto.Crypto; | ||
| 76 | const randomUUID = crypto.randomUUIDv4; | ||
| 77 | const serverEventId = randomUUID.pipe(Effect.map(EventId.make)); | ||
| 78 | const serverCommandId = (tag: string) => | ||
| 79 | randomUUID.pipe(Effect.map((uuid) => CommandId.make(`server:${tag}:${uuid}`))); | ||
| 76 | const orchestrationEngine = yield* OrchestrationEngineService; | 80 | const orchestrationEngine = yield* OrchestrationEngineService; |
| 77 | const projectionSnapshotQuery = yield* ProjectionSnapshotQuery; | 81 | const projectionSnapshotQuery = yield* ProjectionSnapshotQuery; |
| 78 | const providerService = yield* ProviderService; | 82 | const providerService = yield* ProviderService; |
| ... | @@ -87,24 +91,31 @@ const make = Effect.gen(function* () { | ... | @@ -87,24 +91,31 @@ const make = Effect.gen(function* () { |
| 87 | readonly detail: string; | 91 | readonly detail: string; |
| 88 | readonly createdAt: string; | 92 | readonly createdAt: string; |
| 89 | }) => | 93 | }) => |
| 90 | orchestrationEngine.dispatch({ | 94 | Effect.all({ |
| 91 | type: "thread.activity.append", | ||
| 92 | commandId: serverCommandId("checkpoint-revert-failure"), | 95 | commandId: serverCommandId("checkpoint-revert-failure"), |
| 93 | threadId: input.threadId, | 96 | activityId: serverEventId, |
| 94 | activity: { | 97 | }).pipe( |
| 95 | id: EventId.make(crypto.randomUUID()), | 98 | Effect.flatMap(({ commandId, activityId }) => |
| 96 | tone: "error", | 99 | orchestrationEngine.dispatch({ |
| 97 | kind: "checkpoint.revert.failed", | 100 | type: "thread.activity.append", |
| 98 | summary: "Checkpoint revert failed", | 101 | commandId, |
| 99 | payload: { | 102 | threadId: input.threadId, |
| 100 | turnCount: input.turnCount, | 103 | activity: { |
| 101 | detail: input.detail, | 104 | id: activityId, |
| 102 | }, | 105 | tone: "error", |
| 103 | turnId: null, | 106 | kind: "checkpoint.revert.failed", |
| 104 | createdAt: input.createdAt, | 107 | summary: "Checkpoint revert failed", |
| 105 | }, | 108 | payload: { |
| 106 | createdAt: input.createdAt, | 109 | turnCount: input.turnCount, |
| 107 | }); | 110 | detail: input.detail, |
| 111 | }, | ||
| 112 | turnId: null, | ||
| 113 | createdAt: input.createdAt, | ||
| 114 | }, | ||
| 115 | createdAt: input.createdAt, | ||
| 116 | }), | ||
| 117 | ), | ||
| 118 | ); | ||
| 108 | 119 | ||
| 109 | const appendCaptureFailureActivity = (input: { | 120 | const appendCaptureFailureActivity = (input: { |
| 110 | readonly threadId: ThreadId; | 121 | readonly threadId: ThreadId; |
| ... | @@ -112,23 +123,30 @@ const make = Effect.gen(function* () { | ... | @@ -112,23 +123,30 @@ const make = Effect.gen(function* () { |
| 112 | readonly detail: string; | 123 | readonly detail: string; |
| 113 | readonly createdAt: string; | 124 | readonly createdAt: string; |
| 114 | }) => | 125 | }) => |
| 115 | orchestrationEngine.dispatch({ | 126 | Effect.all({ |
| 116 | type: "thread.activity.append", | ||
| 117 | commandId: serverCommandId("checkpoint-capture-failure"), | 127 | commandId: serverCommandId("checkpoint-capture-failure"), |
| 118 | threadId: input.threadId, | 128 | activityId: serverEventId, |
| 119 | activity: { | 129 | }).pipe( |
| 120 | id: EventId.make(crypto.randomUUID()), | 130 | Effect.flatMap(({ commandId, activityId }) => |
| 121 | tone: "error", | 131 | orchestrationEngine.dispatch({ |
| 122 | kind: "checkpoint.capture.failed", | 132 | type: "thread.activity.append", |
| 123 | summary: "Checkpoint capture failed", | 133 | commandId, |
| 124 | payload: { | 134 | threadId: input.threadId, |
| 125 | detail: input.detail, | 135 | activity: { |
| 126 | }, | 136 | id: activityId, |
| 127 | turnId: input.turnId, | 137 | tone: "error", |
| 128 | createdAt: input.createdAt, | 138 | kind: "checkpoint.capture.failed", |
| 129 | }, | 139 | summary: "Checkpoint capture failed", |
| 130 | createdAt: input.createdAt, | 140 | payload: { |
| 131 | }); | 141 | detail: input.detail, |
| 142 | }, | ||
| 143 | turnId: input.turnId, | ||
| 144 | createdAt: input.createdAt, | ||
| 145 | }, | ||
| 146 | createdAt: input.createdAt, | ||
| 147 | }), | ||
| 148 | ), | ||
| 149 | ); | ||
| 132 | 150 | ||
| 133 | const resolveSessionRuntimeForThread = Effect.fn("resolveSessionRuntimeForThread")(function* ( | 151 | const resolveSessionRuntimeForThread = Effect.fn("resolveSessionRuntimeForThread")(function* ( |
| 134 | threadId: ThreadId, | 152 | threadId: ThreadId, |
| ... | @@ -281,7 +299,7 @@ const make = Effect.gen(function* () { | ... | @@ -281,7 +299,7 @@ const make = Effect.gen(function* () { |
| 281 | 299 | ||
| 282 | yield* orchestrationEngine.dispatch({ | 300 | yield* orchestrationEngine.dispatch({ |
| 283 | type: "thread.turn.diff.complete", | 301 | type: "thread.turn.diff.complete", |
| 284 | commandId: serverCommandId("checkpoint-turn-diff-complete"), | 302 | commandId: yield* serverCommandId("checkpoint-turn-diff-complete"), |
| 285 | threadId: input.threadId, | 303 | threadId: input.threadId, |
| 286 | turnId: input.turnId, | 304 | turnId: input.turnId, |
| 287 | completedAt: input.createdAt, | 305 | completedAt: input.createdAt, |
| ... | @@ -311,10 +329,10 @@ const make = Effect.gen(function* () { | ... | @@ -311,10 +329,10 @@ const make = Effect.gen(function* () { |
| 311 | 329 | ||
| 312 | yield* orchestrationEngine.dispatch({ | 330 | yield* orchestrationEngine.dispatch({ |
| 313 | type: "thread.activity.append", | 331 | type: "thread.activity.append", |
| 314 | commandId: serverCommandId("checkpoint-captured-activity"), | 332 | commandId: yield* serverCommandId("checkpoint-captured-activity"), |
| 315 | threadId: input.threadId, | 333 | threadId: input.threadId, |
| 316 | activity: { | 334 | activity: { |
| 317 | id: EventId.make(crypto.randomUUID()), | 335 | id: EventId.make(yield* randomUUID), |
| 318 | tone: "info", | 336 | tone: "info", |
| 319 | kind: "checkpoint.captured", | 337 | kind: "checkpoint.captured", |
| 320 | summary: "Checkpoint captured", | 338 | summary: "Checkpoint captured", |
| ... | @@ -697,7 +715,7 @@ const make = Effect.gen(function* () { | ... | @@ -697,7 +715,7 @@ const make = Effect.gen(function* () { |
| 697 | yield* orchestrationEngine | 715 | yield* orchestrationEngine |
| 698 | .dispatch({ | 716 | .dispatch({ |
| 699 | type: "thread.revert.complete", | 717 | type: "thread.revert.complete", |
| 700 | commandId: serverCommandId("checkpoint-revert-complete"), | 718 | commandId: yield* serverCommandId("checkpoint-revert-complete"), |
| 701 | threadId: event.payload.threadId, | 719 | threadId: event.payload.threadId, |
| 702 | turnCount: event.payload.turnCount, | 720 | turnCount: event.payload.turnCount, |
| 703 | createdAt: now, | 721 | createdAt: now, |
| ... | @@ -787,7 +805,11 @@ const make = Effect.gen(function* () { | ... | @@ -787,7 +805,11 @@ const make = Effect.gen(function* () { |
| 787 | 805 | ||
| 788 | const processInput = ( | 806 | const processInput = ( |
| 789 | input: ReactorInput, | 807 | input: ReactorInput, |
| 790 | ): Effect.Effect<void, CheckpointStoreError | OrchestrationDispatchError, never> => | 808 | ): Effect.Effect< |
| 809 | void, | ||
| 810 | CheckpointStoreError | OrchestrationDispatchError | PlatformError.PlatformError, | ||
| 811 | never | ||
| 812 | > => | ||
| 791 | input.source === "domain" ? processDomainEvent(input.event) : processRuntimeEvent(input.event); | 813 | input.source === "domain" ? processDomainEvent(input.event) : processRuntimeEvent(input.event); |
| 792 | 814 | ||
| 793 | const processInputSafely = (input: ReactorInput) => | 815 | const processInputSafely = (input: ReactorInput) => |
apps/server/src/orchestration/http.ts+4-2| ... | @@ -58,8 +58,10 @@ export const orchestrationSnapshotRouteLayer = HttpRouter.add( | ... | @@ -58,8 +58,10 @@ export const orchestrationSnapshotRouteLayer = HttpRouter.add( |
| 58 | status: 200, | 58 | status: 200, |
| 59 | }); | 59 | }); |
| 60 | }).pipe( | 60 | }).pipe( |
| 61 | Effect.catchTag("OrchestrationDispatchCommandError", respondToOrchestrationHttpError), | 61 | Effect.catchTags({ |
| 62 | Effect.catchTag("OrchestrationGetSnapshotError", respondToOrchestrationHttpError), | 62 | OrchestrationDispatchCommandError: respondToOrchestrationHttpError, |
| 63 | OrchestrationGetSnapshotError: respondToOrchestrationHttpError, | ||
| 64 | }), | ||
| 63 | ), | 65 | ), |
| 64 | ); | 66 | ); |
| 65 | 67 |
apps/server/src/persistence/Layers/AuthSessions.ts+1-1| ... | @@ -40,7 +40,7 @@ const AuthSessionDbRow = Schema.Struct({ | ... | @@ -40,7 +40,7 @@ const AuthSessionDbRow = Schema.Struct({ |
| 40 | revokedAt: Schema.NullOr(Schema.DateTimeUtcFromString), | 40 | revokedAt: Schema.NullOr(Schema.DateTimeUtcFromString), |
| 41 | }); | 41 | }); |
| 42 | 42 | ||
| 43 | function toAuthSessionRecord(row: typeof AuthSessionDbRow.Type): typeof AuthSessionRecord.Type { | 43 | function toAuthSessionRecord(row: typeof AuthSessionDbRow.Type): AuthSessionRecord { |
| 44 | return { | 44 | return { |
| 45 | sessionId: row.sessionId, | 45 | sessionId: row.sessionId, |
| 46 | subject: row.subject, | 46 | subject: row.subject, |
apps/server/src/persistence/Migrations/009_ProviderSessionRuntimeMode.ts+1-3| ... | @@ -1,6 +1,4 @@ | ... | @@ -1,6 +1,4 @@ |
| 1 | import * as SqlClient from "effect/unstable/sql/SqlClient"; | 1 | import * as SqlClient from "effect/unstable/sql/SqlClient"; |
| 2 | import * as Effect from "effect/Effect"; | 2 | import * as Effect from "effect/Effect"; |
| 3 | 3 | ||
| 4 | export default Effect.gen(function* () { | 4 | export default Effect.asVoid(SqlClient.SqlClient); |
| 5 | yield* SqlClient.SqlClient; | ||
| 6 | }); |
apps/server/src/process/externalLauncher.ts+1-1| ... | @@ -257,7 +257,7 @@ export interface ExternalLauncherShape { | ... | @@ -257,7 +257,7 @@ export interface ExternalLauncherShape { |
| 257 | * ExternalLauncher - Service tag for browser/editor launch operations. | 257 | * ExternalLauncher - Service tag for browser/editor launch operations. |
| 258 | */ | 258 | */ |
| 259 | export class ExternalLauncher extends Context.Service<ExternalLauncher, ExternalLauncherShape>()( | 259 | export class ExternalLauncher extends Context.Service<ExternalLauncher, ExternalLauncherShape>()( |
| 260 | "t3/process/ExternalLauncher", | 260 | "t3/process/externalLauncher", |
| 261 | ) {} | 261 | ) {} |
| 262 | 262 | ||
| 263 | // ============================== | 263 | // ============================== |
apps/server/src/processRunner.ts+1-1| ... | @@ -90,7 +90,7 @@ export interface ProcessRunnerShape { | ... | @@ -90,7 +90,7 @@ export interface ProcessRunnerShape { |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | export class ProcessRunner extends Context.Service<ProcessRunner, ProcessRunnerShape>()( | 92 | export class ProcessRunner extends Context.Service<ProcessRunner, ProcessRunnerShape>()( |
| 93 | "t3/process/ProcessRunner", | 93 | "t3/processRunner", |
| 94 | ) {} | 94 | ) {} |
| 95 | 95 | ||
| 96 | const DEFAULT_TIMEOUT = "60 seconds"; | 96 | const DEFAULT_TIMEOUT = "60 seconds"; |
apps/server/src/project/Services/ProjectSetupScriptRunner.ts+1-1| ... | @@ -41,4 +41,4 @@ export interface ProjectSetupScriptRunnerShape { | ... | @@ -41,4 +41,4 @@ export interface ProjectSetupScriptRunnerShape { |
| 41 | export class ProjectSetupScriptRunner extends Context.Service< | 41 | export class ProjectSetupScriptRunner extends Context.Service< |
| 42 | ProjectSetupScriptRunner, | 42 | ProjectSetupScriptRunner, |
| 43 | ProjectSetupScriptRunnerShape | 43 | ProjectSetupScriptRunnerShape |
| 44 | >()("t3/project/ProjectSetupScriptRunner") {} | 44 | >()("t3/project/Services/ProjectSetupScriptRunner") {} |
apps/server/src/provider/Layers/ClaudeAdapter.test.ts+1-1| ... | @@ -42,7 +42,7 @@ const decodeClaudeSettings = Schema.decodeSync(ClaudeSettings); | ... | @@ -42,7 +42,7 @@ const decodeClaudeSettings = Schema.decodeSync(ClaudeSettings); |
| 42 | 42 | ||
| 43 | // Test-local service tag so the rest of the file can keep using `yield* ClaudeAdapter`. | 43 | // Test-local service tag so the rest of the file can keep using `yield* ClaudeAdapter`. |
| 44 | class ClaudeAdapter extends Context.Service<ClaudeAdapter, ClaudeAdapterShape>()( | 44 | class ClaudeAdapter extends Context.Service<ClaudeAdapter, ClaudeAdapterShape>()( |
| 45 | "test/ClaudeAdapter", | 45 | "t3/provider/Layers/ClaudeAdapter.test/ClaudeAdapter", |
| 46 | ) {} | 46 | ) {} |
| 47 | 47 | ||
| 48 | class FakeClaudeQuery implements AsyncIterable<SDKMessage> { | 48 | class FakeClaudeQuery implements AsyncIterable<SDKMessage> { |
apps/server/src/provider/Layers/CodexAdapter.test.ts+1-1| ... | @@ -50,7 +50,7 @@ const decodeCodexSettings = Schema.decodeSync(CodexSettings); | ... | @@ -50,7 +50,7 @@ const decodeCodexSettings = Schema.decodeSync(CodexSettings); |
| 50 | 50 | ||
| 51 | // Test-local service tag so the rest of the file can keep using `yield* CodexAdapter`. | 51 | // Test-local service tag so the rest of the file can keep using `yield* CodexAdapter`. |
| 52 | class CodexAdapter extends Context.Service<CodexAdapter, CodexAdapterShape>()( | 52 | class CodexAdapter extends Context.Service<CodexAdapter, CodexAdapterShape>()( |
| 53 | "test/CodexAdapter", | 53 | "t3/provider/Layers/CodexAdapter.test/CodexAdapter", |
| 54 | ) {} | 54 | ) {} |
| 55 | 55 | ||
| 56 | const asThreadId = (value: string): ThreadId => ThreadId.make(value); | 56 | const asThreadId = (value: string): ThreadId => ThreadId.make(value); |
apps/server/src/provider/Layers/CursorAdapter.test.ts+1-1| ... | @@ -32,7 +32,7 @@ const decodeCursorSettings = Schema.decodeSync(CursorSettings); | ... | @@ -32,7 +32,7 @@ const decodeCursorSettings = Schema.decodeSync(CursorSettings); |
| 32 | 32 | ||
| 33 | // Test-local service tag so the rest of the file can keep using `yield* CursorAdapter`. | 33 | // Test-local service tag so the rest of the file can keep using `yield* CursorAdapter`. |
| 34 | class CursorAdapter extends Context.Service<CursorAdapter, CursorAdapterShape>()( | 34 | class CursorAdapter extends Context.Service<CursorAdapter, CursorAdapterShape>()( |
| 35 | "test/CursorAdapter", | 35 | "t3/provider/Layers/CursorAdapter.test/CursorAdapter", |
| 36 | ) {} | 36 | ) {} |
| 37 | 37 | ||
| 38 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); | 38 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); |
apps/server/src/provider/Layers/CursorAdapter.ts+1-1| ... | @@ -97,7 +97,7 @@ export interface CursorAdapterLiveOptions { | ... | @@ -97,7 +97,7 @@ export interface CursorAdapterLiveOptions { |
| 97 | * Selections are honored when `modelSelection.instanceId` matches this value. | 97 | * Selections are honored when `modelSelection.instanceId` matches this value. |
| 98 | * Defaults to the legacy built-in instance id (`cursor`). | 98 | * Defaults to the legacy built-in instance id (`cursor`). |
| 99 | */ | 99 | */ |
| 100 | readonly instanceId?: typeof ProviderInstanceId.Type; | 100 | readonly instanceId?: ProviderInstanceId; |
| 101 | /** | 101 | /** |
| 102 | * Optional per-session settings resolver. When provided the adapter yields | 102 | * Optional per-session settings resolver. When provided the adapter yields |
| 103 | * this effect at the start of every session and uses the result instead of | 103 | * this effect at the start of every session and uses the result instead of |
apps/server/src/provider/Layers/EventNdjsonLogger.ts+9-20| ... | @@ -14,6 +14,7 @@ import { RotatingFileSink } from "@t3tools/shared/logging"; | ... | @@ -14,6 +14,7 @@ import { RotatingFileSink } from "@t3tools/shared/logging"; |
| 14 | import * as Effect from "effect/Effect"; | 14 | import * as Effect from "effect/Effect"; |
| 15 | import * as Exit from "effect/Exit"; | 15 | import * as Exit from "effect/Exit"; |
| 16 | import * as Logger from "effect/Logger"; | 16 | import * as Logger from "effect/Logger"; |
| 17 | import * as Schema from "effect/Schema"; | ||
| 17 | import * as Scope from "effect/Scope"; | 18 | import * as Scope from "effect/Scope"; |
| 18 | import * as SynchronizedRef from "effect/SynchronizedRef"; | 19 | import * as SynchronizedRef from "effect/SynchronizedRef"; |
| 19 | 20 | ||
| ... | @@ -24,6 +25,7 @@ const DEFAULT_MAX_FILES = 10; | ... | @@ -24,6 +25,7 @@ const DEFAULT_MAX_FILES = 10; |
| 24 | const DEFAULT_BATCH_WINDOW_MS = 200; | 25 | const DEFAULT_BATCH_WINDOW_MS = 200; |
| 25 | const GLOBAL_THREAD_SEGMENT = "_global"; | 26 | const GLOBAL_THREAD_SEGMENT = "_global"; |
| 26 | const LOG_SCOPE = "provider-observability"; | 27 | const LOG_SCOPE = "provider-observability"; |
| 28 | const encodeUnknownJsonString = Schema.encodeUnknownEffect(Schema.UnknownFromJsonString); | ||
| 27 | 29 | ||
| 28 | export type EventNdjsonStream = "native" | "canonical" | "orchestration"; | 30 | export type EventNdjsonStream = "native" | "canonical" | "orchestration"; |
| 29 | 31 | ||
| ... | @@ -87,26 +89,13 @@ function resolveStreamLabel(stream: EventNdjsonStream): string { | ... | @@ -87,26 +89,13 @@ function resolveStreamLabel(stream: EventNdjsonStream): string { |
| 87 | const toLogMessage = Effect.fn("toLogMessage")(function* ( | 89 | const toLogMessage = Effect.fn("toLogMessage")(function* ( |
| 88 | event: unknown, | 90 | event: unknown, |
| 89 | ): Effect.fn.Return<string | undefined> { | 91 | ): Effect.fn.Return<string | undefined> { |
| 90 | const serialized = yield* Effect.sync(() => { | 92 | return yield* encodeUnknownJsonString(event).pipe( |
| 91 | try { | 93 | Effect.catch((error) => |
| 92 | return { ok: true as const, value: JSON.stringify(event) }; | 94 | logWarning("failed to serialize provider event log record", { error }).pipe( |
| 93 | } catch (error) { | 95 | Effect.as(undefined), |
| 94 | return { ok: false as const, error }; | 96 | ), |
| 95 | } | 97 | ), |
| 96 | }); | 98 | ); |
| 97 | |||
| 98 | if (!serialized.ok) { | ||
| 99 | yield* logWarning("failed to serialize provider event log record", { | ||
| 100 | error: serialized.error, | ||
| 101 | }); | ||
| 102 | return undefined; | ||
| 103 | } | ||
| 104 | |||
| 105 | if (typeof serialized.value !== "string") { | ||
| 106 | return undefined; | ||
| 107 | } | ||
| 108 | |||
| 109 | return serialized.value; | ||
| 110 | }); | 99 | }); |
| 111 | 100 | ||
| 112 | const makeThreadWriter = Effect.fn("makeThreadWriter")(function* (input: { | 101 | const makeThreadWriter = Effect.fn("makeThreadWriter")(function* (input: { |
apps/server/src/provider/Layers/OpenCodeAdapter.test.ts+1-1| ... | @@ -37,7 +37,7 @@ import { | ... | @@ -37,7 +37,7 @@ import { |
| 37 | 37 | ||
| 38 | // Test-local service tag so the rest of the file can keep using `yield* OpenCodeAdapter`. | 38 | // Test-local service tag so the rest of the file can keep using `yield* OpenCodeAdapter`. |
| 39 | class OpenCodeAdapter extends Context.Service<OpenCodeAdapter, OpenCodeAdapterShape>()( | 39 | class OpenCodeAdapter extends Context.Service<OpenCodeAdapter, OpenCodeAdapterShape>()( |
| 40 | "test/OpenCodeAdapter", | 40 | "t3/provider/Layers/OpenCodeAdapter.test/OpenCodeAdapter", |
| 41 | ) {} | 41 | ) {} |
| 42 | 42 | ||
| 43 | const asThreadId = (value: string): ThreadId => ThreadId.make(value); | 43 | const asThreadId = (value: string): ThreadId => ThreadId.make(value); |
apps/server/src/provider/Layers/OpenCodeProvider.ts+19-29| ... | @@ -408,35 +408,25 @@ export const checkOpenCodeProviderStatus = Effect.fn("checkOpenCodeProviderStatu | ... | @@ -408,35 +408,25 @@ export const checkOpenCodeProviderStatus = Effect.fn("checkOpenCodeProviderStatu |
| 408 | const inventoryExit = yield* Effect.exit( | 408 | const inventoryExit = yield* Effect.exit( |
| 409 | Effect.scoped( | 409 | Effect.scoped( |
| 410 | Effect.gen(function* () { | 410 | Effect.gen(function* () { |
| 411 | const server = yield* openCodeRuntime | 411 | const server = yield* openCodeRuntime.connectToOpenCodeServer({ |
| 412 | .connectToOpenCodeServer({ | 412 | binaryPath: openCodeSettings.binaryPath, |
| 413 | binaryPath: openCodeSettings.binaryPath, | 413 | serverUrl: openCodeSettings.serverUrl, |
| 414 | serverUrl: openCodeSettings.serverUrl, | 414 | environment, |
| 415 | environment, | 415 | }); |
| 416 | }) | 416 | return yield* openCodeRuntime.loadOpenCodeInventory( |
| 417 | .pipe( | 417 | openCodeRuntime.createOpenCodeSdkClient({ |
| 418 | Effect.mapError( | 418 | baseUrl: server.url, |
| 419 | (cause) => | 419 | directory: cwd, |
| 420 | new OpenCodeProbeError({ cause, detail: openCodeRuntimeErrorDetail(cause) }), | 420 | ...(isExternalServer && openCodeSettings.serverPassword |
| 421 | ), | 421 | ? { serverPassword: openCodeSettings.serverPassword } |
| 422 | ); | 422 | : {}), |
| 423 | return yield* openCodeRuntime | 423 | }), |
| 424 | .loadOpenCodeInventory( | 424 | ); |
| 425 | openCodeRuntime.createOpenCodeSdkClient({ | 425 | }).pipe( |
| 426 | baseUrl: server.url, | 426 | Effect.mapError( |
| 427 | directory: cwd, | 427 | (cause) => new OpenCodeProbeError({ cause, detail: openCodeRuntimeErrorDetail(cause) }), |
| 428 | ...(isExternalServer && openCodeSettings.serverPassword | 428 | ), |
| 429 | ? { serverPassword: openCodeSettings.serverPassword } | 429 | ), |
| 430 | : {}), | ||
| 431 | }), | ||
| 432 | ) | ||
| 433 | .pipe( | ||
| 434 | Effect.mapError( | ||
| 435 | (cause) => | ||
| 436 | new OpenCodeProbeError({ cause, detail: openCodeRuntimeErrorDetail(cause) }), | ||
| 437 | ), | ||
| 438 | ); | ||
| 439 | }), | ||
| 440 | ), | 430 | ), |
| 441 | ); | 431 | ); |
| 442 | if (inventoryExit._tag === "Failure") { | 432 | if (inventoryExit._tag === "Failure") { |
apps/server/src/provider/Layers/ProviderEventLoggers.ts+1-1| ... | @@ -50,7 +50,7 @@ export interface ProviderEventLoggersShape { | ... | @@ -50,7 +50,7 @@ export interface ProviderEventLoggersShape { |
| 50 | export class ProviderEventLoggers extends Context.Service< | 50 | export class ProviderEventLoggers extends Context.Service< |
| 51 | ProviderEventLoggers, | 51 | ProviderEventLoggers, |
| 52 | ProviderEventLoggersShape | 52 | ProviderEventLoggersShape |
| 53 | >()("t3/provider/ProviderEventLoggers") {} | 53 | >()("t3/provider/Layers/ProviderEventLoggers") {} |
| 54 | 54 | ||
| 55 | /** | 55 | /** |
| 56 | * Constant value used by tests / boot layers that want to opt out of native | 56 | * Constant value used by tests / boot layers that want to opt out of native |
apps/server/src/provider/Layers/ProviderService.test.ts+2-6| ... | @@ -346,9 +346,7 @@ it.effect("ProviderServiceLive catches stopAll failures during shutdown", () => | ... | @@ -346,9 +346,7 @@ it.effect("ProviderServiceLive catches stopAll failures during shutdown", () => |
| 346 | const scope = yield* Scope.make(); | 346 | const scope = yield* Scope.make(); |
| 347 | const runtimeServices = yield* Layer.build(providerLayer).pipe(Scope.provide(scope)); | 347 | const runtimeServices = yield* Layer.build(providerLayer).pipe(Scope.provide(scope)); |
| 348 | 348 | ||
| 349 | yield* Effect.gen(function* () { | 349 | yield* ProviderService.pipe(Effect.provide(runtimeServices)); |
| 350 | yield* ProviderService; | ||
| 351 | }).pipe(Effect.provide(runtimeServices)); | ||
| 352 | const closeExit = yield* Scope.close(scope, Exit.void).pipe(Effect.exit); | 350 | const closeExit = yield* Scope.close(scope, Exit.void).pipe(Effect.exit); |
| 353 | 351 | ||
| 354 | assert.equal(Exit.isSuccess(closeExit), true); | 352 | assert.equal(Exit.isSuccess(closeExit), true); |
| ... | @@ -636,9 +634,7 @@ it.effect("ProviderServiceLive keeps persisted resumable sessions on startup", ( | ... | @@ -636,9 +634,7 @@ it.effect("ProviderServiceLive keeps persisted resumable sessions on startup", ( |
| 636 | Layer.provide(Layer.succeed(ProviderEventLoggers, NoOpProviderEventLoggers)), | 634 | Layer.provide(Layer.succeed(ProviderEventLoggers, NoOpProviderEventLoggers)), |
| 637 | ); | 635 | ); |
| 638 | 636 | ||
| 639 | yield* Effect.gen(function* () { | 637 | yield* ProviderService.pipe(Effect.provide(providerLayer)); |
| 640 | yield* ProviderService; | ||
| 641 | }).pipe(Effect.provide(providerLayer)); | ||
| 642 | 638 | ||
| 643 | const persistedProvider = yield* Effect.gen(function* () { | 639 | const persistedProvider = yield* Effect.gen(function* () { |
| 644 | const directory = yield* ProviderSessionDirectory; | 640 | const directory = yield* ProviderSessionDirectory; |
apps/server/src/provider/opencodeRuntime.ts+1-1| ... | @@ -544,7 +544,7 @@ const makeOpenCodeRuntime = Effect.gen(function* () { | ... | @@ -544,7 +544,7 @@ const makeOpenCodeRuntime = Effect.gen(function* () { |
| 544 | }); | 544 | }); |
| 545 | 545 | ||
| 546 | export class OpenCodeRuntime extends Context.Service<OpenCodeRuntime, OpenCodeRuntimeShape>()( | 546 | export class OpenCodeRuntime extends Context.Service<OpenCodeRuntime, OpenCodeRuntimeShape>()( |
| 547 | "t3/provider/OpenCodeRuntime", | 547 | "t3/provider/opencodeRuntime", |
| 548 | ) {} | 548 | ) {} |
| 549 | 549 | ||
| 550 | export const OpenCodeRuntimeLive = Layer.effect(OpenCodeRuntime, makeOpenCodeRuntime).pipe( | 550 | export const OpenCodeRuntimeLive = Layer.effect(OpenCodeRuntime, makeOpenCodeRuntime).pipe( |
apps/server/src/provider/providerMaintenanceRunner.ts+1-1| ... | @@ -53,7 +53,7 @@ export interface ProviderMaintenanceRunnerShape { | ... | @@ -53,7 +53,7 @@ export interface ProviderMaintenanceRunnerShape { |
| 53 | export class ProviderMaintenanceRunner extends Context.Service< | 53 | export class ProviderMaintenanceRunner extends Context.Service< |
| 54 | ProviderMaintenanceRunner, | 54 | ProviderMaintenanceRunner, |
| 55 | ProviderMaintenanceRunnerShape | 55 | ProviderMaintenanceRunnerShape |
| 56 | >()("t3/provider/ProviderMaintenanceRunner") {} | 56 | >()("t3/provider/providerMaintenanceRunner") {} |
| 57 | 57 | ||
| 58 | class ProviderMaintenanceCommandError extends Data.TaggedError("ProviderMaintenanceCommandError")<{ | 58 | class ProviderMaintenanceCommandError extends Data.TaggedError("ProviderMaintenanceCommandError")<{ |
| 59 | readonly message: string; | 59 | readonly message: string; |
apps/server/src/server.test.ts+126-221| ... | @@ -40,6 +40,7 @@ import * as Path from "effect/Path"; | ... | @@ -40,6 +40,7 @@ import * as Path from "effect/Path"; |
| 40 | import * as Stream from "effect/Stream"; | 40 | import * as Stream from "effect/Stream"; |
| 41 | import { ChildProcessSpawner } from "effect/unstable/process"; | 41 | import { ChildProcessSpawner } from "effect/unstable/process"; |
| 42 | import { | 42 | import { |
| 43 | Cookies, | ||
| 43 | FetchHttpClient, | 44 | FetchHttpClient, |
| 44 | HttpBody, | 45 | HttpBody, |
| 45 | HttpClient, | 46 | HttpClient, |
| ... | @@ -780,13 +781,6 @@ const appendSessionCookieToWsUrl = (url: string, sessionCookieHeader: string) => | ... | @@ -780,13 +781,6 @@ const appendSessionCookieToWsUrl = (url: string, sessionCookieHeader: string) => |
| 780 | return isAbsoluteUrl ? next.toString() : `${next.pathname}${next.search}${next.hash}`; | 781 | return isAbsoluteUrl ? next.toString() : `${next.pathname}${next.search}${next.hash}`; |
| 781 | }; | 782 | }; |
| 782 | 783 | ||
| 783 | const getHttpServerUrl = (pathname = "") => | ||
| 784 | Effect.gen(function* () { | ||
| 785 | const server = yield* HttpServer.HttpServer; | ||
| 786 | const address = server.address as HttpServer.TcpAddress; | ||
| 787 | return `http://127.0.0.1:${address.port}${pathname}`; | ||
| 788 | }); | ||
| 789 | |||
| 790 | const bootstrapBrowserSession = ( | 784 | const bootstrapBrowserSession = ( |
| 791 | credential = defaultDesktopBootstrapToken, | 785 | credential = defaultDesktopBootstrapToken, |
| 792 | options?: { | 786 | options?: { |
| ... | @@ -794,20 +788,11 @@ const bootstrapBrowserSession = ( | ... | @@ -794,20 +788,11 @@ const bootstrapBrowserSession = ( |
| 794 | }, | 788 | }, |
| 795 | ) => | 789 | ) => |
| 796 | Effect.gen(function* () { | 790 | Effect.gen(function* () { |
| 797 | const bootstrapUrl = yield* getHttpServerUrl("/api/auth/bootstrap"); | 791 | const response = yield* HttpClient.post("/api/auth/bootstrap", { |
| 798 | const response = yield* Effect.promise(() => | 792 | headers: options?.headers, |
| 799 | fetch(bootstrapUrl, { | 793 | body: yield* HttpBody.json({ credential }), |
| 800 | method: "POST", | 794 | }); |
| 801 | headers: { | 795 | const body = (yield* response.json) as { |
| 802 | "content-type": "application/json", | ||
| 803 | ...options?.headers, | ||
| 804 | }, | ||
| 805 | body: JSON.stringify({ | ||
| 806 | credential, | ||
| 807 | }), | ||
| 808 | }), | ||
| 809 | ); | ||
| 810 | const body = (yield* Effect.promise(() => response.json())) as { | ||
| 811 | readonly authenticated: boolean; | 796 | readonly authenticated: boolean; |
| 812 | readonly sessionMethod: string; | 797 | readonly sessionMethod: string; |
| 813 | readonly expiresAt: string; | 798 | readonly expiresAt: string; |
| ... | @@ -815,7 +800,7 @@ const bootstrapBrowserSession = ( | ... | @@ -815,7 +800,7 @@ const bootstrapBrowserSession = ( |
| 815 | return { | 800 | return { |
| 816 | response, | 801 | response, |
| 817 | body, | 802 | body, |
| 818 | cookie: response.headers.get("set-cookie"), | 803 | cookie: Cookies.toSetCookieHeaders(response.cookies)[0] ?? null, |
| 819 | }; | 804 | }; |
| 820 | }); | 805 | }); |
| 821 | 806 | ||
| ... | @@ -826,20 +811,11 @@ const bootstrapBearerSession = ( | ... | @@ -826,20 +811,11 @@ const bootstrapBearerSession = ( |
| 826 | }, | 811 | }, |
| 827 | ) => | 812 | ) => |
| 828 | Effect.gen(function* () { | 813 | Effect.gen(function* () { |
| 829 | const bootstrapUrl = yield* getHttpServerUrl("/api/auth/bootstrap/bearer"); | 814 | const response = yield* HttpClient.post("/api/auth/bootstrap/bearer", { |
| 830 | const response = yield* Effect.promise(() => | 815 | headers: options?.headers, |
| 831 | fetch(bootstrapUrl, { | 816 | body: yield* HttpBody.json({ credential }), |
| 832 | method: "POST", | 817 | }); |
| 833 | headers: { | 818 | const body = (yield* response.json) as { |
| 834 | "content-type": "application/json", | ||
| 835 | ...options?.headers, | ||
| 836 | }, | ||
| 837 | body: JSON.stringify({ | ||
| 838 | credential, | ||
| 839 | }), | ||
| 840 | }), | ||
| 841 | ); | ||
| 842 | const body = (yield* Effect.promise(() => response.json())) as { | ||
| 843 | readonly authenticated: boolean; | 819 | readonly authenticated: boolean; |
| 844 | readonly sessionMethod: string; | 820 | readonly sessionMethod: string; |
| 845 | readonly expiresAt: string; | 821 | readonly expiresAt: string; |
| ... | @@ -859,7 +835,7 @@ class AuthenticationGetterError extends Data.TaggedError("AuthenticationGetterEr | ... | @@ -859,7 +835,7 @@ class AuthenticationGetterError extends Data.TaggedError("AuthenticationGetterEr |
| 859 | const getAuthenticatedSessionCookieHeader = (credential = defaultDesktopBootstrapToken) => | 835 | const getAuthenticatedSessionCookieHeader = (credential = defaultDesktopBootstrapToken) => |
| 860 | Effect.gen(function* () { | 836 | Effect.gen(function* () { |
| 861 | const { response, cookie } = yield* bootstrapBrowserSession(credential); | 837 | const { response, cookie } = yield* bootstrapBrowserSession(credential); |
| 862 | if (!response.ok) { | 838 | if (response.status !== 200) { |
| 863 | return yield* new AuthenticationGetterError({ | 839 | return yield* new AuthenticationGetterError({ |
| 864 | message: `Expected bootstrap session response to succeed, got ${response.status}`, | 840 | message: `Expected bootstrap session response to succeed, got ${response.status}`, |
| 865 | }); | 841 | }); |
| ... | @@ -877,7 +853,7 @@ const getAuthenticatedSessionCookieHeader = (credential = defaultDesktopBootstra | ... | @@ -877,7 +853,7 @@ const getAuthenticatedSessionCookieHeader = (credential = defaultDesktopBootstra |
| 877 | const getAuthenticatedBearerSessionToken = (credential = defaultDesktopBootstrapToken) => | 853 | const getAuthenticatedBearerSessionToken = (credential = defaultDesktopBootstrapToken) => |
| 878 | Effect.gen(function* () { | 854 | Effect.gen(function* () { |
| 879 | const { response, body } = yield* bootstrapBearerSession(credential); | 855 | const { response, body } = yield* bootstrapBearerSession(credential); |
| 880 | if (!response.ok) { | 856 | if (response.status !== 200) { |
| 881 | return yield* new AuthenticationGetterError({ | 857 | return yield* new AuthenticationGetterError({ |
| 882 | message: `Expected bearer bootstrap response to succeed, got ${response.status}`, | 858 | message: `Expected bearer bootstrap response to succeed, got ${response.status}`, |
| 883 | }); | 859 | }); |
| ... | @@ -908,14 +884,14 @@ const splitHeaderTokens = (value: string | null) => | ... | @@ -908,14 +884,14 @@ const splitHeaderTokens = (value: string | null) => |
| 908 | .filter((token) => token.length > 0) | 884 | .filter((token) => token.length > 0) |
| 909 | .toSorted(); | 885 | .toSorted(); |
| 910 | 886 | ||
| 911 | const assertBrowserApiCorsHeaders = (headers: Headers) => { | 887 | const assertBrowserApiCorsHeaders = (headers: Readonly<Record<string, string | undefined>>) => { |
| 912 | assert.equal(headers.get("access-control-allow-origin"), "*"); | 888 | assert.equal(headers["access-control-allow-origin"], "*"); |
| 913 | assert.deepEqual(splitHeaderTokens(headers.get("access-control-allow-methods")), [ | 889 | assert.deepEqual(splitHeaderTokens(headers["access-control-allow-methods"] ?? null), [ |
| 914 | "GET", | 890 | "GET", |
| 915 | "OPTIONS", | 891 | "OPTIONS", |
| 916 | "POST", | 892 | "POST", |
| 917 | ]); | 893 | ]); |
| 918 | assert.deepEqual(splitHeaderTokens(headers.get("access-control-allow-headers")), [ | 894 | assert.deepEqual(splitHeaderTokens(headers["access-control-allow-headers"] ?? null), [ |
| 919 | "authorization", | 895 | "authorization", |
| 920 | "b3", | 896 | "b3", |
| 921 | "content-type", | 897 | "content-type", |
| ... | @@ -964,14 +940,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -964,14 +940,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 964 | config: { devUrl: new URL("http://127.0.0.1:5173") }, | 940 | config: { devUrl: new URL("http://127.0.0.1:5173") }, |
| 965 | }); | 941 | }); |
| 966 | 942 | ||
| 967 | const url = yield* getHttpServerUrl("/foo/bar?token=test-token"); | 943 | const response = yield* HttpClient.get("/foo/bar?token=test-token").pipe( |
| 968 | const response = yield* Effect.promise(() => fetch(url, { redirect: "manual" })); | 944 | Effect.provideService(FetchHttpClient.RequestInit, { redirect: "manual" }), |
| 945 | ); | ||
| 969 | 946 | ||
| 970 | assert.equal(response.status, 302); | 947 | assert.equal(response.status, 302); |
| 971 | assert.equal( | 948 | assert.equal(response.headers.location, "http://127.0.0.1:5173/foo/bar?token=test-token"); |
| 972 | response.headers.get("location"), | ||
| 973 | "http://127.0.0.1:5173/foo/bar?token=test-token", | ||
| 974 | ); | ||
| 975 | }).pipe(Effect.provide(NodeHttpServer.layerTest)), | 949 | }).pipe(Effect.provide(NodeHttpServer.layerTest)), |
| 976 | ); | 950 | ); |
| 977 | 951 | ||
| ... | @@ -1034,11 +1008,8 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1034,11 +1008,8 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1034 | Effect.gen(function* () { | 1008 | Effect.gen(function* () { |
| 1035 | yield* buildAppUnderTest(); | 1009 | yield* buildAppUnderTest(); |
| 1036 | 1010 | ||
| 1037 | const url = yield* getHttpServerUrl("/.well-known/t3/environment"); | 1011 | const response = yield* HttpClient.get("/.well-known/t3/environment"); |
| 1038 | const response = yield* Effect.promise(() => fetch(url)); | 1012 | const body = (yield* response.json) as typeof testEnvironmentDescriptor; |
| 1039 | const body = (yield* Effect.promise(() => | ||
| 1040 | response.json(), | ||
| 1041 | )) as typeof testEnvironmentDescriptor; | ||
| 1042 | 1013 | ||
| 1043 | assert.equal(response.status, 200); | 1014 | assert.equal(response.status, 200); |
| 1044 | assert.deepEqual(body, testEnvironmentDescriptor); | 1015 | assert.deepEqual(body, testEnvironmentDescriptor); |
| ... | @@ -1049,17 +1020,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1049,17 +1020,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1049 | Effect.gen(function* () { | 1020 | Effect.gen(function* () { |
| 1050 | yield* buildAppUnderTest(); | 1021 | yield* buildAppUnderTest(); |
| 1051 | 1022 | ||
| 1052 | const url = yield* getHttpServerUrl("/.well-known/t3/environment"); | 1023 | const response = yield* HttpClient.get("/.well-known/t3/environment", { |
| 1053 | const response = yield* Effect.promise(() => | 1024 | headers: { |
| 1054 | fetch(url, { | 1025 | origin: crossOriginClientOrigin, |
| 1055 | headers: { | 1026 | }, |
| 1056 | origin: crossOriginClientOrigin, | 1027 | }); |
| 1057 | }, | 1028 | const body = (yield* response.json) as typeof testEnvironmentDescriptor; |
| 1058 | }), | ||
| 1059 | ); | ||
| 1060 | const body = (yield* Effect.promise(() => | ||
| 1061 | response.json(), | ||
| 1062 | )) as typeof testEnvironmentDescriptor; | ||
| 1063 | 1029 | ||
| 1064 | assert.equal(response.status, 200); | 1030 | assert.equal(response.status, 200); |
| 1065 | assertBrowserApiCorsHeaders(response.headers); | 1031 | assertBrowserApiCorsHeaders(response.headers); |
| ... | @@ -1071,9 +1037,8 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1071,9 +1037,8 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1071 | Effect.gen(function* () { | 1037 | Effect.gen(function* () { |
| 1072 | yield* buildAppUnderTest(); | 1038 | yield* buildAppUnderTest(); |
| 1073 | 1039 | ||
| 1074 | const url = yield* getHttpServerUrl("/api/auth/session"); | 1040 | const response = yield* HttpClient.get("/api/auth/session"); |
| 1075 | const response = yield* Effect.promise(() => fetch(url)); | 1041 | const body = (yield* response.json) as { |
| 1076 | const body = (yield* Effect.promise(() => response.json())) as { | ||
| 1077 | readonly authenticated: boolean; | 1042 | readonly authenticated: boolean; |
| 1078 | readonly auth: { | 1043 | readonly auth: { |
| 1079 | readonly policy: string; | 1044 | readonly policy: string; |
| ... | @@ -1111,15 +1076,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1111,15 +1076,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1111 | assert.isUndefined((bootstrapBody as { readonly sessionToken?: string }).sessionToken); | 1076 | assert.isUndefined((bootstrapBody as { readonly sessionToken?: string }).sessionToken); |
| 1112 | assert.isDefined(setCookie); | 1077 | assert.isDefined(setCookie); |
| 1113 | 1078 | ||
| 1114 | const sessionUrl = yield* getHttpServerUrl("/api/auth/session"); | 1079 | const sessionResponse = yield* HttpClient.get("/api/auth/session", { |
| 1115 | const sessionResponse = yield* Effect.promise(() => | 1080 | headers: { |
| 1116 | fetch(sessionUrl, { | 1081 | cookie: setCookie?.split(";")[0] ?? "", |
| 1117 | headers: { | 1082 | }, |
| 1118 | cookie: setCookie?.split(";")[0] ?? "", | 1083 | }); |
| 1119 | }, | 1084 | const sessionBody = (yield* sessionResponse.json) as { |
| 1120 | }), | ||
| 1121 | ); | ||
| 1122 | const sessionBody = (yield* Effect.promise(() => sessionResponse.json())) as { | ||
| 1123 | readonly authenticated: boolean; | 1085 | readonly authenticated: boolean; |
| 1124 | readonly sessionMethod?: string; | 1086 | readonly sessionMethod?: string; |
| 1125 | }; | 1087 | }; |
| ... | @@ -1145,15 +1107,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1145,15 +1107,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1145 | assert.equal(typeof bootstrapBody.sessionToken, "string"); | 1107 | assert.equal(typeof bootstrapBody.sessionToken, "string"); |
| 1146 | assert.isTrue((bootstrapBody.sessionToken?.length ?? 0) > 0); | 1108 | assert.isTrue((bootstrapBody.sessionToken?.length ?? 0) > 0); |
| 1147 | 1109 | ||
| 1148 | const sessionUrl = yield* getHttpServerUrl("/api/auth/session"); | 1110 | const sessionResponse = yield* HttpClient.get("/api/auth/session", { |
| 1149 | const sessionResponse = yield* Effect.promise(() => | 1111 | headers: { |
| 1150 | fetch(sessionUrl, { | 1112 | authorization: `Bearer ${bootstrapBody.sessionToken ?? ""}`, |
| 1151 | headers: { | 1113 | }, |
| 1152 | authorization: `Bearer ${bootstrapBody.sessionToken ?? ""}`, | 1114 | }); |
| 1153 | }, | 1115 | const sessionBody = (yield* sessionResponse.json) as { |
| 1154 | }), | ||
| 1155 | ); | ||
| 1156 | const sessionBody = (yield* Effect.promise(() => sessionResponse.json())) as { | ||
| 1157 | readonly authenticated: boolean; | 1116 | readonly authenticated: boolean; |
| 1158 | readonly sessionMethod?: string; | 1117 | readonly sessionMethod?: string; |
| 1159 | }; | 1118 | }; |
| ... | @@ -1169,16 +1128,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1169,16 +1128,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1169 | yield* buildAppUnderTest(); | 1128 | yield* buildAppUnderTest(); |
| 1170 | 1129 | ||
| 1171 | const bearerToken = yield* getAuthenticatedBearerSessionToken(); | 1130 | const bearerToken = yield* getAuthenticatedBearerSessionToken(); |
| 1172 | const wsTokenUrl = yield* getHttpServerUrl("/api/auth/ws-token"); | 1131 | const wsTokenResponse = yield* HttpClient.post("/api/auth/ws-token", { |
| 1173 | const wsTokenResponse = yield* Effect.promise(() => | 1132 | headers: { |
| 1174 | fetch(wsTokenUrl, { | 1133 | authorization: `Bearer ${bearerToken}`, |
| 1175 | method: "POST", | 1134 | }, |
| 1176 | headers: { | 1135 | }); |
| 1177 | authorization: `Bearer ${bearerToken}`, | 1136 | const wsTokenBody = (yield* wsTokenResponse.json) as { |
| 1178 | }, | ||
| 1179 | }), | ||
| 1180 | ); | ||
| 1181 | const wsTokenBody = (yield* Effect.promise(() => wsTokenResponse.json())) as { | ||
| 1182 | readonly token: string; | 1137 | readonly token: string; |
| 1183 | readonly expiresAt: string; | 1138 | readonly expiresAt: string; |
| 1184 | }; | 1139 | }; |
| ... | @@ -1207,16 +1162,13 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1207,16 +1162,13 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1207 | assert.equal(bootstrapBody.authenticated, true); | 1162 | assert.equal(bootstrapBody.authenticated, true); |
| 1208 | assert.equal(typeof bootstrapBody.sessionToken, "string"); | 1163 | assert.equal(typeof bootstrapBody.sessionToken, "string"); |
| 1209 | 1164 | ||
| 1210 | const sessionUrl = yield* getHttpServerUrl("/api/auth/session"); | 1165 | const sessionResponse = yield* HttpClient.get("/api/auth/session", { |
| 1211 | const sessionResponse = yield* Effect.promise(() => | 1166 | headers: { |
| 1212 | fetch(sessionUrl, { | 1167 | authorization: `Bearer ${bootstrapBody.sessionToken ?? ""}`, |
| 1213 | headers: { | 1168 | origin, |
| 1214 | authorization: `Bearer ${bootstrapBody.sessionToken ?? ""}`, | 1169 | }, |
| 1215 | origin, | 1170 | }); |
| 1216 | }, | 1171 | const sessionBody = (yield* sessionResponse.json) as { |
| 1217 | }), | ||
| 1218 | ); | ||
| 1219 | const sessionBody = (yield* Effect.promise(() => sessionResponse.json())) as { | ||
| 1220 | readonly authenticated: boolean; | 1172 | readonly authenticated: boolean; |
| 1221 | readonly sessionMethod?: string; | 1173 | readonly sessionMethod?: string; |
| 1222 | }; | 1174 | }; |
| ... | @@ -1226,17 +1178,13 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1226,17 +1178,13 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1226 | assert.equal(sessionBody.authenticated, true); | 1178 | assert.equal(sessionBody.authenticated, true); |
| 1227 | assert.equal(sessionBody.sessionMethod, "bearer-session-token"); | 1179 | assert.equal(sessionBody.sessionMethod, "bearer-session-token"); |
| 1228 | 1180 | ||
| 1229 | const wsTokenUrl = yield* getHttpServerUrl("/api/auth/ws-token"); | 1181 | const wsTokenResponse = yield* HttpClient.post("/api/auth/ws-token", { |
| 1230 | const wsTokenResponse = yield* Effect.promise(() => | 1182 | headers: { |
| 1231 | fetch(wsTokenUrl, { | 1183 | authorization: `Bearer ${bootstrapBody.sessionToken ?? ""}`, |
| 1232 | method: "POST", | 1184 | origin, |
| 1233 | headers: { | 1185 | }, |
| 1234 | authorization: `Bearer ${bootstrapBody.sessionToken ?? ""}`, | 1186 | }); |
| 1235 | origin, | 1187 | const wsTokenBody = (yield* wsTokenResponse.json) as { |
| 1236 | }, | ||
| 1237 | }), | ||
| 1238 | ); | ||
| 1239 | const wsTokenBody = (yield* Effect.promise(() => wsTokenResponse.json())) as { | ||
| 1240 | readonly token: string; | 1188 | readonly token: string; |
| 1241 | }; | 1189 | }; |
| 1242 | 1190 | ||
| ... | @@ -1252,17 +1200,13 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1252,17 +1200,13 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1252 | Effect.gen(function* () { | 1200 | Effect.gen(function* () { |
| 1253 | yield* buildAppUnderTest(); | 1201 | yield* buildAppUnderTest(); |
| 1254 | 1202 | ||
| 1255 | const wsTokenUrl = yield* getHttpServerUrl("/api/auth/ws-token"); | 1203 | const response = yield* HttpClient.options("/api/auth/ws-token", { |
| 1256 | const response = yield* Effect.promise(() => | 1204 | headers: { |
| 1257 | fetch(wsTokenUrl, { | 1205 | origin: crossOriginClientOrigin, |
| 1258 | method: "OPTIONS", | 1206 | "access-control-request-method": "POST", |
| 1259 | headers: { | 1207 | "access-control-request-headers": "authorization", |
| 1260 | origin: crossOriginClientOrigin, | 1208 | }, |
| 1261 | "access-control-request-method": "POST", | 1209 | }); |
| 1262 | "access-control-request-headers": "authorization", | ||
| 1263 | }, | ||
| 1264 | }), | ||
| 1265 | ); | ||
| 1266 | 1210 | ||
| 1267 | assert.equal(response.status, 204); | 1211 | assert.equal(response.status, 204); |
| 1268 | assertBrowserApiCorsHeaders(response.headers); | 1212 | assertBrowserApiCorsHeaders(response.headers); |
| ... | @@ -1273,16 +1217,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1273,16 +1217,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1273 | Effect.gen(function* () { | 1217 | Effect.gen(function* () { |
| 1274 | yield* buildAppUnderTest(); | 1218 | yield* buildAppUnderTest(); |
| 1275 | 1219 | ||
| 1276 | const wsTokenUrl = yield* getHttpServerUrl("/api/auth/ws-token"); | 1220 | const response = yield* HttpClient.post("/api/auth/ws-token", { |
| 1277 | const response = yield* Effect.promise(() => | 1221 | headers: { |
| 1278 | fetch(wsTokenUrl, { | 1222 | origin: crossOriginClientOrigin, |
| 1279 | method: "POST", | 1223 | }, |
| 1280 | headers: { | 1224 | }); |
| 1281 | origin: crossOriginClientOrigin, | 1225 | const body = (yield* response.json) as { |
| 1282 | }, | ||
| 1283 | }), | ||
| 1284 | ); | ||
| 1285 | const body = (yield* Effect.promise(() => response.json())) as { | ||
| 1286 | readonly error?: string; | 1226 | readonly error?: string; |
| 1287 | }; | 1227 | }; |
| 1288 | 1228 | ||
| ... | @@ -1357,17 +1297,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1357,17 +1297,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1357 | readonly credential: string; | 1297 | readonly credential: string; |
| 1358 | }>; | 1298 | }>; |
| 1359 | 1299 | ||
| 1360 | const revokeUrl = yield* getHttpServerUrl("/api/auth/pairing-links/revoke"); | 1300 | const revokeResponse = yield* HttpClient.post("/api/auth/pairing-links/revoke", { |
| 1361 | const revokeResponse = yield* Effect.promise(() => | 1301 | headers: { |
| 1362 | fetch(revokeUrl, { | 1302 | cookie: ownerCookie, |
| 1363 | method: "POST", | 1303 | }, |
| 1364 | headers: { | 1304 | body: yield* HttpBody.json({ id: createdBody.id }), |
| 1365 | cookie: ownerCookie, | 1305 | }); |
| 1366 | "content-type": "application/json", | ||
| 1367 | }, | ||
| 1368 | body: JSON.stringify({ id: createdBody.id }), | ||
| 1369 | }), | ||
| 1370 | ); | ||
| 1371 | const revokedBootstrap = yield* bootstrapBrowserSession(createdBody.credential); | 1306 | const revokedBootstrap = yield* bootstrapBrowserSession(createdBody.credential); |
| 1372 | 1307 | ||
| 1373 | assert.equal(createdResponse.status, 200); | 1308 | assert.equal(createdResponse.status, 200); |
| ... | @@ -1420,20 +1355,13 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1420,20 +1355,13 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1420 | }); | 1355 | }); |
| 1421 | 1356 | ||
| 1422 | const ownerCookie = yield* getAuthenticatedSessionCookieHeader(); | 1357 | const ownerCookie = yield* getAuthenticatedSessionCookieHeader(); |
| 1423 | const pairingTokenUrl = yield* getHttpServerUrl("/api/auth/pairing-token"); | 1358 | const ownerPairingResponse = yield* HttpClient.post("/api/auth/pairing-token", { |
| 1424 | const ownerPairingResponse = yield* Effect.promise(() => | 1359 | headers: { |
| 1425 | fetch(pairingTokenUrl, { | 1360 | cookie: ownerCookie, |
| 1426 | method: "POST", | 1361 | }, |
| 1427 | headers: { | 1362 | body: yield* HttpBody.json({ label: "Julius iPhone" }), |
| 1428 | cookie: ownerCookie, | 1363 | }); |
| 1429 | "content-type": "application/json", | 1364 | const ownerPairingBody = (yield* ownerPairingResponse.json) as { |
| 1430 | }, | ||
| 1431 | body: JSON.stringify({ | ||
| 1432 | label: "Julius iPhone", | ||
| 1433 | }), | ||
| 1434 | }), | ||
| 1435 | ); | ||
| 1436 | const ownerPairingBody = (yield* Effect.promise(() => ownerPairingResponse.json())) as { | ||
| 1437 | readonly credential: string; | 1365 | readonly credential: string; |
| 1438 | readonly label?: string; | 1366 | readonly label?: string; |
| 1439 | }; | 1367 | }; |
| ... | @@ -1448,17 +1376,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1448,17 +1376,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1448 | assert.isDefined(pairedSessionCookie); | 1376 | assert.isDefined(pairedSessionCookie); |
| 1449 | 1377 | ||
| 1450 | const pairedSessionCookieHeader = pairedSessionCookie ?? ""; | 1378 | const pairedSessionCookieHeader = pairedSessionCookie ?? ""; |
| 1451 | const listClientsUrl = yield* getHttpServerUrl("/api/auth/clients"); | 1379 | const listBeforeResponse = yield* HttpClient.get("/api/auth/clients", { |
| 1452 | const listBeforeResponse = yield* Effect.promise(() => | 1380 | headers: { |
| 1453 | fetch(listClientsUrl, { | 1381 | cookie: ownerCookie, |
| 1454 | headers: { | 1382 | }, |
| 1455 | cookie: ownerCookie, | 1383 | }); |
| 1456 | }, | 1384 | const clientsBefore = (yield* listBeforeResponse.json) as ReadonlyArray<{ |
| 1457 | }), | ||
| 1458 | ); | ||
| 1459 | const clientsBefore = (yield* Effect.promise(() => | ||
| 1460 | listBeforeResponse.json(), | ||
| 1461 | )) as ReadonlyArray<{ | ||
| 1462 | readonly sessionId: string; | 1385 | readonly sessionId: string; |
| 1463 | readonly current: boolean; | 1386 | readonly current: boolean; |
| 1464 | readonly client: { | 1387 | readonly client: { |
| ... | @@ -1555,17 +1478,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1555,17 +1478,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1555 | const pairedSessionId = clients.find((entry) => !entry.current)?.sessionId; | 1478 | const pairedSessionId = clients.find((entry) => !entry.current)?.sessionId; |
| 1556 | assert.isDefined(pairedSessionId); | 1479 | assert.isDefined(pairedSessionId); |
| 1557 | 1480 | ||
| 1558 | const revokeUrl = yield* getHttpServerUrl("/api/auth/clients/revoke"); | 1481 | const revokeResponse = yield* HttpClient.post("/api/auth/clients/revoke", { |
| 1559 | const revokeResponse = yield* Effect.promise(() => | 1482 | headers: { |
| 1560 | fetch(revokeUrl, { | 1483 | cookie: ownerCookie, |
| 1561 | method: "POST", | 1484 | }, |
| 1562 | headers: { | 1485 | body: yield* HttpBody.json({ sessionId: pairedSessionId }), |
| 1563 | cookie: ownerCookie, | 1486 | }); |
| 1564 | "content-type": "application/json", | ||
| 1565 | }, | ||
| 1566 | body: JSON.stringify({ sessionId: pairedSessionId }), | ||
| 1567 | }), | ||
| 1568 | ); | ||
| 1569 | const pairedClientPairingResponse = yield* HttpClient.post("/api/auth/pairing-token", { | 1487 | const pairedClientPairingResponse = yield* HttpClient.post("/api/auth/pairing-token", { |
| 1570 | headers: { | 1488 | headers: { |
| 1571 | cookie: pairedSessionCookie, | 1489 | cookie: pairedSessionCookie, |
| ... | @@ -1665,16 +1583,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1665,16 +1583,12 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1665 | yield* buildAppUnderTest(); | 1583 | yield* buildAppUnderTest(); |
| 1666 | 1584 | ||
| 1667 | const bearerToken = yield* getAuthenticatedBearerSessionToken(); | 1585 | const bearerToken = yield* getAuthenticatedBearerSessionToken(); |
| 1668 | const wsTokenUrl = yield* getHttpServerUrl("/api/auth/ws-token"); | 1586 | const wsTokenResponse = yield* HttpClient.post("/api/auth/ws-token", { |
| 1669 | const wsTokenResponse = yield* Effect.promise(() => | 1587 | headers: { |
| 1670 | fetch(wsTokenUrl, { | 1588 | authorization: `Bearer ${bearerToken}`, |
| 1671 | method: "POST", | 1589 | }, |
| 1672 | headers: { | 1590 | }); |
| 1673 | authorization: `Bearer ${bearerToken}`, | 1591 | const wsTokenBody = (yield* wsTokenResponse.json) as { |
| 1674 | }, | ||
| 1675 | }), | ||
| 1676 | ); | ||
| 1677 | const wsTokenBody = (yield* Effect.promise(() => wsTokenResponse.json())) as { | ||
| 1678 | readonly token: string; | 1592 | readonly token: string; |
| 1679 | }; | 1593 | }; |
| 1680 | const wsUrl = `${yield* getWsServerUrl("/ws", { authenticated: false })}?wsToken=${encodeURIComponent(wsTokenBody.token)}`; | 1594 | const wsUrl = `${yield* getWsServerUrl("/ws", { authenticated: false })}?wsToken=${encodeURIComponent(wsTokenBody.token)}`; |
| ... | @@ -1876,8 +1790,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1876,8 +1790,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1876 | "content-type": "application/json", | 1790 | "content-type": "application/json", |
| 1877 | origin: "http://localhost:5733", | 1791 | origin: "http://localhost:5733", |
| 1878 | }, | 1792 | }, |
| 1879 | // @effect-diagnostics-next-line preferSchemaOverJson:off | 1793 | body: yield* HttpBody.json(payload), |
| 1880 | body: HttpBody.text(JSON.stringify(payload), "application/json"), | ||
| 1881 | }); | 1794 | }); |
| 1882 | 1795 | ||
| 1883 | assert.equal(response.status, 204); | 1796 | assert.equal(response.status, 204); |
| ... | @@ -1934,31 +1847,24 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1934,31 +1847,24 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1934 | Effect.gen(function* () { | 1847 | Effect.gen(function* () { |
| 1935 | yield* buildAppUnderTest(); | 1848 | yield* buildAppUnderTest(); |
| 1936 | 1849 | ||
| 1937 | const url = yield* getHttpServerUrl("/api/observability/v1/traces"); | 1850 | const response = yield* HttpClient.options("/api/observability/v1/traces", { |
| 1938 | const response = yield* Effect.promise(() => | 1851 | headers: { |
| 1939 | fetch(url, { | 1852 | origin: "http://localhost:5733", |
| 1940 | method: "OPTIONS", | 1853 | "access-control-request-method": "POST", |
| 1941 | headers: { | 1854 | "access-control-request-headers": "content-type", |
| 1942 | origin: "http://localhost:5733", | 1855 | }, |
| 1943 | "access-control-request-method": "POST", | 1856 | }); |
| 1944 | "access-control-request-headers": "content-type", | ||
| 1945 | }, | ||
| 1946 | }), | ||
| 1947 | ); | ||
| 1948 | 1857 | ||
| 1949 | assert.equal(response.status, 204); | 1858 | assert.equal(response.status, 204); |
| 1950 | assert.equal(response.headers.get("access-control-allow-origin"), "*"); | 1859 | assert.equal(response.headers["access-control-allow-origin"], "*"); |
| 1951 | assert.deepEqual(splitHeaderTokens(response.headers.get("access-control-allow-methods")), [ | 1860 | assert.deepEqual( |
| 1952 | "GET", | 1861 | splitHeaderTokens(response.headers["access-control-allow-methods"] ?? null), |
| 1953 | "OPTIONS", | 1862 | ["GET", "OPTIONS", "POST"], |
| 1954 | "POST", | 1863 | ); |
| 1955 | ]); | 1864 | assert.deepEqual( |
| 1956 | assert.deepEqual(splitHeaderTokens(response.headers.get("access-control-allow-headers")), [ | 1865 | splitHeaderTokens(response.headers["access-control-allow-headers"] ?? null), |
| 1957 | "authorization", | 1866 | ["authorization", "b3", "content-type", "traceparent"], |
| 1958 | "b3", | 1867 | ); |
| 1959 | "content-type", | ||
| 1960 | "traceparent", | ||
| 1961 | ]); | ||
| 1962 | }).pipe(Effect.provide(NodeHttpServer.layerTest)), | 1868 | }).pipe(Effect.provide(NodeHttpServer.layerTest)), |
| 1963 | ); | 1869 | ); |
| 1964 | 1870 | ||
| ... | @@ -1995,8 +1901,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { | ... | @@ -1995,8 +1901,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { |
| 1995 | cookie: yield* getAuthenticatedSessionCookieHeader(), | 1901 | cookie: yield* getAuthenticatedSessionCookieHeader(), |
| 1996 | "content-type": "application/json", | 1902 | "content-type": "application/json", |
| 1997 | }, | 1903 | }, |
| 1998 | // @effect-diagnostics-next-line preferSchemaOverJson:off | 1904 | body: yield* HttpBody.json(payload), |
| 1999 | body: HttpBody.text(JSON.stringify(payload), "application/json"), | ||
| 2000 | }); | 1905 | }); |
| 2001 | 1906 | ||
| 2002 | assert.equal(response.status, 204); | 1907 | assert.equal(response.status, 204); |
apps/server/src/serverRuntimeStartup.test.ts+53| ... | @@ -1,10 +1,12 @@ | ... | @@ -1,10 +1,12 @@ |
| 1 | import * as NodeServices from "@effect/platform-node/NodeServices"; | 1 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 2 | import { DEFAULT_MODEL, ProjectId, ProviderInstanceId, ThreadId } from "@t3tools/contracts"; | 2 | import { DEFAULT_MODEL, ProjectId, ProviderInstanceId, ThreadId } from "@t3tools/contracts"; |
| 3 | import { assert, it } from "@effect/vitest"; | 3 | import { assert, it } from "@effect/vitest"; |
| 4 | import * as Crypto from "effect/Crypto"; | ||
| 4 | import * as Deferred from "effect/Deferred"; | 5 | import * as Deferred from "effect/Deferred"; |
| 5 | import * as Effect from "effect/Effect"; | 6 | import * as Effect from "effect/Effect"; |
| 6 | import * as Fiber from "effect/Fiber"; | 7 | import * as Fiber from "effect/Fiber"; |
| 7 | import * as Option from "effect/Option"; | 8 | import * as Option from "effect/Option"; |
| 9 | import * as PlatformError from "effect/PlatformError"; | ||
| 8 | import * as Ref from "effect/Ref"; | 10 | import * as Ref from "effect/Ref"; |
| 9 | import * as Stream from "effect/Stream"; | 11 | import * as Stream from "effect/Stream"; |
| 10 | 12 | ||
| ... | @@ -222,3 +224,54 @@ it.effect("resolveAutoBootstrapWelcomeTargets creates a project and thread when | ... | @@ -222,3 +224,54 @@ it.effect("resolveAutoBootstrapWelcomeTargets creates a project and thread when |
| 222 | assert.deepStrictEqual(yield* Ref.get(dispatchCalls), ["project.create", "thread.create"]); | 224 | assert.deepStrictEqual(yield* Ref.get(dispatchCalls), ["project.create", "thread.create"]); |
| 223 | }), | 225 | }), |
| 224 | ); | 226 | ); |
| 227 | |||
| 228 | it.effect("resolveAutoBootstrapWelcomeTargets preserves typed UUID generation failures", () => | ||
| 229 | Effect.gen(function* () { | ||
| 230 | const crypto = yield* Crypto.Crypto; | ||
| 231 | const uuidError = PlatformError.systemError({ | ||
| 232 | _tag: "Unknown", | ||
| 233 | module: "Crypto", | ||
| 234 | method: "randomUUIDv4", | ||
| 235 | description: "UUID generation unavailable", | ||
| 236 | }); | ||
| 237 | const dispatchCalls = yield* Ref.make<ReadonlyArray<string>>([]); | ||
| 238 | |||
| 239 | const error = yield* resolveAutoBootstrapWelcomeTargets.pipe( | ||
| 240 | Effect.provideService(ServerConfig, { | ||
| 241 | cwd: "/tmp/startup-project", | ||
| 242 | autoBootstrapProjectFromCwd: true, | ||
| 243 | } as never), | ||
| 244 | Effect.provideService(ProjectionSnapshotQuery, { | ||
| 245 | getCommandReadModel: () => Effect.die("unused"), | ||
| 246 | getSnapshot: () => Effect.die("unused"), | ||
| 247 | getShellSnapshot: () => Effect.die("unused"), | ||
| 248 | getArchivedShellSnapshot: () => Effect.die("unused"), | ||
| 249 | getSnapshotSequence: () => Effect.die("unused"), | ||
| 250 | getCounts: () => Effect.die("unused"), | ||
| 251 | getActiveProjectByWorkspaceRoot: () => Effect.succeed(Option.none()), | ||
| 252 | getProjectShellById: () => Effect.die("unused"), | ||
| 253 | getFirstActiveThreadIdByProjectId: () => Effect.succeed(Option.none()), | ||
| 254 | getThreadCheckpointContext: () => Effect.succeed(Option.none()), | ||
| 255 | getFullThreadDiffContext: () => Effect.succeed(Option.none()), | ||
| 256 | getThreadShellById: () => Effect.die("unused"), | ||
| 257 | getThreadDetailById: () => Effect.die("unused"), | ||
| 258 | }), | ||
| 259 | Effect.provideService(OrchestrationEngineService, { | ||
| 260 | readEvents: () => Stream.empty, | ||
| 261 | dispatch: (command) => | ||
| 262 | Ref.update(dispatchCalls, (calls) => [...calls, command.type]).pipe( | ||
| 263 | Effect.as({ sequence: 1 }), | ||
| 264 | ), | ||
| 265 | streamDomainEvents: Stream.empty, | ||
| 266 | } satisfies OrchestrationEngineShape), | ||
| 267 | Effect.provideService(Crypto.Crypto, { | ||
| 268 | ...crypto, | ||
| 269 | randomUUIDv4: Effect.fail(uuidError), | ||
| 270 | }), | ||
| 271 | Effect.flip, | ||
| 272 | ); | ||
| 273 | |||
| 274 | assert.strictEqual(error, uuidError); | ||
| 275 | assert.deepStrictEqual(yield* Ref.get(dispatchCalls), []); | ||
| 276 | }).pipe(Effect.provide(NodeServices.layer)), | ||
| 277 | ); |
apps/server/src/serverRuntimeStartup.ts+7-4| ... | @@ -19,6 +19,7 @@ import * as Ref from "effect/Ref"; | ... | @@ -19,6 +19,7 @@ import * as Ref from "effect/Ref"; |
| 19 | import * as Scope from "effect/Scope"; | 19 | import * as Scope from "effect/Scope"; |
| 20 | import * as Context from "effect/Context"; | 20 | import * as Context from "effect/Context"; |
| 21 | import * as Console from "effect/Console"; | 21 | import * as Console from "effect/Console"; |
| 22 | import * as Crypto from "effect/Crypto"; | ||
| 22 | import * as DateTime from "effect/DateTime"; | 23 | import * as DateTime from "effect/DateTime"; |
| 23 | 24 | ||
| 24 | import { ServerConfig } from "./config.ts"; | 25 | import { ServerConfig } from "./config.ts"; |
| ... | @@ -170,6 +171,8 @@ export const resolveWelcomeBase = Effect.gen(function* () { | ... | @@ -170,6 +171,8 @@ export const resolveWelcomeBase = Effect.gen(function* () { |
| 170 | }); | 171 | }); |
| 171 | 172 | ||
| 172 | export const resolveAutoBootstrapWelcomeTargets = Effect.gen(function* () { | 173 | export const resolveAutoBootstrapWelcomeTargets = Effect.gen(function* () { |
| 174 | const crypto = yield* Crypto.Crypto; | ||
| 175 | const randomUUID = crypto.randomUUIDv4; | ||
| 173 | const serverConfig = yield* ServerConfig; | 176 | const serverConfig = yield* ServerConfig; |
| 174 | const projectionReadModelQuery = yield* ProjectionSnapshotQuery; | 177 | const projectionReadModelQuery = yield* ProjectionSnapshotQuery; |
| 175 | const orchestrationEngine = yield* OrchestrationEngineService; | 178 | const orchestrationEngine = yield* OrchestrationEngineService; |
| ... | @@ -188,12 +191,12 @@ export const resolveAutoBootstrapWelcomeTargets = Effect.gen(function* () { | ... | @@ -188,12 +191,12 @@ export const resolveAutoBootstrapWelcomeTargets = Effect.gen(function* () { |
| 188 | 191 | ||
| 189 | if (Option.isNone(existingProject)) { | 192 | if (Option.isNone(existingProject)) { |
| 190 | const createdAt = DateTime.formatIso(yield* DateTime.now); | 193 | const createdAt = DateTime.formatIso(yield* DateTime.now); |
| 191 | nextProjectId = ProjectId.make(crypto.randomUUID()); | 194 | nextProjectId = ProjectId.make(yield* randomUUID); |
| 192 | const bootstrapProjectTitle = path.basename(serverConfig.cwd) || "project"; | 195 | const bootstrapProjectTitle = path.basename(serverConfig.cwd) || "project"; |
| 193 | nextProjectDefaultModelSelection = getAutoBootstrapDefaultModelSelection(); | 196 | nextProjectDefaultModelSelection = getAutoBootstrapDefaultModelSelection(); |
| 194 | yield* orchestrationEngine.dispatch({ | 197 | yield* orchestrationEngine.dispatch({ |
| 195 | type: "project.create", | 198 | type: "project.create", |
| 196 | commandId: CommandId.make(crypto.randomUUID()), | 199 | commandId: CommandId.make(yield* randomUUID), |
| 197 | projectId: nextProjectId, | 200 | projectId: nextProjectId, |
| 198 | title: bootstrapProjectTitle, | 201 | title: bootstrapProjectTitle, |
| 199 | workspaceRoot: serverConfig.cwd, | 202 | workspaceRoot: serverConfig.cwd, |
| ... | @@ -210,10 +213,10 @@ export const resolveAutoBootstrapWelcomeTargets = Effect.gen(function* () { | ... | @@ -210,10 +213,10 @@ export const resolveAutoBootstrapWelcomeTargets = Effect.gen(function* () { |
| 210 | yield* projectionReadModelQuery.getFirstActiveThreadIdByProjectId(nextProjectId); | 213 | yield* projectionReadModelQuery.getFirstActiveThreadIdByProjectId(nextProjectId); |
| 211 | if (Option.isNone(existingThreadId)) { | 214 | if (Option.isNone(existingThreadId)) { |
| 212 | const createdAt = DateTime.formatIso(yield* DateTime.now); | 215 | const createdAt = DateTime.formatIso(yield* DateTime.now); |
| 213 | const createdThreadId = ThreadId.make(crypto.randomUUID()); | 216 | const createdThreadId = ThreadId.make(yield* randomUUID); |
| 214 | yield* orchestrationEngine.dispatch({ | 217 | yield* orchestrationEngine.dispatch({ |
| 215 | type: "thread.create", | 218 | type: "thread.create", |
| 216 | commandId: CommandId.make(crypto.randomUUID()), | 219 | commandId: CommandId.make(yield* randomUUID), |
| 217 | threadId: createdThreadId, | 220 | threadId: createdThreadId, |
| 218 | projectId: nextProjectId, | 221 | projectId: nextProjectId, |
| 219 | title: "New thread", | 222 | title: "New thread", |
apps/server/src/serverSettings.test.ts+13-11| ... | @@ -16,6 +16,9 @@ import * as Schema from "effect/Schema"; | ... | @@ -16,6 +16,9 @@ import * as Schema from "effect/Schema"; |
| 16 | import { ServerConfig } from "./config.ts"; | 16 | import { ServerConfig } from "./config.ts"; |
| 17 | import { ServerSettingsLive, ServerSettingsService } from "./serverSettings.ts"; | 17 | import { ServerSettingsLive, ServerSettingsService } from "./serverSettings.ts"; |
| 18 | 18 | ||
| 19 | const decodeSettingsPatch = Schema.decodeUnknownEffect(ServerSettingsPatch); | ||
| 20 | const decodeServerSettings = Schema.decodeUnknownEffect(ServerSettings); | ||
| 21 | |||
| 19 | const makeServerSettingsLayer = () => | 22 | const makeServerSettingsLayer = () => |
| 20 | ServerSettingsLive.pipe( | 23 | ServerSettingsLive.pipe( |
| 21 | Layer.provideMerge( | 24 | Layer.provideMerge( |
| ... | @@ -29,15 +32,16 @@ const makeServerSettingsLayer = () => | ... | @@ -29,15 +32,16 @@ const makeServerSettingsLayer = () => |
| 29 | 32 | ||
| 30 | it.layer(NodeServices.layer)("server settings", (it) => { | 33 | it.layer(NodeServices.layer)("server settings", (it) => { |
| 31 | it.effect("decodes nested settings patches", () => | 34 | it.effect("decodes nested settings patches", () => |
| 32 | Effect.sync(() => { | 35 | Effect.gen(function* () { |
| 33 | const decodePatch = Schema.decodeUnknownSync(ServerSettingsPatch); | 36 | assert.deepEqual( |
| 34 | 37 | yield* decodeSettingsPatch({ providers: { codex: { binaryPath: "/tmp/codex" } } }), | |
| 35 | assert.deepEqual(decodePatch({ providers: { codex: { binaryPath: "/tmp/codex" } } }), { | 38 | { |
| 36 | providers: { codex: { binaryPath: "/tmp/codex" } }, | 39 | providers: { codex: { binaryPath: "/tmp/codex" } }, |
| 37 | }); | 40 | }, |
| 41 | ); | ||
| 38 | 42 | ||
| 39 | assert.deepEqual( | 43 | assert.deepEqual( |
| 40 | decodePatch({ | 44 | yield* decodeSettingsPatch({ |
| 41 | textGenerationModelSelection: { | 45 | textGenerationModelSelection: { |
| 42 | options: [{ id: "fastMode", value: false }], | 46 | options: [{ id: "fastMode", value: false }], |
| 43 | }, | 47 | }, |
| ... | @@ -54,10 +58,8 @@ it.layer(NodeServices.layer)("server settings", (it) => { | ... | @@ -54,10 +58,8 @@ it.layer(NodeServices.layer)("server settings", (it) => { |
| 54 | it.effect( | 58 | it.effect( |
| 55 | "decodes legacy object-shaped textGenerationModelSelection.options from settings.json", | 59 | "decodes legacy object-shaped textGenerationModelSelection.options from settings.json", |
| 56 | () => | 60 | () => |
| 57 | Effect.sync(() => { | 61 | Effect.gen(function* () { |
| 58 | const decode = Schema.decodeUnknownSync(ServerSettings); | 62 | const decoded = yield* decodeServerSettings({ |
| 59 | |||
| 60 | const decoded = decode({ | ||
| 61 | textGenerationModelSelection: { | 63 | textGenerationModelSelection: { |
| 62 | provider: ProviderDriverKind.make("codex"), | 64 | provider: ProviderDriverKind.make("codex"), |
| 63 | model: "gpt-5.4-mini", | 65 | model: "gpt-5.4-mini", |
apps/server/src/sourceControl/AzureDevOpsCli.ts+1-1| ... | @@ -94,7 +94,7 @@ export interface AzureDevOpsCliShape { | ... | @@ -94,7 +94,7 @@ export interface AzureDevOpsCliShape { |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | export class AzureDevOpsCli extends Context.Service<AzureDevOpsCli, AzureDevOpsCliShape>()( | 96 | export class AzureDevOpsCli extends Context.Service<AzureDevOpsCli, AzureDevOpsCliShape>()( |
| 97 | "t3/source-control/AzureDevOpsCli", | 97 | "t3/sourceControl/AzureDevOpsCli", |
| 98 | ) {} | 98 | ) {} |
| 99 | 99 | ||
| 100 | function errorText(error: VcsError | unknown): string { | 100 | function errorText(error: VcsError | unknown): string { |
apps/server/src/sourceControl/BitbucketApi.ts+1-1| ... | @@ -154,7 +154,7 @@ export interface BitbucketApiShape { | ... | @@ -154,7 +154,7 @@ export interface BitbucketApiShape { |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | export class BitbucketApi extends Context.Service<BitbucketApi, BitbucketApiShape>()( | 156 | export class BitbucketApi extends Context.Service<BitbucketApi, BitbucketApiShape>()( |
| 157 | "t3/source-control/BitbucketApi", | 157 | "t3/sourceControl/BitbucketApi", |
| 158 | ) {} | 158 | ) {} |
| 159 | 159 | ||
| 160 | function nonEmpty(value: string | undefined): Option.Option<string> { | 160 | function nonEmpty(value: string | undefined): Option.Option<string> { |
apps/server/src/sourceControl/GitHubCli.ts+1-1| ... | @@ -93,7 +93,7 @@ export interface GitHubCliShape { | ... | @@ -93,7 +93,7 @@ export interface GitHubCliShape { |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | export class GitHubCli extends Context.Service<GitHubCli, GitHubCliShape>()( | 95 | export class GitHubCli extends Context.Service<GitHubCli, GitHubCliShape>()( |
| 96 | "t3/source-control/GitHubCli", | 96 | "t3/sourceControl/GitHubCli", |
| 97 | ) {} | 97 | ) {} |
| 98 | 98 | ||
| 99 | function errorText(error: VcsError | unknown): string { | 99 | function errorText(error: VcsError | unknown): string { |
apps/server/src/sourceControl/GitLabCli.ts+1-1| ... | @@ -97,7 +97,7 @@ export interface GitLabCliShape { | ... | @@ -97,7 +97,7 @@ export interface GitLabCliShape { |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | export class GitLabCli extends Context.Service<GitLabCli, GitLabCliShape>()( | 99 | export class GitLabCli extends Context.Service<GitLabCli, GitLabCliShape>()( |
| 100 | "t3/source-control/GitLabCli", | 100 | "t3/sourceControl/GitLabCli", |
| 101 | ) {} | 101 | ) {} |
| 102 | 102 | ||
| 103 | function isVcsProcessSpawnError(error: unknown): boolean { | 103 | function isVcsProcessSpawnError(error: unknown): boolean { |
apps/server/src/sourceControl/SourceControlDiscovery.ts+1-1| ... | @@ -64,7 +64,7 @@ export interface SourceControlDiscoveryShape { | ... | @@ -64,7 +64,7 @@ export interface SourceControlDiscoveryShape { |
| 64 | export class SourceControlDiscovery extends Context.Service< | 64 | export class SourceControlDiscovery extends Context.Service< |
| 65 | SourceControlDiscovery, | 65 | SourceControlDiscovery, |
| 66 | SourceControlDiscoveryShape | 66 | SourceControlDiscoveryShape |
| 67 | >()("t3/source-control/SourceControlDiscovery") {} | 67 | >()("t3/sourceControl/SourceControlDiscovery") {} |
| 68 | 68 | ||
| 69 | export const layer = Layer.effect( | 69 | export const layer = Layer.effect( |
| 70 | SourceControlDiscovery, | 70 | SourceControlDiscovery, |
apps/server/src/sourceControl/SourceControlProvider.ts+1-1| ... | @@ -99,4 +99,4 @@ export interface SourceControlProviderShape { | ... | @@ -99,4 +99,4 @@ export interface SourceControlProviderShape { |
| 99 | export class SourceControlProvider extends Context.Service< | 99 | export class SourceControlProvider extends Context.Service< |
| 100 | SourceControlProvider, | 100 | SourceControlProvider, |
| 101 | SourceControlProviderShape | 101 | SourceControlProviderShape |
| 102 | >()("t3/source-control/SourceControlProvider") {} | 102 | >()("t3/sourceControl/SourceControlProvider") {} |
apps/server/src/sourceControl/SourceControlProviderRegistry.ts+1-1| ... | @@ -51,7 +51,7 @@ export interface SourceControlProviderRegistryShape { | ... | @@ -51,7 +51,7 @@ export interface SourceControlProviderRegistryShape { |
| 51 | export class SourceControlProviderRegistry extends Context.Service< | 51 | export class SourceControlProviderRegistry extends Context.Service< |
| 52 | SourceControlProviderRegistry, | 52 | SourceControlProviderRegistry, |
| 53 | SourceControlProviderRegistryShape | 53 | SourceControlProviderRegistryShape |
| 54 | >()("t3/source-control/SourceControlProviderRegistry") {} | 54 | >()("t3/sourceControl/SourceControlProviderRegistry") {} |
| 55 | 55 | ||
| 56 | function unsupportedProvider( | 56 | function unsupportedProvider( |
| 57 | kind: SourceControlProviderKind, | 57 | kind: SourceControlProviderKind, |
apps/server/src/sourceControl/SourceControlRepositoryService.ts+1-1| ... | @@ -39,7 +39,7 @@ export interface SourceControlRepositoryServiceShape { | ... | @@ -39,7 +39,7 @@ export interface SourceControlRepositoryServiceShape { |
| 39 | export class SourceControlRepositoryService extends Context.Service< | 39 | export class SourceControlRepositoryService extends Context.Service< |
| 40 | SourceControlRepositoryService, | 40 | SourceControlRepositoryService, |
| 41 | SourceControlRepositoryServiceShape | 41 | SourceControlRepositoryServiceShape |
| 42 | >()("t3/source-control/SourceControlRepositoryService") {} | 42 | >()("t3/sourceControl/SourceControlRepositoryService") {} |
| 43 | 43 | ||
| 44 | function detailFromUnknown(cause: unknown): string { | 44 | function detailFromUnknown(cause: unknown): string { |
| 45 | if (typeof cause === "object" && cause !== null) { | 45 | if (typeof cause === "object" && cause !== null) { |
apps/server/src/textGeneration/CodexTextGeneration.ts+16-18| ... | @@ -76,24 +76,22 @@ export const makeCodexTextGeneration = Effect.fn("makeCodexTextGeneration")(func | ... | @@ -76,24 +76,22 @@ export const makeCodexTextGeneration = Effect.fn("makeCodexTextGeneration")(func |
| 76 | operation: string, | 76 | operation: string, |
| 77 | prefix: string, | 77 | prefix: string, |
| 78 | content: string, | 78 | content: string, |
| 79 | ): Effect.Effect<string, TextGenerationError, Scope.Scope> => { | 79 | ): Effect.Effect<string, TextGenerationError, Scope.Scope> => |
| 80 | return Effect.gen(function* () { | 80 | fileSystem |
| 81 | return yield* fileSystem | 81 | .makeTempFileScoped({ |
| 82 | .makeTempFileScoped({ | 82 | prefix: `t3code-${prefix}-${process.pid}-`, |
| 83 | prefix: `t3code-${prefix}-${process.pid}-`, | 83 | }) |
| 84 | }) | 84 | .pipe( |
| 85 | .pipe(Effect.tap((filePath) => fileSystem.writeFileString(filePath, content))); | 85 | Effect.tap((filePath) => fileSystem.writeFileString(filePath, content)), |
| 86 | }).pipe( | 86 | Effect.mapError( |
| 87 | Effect.mapError( | 87 | (cause) => |
| 88 | (cause) => | 88 | new TextGenerationError({ |
| 89 | new TextGenerationError({ | 89 | operation, |
| 90 | operation, | 90 | detail: `Failed to write temp file`, |
| 91 | detail: `Failed to write temp file`, | 91 | cause, |
| 92 | cause, | 92 | }), |
| 93 | }), | 93 | ), |
| 94 | ), | 94 | ); |
| 95 | ); | ||
| 96 | }; | ||
| 97 | 95 | ||
| 98 | const safeUnlink = (filePath: string): Effect.Effect<void, never> => | 96 | const safeUnlink = (filePath: string): Effect.Effect<void, never> => |
| 99 | fileSystem.remove(filePath).pipe(Effect.catch(() => Effect.void)); | 97 | fileSystem.remove(filePath).pipe(Effect.catch(() => Effect.void)); |
apps/server/src/textGeneration/TextGeneration.ts+1-1| ... | @@ -116,7 +116,7 @@ export interface TextGenerationShape { | ... | @@ -116,7 +116,7 @@ export interface TextGenerationShape { |
| 116 | * TextGeneration - Service tag for commit and PR text generation. | 116 | * TextGeneration - Service tag for commit and PR text generation. |
| 117 | */ | 117 | */ |
| 118 | export class TextGeneration extends Context.Service<TextGeneration, TextGenerationShape>()( | 118 | export class TextGeneration extends Context.Service<TextGeneration, TextGenerationShape>()( |
| 119 | "t3/text-generation/TextGeneration", | 119 | "t3/textGeneration/TextGeneration", |
| 120 | ) {} | 120 | ) {} |
| 121 | 121 | ||
| 122 | type TextGenerationOp = | 122 | type TextGenerationOp = |
apps/server/src/ws.ts+49-32| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | import * as Cause from "effect/Cause"; | 1 | import * as Cause from "effect/Cause"; |
| 2 | import * as Crypto from "effect/Crypto"; | ||
| 2 | import * as DateTime from "effect/DateTime"; | 3 | import * as DateTime from "effect/DateTime"; |
| 3 | import * as Duration from "effect/Duration"; | 4 | import * as Duration from "effect/Duration"; |
| 4 | import * as Effect from "effect/Effect"; | 5 | import * as Effect from "effect/Effect"; |
| ... | @@ -160,6 +161,7 @@ function toAuthAccessStreamEvent( | ... | @@ -160,6 +161,7 @@ function toAuthAccessStreamEvent( |
| 160 | const makeWsRpcLayer = (currentSessionId: AuthSessionId) => | 161 | const makeWsRpcLayer = (currentSessionId: AuthSessionId) => |
| 161 | WsRpcGroup.toLayer( | 162 | WsRpcGroup.toLayer( |
| 162 | Effect.gen(function* () { | 163 | Effect.gen(function* () { |
| 164 | const crypto = yield* Crypto.Crypto; | ||
| 163 | const projectionSnapshotQuery = yield* ProjectionSnapshotQuery; | 165 | const projectionSnapshotQuery = yield* ProjectionSnapshotQuery; |
| 164 | const orchestrationEngine = yield* OrchestrationEngineService; | 166 | const orchestrationEngine = yield* OrchestrationEngineService; |
| 165 | const checkpointDiffQuery = yield* CheckpointDiffQuery; | 167 | const checkpointDiffQuery = yield* CheckpointDiffQuery; |
| ... | @@ -195,8 +197,21 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => | ... | @@ -195,8 +197,21 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => |
| 195 | const sessions = yield* SessionCredentialService; | 197 | const sessions = yield* SessionCredentialService; |
| 196 | const processDiagnostics = yield* ProcessDiagnostics.ProcessDiagnostics; | 198 | const processDiagnostics = yield* ProcessDiagnostics.ProcessDiagnostics; |
| 197 | const processResourceMonitor = yield* ProcessResourceMonitor.ProcessResourceMonitor; | 199 | const processResourceMonitor = yield* ProcessResourceMonitor.ProcessResourceMonitor; |
| 200 | const toDispatchCommandError = (cause: unknown, fallbackMessage: string) => | ||
| 201 | isOrchestrationDispatchCommandError(cause) | ||
| 202 | ? cause | ||
| 203 | : new OrchestrationDispatchCommandError({ | ||
| 204 | message: cause instanceof Error ? cause.message : fallbackMessage, | ||
| 205 | cause, | ||
| 206 | }); | ||
| 207 | const randomUUID = crypto.randomUUIDv4.pipe( | ||
| 208 | Effect.mapError((cause) => | ||
| 209 | toDispatchCommandError(cause, "Failed to generate orchestration command identifier."), | ||
| 210 | ), | ||
| 211 | ); | ||
| 212 | const serverEventId = randomUUID.pipe(Effect.map(EventId.make)); | ||
| 198 | const serverCommandId = (tag: string) => | 213 | const serverCommandId = (tag: string) => |
| 199 | CommandId.make(`server:${tag}:${crypto.randomUUID()}`); | 214 | randomUUID.pipe(Effect.map((uuid) => CommandId.make(`server:${tag}:${uuid}`))); |
| 200 | 215 | ||
| 201 | const loadAuthAccessSnapshot = () => | 216 | const loadAuthAccessSnapshot = () => |
| 202 | Effect.all({ | 217 | Effect.all({ |
| ... | @@ -212,29 +227,28 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => | ... | @@ -212,29 +227,28 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => |
| 212 | readonly payload: Record<string, unknown>; | 227 | readonly payload: Record<string, unknown>; |
| 213 | readonly tone: "info" | "error"; | 228 | readonly tone: "info" | "error"; |
| 214 | }) => | 229 | }) => |
| 215 | orchestrationEngine.dispatch({ | 230 | Effect.all({ |
| 216 | type: "thread.activity.append", | ||
| 217 | commandId: serverCommandId("setup-script-activity"), | 231 | commandId: serverCommandId("setup-script-activity"), |
| 218 | threadId: input.threadId, | 232 | activityId: serverEventId, |
| 219 | activity: { | 233 | }).pipe( |
| 220 | id: EventId.make(crypto.randomUUID()), | 234 | Effect.flatMap(({ commandId, activityId }) => |
| 221 | tone: input.tone, | 235 | orchestrationEngine.dispatch({ |
| 222 | kind: input.kind, | 236 | type: "thread.activity.append", |
| 223 | summary: input.summary, | 237 | commandId, |
| 224 | payload: input.payload, | 238 | threadId: input.threadId, |
| 225 | turnId: null, | 239 | activity: { |
| 226 | createdAt: input.createdAt, | 240 | id: activityId, |
| 227 | }, | 241 | tone: input.tone, |
| 228 | createdAt: input.createdAt, | 242 | kind: input.kind, |
| 229 | }); | 243 | summary: input.summary, |
| 230 | 244 | payload: input.payload, | |
| 231 | const toDispatchCommandError = (cause: unknown, fallbackMessage: string) => | 245 | turnId: null, |
| 232 | isOrchestrationDispatchCommandError(cause) | 246 | createdAt: input.createdAt, |
| 233 | ? cause | 247 | }, |
| 234 | : new OrchestrationDispatchCommandError({ | 248 | createdAt: input.createdAt, |
| 235 | message: cause instanceof Error ? cause.message : fallbackMessage, | 249 | }), |
| 236 | cause, | 250 | ), |
| 237 | }); | 251 | ); |
| 238 | 252 | ||
| 239 | const toBootstrapDispatchCommandCauseError = (cause: Cause.Cause<unknown>) => { | 253 | const toBootstrapDispatchCommandCauseError = (cause: Cause.Cause<unknown>) => { |
| 240 | const error = Cause.squash(cause); | 254 | const error = Cause.squash(cause); |
| ... | @@ -370,13 +384,16 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => | ... | @@ -370,13 +384,16 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => |
| 370 | 384 | ||
| 371 | const cleanupCreatedThread = () => | 385 | const cleanupCreatedThread = () => |
| 372 | createdThread | 386 | createdThread |
| 373 | ? orchestrationEngine | 387 | ? serverCommandId("bootstrap-thread-delete").pipe( |
| 374 | .dispatch({ | 388 | Effect.flatMap((commandId) => |
| 375 | type: "thread.delete", | 389 | orchestrationEngine.dispatch({ |
| 376 | commandId: serverCommandId("bootstrap-thread-delete"), | 390 | type: "thread.delete", |
| 377 | threadId: command.threadId, | 391 | commandId, |
| 378 | }) | 392 | threadId: command.threadId, |
| 379 | .pipe(Effect.ignoreCause({ log: true })) | 393 | }), |
| 394 | ), | ||
| 395 | Effect.ignoreCause({ log: true }), | ||
| 396 | ) | ||
| 380 | : Effect.void; | 397 | : Effect.void; |
| 381 | 398 | ||
| 382 | const recordSetupScriptLaunchFailure = (input: { | 399 | const recordSetupScriptLaunchFailure = (input: { |
| ... | @@ -499,7 +516,7 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => | ... | @@ -499,7 +516,7 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => |
| 499 | if (bootstrap?.createThread) { | 516 | if (bootstrap?.createThread) { |
| 500 | yield* orchestrationEngine.dispatch({ | 517 | yield* orchestrationEngine.dispatch({ |
| 501 | type: "thread.create", | 518 | type: "thread.create", |
| 502 | commandId: serverCommandId("bootstrap-thread-create"), | 519 | commandId: yield* serverCommandId("bootstrap-thread-create"), |
| 503 | threadId: command.threadId, | 520 | threadId: command.threadId, |
| 504 | projectId: bootstrap.createThread.projectId, | 521 | projectId: bootstrap.createThread.projectId, |
| 505 | title: bootstrap.createThread.title, | 522 | title: bootstrap.createThread.title, |
| ... | @@ -523,7 +540,7 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => | ... | @@ -523,7 +540,7 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => |
| 523 | targetWorktreePath = worktree.worktree.path; | 540 | targetWorktreePath = worktree.worktree.path; |
| 524 | yield* orchestrationEngine.dispatch({ | 541 | yield* orchestrationEngine.dispatch({ |
| 525 | type: "thread.meta.update", | 542 | type: "thread.meta.update", |
| 526 | commandId: serverCommandId("bootstrap-thread-meta-update"), | 543 | commandId: yield* serverCommandId("bootstrap-thread-meta-update"), |
| 527 | threadId: command.threadId, | 544 | threadId: command.threadId, |
| 528 | branch: worktree.worktree.refName, | 545 | branch: worktree.worktree.refName, |
| 529 | worktreePath: targetWorktreePath, | 546 | worktreePath: targetWorktreePath, |
apps/server/tsconfig.json-1| ... | @@ -1,7 +1,6 @@ | ... | @@ -1,7 +1,6 @@ |
| 1 | { | 1 | { |
| 2 | "extends": "../../tsconfig.base.json", | 2 | "extends": "../../tsconfig.base.json", |
| 3 | "compilerOptions": { | 3 | "compilerOptions": { |
| 4 | "composite": true, | ||
| 5 | "types": ["node", "bun"], | 4 | "types": ["node", "bun"], |
| 6 | "lib": ["ESNext", "esnext.disposable"] | 5 | "lib": ["ESNext", "esnext.disposable"] |
| 7 | }, | 6 | }, |
apps/web/package.json+1-3| ... | @@ -7,7 +7,7 @@ | ... | @@ -7,7 +7,7 @@ |
| 7 | "dev": "vite", | 7 | "dev": "vite", |
| 8 | "build": "vite build", | 8 | "build": "vite build", |
| 9 | "preview": "vite preview", | 9 | "preview": "vite preview", |
| 10 | "typecheck": "tsc --noEmit", | 10 | "typecheck": "tsgo --noEmit", |
| 11 | "test": "vitest run --passWithNoTests", | 11 | "test": "vitest run --passWithNoTests", |
| 12 | "test:browser": "vitest run --config vitest.browser.config.ts", | 12 | "test:browser": "vitest run --config vitest.browser.config.ts", |
| 13 | "test:browser:install": "playwright install --with-deps chromium" | 13 | "test:browser:install": "playwright install --with-deps chromium" |
| ... | @@ -43,7 +43,6 @@ | ... | @@ -43,7 +43,6 @@ |
| 43 | "zustand": "^5.0.11" | 43 | "zustand": "^5.0.11" |
| 44 | }, | 44 | }, |
| 45 | "devDependencies": { | 45 | "devDependencies": { |
| 46 | "@effect/language-service": "catalog:", | ||
| 47 | "@rolldown/plugin-babel": "^0.2.0", | 46 | "@rolldown/plugin-babel": "^0.2.0", |
| 48 | "@tailwindcss/vite": "^4.0.0", | 47 | "@tailwindcss/vite": "^4.0.0", |
| 49 | "@tanstack/router-plugin": "^1.161.0", | 48 | "@tanstack/router-plugin": "^1.161.0", |
| ... | @@ -57,7 +56,6 @@ | ... | @@ -57,7 +56,6 @@ |
| 57 | "msw": "2.12.11", | 56 | "msw": "2.12.11", |
| 58 | "playwright": "^1.58.2", | 57 | "playwright": "^1.58.2", |
| 59 | "tailwindcss": "^4.0.0", | 58 | "tailwindcss": "^4.0.0", |
| 60 | "typescript": "catalog:", | ||
| 61 | "vite": "^8.0.0", | 59 | "vite": "^8.0.0", |
| 62 | "vitest": "catalog:", | 60 | "vitest": "catalog:", |
| 63 | "vitest-browser-react": "^2.0.5" | 61 | "vitest-browser-react": "^2.0.5" |
apps/web/src/session-logic.test.ts+3-1| ... | @@ -22,6 +22,8 @@ import { | ... | @@ -22,6 +22,8 @@ import { |
| 22 | isLatestTurnSettled, | 22 | isLatestTurnSettled, |
| 23 | } from "./session-logic"; | 23 | } from "./session-logic"; |
| 24 | 24 | ||
| 25 | let nextActivityId = 0; | ||
| 26 | |||
| 25 | function makeActivity(overrides: { | 27 | function makeActivity(overrides: { |
| 26 | id?: string; | 28 | id?: string; |
| 27 | createdAt?: string; | 29 | createdAt?: string; |
| ... | @@ -34,7 +36,7 @@ function makeActivity(overrides: { | ... | @@ -34,7 +36,7 @@ function makeActivity(overrides: { |
| 34 | }): OrchestrationThreadActivity { | 36 | }): OrchestrationThreadActivity { |
| 35 | const payload = overrides.payload ?? {}; | 37 | const payload = overrides.payload ?? {}; |
| 36 | return { | 38 | return { |
| 37 | id: EventId.make(overrides.id ?? crypto.randomUUID()), | 39 | id: EventId.make(overrides.id ?? `activity-${nextActivityId++}`), |
| 38 | createdAt: overrides.createdAt ?? "2026-02-23T00:00:00.000Z", | 40 | createdAt: overrides.createdAt ?? "2026-02-23T00:00:00.000Z", |
| 39 | kind: overrides.kind ?? "tool.started", | 41 | kind: overrides.kind ?? "tool.started", |
| 40 | summary: overrides.summary ?? "Tool call", | 42 | summary: overrides.summary ?? "Tool call", |
apps/web/tsconfig.json+6-15| ... | @@ -15,22 +15,13 @@ | ... | @@ -15,22 +15,13 @@ |
| 15 | "plugins": [ | 15 | "plugins": [ |
| 16 | { | 16 | { |
| 17 | "name": "@effect/language-service", | 17 | "name": "@effect/language-service", |
| 18 | "namespaceImportPackages": ["@effect/platform-node", "effect"], | 18 | // Diagnostic severities are deep-merged with tsconfig.base.json; list only web-specific overrides here. |
| 19 | "diagnosticSeverity": { | 19 | "diagnosticSeverity": { |
| 20 | "importFromBarrel": "error", | 20 | "globalDate": "off", |
| 21 | "anyUnknownInErrorContext": "error", | 21 | "globalConsole": "off", |
| 22 | "unsafeEffectTypeAssertion": "error", | 22 | "globalRandom": "off", |
| 23 | "instanceOfSchema": "error", | 23 | "globalTimers": "off", |
| 24 | "deterministicKeys": "error", | 24 | "globalFetch": "off" |
| 25 | "strictEffectProvide": "off", | ||
| 26 | "missingEffectServiceDependency": "error", | ||
| 27 | "leakingRequirements": "error", | ||
| 28 | "globalErrorInEffectCatch": "error", | ||
| 29 | "globalErrorInEffectFailure": "error", | ||
| 30 | "unknownInEffectCatch": "error", | ||
| 31 | "strictBooleanExpressions": "off", | ||
| 32 | "preferSchemaOverJson": "error", | ||
| 33 | "schemaSyncInEffect": "error" | ||
| 34 | } | 25 | } |
| 35 | } | 26 | } |
| 36 | ] | 27 | ] |
bun.lock+40-31| ... | @@ -5,13 +5,13 @@ | ... | @@ -5,13 +5,13 @@ |
| 5 | "": { | 5 | "": { |
| 6 | "name": "@t3tools/monorepo", | 6 | "name": "@t3tools/monorepo", |
| 7 | "devDependencies": { | 7 | "devDependencies": { |
| 8 | "@effect/language-service": "catalog:", | 8 | "@effect/tsgo": "catalog:", |
| 9 | "@oxlint/plugins": "^1.63.0", | 9 | "@oxlint/plugins": "^1.63.0", |
| 10 | "@types/node": "catalog:", | 10 | "@types/node": "catalog:", |
| 11 | "@typescript/native-preview": "catalog:", | ||
| 11 | "oxfmt": "^0.40.0", | 12 | "oxfmt": "^0.40.0", |
| 12 | "oxlint": "^1.63.0", | 13 | "oxlint": "^1.63.0", |
| 13 | "turbo": "^2.3.3", | 14 | "turbo": "^2.3.3", |
| 14 | "typescript": "catalog:", | ||
| 15 | "vitest": "catalog:", | 15 | "vitest": "catalog:", |
| 16 | }, | 16 | }, |
| 17 | }, | 17 | }, |
| ... | @@ -29,11 +29,9 @@ | ... | @@ -29,11 +29,9 @@ |
| 29 | "electron-updater": "^6.6.2", | 29 | "electron-updater": "^6.6.2", |
| 30 | }, | 30 | }, |
| 31 | "devDependencies": { | 31 | "devDependencies": { |
| 32 | "@effect/language-service": "catalog:", | ||
| 33 | "@effect/vitest": "catalog:", | 32 | "@effect/vitest": "catalog:", |
| 34 | "@types/node": "catalog:", | 33 | "@types/node": "catalog:", |
| 35 | "tsdown": "catalog:", | 34 | "tsdown": "catalog:", |
| 36 | "typescript": "catalog:", | ||
| 37 | "vitest": "catalog:", | 35 | "vitest": "catalog:", |
| 38 | }, | 36 | }, |
| 39 | }, | 37 | }, |
| ... | @@ -66,7 +64,6 @@ | ... | @@ -66,7 +64,6 @@ |
| 66 | "node-pty": "^1.1.0", | 64 | "node-pty": "^1.1.0", |
| 67 | }, | 65 | }, |
| 68 | "devDependencies": { | 66 | "devDependencies": { |
| 69 | "@effect/language-service": "catalog:", | ||
| 70 | "@effect/vitest": "catalog:", | 67 | "@effect/vitest": "catalog:", |
| 71 | "@t3tools/contracts": "workspace:*", | 68 | "@t3tools/contracts": "workspace:*", |
| 72 | "@t3tools/shared": "workspace:*", | 69 | "@t3tools/shared": "workspace:*", |
| ... | @@ -77,7 +74,6 @@ | ... | @@ -77,7 +74,6 @@ |
| 77 | "effect-acp": "workspace:*", | 74 | "effect-acp": "workspace:*", |
| 78 | "effect-codex-app-server": "workspace:*", | 75 | "effect-codex-app-server": "workspace:*", |
| 79 | "tsdown": "catalog:", | 76 | "tsdown": "catalog:", |
| 80 | "typescript": "catalog:", | ||
| 81 | "vitest": "catalog:", | 77 | "vitest": "catalog:", |
| 82 | }, | 78 | }, |
| 83 | }, | 79 | }, |
| ... | @@ -115,7 +111,6 @@ | ... | @@ -115,7 +111,6 @@ |
| 115 | "zustand": "^5.0.11", | 111 | "zustand": "^5.0.11", |
| 116 | }, | 112 | }, |
| 117 | "devDependencies": { | 113 | "devDependencies": { |
| 118 | "@effect/language-service": "catalog:", | ||
| 119 | "@rolldown/plugin-babel": "^0.2.0", | 114 | "@rolldown/plugin-babel": "^0.2.0", |
| 120 | "@tailwindcss/vite": "^4.0.0", | 115 | "@tailwindcss/vite": "^4.0.0", |
| 121 | "@tanstack/router-plugin": "^1.161.0", | 116 | "@tanstack/router-plugin": "^1.161.0", |
| ... | @@ -129,7 +124,6 @@ | ... | @@ -129,7 +124,6 @@ |
| 129 | "msw": "2.12.11", | 124 | "msw": "2.12.11", |
| 130 | "playwright": "^1.58.2", | 125 | "playwright": "^1.58.2", |
| 131 | "tailwindcss": "^4.0.0", | 126 | "tailwindcss": "^4.0.0", |
| 132 | "typescript": "catalog:", | ||
| 133 | "vite": "^8.0.0", | 127 | "vite": "^8.0.0", |
| 134 | "vitest": "catalog:", | 128 | "vitest": "catalog:", |
| 135 | "vitest-browser-react": "^2.0.5", | 129 | "vitest-browser-react": "^2.0.5", |
| ... | @@ -143,10 +137,8 @@ | ... | @@ -143,10 +137,8 @@ |
| 143 | "effect": "catalog:", | 137 | "effect": "catalog:", |
| 144 | }, | 138 | }, |
| 145 | "devDependencies": { | 139 | "devDependencies": { |
| 146 | "@effect/language-service": "catalog:", | ||
| 147 | "@effect/vitest": "catalog:", | 140 | "@effect/vitest": "catalog:", |
| 148 | "@types/bun": "catalog:", | 141 | "@types/bun": "catalog:", |
| 149 | "typescript": "catalog:", | ||
| 150 | "vitest": "catalog:", | 142 | "vitest": "catalog:", |
| 151 | }, | 143 | }, |
| 152 | }, | 144 | }, |
| ... | @@ -158,8 +150,6 @@ | ... | @@ -158,8 +150,6 @@ |
| 158 | "effect": "catalog:", | 150 | "effect": "catalog:", |
| 159 | }, | 151 | }, |
| 160 | "devDependencies": { | 152 | "devDependencies": { |
| 161 | "@effect/language-service": "catalog:", | ||
| 162 | "typescript": "catalog:", | ||
| 163 | "vitest": "catalog:", | 153 | "vitest": "catalog:", |
| 164 | }, | 154 | }, |
| 165 | }, | 155 | }, |
| ... | @@ -170,9 +160,7 @@ | ... | @@ -170,9 +160,7 @@ |
| 170 | "effect": "catalog:", | 160 | "effect": "catalog:", |
| 171 | }, | 161 | }, |
| 172 | "devDependencies": { | 162 | "devDependencies": { |
| 173 | "@effect/language-service": "catalog:", | ||
| 174 | "@effect/vitest": "catalog:", | 163 | "@effect/vitest": "catalog:", |
| 175 | "typescript": "catalog:", | ||
| 176 | "vitest": "catalog:", | 164 | "vitest": "catalog:", |
| 177 | }, | 165 | }, |
| 178 | }, | 166 | }, |
| ... | @@ -182,11 +170,10 @@ | ... | @@ -182,11 +170,10 @@ |
| 182 | "effect": "catalog:", | 170 | "effect": "catalog:", |
| 183 | }, | 171 | }, |
| 184 | "devDependencies": { | 172 | "devDependencies": { |
| 185 | "@effect/language-service": "catalog:", | ||
| 186 | "@effect/openapi-generator": "catalog:", | 173 | "@effect/openapi-generator": "catalog:", |
| 187 | "@effect/platform-node": "catalog:", | 174 | "@effect/platform-node": "catalog:", |
| 188 | "@effect/vitest": "catalog:", | 175 | "@effect/vitest": "catalog:", |
| 189 | "typescript": "catalog:", | 176 | "@types/node": "catalog:", |
| 190 | "vitest": "catalog:", | 177 | "vitest": "catalog:", |
| 191 | }, | 178 | }, |
| 192 | }, | 179 | }, |
| ... | @@ -196,11 +183,10 @@ | ... | @@ -196,11 +183,10 @@ |
| 196 | "effect": "catalog:", | 183 | "effect": "catalog:", |
| 197 | }, | 184 | }, |
| 198 | "devDependencies": { | 185 | "devDependencies": { |
| 199 | "@effect/language-service": "catalog:", | ||
| 200 | "@effect/openapi-generator": "catalog:", | 186 | "@effect/openapi-generator": "catalog:", |
| 201 | "@effect/platform-node": "catalog:", | 187 | "@effect/platform-node": "catalog:", |
| 202 | "@effect/vitest": "catalog:", | 188 | "@effect/vitest": "catalog:", |
| 203 | "typescript": "catalog:", | 189 | "@types/node": "catalog:", |
| 204 | "vitest": "catalog:", | 190 | "vitest": "catalog:", |
| 205 | }, | 191 | }, |
| 206 | }, | 192 | }, |
| ... | @@ -211,11 +197,9 @@ | ... | @@ -211,11 +197,9 @@ |
| 211 | "effect": "catalog:", | 197 | "effect": "catalog:", |
| 212 | }, | 198 | }, |
| 213 | "devDependencies": { | 199 | "devDependencies": { |
| 214 | "@effect/language-service": "catalog:", | ||
| 215 | "@effect/platform-node": "catalog:", | 200 | "@effect/platform-node": "catalog:", |
| 216 | "@effect/vitest": "catalog:", | 201 | "@effect/vitest": "catalog:", |
| 217 | "@types/node": "catalog:", | 202 | "@types/node": "catalog:", |
| 218 | "typescript": "catalog:", | ||
| 219 | "vitest": "catalog:", | 203 | "vitest": "catalog:", |
| 220 | }, | 204 | }, |
| 221 | }, | 205 | }, |
| ... | @@ -227,11 +211,9 @@ | ... | @@ -227,11 +211,9 @@ |
| 227 | "effect": "catalog:", | 211 | "effect": "catalog:", |
| 228 | }, | 212 | }, |
| 229 | "devDependencies": { | 213 | "devDependencies": { |
| 230 | "@effect/language-service": "catalog:", | ||
| 231 | "@effect/platform-node": "catalog:", | 214 | "@effect/platform-node": "catalog:", |
| 232 | "@effect/vitest": "catalog:", | 215 | "@effect/vitest": "catalog:", |
| 233 | "@types/node": "catalog:", | 216 | "@types/node": "catalog:", |
| 234 | "typescript": "catalog:", | ||
| 235 | "vitest": "catalog:", | 217 | "vitest": "catalog:", |
| 236 | }, | 218 | }, |
| 237 | }, | 219 | }, |
| ... | @@ -242,10 +224,8 @@ | ... | @@ -242,10 +224,8 @@ |
| 242 | "effect": "catalog:", | 224 | "effect": "catalog:", |
| 243 | }, | 225 | }, |
| 244 | "devDependencies": { | 226 | "devDependencies": { |
| 245 | "@effect/language-service": "catalog:", | ||
| 246 | "@effect/vitest": "catalog:", | 227 | "@effect/vitest": "catalog:", |
| 247 | "@types/node": "catalog:", | 228 | "@types/node": "catalog:", |
| 248 | "typescript": "catalog:", | ||
| 249 | "vitest": "catalog:", | 229 | "vitest": "catalog:", |
| 250 | }, | 230 | }, |
| 251 | }, | 231 | }, |
| ... | @@ -259,10 +239,8 @@ | ... | @@ -259,10 +239,8 @@ |
| 259 | "effect": "catalog:", | 239 | "effect": "catalog:", |
| 260 | }, | 240 | }, |
| 261 | "devDependencies": { | 241 | "devDependencies": { |
| 262 | "@effect/language-service": "catalog:", | ||
| 263 | "@effect/vitest": "catalog:", | 242 | "@effect/vitest": "catalog:", |
| 264 | "@types/bun": "catalog:", | 243 | "@types/bun": "catalog:", |
| 265 | "typescript": "catalog:", | ||
| 266 | "vitest": "catalog:", | 244 | "vitest": "catalog:", |
| 267 | }, | 245 | }, |
| 268 | }, | 246 | }, |
| ... | @@ -286,19 +264,20 @@ | ... | @@ -286,19 +264,20 @@ |
| 286 | }, | 264 | }, |
| 287 | "catalog": { | 265 | "catalog": { |
| 288 | "@effect/atom-react": "4.0.0-beta.73", | 266 | "@effect/atom-react": "4.0.0-beta.73", |
| 289 | "@effect/language-service": "0.84.2", | ||
| 290 | "@effect/openapi-generator": "4.0.0-beta.73", | 267 | "@effect/openapi-generator": "4.0.0-beta.73", |
| 291 | "@effect/platform-bun": "4.0.0-beta.73", | 268 | "@effect/platform-bun": "4.0.0-beta.73", |
| 292 | "@effect/platform-node": "4.0.0-beta.73", | 269 | "@effect/platform-node": "4.0.0-beta.73", |
| 293 | "@effect/platform-node-shared": "4.0.0-beta.73", | 270 | "@effect/platform-node-shared": "4.0.0-beta.73", |
| 294 | "@effect/sql-sqlite-bun": "4.0.0-beta.73", | 271 | "@effect/sql-sqlite-bun": "4.0.0-beta.73", |
| 272 | "@effect/tsgo": "0.11.4", | ||
| 295 | "@effect/vitest": "4.0.0-beta.73", | 273 | "@effect/vitest": "4.0.0-beta.73", |
| 296 | "@pierre/diffs": "1.1.20", | 274 | "@pierre/diffs": "1.1.20", |
| 297 | "@types/bun": "^1.3.11", | 275 | "@types/bun": "^1.3.11", |
| 298 | "@types/node": "^24.10.13", | 276 | "@types/node": "^24.10.13", |
| 277 | "@typescript/native-preview": "7.0.0-dev.20260527.2", | ||
| 299 | "effect": "4.0.0-beta.73", | 278 | "effect": "4.0.0-beta.73", |
| 300 | "tsdown": "^0.20.3", | 279 | "tsdown": "^0.20.3", |
| 301 | "typescript": "^5.7.3", | 280 | "typescript": "~6.0.3", |
| 302 | "vitest": "^4.0.0", | 281 | "vitest": "^4.0.0", |
| 303 | }, | 282 | }, |
| 304 | "packages": { | 283 | "packages": { |
| ... | @@ -402,8 +381,6 @@ | ... | @@ -402,8 +381,6 @@ |
| 402 | 381 | ||
| 403 | "@effect/atom-react": ["@effect/atom-react@4.0.0-beta.73", "", { "peerDependencies": { "effect": "^4.0.0-beta.73", "react": "^19.2.4", "scheduler": "*" } }, "sha512-RjNqEMV3z3iEFRBtJ1RVuxBNFMYxhDo2iRwck3kBYjrBuXWrKIRyqnunWJdL2KX97Gqp0orxaujG7qnIA5aIEA=="], | 382 | "@effect/atom-react": ["@effect/atom-react@4.0.0-beta.73", "", { "peerDependencies": { "effect": "^4.0.0-beta.73", "react": "^19.2.4", "scheduler": "*" } }, "sha512-RjNqEMV3z3iEFRBtJ1RVuxBNFMYxhDo2iRwck3kBYjrBuXWrKIRyqnunWJdL2KX97Gqp0orxaujG7qnIA5aIEA=="], |
| 404 | 383 | ||
| 405 | "@effect/language-service": ["@effect/language-service@0.84.2", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-l04qNxpiA8rY5yXWckRPJ7Mk5MNerXuNymSFf+IdflfI5i8jgL1bpBNLuP6ijg7wgjdHc/KmTnCj2kT0SCntuA=="], | ||
| 406 | |||
| 407 | "@effect/openapi-generator": ["@effect/openapi-generator@4.0.0-beta.73", "", { "peerDependencies": { "@effect/platform-node": "^4.0.0-beta.73", "effect": "^4.0.0-beta.73" }, "bin": { "openapigen": "dist/bin.js" } }, "sha512-tN1mKreMo6kypkuPy8Jt3eGoI0DberzD2/5XxEh17lTdyLg7/SUZv3LssRxtzO5+uIYzLNIHfT2zESz7gjCnwA=="], | 384 | "@effect/openapi-generator": ["@effect/openapi-generator@4.0.0-beta.73", "", { "peerDependencies": { "@effect/platform-node": "^4.0.0-beta.73", "effect": "^4.0.0-beta.73" }, "bin": { "openapigen": "dist/bin.js" } }, "sha512-tN1mKreMo6kypkuPy8Jt3eGoI0DberzD2/5XxEh17lTdyLg7/SUZv3LssRxtzO5+uIYzLNIHfT2zESz7gjCnwA=="], |
| 408 | 385 | ||
| 409 | "@effect/platform-bun": ["@effect/platform-bun@4.0.0-beta.73", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.73" }, "peerDependencies": { "effect": "^4.0.0-beta.73" } }, "sha512-AQcE89eEVp0xA3SafaswiHPfo6V2YPg7T6PQbQqYK4/S2Sia5cadCm/6y7pfRmuOd4jkWI6VMbNtEDkM0NOBpw=="], | 386 | "@effect/platform-bun": ["@effect/platform-bun@4.0.0-beta.73", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.73" }, "peerDependencies": { "effect": "^4.0.0-beta.73" } }, "sha512-AQcE89eEVp0xA3SafaswiHPfo6V2YPg7T6PQbQqYK4/S2Sia5cadCm/6y7pfRmuOd4jkWI6VMbNtEDkM0NOBpw=="], |
| ... | @@ -414,6 +391,22 @@ | ... | @@ -414,6 +391,22 @@ |
| 414 | 391 | ||
| 415 | "@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-beta.73", "", { "peerDependencies": { "effect": "^4.0.0-beta.73" } }, "sha512-dkTDDeBLjaKo7h1IE049Oj2BDKQOT+Kc57KbBVaSk36dRdsEmVspRMP7OGbZj3etJU3lL1GJi1BIfnb4N3uMRw=="], | 392 | "@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-beta.73", "", { "peerDependencies": { "effect": "^4.0.0-beta.73" } }, "sha512-dkTDDeBLjaKo7h1IE049Oj2BDKQOT+Kc57KbBVaSk36dRdsEmVspRMP7OGbZj3etJU3lL1GJi1BIfnb4N3uMRw=="], |
| 416 | 393 | ||
| 394 | "@effect/tsgo": ["@effect/tsgo@0.11.4", "", { "optionalDependencies": { "@effect/tsgo-darwin-arm64": "0.11.4", "@effect/tsgo-darwin-x64": "0.11.4", "@effect/tsgo-linux-arm": "0.11.4", "@effect/tsgo-linux-arm64": "0.11.4", "@effect/tsgo-linux-x64": "0.11.4", "@effect/tsgo-win32-arm64": "0.11.4", "@effect/tsgo-win32-x64": "0.11.4" }, "bin": { "effect-tsgo": "dist/effect-tsgo.js" } }, "sha512-wliq5Dis2gLoIUKoCRT3Iv5kpO+fKrUBJPPxIsHADeirk9HMQevKvYaBpGS3Khw1tNLmoQWsSX559owJAdHgBA=="], | ||
| 395 | |||
| 396 | "@effect/tsgo-darwin-arm64": ["@effect/tsgo-darwin-arm64@0.11.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rslT4W8tWY8pdd48kDpY7Q+yo0xkrmcEySG1+sJfb06w7TwbywjHsGlC0BmcUaQt0qmLY+BApbWWDfZw7fgwjw=="], | ||
| 397 | |||
| 398 | "@effect/tsgo-darwin-x64": ["@effect/tsgo-darwin-x64@0.11.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-p3v3j+zp7L7yx5ctjvA1W85I4WjOpbOcga8kUu5MFEKfYfsApxUHXwsunCVbUKwrpXqcTc0sw9AjnCNs6i6GRw=="], | ||
| 399 | |||
| 400 | "@effect/tsgo-linux-arm": ["@effect/tsgo-linux-arm@0.11.4", "", { "os": "linux", "cpu": "arm" }, "sha512-uXsw+IbO+ltn/fbhOWWqXK8ZW3Qa5EZD+wnGbF3gIGWINthbF+/7X+CgRzvcgLBWeBfV6F83hAmOaEZ4hQmd+w=="], | ||
| 401 | |||
| 402 | "@effect/tsgo-linux-arm64": ["@effect/tsgo-linux-arm64@0.11.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-dz5ZIQUnRzN9mpVcELYCmVERpmstes5rVHbKUb7DOWCbrbupT3tV1LCzOaNX9sIsoBKmpvdGvAWEPLHgymSgTQ=="], | ||
| 403 | |||
| 404 | "@effect/tsgo-linux-x64": ["@effect/tsgo-linux-x64@0.11.4", "", { "os": "linux", "cpu": "x64" }, "sha512-P3m7Y4FJtziL13Muffyb99AnQeTRvo0/knfYRqoHKNwYUaNM59RO3qFi5y57Hasgd8rKat0xTPmUkK6koZPPFQ=="], | ||
| 405 | |||
| 406 | "@effect/tsgo-win32-arm64": ["@effect/tsgo-win32-arm64@0.11.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-FKLm9Y+luZSdLpfkbdw8VXa8xy0zR+Asg078qemqHHGwRQLDVGjvIk7tj1HxBM6VQN+TwsofDd225ht83kMk8w=="], | ||
| 407 | |||
| 408 | "@effect/tsgo-win32-x64": ["@effect/tsgo-win32-x64@0.11.4", "", { "os": "win32", "cpu": "x64" }, "sha512-oc4Y8TbLlv0b1deAILAEep1N6pnSS1d4pk7gJJM4NDXrTKWDyEulO6tXwRQ6vWkO2lhLTUVWHDFfzmMJj3HxPQ=="], | ||
| 409 | |||
| 417 | "@effect/vitest": ["@effect/vitest@4.0.0-beta.73", "", { "peerDependencies": { "effect": "^4.0.0-beta.73", "vitest": "^3.0.0 || ^4.0.0" } }, "sha512-HIZa0aekh0ak1YfzCv8GTN75Vbvxp8g+W+z9KczvtUT+LvitX3i9nhLWZLKRrUP1LaJFLPJS2UG9ZGXjxgbjBg=="], | 410 | "@effect/vitest": ["@effect/vitest@4.0.0-beta.73", "", { "peerDependencies": { "effect": "^4.0.0-beta.73", "vitest": "^3.0.0 || ^4.0.0" } }, "sha512-HIZa0aekh0ak1YfzCv8GTN75Vbvxp8g+W+z9KczvtUT+LvitX3i9nhLWZLKRrUP1LaJFLPJS2UG9ZGXjxgbjBg=="], |
| 418 | 411 | ||
| 419 | "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], | 412 | "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], |
| ... | @@ -934,6 +927,22 @@ | ... | @@ -934,6 +927,22 @@ |
| 934 | 927 | ||
| 935 | "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], | 928 | "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], |
| 936 | 929 | ||
| 930 | "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260527.2", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260527.2", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260527.2", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260527.2", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260527.2", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260527.2", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260527.2", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260527.2" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-piqkDwikVeizCFqA1lcwI5F4wOAtBdxuliWe77ApBNRyBPPvfCJB+u/HYi9/8t5nd0sWvFs6/qt/AzJ1CCoykQ=="], | ||
| 931 | |||
| 932 | "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260527.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-3LqSu4DlxkEfeC/Z/29QMCJn5jjkDtXI7LYuxfmjdmAatS6umDKqm8J17fnP/7fyrZUMBTIYRwSDpChGV3G1ew=="], | ||
| 933 | |||
| 934 | "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260527.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-H4+sxE9qaBbLF83wMdWE0FsgfK0Pom+/O+/oxqyGzhVkDJlNt3vfpgQZMit48/Gm44AacGfBggJ9Dhbi3aeSFw=="], | ||
| 935 | |||
| 936 | "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260527.2", "", { "os": "linux", "cpu": "arm" }, "sha512-6I9Cv9ozwfS9zB9vRQDPIYseLX3artEO9jl3yVgLj4ishwlSF4cWAbIsjl5IztPaEgHv8coej/6tX1D0uaBzXg=="], | ||
| 937 | |||
| 938 | "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260527.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-BGUDMjC2Z3TTdZRkGGwhBLelkP5UYgO2rbep8aF4dS3fu7T5lFPPrnfS6EgqJgie+cF5Fsev7xEq8wWyBDM+lg=="], | ||
| 939 | |||
| 940 | "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260527.2", "", { "os": "linux", "cpu": "x64" }, "sha512-vpazOu+ozlxBo8U57YJMzsOPuxAV8H7fu36KJ8ea8At/D8pdGmOAy5TuB+9OBQV9JDe0OXJMy2kmbhOpmkTAmA=="], | ||
| 941 | |||
| 942 | "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260527.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-DBFnFE3V6AITkPO1K1VxXf3yEZKjU2FwtXlNwRqhzDu0rrL2SsJHOSrBDX+OacTxQFzZMxFcpiuhV8jHZALPEg=="], | ||
| 943 | |||
| 944 | "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260527.2", "", { "os": "win32", "cpu": "x64" }, "sha512-1tBlErMvQgcMqqYwsx4tytupcjCJcOUXD3vBn1Wb/kAvus1FzWQAFE0fcKBvLfcqLQfTiiEwKKEtbLjGmakqqg=="], | ||
| 945 | |||
| 937 | "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], | 946 | "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], |
| 938 | 947 | ||
| 939 | "@vercel/config": ["@vercel/config@0.3.0", "", { "dependencies": { "@vercel/routing-utils": "6.2.0", "pretty-cache-header": "^1.0.0", "zod": "^3.22.0" }, "bin": { "config": "dist/cli.js" } }, "sha512-Tf5k5y2F478oTiQcU5R8Ntix1UejE6NdduZnI7aa1XXxjCtifX1XdRS/D2uTjiQAwIL3pLa1LSAN80ABbba+TQ=="], | 948 | "@vercel/config": ["@vercel/config@0.3.0", "", { "dependencies": { "@vercel/routing-utils": "6.2.0", "pretty-cache-header": "^1.0.0", "zod": "^3.22.0" }, "bin": { "config": "dist/cli.js" } }, "sha512-Tf5k5y2F478oTiQcU5R8Ntix1UejE6NdduZnI7aa1XXxjCtifX1XdRS/D2uTjiQAwIL3pLa1LSAN80ABbba+TQ=="], |
| ... | @@ -1982,7 +1991,7 @@ | ... | @@ -1982,7 +1991,7 @@ |
| 1982 | 1991 | ||
| 1983 | "typesafe-path": ["typesafe-path@0.2.2", "", {}, "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA=="], | 1992 | "typesafe-path": ["typesafe-path@0.2.2", "", {}, "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA=="], |
| 1984 | 1993 | ||
| 1985 | "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], | 1994 | "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], |
| 1986 | 1995 | ||
| 1987 | "typescript-auto-import-cache": ["typescript-auto-import-cache@0.3.6", "", { "dependencies": { "semver": "^7.3.8" } }, "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ=="], | 1996 | "typescript-auto-import-cache": ["typescript-auto-import-cache@0.3.6", "", { "dependencies": { "semver": "^7.3.8" } }, "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ=="], |
| 1988 | 1997 |
oxlint-plugin-t3code/package.json+1-3| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | "private": true, | 3 | "private": true, |
| 4 | "type": "module", | 4 | "type": "module", |
| 5 | "scripts": { | 5 | "scripts": { |
| 6 | "typecheck": "tsc --noEmit", | 6 | "typecheck": "tsgo --noEmit", |
| 7 | "test": "vitest run" | 7 | "test": "vitest run" |
| 8 | }, | 8 | }, |
| 9 | "dependencies": { | 9 | "dependencies": { |
| ... | @@ -12,10 +12,8 @@ | ... | @@ -12,10 +12,8 @@ |
| 12 | "effect": "catalog:" | 12 | "effect": "catalog:" |
| 13 | }, | 13 | }, |
| 14 | "devDependencies": { | 14 | "devDependencies": { |
| 15 | "@effect/language-service": "catalog:", | ||
| 16 | "@effect/vitest": "catalog:", | 15 | "@effect/vitest": "catalog:", |
| 17 | "@types/bun": "catalog:", | 16 | "@types/bun": "catalog:", |
| 18 | "typescript": "catalog:", | ||
| 19 | "vitest": "catalog:" | 17 | "vitest": "catalog:" |
| 20 | } | 18 | } |
| 21 | } | 19 | } |
package.json+6-5| ... | @@ -17,18 +17,19 @@ | ... | @@ -17,18 +17,19 @@ |
| 17 | "@effect/platform-node-shared": "4.0.0-beta.73", | 17 | "@effect/platform-node-shared": "4.0.0-beta.73", |
| 18 | "@effect/sql-sqlite-bun": "4.0.0-beta.73", | 18 | "@effect/sql-sqlite-bun": "4.0.0-beta.73", |
| 19 | "@effect/vitest": "4.0.0-beta.73", | 19 | "@effect/vitest": "4.0.0-beta.73", |
| 20 | "@effect/language-service": "0.84.2", | 20 | "@effect/tsgo": "0.11.4", |
| 21 | "@pierre/diffs": "1.1.20", | 21 | "@pierre/diffs": "1.1.20", |
| 22 | "@types/bun": "^1.3.11", | 22 | "@types/bun": "^1.3.11", |
| 23 | "@types/node": "^24.10.13", | 23 | "@types/node": "^24.10.13", |
| 24 | "@typescript/native-preview": "7.0.0-dev.20260527.2", | ||
| 24 | "tsdown": "^0.20.3", | 25 | "tsdown": "^0.20.3", |
| 25 | "typescript": "^5.7.3", | 26 | "typescript": "~6.0.3", |
| 26 | "vitest": "^4.0.0" | 27 | "vitest": "^4.0.0" |
| 27 | } | 28 | } |
| 28 | }, | 29 | }, |
| 29 | "type": "module", | 30 | "type": "module", |
| 30 | "scripts": { | 31 | "scripts": { |
| 31 | "prepare": "effect-language-service patch", | 32 | "prepare": "effect-tsgo patch", |
| 32 | "dev": "node scripts/dev-runner.ts dev", | 33 | "dev": "node scripts/dev-runner.ts dev", |
| 33 | "dev:server": "node scripts/dev-runner.ts dev:server", | 34 | "dev:server": "node scripts/dev-runner.ts dev:server", |
| 34 | "dev:web": "node scripts/dev-runner.ts dev:web", | 35 | "dev:web": "node scripts/dev-runner.ts dev:web", |
| ... | @@ -61,13 +62,13 @@ | ... | @@ -61,13 +62,13 @@ |
| 61 | "sync:vscode-icons": "node scripts/sync-vscode-icons.mjs" | 62 | "sync:vscode-icons": "node scripts/sync-vscode-icons.mjs" |
| 62 | }, | 63 | }, |
| 63 | "devDependencies": { | 64 | "devDependencies": { |
| 64 | "@effect/language-service": "catalog:", | 65 | "@effect/tsgo": "catalog:", |
| 65 | "@oxlint/plugins": "^1.63.0", | 66 | "@oxlint/plugins": "^1.63.0", |
| 66 | "@types/node": "catalog:", | 67 | "@types/node": "catalog:", |
| 68 | "@typescript/native-preview": "catalog:", | ||
| 67 | "oxfmt": "^0.40.0", | 69 | "oxfmt": "^0.40.0", |
| 68 | "oxlint": "^1.63.0", | 70 | "oxlint": "^1.63.0", |
| 69 | "turbo": "^2.3.3", | 71 | "turbo": "^2.3.3", |
| 70 | "typescript": "catalog:", | ||
| 71 | "vitest": "catalog:" | 72 | "vitest": "catalog:" |
| 72 | }, | 73 | }, |
| 73 | "overrides": { | 74 | "overrides": { |
packages/client-runtime/package.json+1-3| ... | @@ -9,7 +9,7 @@ | ... | @@ -9,7 +9,7 @@ |
| 9 | } | 9 | } |
| 10 | }, | 10 | }, |
| 11 | "scripts": { | 11 | "scripts": { |
| 12 | "typecheck": "tsc --noEmit", | 12 | "typecheck": "tsgo --noEmit", |
| 13 | "test": "vitest run" | 13 | "test": "vitest run" |
| 14 | }, | 14 | }, |
| 15 | "dependencies": { | 15 | "dependencies": { |
| ... | @@ -18,8 +18,6 @@ | ... | @@ -18,8 +18,6 @@ |
| 18 | "effect": "catalog:" | 18 | "effect": "catalog:" |
| 19 | }, | 19 | }, |
| 20 | "devDependencies": { | 20 | "devDependencies": { |
| 21 | "@effect/language-service": "catalog:", | ||
| 22 | "typescript": "catalog:", | ||
| 23 | "vitest": "catalog:" | 21 | "vitest": "catalog:" |
| 24 | } | 22 | } |
| 25 | } | 23 | } |
packages/contracts/package.json+1-3| ... | @@ -17,16 +17,14 @@ | ... | @@ -17,16 +17,14 @@ |
| 17 | } | 17 | } |
| 18 | }, | 18 | }, |
| 19 | "scripts": { | 19 | "scripts": { |
| 20 | "typecheck": "tsc --noEmit", | 20 | "typecheck": "tsgo --noEmit", |
| 21 | "test": "vitest run" | 21 | "test": "vitest run" |
| 22 | }, | 22 | }, |
| 23 | "dependencies": { | 23 | "dependencies": { |
| 24 | "effect": "catalog:" | 24 | "effect": "catalog:" |
| 25 | }, | 25 | }, |
| 26 | "devDependencies": { | 26 | "devDependencies": { |
| 27 | "@effect/language-service": "catalog:", | ||
| 28 | "@effect/vitest": "catalog:", | 27 | "@effect/vitest": "catalog:", |
| 29 | "typescript": "catalog:", | ||
| 30 | "vitest": "catalog:" | 28 | "vitest": "catalog:" |
| 31 | } | 29 | } |
| 32 | } | 30 | } |
packages/contracts/src/orchestration.test.ts+4-3| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | import assert from "node:assert/strict"; | 1 | import { assert, it } from "@effect/vitest"; |
| 2 | import { it } from "@effect/vitest"; | ||
| 3 | import * as Effect from "effect/Effect"; | 2 | import * as Effect from "effect/Effect"; |
| 4 | import * as Schema from "effect/Schema"; | 3 | import * as Schema from "effect/Schema"; |
| 5 | 4 | ||
| ... | @@ -379,7 +378,9 @@ it.effect("decodes thread archived and unarchived events", () => | ... | @@ -379,7 +378,9 @@ it.effect("decodes thread archived and unarchived events", () => |
| 379 | }, | 378 | }, |
| 380 | }); | 379 | }); |
| 381 | 380 | ||
| 382 | assert.strictEqual(archived.type, "thread.archived"); | 381 | if (archived.type !== "thread.archived") { |
| 382 | assert.fail(`Expected thread.archived event, received ${archived.type}.`); | ||
| 383 | } | ||
| 383 | assert.strictEqual(archived.payload.archivedAt, "2026-01-01T00:00:00.000Z"); | 384 | assert.strictEqual(archived.payload.archivedAt, "2026-01-01T00:00:00.000Z"); |
| 384 | assert.strictEqual(unarchived.type, "thread.unarchived"); | 385 | assert.strictEqual(unarchived.type, "thread.unarchived"); |
| 385 | }), | 386 | }), |
packages/effect-acp/package.json+2-3| ... | @@ -33,7 +33,7 @@ | ... | @@ -33,7 +33,7 @@ |
| 33 | } | 33 | } |
| 34 | }, | 34 | }, |
| 35 | "scripts": { | 35 | "scripts": { |
| 36 | "typecheck": "tsc --noEmit", | 36 | "typecheck": "tsgo --noEmit", |
| 37 | "test": "vitest run", | 37 | "test": "vitest run", |
| 38 | "generate": "bun run scripts/generate.ts" | 38 | "generate": "bun run scripts/generate.ts" |
| 39 | }, | 39 | }, |
| ... | @@ -41,11 +41,10 @@ | ... | @@ -41,11 +41,10 @@ |
| 41 | "effect": "catalog:" | 41 | "effect": "catalog:" |
| 42 | }, | 42 | }, |
| 43 | "devDependencies": { | 43 | "devDependencies": { |
| 44 | "@effect/language-service": "catalog:", | ||
| 45 | "@effect/openapi-generator": "catalog:", | 44 | "@effect/openapi-generator": "catalog:", |
| 46 | "@effect/platform-node": "catalog:", | 45 | "@effect/platform-node": "catalog:", |
| 47 | "@effect/vitest": "catalog:", | 46 | "@effect/vitest": "catalog:", |
| 48 | "typescript": "catalog:", | 47 | "@types/node": "catalog:", |
| 49 | "vitest": "catalog:" | 48 | "vitest": "catalog:" |
| 50 | } | 49 | } |
| 51 | } | 50 | } |
packages/effect-acp/scripts/generate.ts+3-6| ... | @@ -146,7 +146,7 @@ function collectSchemaEntries( | ... | @@ -146,7 +146,7 @@ function collectSchemaEntries( |
| 146 | return entries; | 146 | return entries; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.Json.Type { | 149 | function normalizeNullableTypes(value: Schema.Json): Schema.Json { |
| 150 | if (Array.isArray(value)) { | 150 | if (Array.isArray(value)) { |
| 151 | return value.map(normalizeNullableTypes); | 151 | return value.map(normalizeNullableTypes); |
| 152 | } | 152 | } |
| ... | @@ -158,10 +158,7 @@ function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.J | ... | @@ -158,10 +158,7 @@ function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.J |
| 158 | key, | 158 | key, |
| 159 | normalizeNullableTypes(child), | 159 | normalizeNullableTypes(child), |
| 160 | ]); | 160 | ]); |
| 161 | const normalizedObject = Object.fromEntries(normalizedEntries) as Record< | 161 | const normalizedObject = Object.fromEntries(normalizedEntries) as Record<string, Schema.Json>; |
| 162 | string, | ||
| 163 | typeof Schema.Json.Type | ||
| 164 | >; | ||
| 165 | const typeValue = normalizedObject.type; | 162 | const typeValue = normalizedObject.type; |
| 166 | 163 | ||
| 167 | if (!Array.isArray(typeValue)) { | 164 | if (!Array.isArray(typeValue)) { |
| ... | @@ -179,7 +176,7 @@ function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.J | ... | @@ -179,7 +176,7 @@ function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.J |
| 179 | } | 176 | } |
| 180 | const nonNullType = nonNullTypes[0]!; | 177 | const nonNullType = nonNullTypes[0]!; |
| 181 | 178 | ||
| 182 | const nextObject: Record<string, typeof Schema.Json.Type> = {}; | 179 | const nextObject: Record<string, Schema.Json> = {}; |
| 183 | for (const [key, child] of Object.entries(normalizedObject)) { | 180 | for (const [key, child] of Object.entries(normalizedObject)) { |
| 184 | if (key !== "type") { | 181 | if (key !== "type") { |
| 185 | nextObject[key] = child; | 182 | nextObject[key] = child; |
packages/effect-acp/src/agent.ts+3-1| ... | @@ -207,7 +207,9 @@ export interface AcpAgentShape { | ... | @@ -207,7 +207,9 @@ export interface AcpAgentShape { |
| 207 | ) => Effect.Effect<void>; | 207 | ) => Effect.Effect<void>; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | export class AcpAgent extends Context.Service<AcpAgent, AcpAgentShape>()("effect-acp/AcpAgent") {} | 210 | export class AcpAgent extends Context.Service<AcpAgent, AcpAgentShape>()( |
| 211 | "effect-acp/agent/AcpAgent", | ||
| 212 | ) {} | ||
| 211 | 213 | ||
| 212 | interface AcpCoreAgentRequestHandlers { | 214 | interface AcpCoreAgentRequestHandlers { |
| 213 | initialize?: ( | 215 | initialize?: ( |
packages/effect-acp/src/client.ts+1-1| ... | @@ -263,7 +263,7 @@ export interface AcpClientShape { | ... | @@ -263,7 +263,7 @@ export interface AcpClientShape { |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | export class AcpClient extends Context.Service<AcpClient, AcpClientShape>()( | 265 | export class AcpClient extends Context.Service<AcpClient, AcpClientShape>()( |
| 266 | "effect-acp/AcpClient", | 266 | "effect-acp/client/AcpClient", |
| 267 | ) {} | 267 | ) {} |
| 268 | 268 | ||
| 269 | interface AcpCoreRequestHandlers { | 269 | interface AcpCoreRequestHandlers { |
packages/effect-acp/src/protocol.ts+2-2| ... | @@ -29,12 +29,12 @@ export type AcpIncomingNotification = | ... | @@ -29,12 +29,12 @@ export type AcpIncomingNotification = |
| 29 | | { | 29 | | { |
| 30 | readonly _tag: "SessionUpdate"; | 30 | readonly _tag: "SessionUpdate"; |
| 31 | readonly method: typeof CLIENT_METHODS.session_update; | 31 | readonly method: typeof CLIENT_METHODS.session_update; |
| 32 | readonly params: typeof AcpSchema.SessionNotification.Type; | 32 | readonly params: AcpSchema.SessionNotification; |
| 33 | } | 33 | } |
| 34 | | { | 34 | | { |
| 35 | readonly _tag: "ElicitationComplete"; | 35 | readonly _tag: "ElicitationComplete"; |
| 36 | readonly method: typeof CLIENT_METHODS.session_elicitation_complete; | 36 | readonly method: typeof CLIENT_METHODS.session_elicitation_complete; |
| 37 | readonly params: typeof AcpSchema.ElicitationCompleteNotification.Type; | 37 | readonly params: AcpSchema.ElicitationCompleteNotification; |
| 38 | } | 38 | } |
| 39 | | { | 39 | | { |
| 40 | readonly _tag: "ExtNotification"; | 40 | readonly _tag: "ExtNotification"; |
packages/effect-acp/tsconfig.json+3-1| ... | @@ -1,5 +1,7 @@ | ... | @@ -1,5 +1,7 @@ |
| 1 | { | 1 | { |
| 2 | "extends": "../../tsconfig.base.json", | 2 | "extends": "../../tsconfig.base.json", |
| 3 | "compilerOptions": {}, | 3 | "compilerOptions": { |
| 4 | "types": ["node"] | ||
| 5 | }, | ||
| 4 | "include": ["src", "scripts", "test"] | 6 | "include": ["src", "scripts", "test"] |
| 5 | } | 7 | } |
packages/effect-codex-app-server/package.json+2-3| ... | @@ -25,7 +25,7 @@ | ... | @@ -25,7 +25,7 @@ |
| 25 | } | 25 | } |
| 26 | }, | 26 | }, |
| 27 | "scripts": { | 27 | "scripts": { |
| 28 | "typecheck": "tsc --noEmit", | 28 | "typecheck": "tsgo --noEmit", |
| 29 | "test": "vitest run", | 29 | "test": "vitest run", |
| 30 | "generate": "bun run scripts/generate.ts", | 30 | "generate": "bun run scripts/generate.ts", |
| 31 | "probe": "bun run test/examples/codex-app-server-probe.ts" | 31 | "probe": "bun run test/examples/codex-app-server-probe.ts" |
| ... | @@ -34,11 +34,10 @@ | ... | @@ -34,11 +34,10 @@ |
| 34 | "effect": "catalog:" | 34 | "effect": "catalog:" |
| 35 | }, | 35 | }, |
| 36 | "devDependencies": { | 36 | "devDependencies": { |
| 37 | "@effect/language-service": "catalog:", | ||
| 38 | "@effect/openapi-generator": "catalog:", | 37 | "@effect/openapi-generator": "catalog:", |
| 39 | "@effect/platform-node": "catalog:", | 38 | "@effect/platform-node": "catalog:", |
| 40 | "@effect/vitest": "catalog:", | 39 | "@effect/vitest": "catalog:", |
| 41 | "typescript": "catalog:", | 40 | "@types/node": "catalog:", |
| 42 | "vitest": "catalog:" | 41 | "vitest": "catalog:" |
| 43 | } | 42 | } |
| 44 | } | 43 | } |
packages/effect-codex-app-server/scripts/generate.ts+12-15| ... | @@ -70,7 +70,7 @@ class GeneratorError extends Schema.TaggedErrorClass<GeneratorError>()("Generato | ... | @@ -70,7 +70,7 @@ class GeneratorError extends Schema.TaggedErrorClass<GeneratorError>()("Generato |
| 70 | } | 70 | } |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | const ManualSchemas: Record<string, typeof Schema.Json.Type> = { | 73 | const ManualSchemas: Record<string, Schema.Json> = { |
| 74 | GetAuthStatusParams: { | 74 | GetAuthStatusParams: { |
| 75 | type: "object", | 75 | type: "object", |
| 76 | title: "GetAuthStatusParams", | 76 | title: "GetAuthStatusParams", |
| ... | @@ -218,7 +218,7 @@ function collectSchemaEntries( | ... | @@ -218,7 +218,7 @@ function collectSchemaEntries( |
| 218 | return entries; | 218 | return entries; |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.Json.Type { | 221 | function normalizeNullableTypes(value: Schema.Json): Schema.Json { |
| 222 | if (Array.isArray(value)) { | 222 | if (Array.isArray(value)) { |
| 223 | return value.map(normalizeNullableTypes); | 223 | return value.map(normalizeNullableTypes); |
| 224 | } | 224 | } |
| ... | @@ -230,10 +230,7 @@ function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.J | ... | @@ -230,10 +230,7 @@ function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.J |
| 230 | key, | 230 | key, |
| 231 | normalizeNullableTypes(child), | 231 | normalizeNullableTypes(child), |
| 232 | ]); | 232 | ]); |
| 233 | const normalizedObject = Object.fromEntries(normalizedEntries) as Record< | 233 | const normalizedObject = Object.fromEntries(normalizedEntries) as Record<string, Schema.Json>; |
| 234 | string, | ||
| 235 | typeof Schema.Json.Type | ||
| 236 | >; | ||
| 237 | const typeValue = normalizedObject.type; | 234 | const typeValue = normalizedObject.type; |
| 238 | 235 | ||
| 239 | if (!Array.isArray(typeValue)) { | 236 | if (!Array.isArray(typeValue)) { |
| ... | @@ -251,7 +248,7 @@ function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.J | ... | @@ -251,7 +248,7 @@ function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.J |
| 251 | } | 248 | } |
| 252 | const nonNullType = nonNullTypes[0]!; | 249 | const nonNullType = nonNullTypes[0]!; |
| 253 | 250 | ||
| 254 | const nextObject: Record<string, typeof Schema.Json.Type> = {}; | 251 | const nextObject: Record<string, Schema.Json> = {}; |
| 255 | for (const [key, child] of Object.entries(normalizedObject)) { | 252 | for (const [key, child] of Object.entries(normalizedObject)) { |
| 256 | if (key !== "type") { | 253 | if (key !== "type") { |
| 257 | nextObject[key] = child; | 254 | nextObject[key] = child; |
| ... | @@ -269,7 +266,7 @@ function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.J | ... | @@ -269,7 +266,7 @@ function normalizeNullableTypes(value: typeof Schema.Json.Type): typeof Schema.J |
| 269 | }; | 266 | }; |
| 270 | } | 267 | } |
| 271 | 268 | ||
| 272 | function stripNullDefaults(value: typeof Schema.Json.Type): typeof Schema.Json.Type { | 269 | function stripNullDefaults(value: Schema.Json): Schema.Json { |
| 273 | if (Array.isArray(value)) { | 270 | if (Array.isArray(value)) { |
| 274 | return value.map(stripNullDefaults); | 271 | return value.map(stripNullDefaults); |
| 275 | } | 272 | } |
| ... | @@ -281,7 +278,7 @@ function stripNullDefaults(value: typeof Schema.Json.Type): typeof Schema.Json.T | ... | @@ -281,7 +278,7 @@ function stripNullDefaults(value: typeof Schema.Json.Type): typeof Schema.Json.T |
| 281 | Object.entries(value) | 278 | Object.entries(value) |
| 282 | .filter(([key, child]) => !(key === "default" && child === null)) | 279 | .filter(([key, child]) => !(key === "default" && child === null)) |
| 283 | .map(([key, child]) => [key, stripNullDefaults(child)]), | 280 | .map(([key, child]) => [key, stripNullDefaults(child)]), |
| 284 | ) as typeof Schema.Json.Type; | 281 | ) as Schema.Json; |
| 285 | } | 282 | } |
| 286 | 283 | ||
| 287 | function toPascalCaseMethod(method: string) { | 284 | function toPascalCaseMethod(method: string) { |
| ... | @@ -417,7 +414,7 @@ function renderSchemaMap( | ... | @@ -417,7 +414,7 @@ function renderSchemaMap( |
| 417 | } | 414 | } |
| 418 | 415 | ||
| 419 | function renderSchemaTypeReference(schemaName: string) { | 416 | function renderSchemaTypeReference(schemaName: string) { |
| 420 | return schemaName === "undefined" ? "undefined" : `typeof CodexSchema.${schemaName}.Type`; | 417 | return schemaName === "undefined" ? "undefined" : `CodexSchema.${schemaName}`; |
| 421 | } | 418 | } |
| 422 | 419 | ||
| 423 | function exportNameForPath(filePath: string): string { | 420 | function exportNameForPath(filePath: string): string { |
| ... | @@ -468,11 +465,11 @@ function buildJsonSchemaFiles( | ... | @@ -468,11 +465,11 @@ function buildJsonSchemaFiles( |
| 468 | } | 465 | } |
| 469 | 466 | ||
| 470 | function rewriteExternalRefs( | 467 | function rewriteExternalRefs( |
| 471 | value: typeof Schema.Json.Type, | 468 | value: Schema.Json, |
| 472 | localDefinitionNames: ReadonlyMap<string, string>, | 469 | localDefinitionNames: ReadonlyMap<string, string>, |
| 473 | currentNamespace: string | undefined, | 470 | currentNamespace: string | undefined, |
| 474 | exportNameByQualifiedName: ReadonlyMap<string, string>, | 471 | exportNameByQualifiedName: ReadonlyMap<string, string>, |
| 475 | ): typeof Schema.Json.Type { | 472 | ): Schema.Json { |
| 476 | if (Array.isArray(value)) { | 473 | if (Array.isArray(value)) { |
| 477 | return value.map((entry) => | 474 | return value.map((entry) => |
| 478 | rewriteExternalRefs(entry, localDefinitionNames, currentNamespace, exportNameByQualifiedName), | 475 | rewriteExternalRefs(entry, localDefinitionNames, currentNamespace, exportNameByQualifiedName), |
| ... | @@ -522,7 +519,7 @@ function rewriteExternalRefs( | ... | @@ -522,7 +519,7 @@ function rewriteExternalRefs( |
| 522 | ), | 519 | ), |
| 523 | ]; | 520 | ]; |
| 524 | }), | 521 | }), |
| 525 | ) as typeof Schema.Json.Type; | 522 | ) as Schema.Json; |
| 526 | } | 523 | } |
| 527 | 524 | ||
| 528 | const generateFiles = Effect.fn("generateFiles")(function* () { | 525 | const generateFiles = Effect.fn("generateFiles")(function* () { |
| ... | @@ -543,7 +540,7 @@ const generateFiles = Effect.fn("generateFiles")(function* () { | ... | @@ -543,7 +540,7 @@ const generateFiles = Effect.fn("generateFiles")(function* () { |
| 543 | const exportNameByQualifiedName = new Map( | 540 | const exportNameByQualifiedName = new Map( |
| 544 | jsonSchemaFiles.map((file) => [file.qualifiedName, file.exportName]), | 541 | jsonSchemaFiles.map((file) => [file.qualifiedName, file.exportName]), |
| 545 | ); | 542 | ); |
| 546 | const aggregateSchemas: Record<string, typeof Schema.Json.Type> = {}; | 543 | const aggregateSchemas: Record<string, Schema.Json> = {}; |
| 547 | 544 | ||
| 548 | for (const file of jsonSchemaFiles) { | 545 | for (const file of jsonSchemaFiles) { |
| 549 | const raw = yield* fetchText(file.downloadUrl); | 546 | const raw = yield* fetchText(file.downloadUrl); |
| ... | @@ -568,7 +565,7 @@ const generateFiles = Effect.fn("generateFiles")(function* () { | ... | @@ -568,7 +565,7 @@ const generateFiles = Effect.fn("generateFiles")(function* () { |
| 568 | ); | 565 | ); |
| 569 | } | 566 | } |
| 570 | 567 | ||
| 571 | const topLevelSchema: Record<string, typeof Schema.Json.Type> = {}; | 568 | const topLevelSchema: Record<string, Schema.Json> = {}; |
| 572 | for (const [key, value] of Object.entries(parsed)) { | 569 | for (const [key, value] of Object.entries(parsed)) { |
| 573 | if (key !== "definitions") { | 570 | if (key !== "definitions") { |
| 574 | topLevelSchema[key] = value; | 571 | topLevelSchema[key] = value; |
packages/effect-codex-app-server/src/_generated/meta.gen.ts+233-233| ... | @@ -173,165 +173,165 @@ export type ServerRequestMethod = keyof typeof SERVER_REQUEST_METHODS; | ... | @@ -173,165 +173,165 @@ export type ServerRequestMethod = keyof typeof SERVER_REQUEST_METHODS; |
| 173 | export type ServerNotificationMethod = keyof typeof SERVER_NOTIFICATION_METHODS; | 173 | export type ServerNotificationMethod = keyof typeof SERVER_NOTIFICATION_METHODS; |
| 174 | 174 | ||
| 175 | export interface ClientRequestParamsByMethod { | 175 | export interface ClientRequestParamsByMethod { |
| 176 | readonly initialize: typeof CodexSchema.V1InitializeParams.Type; | 176 | readonly initialize: CodexSchema.V1InitializeParams; |
| 177 | readonly "thread/start": typeof CodexSchema.V2ThreadStartParams.Type; | 177 | readonly "thread/start": CodexSchema.V2ThreadStartParams; |
| 178 | readonly "thread/resume": typeof CodexSchema.V2ThreadResumeParams.Type; | 178 | readonly "thread/resume": CodexSchema.V2ThreadResumeParams; |
| 179 | readonly "thread/fork": typeof CodexSchema.V2ThreadForkParams.Type; | 179 | readonly "thread/fork": CodexSchema.V2ThreadForkParams; |
| 180 | readonly "thread/archive": typeof CodexSchema.V2ThreadArchiveParams.Type; | 180 | readonly "thread/archive": CodexSchema.V2ThreadArchiveParams; |
| 181 | readonly "thread/unsubscribe": typeof CodexSchema.V2ThreadUnsubscribeParams.Type; | 181 | readonly "thread/unsubscribe": CodexSchema.V2ThreadUnsubscribeParams; |
| 182 | readonly "thread/name/set": typeof CodexSchema.V2ThreadSetNameParams.Type; | 182 | readonly "thread/name/set": CodexSchema.V2ThreadSetNameParams; |
| 183 | readonly "thread/metadata/update": typeof CodexSchema.V2ThreadMetadataUpdateParams.Type; | 183 | readonly "thread/metadata/update": CodexSchema.V2ThreadMetadataUpdateParams; |
| 184 | readonly "thread/unarchive": typeof CodexSchema.V2ThreadUnarchiveParams.Type; | 184 | readonly "thread/unarchive": CodexSchema.V2ThreadUnarchiveParams; |
| 185 | readonly "thread/compact/start": typeof CodexSchema.V2ThreadCompactStartParams.Type; | 185 | readonly "thread/compact/start": CodexSchema.V2ThreadCompactStartParams; |
| 186 | readonly "thread/shellCommand": typeof CodexSchema.V2ThreadShellCommandParams.Type; | 186 | readonly "thread/shellCommand": CodexSchema.V2ThreadShellCommandParams; |
| 187 | readonly "thread/approveGuardianDeniedAction": typeof CodexSchema.V2ThreadApproveGuardianDeniedActionParams.Type; | 187 | readonly "thread/approveGuardianDeniedAction": CodexSchema.V2ThreadApproveGuardianDeniedActionParams; |
| 188 | readonly "thread/rollback": typeof CodexSchema.V2ThreadRollbackParams.Type; | 188 | readonly "thread/rollback": CodexSchema.V2ThreadRollbackParams; |
| 189 | readonly "thread/list": typeof CodexSchema.V2ThreadListParams.Type; | 189 | readonly "thread/list": CodexSchema.V2ThreadListParams; |
| 190 | readonly "thread/loaded/list": typeof CodexSchema.V2ThreadLoadedListParams.Type; | 190 | readonly "thread/loaded/list": CodexSchema.V2ThreadLoadedListParams; |
| 191 | readonly "thread/read": typeof CodexSchema.V2ThreadReadParams.Type; | 191 | readonly "thread/read": CodexSchema.V2ThreadReadParams; |
| 192 | readonly "thread/inject_items": typeof CodexSchema.V2ThreadInjectItemsParams.Type; | 192 | readonly "thread/inject_items": CodexSchema.V2ThreadInjectItemsParams; |
| 193 | readonly "skills/list": typeof CodexSchema.V2SkillsListParams.Type; | 193 | readonly "skills/list": CodexSchema.V2SkillsListParams; |
| 194 | readonly "hooks/list": typeof CodexSchema.V2HooksListParams.Type; | 194 | readonly "hooks/list": CodexSchema.V2HooksListParams; |
| 195 | readonly "marketplace/add": typeof CodexSchema.V2MarketplaceAddParams.Type; | 195 | readonly "marketplace/add": CodexSchema.V2MarketplaceAddParams; |
| 196 | readonly "marketplace/remove": typeof CodexSchema.V2MarketplaceRemoveParams.Type; | 196 | readonly "marketplace/remove": CodexSchema.V2MarketplaceRemoveParams; |
| 197 | readonly "marketplace/upgrade": typeof CodexSchema.V2MarketplaceUpgradeParams.Type; | 197 | readonly "marketplace/upgrade": CodexSchema.V2MarketplaceUpgradeParams; |
| 198 | readonly "plugin/list": typeof CodexSchema.V2PluginListParams.Type; | 198 | readonly "plugin/list": CodexSchema.V2PluginListParams; |
| 199 | readonly "plugin/read": typeof CodexSchema.V2PluginReadParams.Type; | 199 | readonly "plugin/read": CodexSchema.V2PluginReadParams; |
| 200 | readonly "plugin/skill/read": typeof CodexSchema.V2PluginSkillReadParams.Type; | 200 | readonly "plugin/skill/read": CodexSchema.V2PluginSkillReadParams; |
| 201 | readonly "plugin/share/save": typeof CodexSchema.V2PluginShareSaveParams.Type; | 201 | readonly "plugin/share/save": CodexSchema.V2PluginShareSaveParams; |
| 202 | readonly "plugin/share/updateTargets": typeof CodexSchema.V2PluginShareUpdateTargetsParams.Type; | 202 | readonly "plugin/share/updateTargets": CodexSchema.V2PluginShareUpdateTargetsParams; |
| 203 | readonly "plugin/share/list": typeof CodexSchema.V2PluginShareListParams.Type; | 203 | readonly "plugin/share/list": CodexSchema.V2PluginShareListParams; |
| 204 | readonly "plugin/share/delete": typeof CodexSchema.V2PluginShareDeleteParams.Type; | 204 | readonly "plugin/share/delete": CodexSchema.V2PluginShareDeleteParams; |
| 205 | readonly "app/list": typeof CodexSchema.V2AppsListParams.Type; | 205 | readonly "app/list": CodexSchema.V2AppsListParams; |
| 206 | readonly "fs/readFile": typeof CodexSchema.V2FsReadFileParams.Type; | 206 | readonly "fs/readFile": CodexSchema.V2FsReadFileParams; |
| 207 | readonly "fs/writeFile": typeof CodexSchema.V2FsWriteFileParams.Type; | 207 | readonly "fs/writeFile": CodexSchema.V2FsWriteFileParams; |
| 208 | readonly "fs/createDirectory": typeof CodexSchema.V2FsCreateDirectoryParams.Type; | 208 | readonly "fs/createDirectory": CodexSchema.V2FsCreateDirectoryParams; |
| 209 | readonly "fs/getMetadata": typeof CodexSchema.V2FsGetMetadataParams.Type; | 209 | readonly "fs/getMetadata": CodexSchema.V2FsGetMetadataParams; |
| 210 | readonly "fs/readDirectory": typeof CodexSchema.V2FsReadDirectoryParams.Type; | 210 | readonly "fs/readDirectory": CodexSchema.V2FsReadDirectoryParams; |
| 211 | readonly "fs/remove": typeof CodexSchema.V2FsRemoveParams.Type; | 211 | readonly "fs/remove": CodexSchema.V2FsRemoveParams; |
| 212 | readonly "fs/copy": typeof CodexSchema.V2FsCopyParams.Type; | 212 | readonly "fs/copy": CodexSchema.V2FsCopyParams; |
| 213 | readonly "fs/watch": typeof CodexSchema.V2FsWatchParams.Type; | 213 | readonly "fs/watch": CodexSchema.V2FsWatchParams; |
| 214 | readonly "fs/unwatch": typeof CodexSchema.V2FsUnwatchParams.Type; | 214 | readonly "fs/unwatch": CodexSchema.V2FsUnwatchParams; |
| 215 | readonly "skills/config/write": typeof CodexSchema.V2SkillsConfigWriteParams.Type; | 215 | readonly "skills/config/write": CodexSchema.V2SkillsConfigWriteParams; |
| 216 | readonly "plugin/install": typeof CodexSchema.V2PluginInstallParams.Type; | 216 | readonly "plugin/install": CodexSchema.V2PluginInstallParams; |
| 217 | readonly "plugin/uninstall": typeof CodexSchema.V2PluginUninstallParams.Type; | 217 | readonly "plugin/uninstall": CodexSchema.V2PluginUninstallParams; |
| 218 | readonly "turn/start": typeof CodexSchema.V2TurnStartParams.Type; | 218 | readonly "turn/start": CodexSchema.V2TurnStartParams; |
| 219 | readonly "turn/steer": typeof CodexSchema.V2TurnSteerParams.Type; | 219 | readonly "turn/steer": CodexSchema.V2TurnSteerParams; |
| 220 | readonly "turn/interrupt": typeof CodexSchema.V2TurnInterruptParams.Type; | 220 | readonly "turn/interrupt": CodexSchema.V2TurnInterruptParams; |
| 221 | readonly "review/start": typeof CodexSchema.V2ReviewStartParams.Type; | 221 | readonly "review/start": CodexSchema.V2ReviewStartParams; |
| 222 | readonly "model/list": typeof CodexSchema.V2ModelListParams.Type; | 222 | readonly "model/list": CodexSchema.V2ModelListParams; |
| 223 | readonly "modelProvider/capabilities/read": typeof CodexSchema.V2ModelProviderCapabilitiesReadParams.Type; | 223 | readonly "modelProvider/capabilities/read": CodexSchema.V2ModelProviderCapabilitiesReadParams; |
| 224 | readonly "experimentalFeature/list": typeof CodexSchema.V2ExperimentalFeatureListParams.Type; | 224 | readonly "experimentalFeature/list": CodexSchema.V2ExperimentalFeatureListParams; |
| 225 | readonly "experimentalFeature/enablement/set": typeof CodexSchema.V2ExperimentalFeatureEnablementSetParams.Type; | 225 | readonly "experimentalFeature/enablement/set": CodexSchema.V2ExperimentalFeatureEnablementSetParams; |
| 226 | readonly "mcpServer/oauth/login": typeof CodexSchema.V2McpServerOauthLoginParams.Type; | 226 | readonly "mcpServer/oauth/login": CodexSchema.V2McpServerOauthLoginParams; |
| 227 | readonly "config/mcpServer/reload": undefined; | 227 | readonly "config/mcpServer/reload": undefined; |
| 228 | readonly "mcpServerStatus/list": typeof CodexSchema.V2ListMcpServerStatusParams.Type; | 228 | readonly "mcpServerStatus/list": CodexSchema.V2ListMcpServerStatusParams; |
| 229 | readonly "mcpServer/resource/read": typeof CodexSchema.V2McpResourceReadParams.Type; | 229 | readonly "mcpServer/resource/read": CodexSchema.V2McpResourceReadParams; |
| 230 | readonly "mcpServer/tool/call": typeof CodexSchema.V2McpServerToolCallParams.Type; | 230 | readonly "mcpServer/tool/call": CodexSchema.V2McpServerToolCallParams; |
| 231 | readonly "windowsSandbox/setupStart": typeof CodexSchema.V2WindowsSandboxSetupStartParams.Type; | 231 | readonly "windowsSandbox/setupStart": CodexSchema.V2WindowsSandboxSetupStartParams; |
| 232 | readonly "windowsSandbox/readiness": undefined; | 232 | readonly "windowsSandbox/readiness": undefined; |
| 233 | readonly "account/login/start": typeof CodexSchema.V2LoginAccountParams.Type; | 233 | readonly "account/login/start": CodexSchema.V2LoginAccountParams; |
| 234 | readonly "account/login/cancel": typeof CodexSchema.V2CancelLoginAccountParams.Type; | 234 | readonly "account/login/cancel": CodexSchema.V2CancelLoginAccountParams; |
| 235 | readonly "account/logout": undefined; | 235 | readonly "account/logout": undefined; |
| 236 | readonly "account/rateLimits/read": undefined; | 236 | readonly "account/rateLimits/read": undefined; |
| 237 | readonly "account/sendAddCreditsNudgeEmail": typeof CodexSchema.V2SendAddCreditsNudgeEmailParams.Type; | 237 | readonly "account/sendAddCreditsNudgeEmail": CodexSchema.V2SendAddCreditsNudgeEmailParams; |
| 238 | readonly "feedback/upload": typeof CodexSchema.V2FeedbackUploadParams.Type; | 238 | readonly "feedback/upload": CodexSchema.V2FeedbackUploadParams; |
| 239 | readonly "command/exec": typeof CodexSchema.V2CommandExecParams.Type; | 239 | readonly "command/exec": CodexSchema.V2CommandExecParams; |
| 240 | readonly "command/exec/write": typeof CodexSchema.V2CommandExecWriteParams.Type; | 240 | readonly "command/exec/write": CodexSchema.V2CommandExecWriteParams; |
| 241 | readonly "command/exec/terminate": typeof CodexSchema.V2CommandExecTerminateParams.Type; | 241 | readonly "command/exec/terminate": CodexSchema.V2CommandExecTerminateParams; |
| 242 | readonly "command/exec/resize": typeof CodexSchema.V2CommandExecResizeParams.Type; | 242 | readonly "command/exec/resize": CodexSchema.V2CommandExecResizeParams; |
| 243 | readonly "config/read": typeof CodexSchema.V2ConfigReadParams.Type; | 243 | readonly "config/read": CodexSchema.V2ConfigReadParams; |
| 244 | readonly "externalAgentConfig/detect": typeof CodexSchema.V2ExternalAgentConfigDetectParams.Type; | 244 | readonly "externalAgentConfig/detect": CodexSchema.V2ExternalAgentConfigDetectParams; |
| 245 | readonly "externalAgentConfig/import": typeof CodexSchema.V2ExternalAgentConfigImportParams.Type; | 245 | readonly "externalAgentConfig/import": CodexSchema.V2ExternalAgentConfigImportParams; |
| 246 | readonly "config/value/write": typeof CodexSchema.V2ConfigValueWriteParams.Type; | 246 | readonly "config/value/write": CodexSchema.V2ConfigValueWriteParams; |
| 247 | readonly "config/batchWrite": typeof CodexSchema.V2ConfigBatchWriteParams.Type; | 247 | readonly "config/batchWrite": CodexSchema.V2ConfigBatchWriteParams; |
| 248 | readonly "configRequirements/read": undefined; | 248 | readonly "configRequirements/read": undefined; |
| 249 | readonly "account/read": typeof CodexSchema.V2GetAccountParams.Type; | 249 | readonly "account/read": CodexSchema.V2GetAccountParams; |
| 250 | readonly getConversationSummary: typeof CodexSchema.GetConversationSummaryParams.Type; | 250 | readonly getConversationSummary: CodexSchema.GetConversationSummaryParams; |
| 251 | readonly gitDiffToRemote: typeof CodexSchema.GitDiffToRemoteParams.Type; | 251 | readonly gitDiffToRemote: CodexSchema.GitDiffToRemoteParams; |
| 252 | readonly getAuthStatus: typeof CodexSchema.GetAuthStatusParams.Type; | 252 | readonly getAuthStatus: CodexSchema.GetAuthStatusParams; |
| 253 | readonly fuzzyFileSearch: typeof CodexSchema.FuzzyFileSearchParams.Type; | 253 | readonly fuzzyFileSearch: CodexSchema.FuzzyFileSearchParams; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | export interface ClientRequestResponsesByMethod { | 256 | export interface ClientRequestResponsesByMethod { |
| 257 | readonly initialize: typeof CodexSchema.V1InitializeResponse.Type; | 257 | readonly initialize: CodexSchema.V1InitializeResponse; |
| 258 | readonly "thread/start": typeof CodexSchema.V2ThreadStartResponse.Type; | 258 | readonly "thread/start": CodexSchema.V2ThreadStartResponse; |
| 259 | readonly "thread/resume": typeof CodexSchema.V2ThreadResumeResponse.Type; | 259 | readonly "thread/resume": CodexSchema.V2ThreadResumeResponse; |
| 260 | readonly "thread/fork": typeof CodexSchema.V2ThreadForkResponse.Type; | 260 | readonly "thread/fork": CodexSchema.V2ThreadForkResponse; |
| 261 | readonly "thread/archive": typeof CodexSchema.V2ThreadArchiveResponse.Type; | 261 | readonly "thread/archive": CodexSchema.V2ThreadArchiveResponse; |
| 262 | readonly "thread/unsubscribe": typeof CodexSchema.V2ThreadUnsubscribeResponse.Type; | 262 | readonly "thread/unsubscribe": CodexSchema.V2ThreadUnsubscribeResponse; |
| 263 | readonly "thread/name/set": typeof CodexSchema.V2ThreadSetNameResponse.Type; | 263 | readonly "thread/name/set": CodexSchema.V2ThreadSetNameResponse; |
| 264 | readonly "thread/metadata/update": typeof CodexSchema.V2ThreadMetadataUpdateResponse.Type; | 264 | readonly "thread/metadata/update": CodexSchema.V2ThreadMetadataUpdateResponse; |
| 265 | readonly "thread/unarchive": typeof CodexSchema.V2ThreadUnarchiveResponse.Type; | 265 | readonly "thread/unarchive": CodexSchema.V2ThreadUnarchiveResponse; |
| 266 | readonly "thread/compact/start": typeof CodexSchema.V2ThreadCompactStartResponse.Type; | 266 | readonly "thread/compact/start": CodexSchema.V2ThreadCompactStartResponse; |
| 267 | readonly "thread/shellCommand": typeof CodexSchema.V2ThreadShellCommandResponse.Type; | 267 | readonly "thread/shellCommand": CodexSchema.V2ThreadShellCommandResponse; |
| 268 | readonly "thread/approveGuardianDeniedAction": typeof CodexSchema.V2ThreadApproveGuardianDeniedActionResponse.Type; | 268 | readonly "thread/approveGuardianDeniedAction": CodexSchema.V2ThreadApproveGuardianDeniedActionResponse; |
| 269 | readonly "thread/rollback": typeof CodexSchema.V2ThreadRollbackResponse.Type; | 269 | readonly "thread/rollback": CodexSchema.V2ThreadRollbackResponse; |
| 270 | readonly "thread/list": typeof CodexSchema.V2ThreadListResponse.Type; | 270 | readonly "thread/list": CodexSchema.V2ThreadListResponse; |
| 271 | readonly "thread/loaded/list": typeof CodexSchema.V2ThreadLoadedListResponse.Type; | 271 | readonly "thread/loaded/list": CodexSchema.V2ThreadLoadedListResponse; |
| 272 | readonly "thread/read": typeof CodexSchema.V2ThreadReadResponse.Type; | 272 | readonly "thread/read": CodexSchema.V2ThreadReadResponse; |
| 273 | readonly "thread/inject_items": typeof CodexSchema.V2ThreadInjectItemsResponse.Type; | 273 | readonly "thread/inject_items": CodexSchema.V2ThreadInjectItemsResponse; |
| 274 | readonly "skills/list": typeof CodexSchema.V2SkillsListResponse.Type; | 274 | readonly "skills/list": CodexSchema.V2SkillsListResponse; |
| 275 | readonly "hooks/list": typeof CodexSchema.V2HooksListResponse.Type; | 275 | readonly "hooks/list": CodexSchema.V2HooksListResponse; |
| 276 | readonly "marketplace/add": typeof CodexSchema.V2MarketplaceAddResponse.Type; | 276 | readonly "marketplace/add": CodexSchema.V2MarketplaceAddResponse; |
| 277 | readonly "marketplace/remove": typeof CodexSchema.V2MarketplaceRemoveResponse.Type; | 277 | readonly "marketplace/remove": CodexSchema.V2MarketplaceRemoveResponse; |
| 278 | readonly "marketplace/upgrade": typeof CodexSchema.V2MarketplaceUpgradeResponse.Type; | 278 | readonly "marketplace/upgrade": CodexSchema.V2MarketplaceUpgradeResponse; |
| 279 | readonly "plugin/list": typeof CodexSchema.V2PluginListResponse.Type; | 279 | readonly "plugin/list": CodexSchema.V2PluginListResponse; |
| 280 | readonly "plugin/read": typeof CodexSchema.V2PluginReadResponse.Type; | 280 | readonly "plugin/read": CodexSchema.V2PluginReadResponse; |
| 281 | readonly "plugin/skill/read": typeof CodexSchema.V2PluginSkillReadResponse.Type; | 281 | readonly "plugin/skill/read": CodexSchema.V2PluginSkillReadResponse; |
| 282 | readonly "plugin/share/save": typeof CodexSchema.V2PluginShareSaveResponse.Type; | 282 | readonly "plugin/share/save": CodexSchema.V2PluginShareSaveResponse; |
| 283 | readonly "plugin/share/updateTargets": typeof CodexSchema.V2PluginShareUpdateTargetsResponse.Type; | 283 | readonly "plugin/share/updateTargets": CodexSchema.V2PluginShareUpdateTargetsResponse; |
| 284 | readonly "plugin/share/list": typeof CodexSchema.V2PluginShareListResponse.Type; | 284 | readonly "plugin/share/list": CodexSchema.V2PluginShareListResponse; |
| 285 | readonly "plugin/share/delete": typeof CodexSchema.V2PluginShareDeleteResponse.Type; | 285 | readonly "plugin/share/delete": CodexSchema.V2PluginShareDeleteResponse; |
| 286 | readonly "app/list": typeof CodexSchema.V2AppsListResponse.Type; | 286 | readonly "app/list": CodexSchema.V2AppsListResponse; |
| 287 | readonly "fs/readFile": typeof CodexSchema.V2FsReadFileResponse.Type; | 287 | readonly "fs/readFile": CodexSchema.V2FsReadFileResponse; |
| 288 | readonly "fs/writeFile": typeof CodexSchema.V2FsWriteFileResponse.Type; | 288 | readonly "fs/writeFile": CodexSchema.V2FsWriteFileResponse; |
| 289 | readonly "fs/createDirectory": typeof CodexSchema.V2FsCreateDirectoryResponse.Type; | 289 | readonly "fs/createDirectory": CodexSchema.V2FsCreateDirectoryResponse; |
| 290 | readonly "fs/getMetadata": typeof CodexSchema.V2FsGetMetadataResponse.Type; | 290 | readonly "fs/getMetadata": CodexSchema.V2FsGetMetadataResponse; |
| 291 | readonly "fs/readDirectory": typeof CodexSchema.V2FsReadDirectoryResponse.Type; | 291 | readonly "fs/readDirectory": CodexSchema.V2FsReadDirectoryResponse; |
| 292 | readonly "fs/remove": typeof CodexSchema.V2FsRemoveResponse.Type; | 292 | readonly "fs/remove": CodexSchema.V2FsRemoveResponse; |
| 293 | readonly "fs/copy": typeof CodexSchema.V2FsCopyResponse.Type; | 293 | readonly "fs/copy": CodexSchema.V2FsCopyResponse; |
| 294 | readonly "fs/watch": typeof CodexSchema.V2FsWatchResponse.Type; | 294 | readonly "fs/watch": CodexSchema.V2FsWatchResponse; |
| 295 | readonly "fs/unwatch": typeof CodexSchema.V2FsUnwatchResponse.Type; | 295 | readonly "fs/unwatch": CodexSchema.V2FsUnwatchResponse; |
| 296 | readonly "skills/config/write": typeof CodexSchema.V2SkillsConfigWriteResponse.Type; | 296 | readonly "skills/config/write": CodexSchema.V2SkillsConfigWriteResponse; |
| 297 | readonly "plugin/install": typeof CodexSchema.V2PluginInstallResponse.Type; | 297 | readonly "plugin/install": CodexSchema.V2PluginInstallResponse; |
| 298 | readonly "plugin/uninstall": typeof CodexSchema.V2PluginUninstallResponse.Type; | 298 | readonly "plugin/uninstall": CodexSchema.V2PluginUninstallResponse; |
| 299 | readonly "turn/start": typeof CodexSchema.V2TurnStartResponse.Type; | 299 | readonly "turn/start": CodexSchema.V2TurnStartResponse; |
| 300 | readonly "turn/steer": typeof CodexSchema.V2TurnSteerResponse.Type; | 300 | readonly "turn/steer": CodexSchema.V2TurnSteerResponse; |
| 301 | readonly "turn/interrupt": typeof CodexSchema.V2TurnInterruptResponse.Type; | 301 | readonly "turn/interrupt": CodexSchema.V2TurnInterruptResponse; |
| 302 | readonly "review/start": typeof CodexSchema.V2ReviewStartResponse.Type; | 302 | readonly "review/start": CodexSchema.V2ReviewStartResponse; |
| 303 | readonly "model/list": typeof CodexSchema.V2ModelListResponse.Type; | 303 | readonly "model/list": CodexSchema.V2ModelListResponse; |
| 304 | readonly "modelProvider/capabilities/read": typeof CodexSchema.V2ModelProviderCapabilitiesReadResponse.Type; | 304 | readonly "modelProvider/capabilities/read": CodexSchema.V2ModelProviderCapabilitiesReadResponse; |
| 305 | readonly "experimentalFeature/list": typeof CodexSchema.V2ExperimentalFeatureListResponse.Type; | 305 | readonly "experimentalFeature/list": CodexSchema.V2ExperimentalFeatureListResponse; |
| 306 | readonly "experimentalFeature/enablement/set": typeof CodexSchema.V2ExperimentalFeatureEnablementSetResponse.Type; | 306 | readonly "experimentalFeature/enablement/set": CodexSchema.V2ExperimentalFeatureEnablementSetResponse; |
| 307 | readonly "mcpServer/oauth/login": typeof CodexSchema.V2McpServerOauthLoginResponse.Type; | 307 | readonly "mcpServer/oauth/login": CodexSchema.V2McpServerOauthLoginResponse; |
| 308 | readonly "config/mcpServer/reload": typeof CodexSchema.V2McpServerRefreshResponse.Type; | 308 | readonly "config/mcpServer/reload": CodexSchema.V2McpServerRefreshResponse; |
| 309 | readonly "mcpServerStatus/list": typeof CodexSchema.V2ListMcpServerStatusResponse.Type; | 309 | readonly "mcpServerStatus/list": CodexSchema.V2ListMcpServerStatusResponse; |
| 310 | readonly "mcpServer/resource/read": typeof CodexSchema.V2McpResourceReadResponse.Type; | 310 | readonly "mcpServer/resource/read": CodexSchema.V2McpResourceReadResponse; |
| 311 | readonly "mcpServer/tool/call": typeof CodexSchema.V2McpServerToolCallResponse.Type; | 311 | readonly "mcpServer/tool/call": CodexSchema.V2McpServerToolCallResponse; |
| 312 | readonly "windowsSandbox/setupStart": typeof CodexSchema.V2WindowsSandboxSetupStartResponse.Type; | 312 | readonly "windowsSandbox/setupStart": CodexSchema.V2WindowsSandboxSetupStartResponse; |
| 313 | readonly "windowsSandbox/readiness": typeof CodexSchema.V2WindowsSandboxReadinessResponse.Type; | 313 | readonly "windowsSandbox/readiness": CodexSchema.V2WindowsSandboxReadinessResponse; |
| 314 | readonly "account/login/start": typeof CodexSchema.V2LoginAccountResponse.Type; | 314 | readonly "account/login/start": CodexSchema.V2LoginAccountResponse; |
| 315 | readonly "account/login/cancel": typeof CodexSchema.V2CancelLoginAccountResponse.Type; | 315 | readonly "account/login/cancel": CodexSchema.V2CancelLoginAccountResponse; |
| 316 | readonly "account/logout": typeof CodexSchema.V2LogoutAccountResponse.Type; | 316 | readonly "account/logout": CodexSchema.V2LogoutAccountResponse; |
| 317 | readonly "account/rateLimits/read": typeof CodexSchema.V2GetAccountRateLimitsResponse.Type; | 317 | readonly "account/rateLimits/read": CodexSchema.V2GetAccountRateLimitsResponse; |
| 318 | readonly "account/sendAddCreditsNudgeEmail": typeof CodexSchema.V2SendAddCreditsNudgeEmailResponse.Type; | 318 | readonly "account/sendAddCreditsNudgeEmail": CodexSchema.V2SendAddCreditsNudgeEmailResponse; |
| 319 | readonly "feedback/upload": typeof CodexSchema.V2FeedbackUploadResponse.Type; | 319 | readonly "feedback/upload": CodexSchema.V2FeedbackUploadResponse; |
| 320 | readonly "command/exec": typeof CodexSchema.V2CommandExecResponse.Type; | 320 | readonly "command/exec": CodexSchema.V2CommandExecResponse; |
| 321 | readonly "command/exec/write": typeof CodexSchema.V2CommandExecWriteResponse.Type; | 321 | readonly "command/exec/write": CodexSchema.V2CommandExecWriteResponse; |
| 322 | readonly "command/exec/terminate": typeof CodexSchema.V2CommandExecTerminateResponse.Type; | 322 | readonly "command/exec/terminate": CodexSchema.V2CommandExecTerminateResponse; |
| 323 | readonly "command/exec/resize": typeof CodexSchema.V2CommandExecResizeResponse.Type; | 323 | readonly "command/exec/resize": CodexSchema.V2CommandExecResizeResponse; |
| 324 | readonly "config/read": typeof CodexSchema.V2ConfigReadResponse.Type; | 324 | readonly "config/read": CodexSchema.V2ConfigReadResponse; |
| 325 | readonly "externalAgentConfig/detect": typeof CodexSchema.V2ExternalAgentConfigDetectResponse.Type; | 325 | readonly "externalAgentConfig/detect": CodexSchema.V2ExternalAgentConfigDetectResponse; |
| 326 | readonly "externalAgentConfig/import": typeof CodexSchema.V2ExternalAgentConfigImportResponse.Type; | 326 | readonly "externalAgentConfig/import": CodexSchema.V2ExternalAgentConfigImportResponse; |
| 327 | readonly "config/value/write": typeof CodexSchema.V2ConfigWriteResponse.Type; | 327 | readonly "config/value/write": CodexSchema.V2ConfigWriteResponse; |
| 328 | readonly "config/batchWrite": typeof CodexSchema.V2ConfigWriteResponse.Type; | 328 | readonly "config/batchWrite": CodexSchema.V2ConfigWriteResponse; |
| 329 | readonly "configRequirements/read": typeof CodexSchema.V2ConfigRequirementsReadResponse.Type; | 329 | readonly "configRequirements/read": CodexSchema.V2ConfigRequirementsReadResponse; |
| 330 | readonly "account/read": typeof CodexSchema.V2GetAccountResponse.Type; | 330 | readonly "account/read": CodexSchema.V2GetAccountResponse; |
| 331 | readonly getConversationSummary: typeof CodexSchema.GetConversationSummaryResponse.Type; | 331 | readonly getConversationSummary: CodexSchema.GetConversationSummaryResponse; |
| 332 | readonly gitDiffToRemote: typeof CodexSchema.GitDiffToRemoteResponse.Type; | 332 | readonly gitDiffToRemote: CodexSchema.GitDiffToRemoteResponse; |
| 333 | readonly getAuthStatus: typeof CodexSchema.GetAuthStatusResponse.Type; | 333 | readonly getAuthStatus: CodexSchema.GetAuthStatusResponse; |
| 334 | readonly fuzzyFileSearch: typeof CodexSchema.FuzzyFileSearchResponse.Type; | 334 | readonly fuzzyFileSearch: CodexSchema.FuzzyFileSearchResponse; |
| 335 | } | 335 | } |
| 336 | 336 | ||
| 337 | export interface ClientNotificationParamsByMethod { | 337 | export interface ClientNotificationParamsByMethod { |
| ... | @@ -339,94 +339,94 @@ export interface ClientNotificationParamsByMethod { | ... | @@ -339,94 +339,94 @@ export interface ClientNotificationParamsByMethod { |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | export interface ServerRequestParamsByMethod { | 341 | export interface ServerRequestParamsByMethod { |
| 342 | readonly "item/commandExecution/requestApproval": typeof CodexSchema.CommandExecutionRequestApprovalParams.Type; | 342 | readonly "item/commandExecution/requestApproval": CodexSchema.CommandExecutionRequestApprovalParams; |
| 343 | readonly "item/fileChange/requestApproval": typeof CodexSchema.FileChangeRequestApprovalParams.Type; | 343 | readonly "item/fileChange/requestApproval": CodexSchema.FileChangeRequestApprovalParams; |
| 344 | readonly "item/tool/requestUserInput": typeof CodexSchema.ToolRequestUserInputParams.Type; | 344 | readonly "item/tool/requestUserInput": CodexSchema.ToolRequestUserInputParams; |
| 345 | readonly "mcpServer/elicitation/request": typeof CodexSchema.McpServerElicitationRequestParams.Type; | 345 | readonly "mcpServer/elicitation/request": CodexSchema.McpServerElicitationRequestParams; |
| 346 | readonly "item/permissions/requestApproval": typeof CodexSchema.PermissionsRequestApprovalParams.Type; | 346 | readonly "item/permissions/requestApproval": CodexSchema.PermissionsRequestApprovalParams; |
| 347 | readonly "item/tool/call": typeof CodexSchema.DynamicToolCallParams.Type; | 347 | readonly "item/tool/call": CodexSchema.DynamicToolCallParams; |
| 348 | readonly "account/chatgptAuthTokens/refresh": typeof CodexSchema.ChatgptAuthTokensRefreshParams.Type; | 348 | readonly "account/chatgptAuthTokens/refresh": CodexSchema.ChatgptAuthTokensRefreshParams; |
| 349 | readonly applyPatchApproval: typeof CodexSchema.ApplyPatchApprovalParams.Type; | 349 | readonly applyPatchApproval: CodexSchema.ApplyPatchApprovalParams; |
| 350 | readonly execCommandApproval: typeof CodexSchema.ExecCommandApprovalParams.Type; | 350 | readonly execCommandApproval: CodexSchema.ExecCommandApprovalParams; |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | export interface ServerRequestResponsesByMethod { | 353 | export interface ServerRequestResponsesByMethod { |
| 354 | readonly "item/commandExecution/requestApproval": typeof CodexSchema.CommandExecutionRequestApprovalResponse.Type; | 354 | readonly "item/commandExecution/requestApproval": CodexSchema.CommandExecutionRequestApprovalResponse; |
| 355 | readonly "item/fileChange/requestApproval": typeof CodexSchema.FileChangeRequestApprovalResponse.Type; | 355 | readonly "item/fileChange/requestApproval": CodexSchema.FileChangeRequestApprovalResponse; |
| 356 | readonly "item/tool/requestUserInput": typeof CodexSchema.ToolRequestUserInputResponse.Type; | 356 | readonly "item/tool/requestUserInput": CodexSchema.ToolRequestUserInputResponse; |
| 357 | readonly "mcpServer/elicitation/request": typeof CodexSchema.McpServerElicitationRequestResponse.Type; | 357 | readonly "mcpServer/elicitation/request": CodexSchema.McpServerElicitationRequestResponse; |
| 358 | readonly "item/permissions/requestApproval": typeof CodexSchema.PermissionsRequestApprovalResponse.Type; | 358 | readonly "item/permissions/requestApproval": CodexSchema.PermissionsRequestApprovalResponse; |
| 359 | readonly "item/tool/call": typeof CodexSchema.DynamicToolCallResponse.Type; | 359 | readonly "item/tool/call": CodexSchema.DynamicToolCallResponse; |
| 360 | readonly "account/chatgptAuthTokens/refresh": typeof CodexSchema.ChatgptAuthTokensRefreshResponse.Type; | 360 | readonly "account/chatgptAuthTokens/refresh": CodexSchema.ChatgptAuthTokensRefreshResponse; |
| 361 | readonly applyPatchApproval: typeof CodexSchema.ApplyPatchApprovalResponse.Type; | 361 | readonly applyPatchApproval: CodexSchema.ApplyPatchApprovalResponse; |
| 362 | readonly execCommandApproval: typeof CodexSchema.ExecCommandApprovalResponse.Type; | 362 | readonly execCommandApproval: CodexSchema.ExecCommandApprovalResponse; |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | export interface ServerNotificationParamsByMethod { | 365 | export interface ServerNotificationParamsByMethod { |
| 366 | readonly error: typeof CodexSchema.V2ErrorNotification.Type; | 366 | readonly error: CodexSchema.V2ErrorNotification; |
| 367 | readonly "thread/started": typeof CodexSchema.V2ThreadStartedNotification.Type; | 367 | readonly "thread/started": CodexSchema.V2ThreadStartedNotification; |
| 368 | readonly "thread/status/changed": typeof CodexSchema.V2ThreadStatusChangedNotification.Type; | 368 | readonly "thread/status/changed": CodexSchema.V2ThreadStatusChangedNotification; |
| 369 | readonly "thread/archived": typeof CodexSchema.V2ThreadArchivedNotification.Type; | 369 | readonly "thread/archived": CodexSchema.V2ThreadArchivedNotification; |
| 370 | readonly "thread/unarchived": typeof CodexSchema.V2ThreadUnarchivedNotification.Type; | 370 | readonly "thread/unarchived": CodexSchema.V2ThreadUnarchivedNotification; |
| 371 | readonly "thread/closed": typeof CodexSchema.V2ThreadClosedNotification.Type; | 371 | readonly "thread/closed": CodexSchema.V2ThreadClosedNotification; |
| 372 | readonly "skills/changed": typeof CodexSchema.V2SkillsChangedNotification.Type; | 372 | readonly "skills/changed": CodexSchema.V2SkillsChangedNotification; |
| 373 | readonly "thread/name/updated": typeof CodexSchema.V2ThreadNameUpdatedNotification.Type; | 373 | readonly "thread/name/updated": CodexSchema.V2ThreadNameUpdatedNotification; |
| 374 | readonly "thread/goal/updated": typeof CodexSchema.V2ThreadGoalUpdatedNotification.Type; | 374 | readonly "thread/goal/updated": CodexSchema.V2ThreadGoalUpdatedNotification; |
| 375 | readonly "thread/goal/cleared": typeof CodexSchema.V2ThreadGoalClearedNotification.Type; | 375 | readonly "thread/goal/cleared": CodexSchema.V2ThreadGoalClearedNotification; |
| 376 | readonly "thread/tokenUsage/updated": typeof CodexSchema.V2ThreadTokenUsageUpdatedNotification.Type; | 376 | readonly "thread/tokenUsage/updated": CodexSchema.V2ThreadTokenUsageUpdatedNotification; |
| 377 | readonly "turn/started": typeof CodexSchema.V2TurnStartedNotification.Type; | 377 | readonly "turn/started": CodexSchema.V2TurnStartedNotification; |
| 378 | readonly "hook/started": typeof CodexSchema.V2HookStartedNotification.Type; | 378 | readonly "hook/started": CodexSchema.V2HookStartedNotification; |
| 379 | readonly "turn/completed": typeof CodexSchema.V2TurnCompletedNotification.Type; | 379 | readonly "turn/completed": CodexSchema.V2TurnCompletedNotification; |
| 380 | readonly "hook/completed": typeof CodexSchema.V2HookCompletedNotification.Type; | 380 | readonly "hook/completed": CodexSchema.V2HookCompletedNotification; |
| 381 | readonly "turn/diff/updated": typeof CodexSchema.V2TurnDiffUpdatedNotification.Type; | 381 | readonly "turn/diff/updated": CodexSchema.V2TurnDiffUpdatedNotification; |
| 382 | readonly "turn/plan/updated": typeof CodexSchema.V2TurnPlanUpdatedNotification.Type; | 382 | readonly "turn/plan/updated": CodexSchema.V2TurnPlanUpdatedNotification; |
| 383 | readonly "item/started": typeof CodexSchema.V2ItemStartedNotification.Type; | 383 | readonly "item/started": CodexSchema.V2ItemStartedNotification; |
| 384 | readonly "item/autoApprovalReview/started": typeof CodexSchema.V2ItemGuardianApprovalReviewStartedNotification.Type; | 384 | readonly "item/autoApprovalReview/started": CodexSchema.V2ItemGuardianApprovalReviewStartedNotification; |
| 385 | readonly "item/autoApprovalReview/completed": typeof CodexSchema.V2ItemGuardianApprovalReviewCompletedNotification.Type; | 385 | readonly "item/autoApprovalReview/completed": CodexSchema.V2ItemGuardianApprovalReviewCompletedNotification; |
| 386 | readonly "item/completed": typeof CodexSchema.V2ItemCompletedNotification.Type; | 386 | readonly "item/completed": CodexSchema.V2ItemCompletedNotification; |
| 387 | readonly "rawResponseItem/completed": typeof CodexSchema.V2RawResponseItemCompletedNotification.Type; | 387 | readonly "rawResponseItem/completed": CodexSchema.V2RawResponseItemCompletedNotification; |
| 388 | readonly "item/agentMessage/delta": typeof CodexSchema.V2AgentMessageDeltaNotification.Type; | 388 | readonly "item/agentMessage/delta": CodexSchema.V2AgentMessageDeltaNotification; |
| 389 | readonly "item/plan/delta": typeof CodexSchema.V2PlanDeltaNotification.Type; | 389 | readonly "item/plan/delta": CodexSchema.V2PlanDeltaNotification; |
| 390 | readonly "command/exec/outputDelta": typeof CodexSchema.V2CommandExecOutputDeltaNotification.Type; | 390 | readonly "command/exec/outputDelta": CodexSchema.V2CommandExecOutputDeltaNotification; |
| 391 | readonly "process/outputDelta": typeof CodexSchema.V2ProcessOutputDeltaNotification.Type; | 391 | readonly "process/outputDelta": CodexSchema.V2ProcessOutputDeltaNotification; |
| 392 | readonly "process/exited": typeof CodexSchema.V2ProcessExitedNotification.Type; | 392 | readonly "process/exited": CodexSchema.V2ProcessExitedNotification; |
| 393 | readonly "item/commandExecution/outputDelta": typeof CodexSchema.V2CommandExecutionOutputDeltaNotification.Type; | 393 | readonly "item/commandExecution/outputDelta": CodexSchema.V2CommandExecutionOutputDeltaNotification; |
| 394 | readonly "item/commandExecution/terminalInteraction": typeof CodexSchema.V2TerminalInteractionNotification.Type; | 394 | readonly "item/commandExecution/terminalInteraction": CodexSchema.V2TerminalInteractionNotification; |
| 395 | readonly "item/fileChange/outputDelta": typeof CodexSchema.V2FileChangeOutputDeltaNotification.Type; | 395 | readonly "item/fileChange/outputDelta": CodexSchema.V2FileChangeOutputDeltaNotification; |
| 396 | readonly "item/fileChange/patchUpdated": typeof CodexSchema.V2FileChangePatchUpdatedNotification.Type; | 396 | readonly "item/fileChange/patchUpdated": CodexSchema.V2FileChangePatchUpdatedNotification; |
| 397 | readonly "serverRequest/resolved": typeof CodexSchema.V2ServerRequestResolvedNotification.Type; | 397 | readonly "serverRequest/resolved": CodexSchema.V2ServerRequestResolvedNotification; |
| 398 | readonly "item/mcpToolCall/progress": typeof CodexSchema.V2McpToolCallProgressNotification.Type; | 398 | readonly "item/mcpToolCall/progress": CodexSchema.V2McpToolCallProgressNotification; |
| 399 | readonly "mcpServer/oauthLogin/completed": typeof CodexSchema.V2McpServerOauthLoginCompletedNotification.Type; | 399 | readonly "mcpServer/oauthLogin/completed": CodexSchema.V2McpServerOauthLoginCompletedNotification; |
| 400 | readonly "mcpServer/startupStatus/updated": typeof CodexSchema.V2McpServerStatusUpdatedNotification.Type; | 400 | readonly "mcpServer/startupStatus/updated": CodexSchema.V2McpServerStatusUpdatedNotification; |
| 401 | readonly "account/updated": typeof CodexSchema.V2AccountUpdatedNotification.Type; | 401 | readonly "account/updated": CodexSchema.V2AccountUpdatedNotification; |
| 402 | readonly "account/rateLimits/updated": typeof CodexSchema.V2AccountRateLimitsUpdatedNotification.Type; | 402 | readonly "account/rateLimits/updated": CodexSchema.V2AccountRateLimitsUpdatedNotification; |
| 403 | readonly "app/list/updated": typeof CodexSchema.V2AppListUpdatedNotification.Type; | 403 | readonly "app/list/updated": CodexSchema.V2AppListUpdatedNotification; |
| 404 | readonly "remoteControl/status/changed": typeof CodexSchema.V2RemoteControlStatusChangedNotification.Type; | 404 | readonly "remoteControl/status/changed": CodexSchema.V2RemoteControlStatusChangedNotification; |
| 405 | readonly "externalAgentConfig/import/completed": typeof CodexSchema.V2ExternalAgentConfigImportCompletedNotification.Type; | 405 | readonly "externalAgentConfig/import/completed": CodexSchema.V2ExternalAgentConfigImportCompletedNotification; |
| 406 | readonly "fs/changed": typeof CodexSchema.V2FsChangedNotification.Type; | 406 | readonly "fs/changed": CodexSchema.V2FsChangedNotification; |
| 407 | readonly "item/reasoning/summaryTextDelta": typeof CodexSchema.V2ReasoningSummaryTextDeltaNotification.Type; | 407 | readonly "item/reasoning/summaryTextDelta": CodexSchema.V2ReasoningSummaryTextDeltaNotification; |
| 408 | readonly "item/reasoning/summaryPartAdded": typeof CodexSchema.V2ReasoningSummaryPartAddedNotification.Type; | 408 | readonly "item/reasoning/summaryPartAdded": CodexSchema.V2ReasoningSummaryPartAddedNotification; |
| 409 | readonly "item/reasoning/textDelta": typeof CodexSchema.V2ReasoningTextDeltaNotification.Type; | 409 | readonly "item/reasoning/textDelta": CodexSchema.V2ReasoningTextDeltaNotification; |
| 410 | readonly "thread/compacted": typeof CodexSchema.V2ContextCompactedNotification.Type; | 410 | readonly "thread/compacted": CodexSchema.V2ContextCompactedNotification; |
| 411 | readonly "model/rerouted": typeof CodexSchema.V2ModelReroutedNotification.Type; | 411 | readonly "model/rerouted": CodexSchema.V2ModelReroutedNotification; |
| 412 | readonly "model/verification": typeof CodexSchema.V2ModelVerificationNotification.Type; | 412 | readonly "model/verification": CodexSchema.V2ModelVerificationNotification; |
| 413 | readonly warning: typeof CodexSchema.V2WarningNotification.Type; | 413 | readonly warning: CodexSchema.V2WarningNotification; |
| 414 | readonly guardianWarning: typeof CodexSchema.V2GuardianWarningNotification.Type; | 414 | readonly guardianWarning: CodexSchema.V2GuardianWarningNotification; |
| 415 | readonly deprecationNotice: typeof CodexSchema.V2DeprecationNoticeNotification.Type; | 415 | readonly deprecationNotice: CodexSchema.V2DeprecationNoticeNotification; |
| 416 | readonly configWarning: typeof CodexSchema.V2ConfigWarningNotification.Type; | 416 | readonly configWarning: CodexSchema.V2ConfigWarningNotification; |
| 417 | readonly "fuzzyFileSearch/sessionUpdated": typeof CodexSchema.FuzzyFileSearchSessionUpdatedNotification.Type; | 417 | readonly "fuzzyFileSearch/sessionUpdated": CodexSchema.FuzzyFileSearchSessionUpdatedNotification; |
| 418 | readonly "fuzzyFileSearch/sessionCompleted": typeof CodexSchema.FuzzyFileSearchSessionCompletedNotification.Type; | 418 | readonly "fuzzyFileSearch/sessionCompleted": CodexSchema.FuzzyFileSearchSessionCompletedNotification; |
| 419 | readonly "thread/realtime/started": typeof CodexSchema.V2ThreadRealtimeStartedNotification.Type; | 419 | readonly "thread/realtime/started": CodexSchema.V2ThreadRealtimeStartedNotification; |
| 420 | readonly "thread/realtime/itemAdded": typeof CodexSchema.V2ThreadRealtimeItemAddedNotification.Type; | 420 | readonly "thread/realtime/itemAdded": CodexSchema.V2ThreadRealtimeItemAddedNotification; |
| 421 | readonly "thread/realtime/transcript/delta": typeof CodexSchema.V2ThreadRealtimeTranscriptDeltaNotification.Type; | 421 | readonly "thread/realtime/transcript/delta": CodexSchema.V2ThreadRealtimeTranscriptDeltaNotification; |
| 422 | readonly "thread/realtime/transcript/done": typeof CodexSchema.V2ThreadRealtimeTranscriptDoneNotification.Type; | 422 | readonly "thread/realtime/transcript/done": CodexSchema.V2ThreadRealtimeTranscriptDoneNotification; |
| 423 | readonly "thread/realtime/outputAudio/delta": typeof CodexSchema.V2ThreadRealtimeOutputAudioDeltaNotification.Type; | 423 | readonly "thread/realtime/outputAudio/delta": CodexSchema.V2ThreadRealtimeOutputAudioDeltaNotification; |
| 424 | readonly "thread/realtime/sdp": typeof CodexSchema.V2ThreadRealtimeSdpNotification.Type; | 424 | readonly "thread/realtime/sdp": CodexSchema.V2ThreadRealtimeSdpNotification; |
| 425 | readonly "thread/realtime/error": typeof CodexSchema.V2ThreadRealtimeErrorNotification.Type; | 425 | readonly "thread/realtime/error": CodexSchema.V2ThreadRealtimeErrorNotification; |
| 426 | readonly "thread/realtime/closed": typeof CodexSchema.V2ThreadRealtimeClosedNotification.Type; | 426 | readonly "thread/realtime/closed": CodexSchema.V2ThreadRealtimeClosedNotification; |
| 427 | readonly "windows/worldWritableWarning": typeof CodexSchema.V2WindowsWorldWritableWarningNotification.Type; | 427 | readonly "windows/worldWritableWarning": CodexSchema.V2WindowsWorldWritableWarningNotification; |
| 428 | readonly "windowsSandbox/setupCompleted": typeof CodexSchema.V2WindowsSandboxSetupCompletedNotification.Type; | 428 | readonly "windowsSandbox/setupCompleted": CodexSchema.V2WindowsSandboxSetupCompletedNotification; |
| 429 | readonly "account/login/completed": typeof CodexSchema.V2AccountLoginCompletedNotification.Type; | 429 | readonly "account/login/completed": CodexSchema.V2AccountLoginCompletedNotification; |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | export const CLIENT_REQUEST_PARAMS = { | 432 | export const CLIENT_REQUEST_PARAMS = { |
packages/effect-codex-app-server/src/client.ts+1-1| ... | @@ -75,7 +75,7 @@ export interface CodexAppServerClientShape { | ... | @@ -75,7 +75,7 @@ export interface CodexAppServerClientShape { |
| 75 | export class CodexAppServerClient extends Context.Service< | 75 | export class CodexAppServerClient extends Context.Service< |
| 76 | CodexAppServerClient, | 76 | CodexAppServerClient, |
| 77 | CodexAppServerClientShape | 77 | CodexAppServerClientShape |
| 78 | >()("effect-codex-app-server/CodexAppServerClient") {} | 78 | >()("effect-codex-app-server/client/CodexAppServerClient") {} |
| 79 | 79 | ||
| 80 | type ServerRequestHandler = ( | 80 | type ServerRequestHandler = ( |
| 81 | payload: unknown, | 81 | payload: unknown, |
packages/effect-codex-app-server/tsconfig.json+3-1| ... | @@ -1,5 +1,7 @@ | ... | @@ -1,5 +1,7 @@ |
| 1 | { | 1 | { |
| 2 | "extends": "../../tsconfig.base.json", | 2 | "extends": "../../tsconfig.base.json", |
| 3 | "compilerOptions": {}, | 3 | "compilerOptions": { |
| 4 | "types": ["node"] | ||
| 5 | }, | ||
| 4 | "include": ["src", "scripts", "test"] | 6 | "include": ["src", "scripts", "test"] |
| 5 | } | 7 | } |
packages/shared/package.json+1-3| ... | @@ -93,7 +93,7 @@ | ... | @@ -93,7 +93,7 @@ |
| 93 | } | 93 | } |
| 94 | }, | 94 | }, |
| 95 | "scripts": { | 95 | "scripts": { |
| 96 | "typecheck": "tsc --noEmit", | 96 | "typecheck": "tsgo --noEmit", |
| 97 | "test": "vitest run" | 97 | "test": "vitest run" |
| 98 | }, | 98 | }, |
| 99 | "dependencies": { | 99 | "dependencies": { |
| ... | @@ -101,11 +101,9 @@ | ... | @@ -101,11 +101,9 @@ |
| 101 | "effect": "catalog:" | 101 | "effect": "catalog:" |
| 102 | }, | 102 | }, |
| 103 | "devDependencies": { | 103 | "devDependencies": { |
| 104 | "@effect/language-service": "catalog:", | ||
| 105 | "@effect/platform-node": "catalog:", | 104 | "@effect/platform-node": "catalog:", |
| 106 | "@effect/vitest": "catalog:", | 105 | "@effect/vitest": "catalog:", |
| 107 | "@types/node": "catalog:", | 106 | "@types/node": "catalog:", |
| 108 | "typescript": "catalog:", | ||
| 109 | "vitest": "catalog:" | 107 | "vitest": "catalog:" |
| 110 | } | 108 | } |
| 111 | } | 109 | } |
packages/shared/src/schemaJson.test.ts+21-1| ... | @@ -1,6 +1,9 @@ | ... | @@ -1,6 +1,9 @@ |
| 1 | import * as Schema from "effect/Schema"; | ||
| 1 | import { describe, expect, it } from "vitest"; | 2 | import { describe, expect, it } from "vitest"; |
| 2 | 3 | ||
| 3 | import { extractJsonObject } from "./schemaJson.ts"; | 4 | import { extractJsonObject, fromLenientJson } from "./schemaJson.ts"; |
| 5 | |||
| 6 | const decodeLenientJson = Schema.decodeUnknownSync(fromLenientJson(Schema.Unknown)); | ||
| 4 | 7 | ||
| 5 | describe("schemaJson helpers", () => { | 8 | describe("schemaJson helpers", () => { |
| 6 | it("extracts a balanced JSON object from surrounding text", () => { | 9 | it("extracts a balanced JSON object from surrounding text", () => { |
| ... | @@ -28,4 +31,21 @@ Done.`), | ... | @@ -28,4 +31,21 @@ Done.`), |
| 28 | it("returns trimmed input when no JSON object starts", () => { | 31 | it("returns trimmed input when no JSON object starts", () => { |
| 29 | expect(extractJsonObject(" no structured output ")).toBe("no structured output"); | 32 | expect(extractJsonObject(" no structured output ")).toBe("no structured output"); |
| 30 | }); | 33 | }); |
| 34 | |||
| 35 | it("decodes JSON with comments and trailing commas", () => { | ||
| 36 | expect( | ||
| 37 | decodeLenientJson(`{ | ||
| 38 | // Comments are valid in settings files. | ||
| 39 | "enabled": true, | ||
| 40 | "values": [1, 2,], | ||
| 41 | }`), | ||
| 42 | ).toEqual({ | ||
| 43 | enabled: true, | ||
| 44 | values: [1, 2], | ||
| 45 | }); | ||
| 46 | }); | ||
| 47 | |||
| 48 | it("rejects malformed JSON after lenient preprocessing", () => { | ||
| 49 | expect(() => decodeLenientJson('{ "enabled": true,, }')).toThrow(); | ||
| 50 | }); | ||
| 31 | }); | 51 | }); |
packages/shared/src/schemaJson.ts+26-25| ... | @@ -45,32 +45,33 @@ export const formatSchemaError = (cause: Cause.Cause<Schema.SchemaError>) => { | ... | @@ -45,32 +45,33 @@ export const formatSchemaError = (cause: Cause.Cause<Schema.SchemaError>) => { |
| 45 | * A `Getter` that parses a lenient JSON string (tolerating trailing commas | 45 | * A `Getter` that parses a lenient JSON string (tolerating trailing commas |
| 46 | * and JS-style comments) into an unknown value. | 46 | * and JS-style comments) into an unknown value. |
| 47 | * | 47 | * |
| 48 | * Mirrors `SchemaGetter.parseJson()` but uses `parseLenientJson` instead | 48 | * Mirrors `SchemaGetter.parseJson()` but strips JSONC syntax before parsing. |
| 49 | * of `JSON.parse`. | ||
| 50 | */ | 49 | */ |
| 51 | const parseLenientJsonGetter = SchemaGetter.onSome((input: string) => | 50 | const decodeJsonString = Schema.decodeEffect(Schema.UnknownFromJsonString); |
| 52 | Effect.try({ | 51 | |
| 53 | try: () => { | 52 | const parseLenientJsonGetter = SchemaGetter.onSome((input: string) => { |
| 54 | // Strip single-line comments — alternation preserves quoted strings. | 53 | // Strip single-line comments - alternation preserves quoted strings. |
| 55 | let stripped = input.replace( | 54 | let stripped = input.replace( |
| 56 | /("(?:[^"\\]|\\.)*")|\/\/[^\n]*/g, | 55 | /("(?:[^"\\]|\\.)*")|\/\/[^\n]*/g, |
| 57 | (match, stringLiteral: string | undefined) => (stringLiteral ? match : ""), | 56 | (match, stringLiteral: string | undefined) => (stringLiteral ? match : ""), |
| 58 | ); | 57 | ); |
| 59 | 58 | ||
| 60 | // Strip multi-line comments. | 59 | // Strip multi-line comments. |
| 61 | stripped = stripped.replace( | 60 | stripped = stripped.replace( |
| 62 | /("(?:[^"\\]|\\.)*")|\/\*[\s\S]*?\*\//g, | 61 | /("(?:[^"\\]|\\.)*")|\/\*[\s\S]*?\*\//g, |
| 63 | (match, stringLiteral: string | undefined) => (stringLiteral ? match : ""), | 62 | (match, stringLiteral: string | undefined) => (stringLiteral ? match : ""), |
| 64 | ); | 63 | ); |
| 65 | 64 | ||
| 66 | // Strip trailing commas before `}` or `]`. | 65 | // Strip trailing commas before `}` or `]`. |
| 67 | stripped = stripped.replace(/,(\s*[}\]])/g, "$1"); | 66 | stripped = stripped.replace(/,(\s*[}\]])/g, "$1"); |
| 68 | 67 | ||
| 69 | return Option.some(JSON.parse(stripped)); | 68 | return decodeJsonString(stripped).pipe( |
| 70 | }, | 69 | Effect.map(Option.some), |
| 71 | catch: (e) => new SchemaIssue.InvalidValue(Option.some(input), { message: String(e) }), | 70 | Effect.mapError( |
| 72 | }), | 71 | (error) => new SchemaIssue.InvalidValue(Option.some(input), { message: String(error) }), |
| 73 | ); | 72 | ), |
| 73 | ); | ||
| 74 | }); | ||
| 74 | 75 | ||
| 75 | /** | 76 | /** |
| 76 | * Schema transformation: lenient JSONC string ↔ unknown. | 77 | * Schema transformation: lenient JSONC string ↔ unknown. |
packages/shared/tsconfig.json+3-1| ... | @@ -1,5 +1,7 @@ | ... | @@ -1,5 +1,7 @@ |
| 1 | { | 1 | { |
| 2 | "extends": "../../tsconfig.base.json", | 2 | "extends": "../../tsconfig.base.json", |
| 3 | "compilerOptions": {}, | 3 | "compilerOptions": { |
| 4 | "types": ["node"] | ||
| 5 | }, | ||
| 4 | "include": ["src"] | 6 | "include": ["src"] |
| 5 | } | 7 | } |
packages/ssh/package.json+1-3| ... | @@ -25,7 +25,7 @@ | ... | @@ -25,7 +25,7 @@ |
| 25 | } | 25 | } |
| 26 | }, | 26 | }, |
| 27 | "scripts": { | 27 | "scripts": { |
| 28 | "typecheck": "tsc --noEmit", | 28 | "typecheck": "tsgo --noEmit", |
| 29 | "test": "vitest run" | 29 | "test": "vitest run" |
| 30 | }, | 30 | }, |
| 31 | "dependencies": { | 31 | "dependencies": { |
| ... | @@ -34,11 +34,9 @@ | ... | @@ -34,11 +34,9 @@ |
| 34 | "effect": "catalog:" | 34 | "effect": "catalog:" |
| 35 | }, | 35 | }, |
| 36 | "devDependencies": { | 36 | "devDependencies": { |
| 37 | "@effect/language-service": "catalog:", | ||
| 38 | "@effect/platform-node": "catalog:", | 37 | "@effect/platform-node": "catalog:", |
| 39 | "@effect/vitest": "catalog:", | 38 | "@effect/vitest": "catalog:", |
| 40 | "@types/node": "catalog:", | 39 | "@types/node": "catalog:", |
| 41 | "typescript": "catalog:", | ||
| 42 | "vitest": "catalog:" | 40 | "vitest": "catalog:" |
| 43 | } | 41 | } |
| 44 | } | 42 | } |
packages/ssh/src/auth.ts+1-1| ... | @@ -39,7 +39,7 @@ export interface SshPasswordPromptShape { | ... | @@ -39,7 +39,7 @@ export interface SshPasswordPromptShape { |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | export class SshPasswordPrompt extends Context.Service<SshPasswordPrompt, SshPasswordPromptShape>()( | 41 | export class SshPasswordPrompt extends Context.Service<SshPasswordPrompt, SshPasswordPromptShape>()( |
| 42 | "@t3tools/ssh/SshPasswordPrompt", | 42 | "@t3tools/ssh/auth/SshPasswordPrompt", |
| 43 | ) { | 43 | ) { |
| 44 | static readonly disabledLayer = Layer.succeed( | 44 | static readonly disabledLayer = Layer.succeed( |
| 45 | SshPasswordPrompt, | 45 | SshPasswordPrompt, |
packages/ssh/src/tunnel.ts+4-1| ... | @@ -1753,10 +1753,13 @@ const makeSshEnvironmentManager = Effect.fn("ssh/tunnel.SshEnvironmentManager.ma | ... | @@ -1753,10 +1753,13 @@ const makeSshEnvironmentManager = Effect.fn("ssh/tunnel.SshEnvironmentManager.ma |
| 1753 | return SshEnvironmentManager.of({ ensureEnvironment, disconnectEnvironment }); | 1753 | return SshEnvironmentManager.of({ ensureEnvironment, disconnectEnvironment }); |
| 1754 | }); | 1754 | }); |
| 1755 | 1755 | ||
| 1756 | /** | ||
| 1757 | * @effect-expect-leaking ChildProcessSpawner | FileSystem | HttpClient | NetService | Path | SshPasswordPrompt | ||
| 1758 | */ | ||
| 1756 | export class SshEnvironmentManager extends Context.Service< | 1759 | export class SshEnvironmentManager extends Context.Service< |
| 1757 | SshEnvironmentManager, | 1760 | SshEnvironmentManager, |
| 1758 | SshEnvironmentManagerShape | 1761 | SshEnvironmentManagerShape |
| 1759 | >()("@t3tools/ssh/SshEnvironmentManager") { | 1762 | >()("@t3tools/ssh/tunnel/SshEnvironmentManager") { |
| 1760 | static readonly layer = (options: SshEnvironmentManagerOptions = {}) => | 1763 | static readonly layer = (options: SshEnvironmentManagerOptions = {}) => |
| 1761 | Layer.effect(SshEnvironmentManager, makeSshEnvironmentManager(options)); | 1764 | Layer.effect(SshEnvironmentManager, makeSshEnvironmentManager(options)); |
| 1762 | } | 1765 | } |
packages/ssh/tsconfig.json+3-1| ... | @@ -1,5 +1,7 @@ | ... | @@ -1,5 +1,7 @@ |
| 1 | { | 1 | { |
| 2 | "extends": "../../tsconfig.base.json", | 2 | "extends": "../../tsconfig.base.json", |
| 3 | "compilerOptions": {}, | 3 | "compilerOptions": { |
| 4 | "types": ["node"] | ||
| 5 | }, | ||
| 4 | "include": ["src"] | 6 | "include": ["src"] |
| 5 | } | 7 | } |
packages/tailscale/package.json+1-3| ... | @@ -9,7 +9,7 @@ | ... | @@ -9,7 +9,7 @@ |
| 9 | } | 9 | } |
| 10 | }, | 10 | }, |
| 11 | "scripts": { | 11 | "scripts": { |
| 12 | "typecheck": "tsc --noEmit", | 12 | "typecheck": "tsgo --noEmit", |
| 13 | "test": "vitest run" | 13 | "test": "vitest run" |
| 14 | }, | 14 | }, |
| 15 | "dependencies": { | 15 | "dependencies": { |
| ... | @@ -17,10 +17,8 @@ | ... | @@ -17,10 +17,8 @@ |
| 17 | "effect": "catalog:" | 17 | "effect": "catalog:" |
| 18 | }, | 18 | }, |
| 19 | "devDependencies": { | 19 | "devDependencies": { |
| 20 | "@effect/language-service": "catalog:", | ||
| 21 | "@effect/vitest": "catalog:", | 20 | "@effect/vitest": "catalog:", |
| 22 | "@types/node": "catalog:", | 21 | "@types/node": "catalog:", |
| 23 | "typescript": "catalog:", | ||
| 24 | "vitest": "catalog:" | 22 | "vitest": "catalog:" |
| 25 | } | 23 | } |
| 26 | } | 24 | } |
packages/tailscale/tsconfig.json+3-1| ... | @@ -1,5 +1,7 @@ | ... | @@ -1,5 +1,7 @@ |
| 1 | { | 1 | { |
| 2 | "extends": "../../tsconfig.base.json", | 2 | "extends": "../../tsconfig.base.json", |
| 3 | "compilerOptions": {}, | 3 | "compilerOptions": { |
| 4 | "types": ["node"] | ||
| 5 | }, | ||
| 4 | "include": ["src"] | 6 | "include": ["src"] |
| 5 | } | 7 | } |
scripts/package.json+1-3| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | "private": true, | 3 | "private": true, |
| 4 | "type": "module", | 4 | "type": "module", |
| 5 | "scripts": { | 5 | "scripts": { |
| 6 | "typecheck": "tsc --noEmit", | 6 | "typecheck": "tsgo --noEmit", |
| 7 | "test": "vitest run" | 7 | "test": "vitest run" |
| 8 | }, | 8 | }, |
| 9 | "dependencies": { | 9 | "dependencies": { |
| ... | @@ -14,10 +14,8 @@ | ... | @@ -14,10 +14,8 @@ |
| 14 | "effect": "catalog:" | 14 | "effect": "catalog:" |
| 15 | }, | 15 | }, |
| 16 | "devDependencies": { | 16 | "devDependencies": { |
| 17 | "@effect/language-service": "catalog:", | ||
| 18 | "@effect/vitest": "catalog:", | 17 | "@effect/vitest": "catalog:", |
| 19 | "@types/bun": "catalog:", | 18 | "@types/bun": "catalog:", |
| 20 | "typescript": "catalog:", | ||
| 21 | "vitest": "catalog:" | 19 | "vitest": "catalog:" |
| 22 | } | 20 | } |
| 23 | } | 21 | } |
tsconfig.base.json+4-1| ... | @@ -35,6 +35,7 @@ | ... | @@ -35,6 +35,7 @@ |
| 35 | "globalErrorInEffectFailure": "error", | 35 | "globalErrorInEffectFailure": "error", |
| 36 | "unknownInEffectCatch": "error", | 36 | "unknownInEffectCatch": "error", |
| 37 | "strictBooleanExpressions": "off", | 37 | "strictBooleanExpressions": "off", |
| 38 | "lazyEffect": "off", | ||
| 38 | "preferSchemaOverJson": "error", | 39 | "preferSchemaOverJson": "error", |
| 39 | "schemaSyncInEffect": "error", | 40 | "schemaSyncInEffect": "error", |
| 40 | "cryptoRandomUUID": "error", | 41 | "cryptoRandomUUID": "error", |
| ... | @@ -47,7 +48,9 @@ | ... | @@ -47,7 +48,9 @@ |
| 47 | "globalRandom": "error", | 48 | "globalRandom": "error", |
| 48 | "globalRandomInEffect": "error", | 49 | "globalRandomInEffect": "error", |
| 49 | "globalTimers": "error", | 50 | "globalTimers": "error", |
| 50 | "globalTimersInEffect": "error" | 51 | "globalTimersInEffect": "error", |
| 52 | "globalFetch": "error", | ||
| 53 | "globalFetchInEffect": "error" | ||
| 51 | } | 54 | } |
| 52 | } | 55 | } |
| 53 | ] | 56 | ] |