t3code-cli 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/application.js +1 -1
  2. package/dist/auth.js +1 -1
  3. package/dist/bin.js +48 -31
  4. package/dist/cli.js +1 -1
  5. package/dist/config.js +1 -1
  6. package/dist/connection.js +1 -1
  7. package/dist/index.js +1 -1
  8. package/dist/node.js +1 -1
  9. package/dist/rolldown-runtime.js +1 -1
  10. package/dist/rpc.js +1 -1
  11. package/dist/shared.js +11971 -1517
  12. package/dist/src/application/actions.d.ts +1 -1
  13. package/dist/src/application/layer.d.ts +42 -42
  14. package/dist/src/application/project-commands.d.ts +3 -3
  15. package/dist/src/application/projects.d.ts +1 -1
  16. package/dist/src/application/shell-sequence.d.ts +23 -28
  17. package/dist/src/application/terminals.d.ts +6 -6
  18. package/dist/src/application/thread-commands.d.ts +18 -18
  19. package/dist/src/application/thread-update.d.ts +1 -1
  20. package/dist/src/application/thread-wait.d.ts +19 -24
  21. package/dist/src/application/threads.d.ts +124 -149
  22. package/dist/src/auth/error.d.ts +1 -2
  23. package/dist/src/auth/layer.d.ts +2 -2
  24. package/dist/src/auth/local-origin.d.ts +2 -2
  25. package/dist/src/auth/local-token.d.ts +2 -2
  26. package/dist/src/auth/remote-error.d.ts +3 -0
  27. package/dist/src/config/config.d.ts +2 -2
  28. package/dist/src/config/credential/service.d.ts +2 -2
  29. package/dist/src/config/keystore/file.d.ts +1 -1
  30. package/dist/src/config/persist/migration.d.ts +3 -3
  31. package/dist/src/config/persist/persist.d.ts +4 -4
  32. package/dist/src/connection/error.d.ts +3 -1
  33. package/dist/src/connection/prepared.d.ts +14 -0
  34. package/dist/src/domain/helpers.d.ts +46 -51
  35. package/dist/src/domain/model-config.d.ts +91 -86
  36. package/dist/src/domain/thread-lifecycle.d.ts +23 -28
  37. package/dist/src/orchestration/layer.d.ts +308 -523
  38. package/dist/src/rpc/error.d.ts +4 -6
  39. package/dist/src/rpc/index.d.ts +3 -2
  40. package/dist/src/rpc/layer.d.ts +1890 -2299
  41. package/dist/src/rpc/operation.d.ts +4 -6260
  42. package/dist/src/rpc/service.d.ts +1 -1
  43. package/dist/src/rpc/session.d.ts +22 -0
  44. package/dist/src/rpc/ws-group.d.ts +439 -1180
  45. package/dist/src/runtime/layer.d.ts +10 -10
  46. package/dist/src/sql/node-sqlite-client.d.ts +1 -1
  47. package/dist/t3tools.js +2 -2
  48. package/package.json +8 -7
  49. package/src/application/thread-wait.ts +4 -0
  50. package/src/auth/error.ts +2 -8
  51. package/src/auth/remote-error.ts +17 -0
  52. package/src/auth/transport.ts +45 -114
  53. package/src/connection/error.ts +4 -1
  54. package/src/connection/layer.ts +5 -2
  55. package/src/connection/prepared.ts +83 -0
  56. package/src/orchestration/layer.ts +2 -1
  57. package/src/rpc/error.ts +9 -16
  58. package/src/rpc/index.ts +3 -2
  59. package/src/rpc/layer.ts +17 -51
  60. package/src/rpc/operation.ts +16 -2
  61. package/src/rpc/service.ts +2 -1
  62. package/src/rpc/session.ts +168 -0
  63. package/src/rpc/ws-group.ts +12 -26
  64. package/src/runtime/layer.ts +6 -3
@@ -0,0 +1,83 @@
1
+ import { resolveRemoteWebSocketConnectionUrl } from "@t3tools/client-runtime/authorization";
2
+ import {
3
+ BearerConnectionTarget,
4
+ type ConnectionAttemptError,
5
+ mapRemoteEnvironmentError,
6
+ type PreparedConnection,
7
+ } from "@t3tools/client-runtime/connection";
8
+ import { fetchRemoteEnvironmentDescriptor } from "@t3tools/client-runtime/environment";
9
+ import * as Context from "effect/Context";
10
+ import * as Effect from "effect/Effect";
11
+ import * as Layer from "effect/Layer";
12
+ import { HttpClient } from "effect/unstable/http";
13
+
14
+ import { toWebSocketEndpointUrl } from "../config/url/url.ts";
15
+ import { T3CodeConnectionError } from "./error.ts";
16
+ import { T3CodeConnectionProvider } from "./service.ts";
17
+ import type { T3CodeConnection } from "./type.ts";
18
+
19
+ export class T3PreparedConnectionProvider extends Context.Service<
20
+ T3PreparedConnectionProvider,
21
+ {
22
+ readonly get: Effect.Effect<PreparedConnection, ConnectionAttemptError | T3CodeConnectionError>;
23
+ }
24
+ >()("t3cli/T3PreparedConnectionProvider") {}
25
+
26
+ const makePreparedConnection = Effect.fn("makePreparedConnection")(function* (
27
+ connection: T3CodeConnection,
28
+ ) {
29
+ const httpBaseUrl = connection.origin.url;
30
+ const wsBaseUrl = yield* toWebSocketEndpointUrl(httpBaseUrl, "/ws").pipe(
31
+ Effect.mapError(
32
+ (error) =>
33
+ new T3CodeConnectionError({
34
+ message: "failed to resolve websocket endpoint",
35
+ cause: error,
36
+ }),
37
+ ),
38
+ );
39
+ const descriptor = yield* fetchRemoteEnvironmentDescriptor({ httpBaseUrl }).pipe(
40
+ Effect.mapError(mapRemoteEnvironmentError),
41
+ );
42
+ const socketUrl = yield* resolveRemoteWebSocketConnectionUrl({
43
+ httpBaseUrl,
44
+ wsBaseUrl,
45
+ bearerToken: connection.auth.token,
46
+ }).pipe(Effect.mapError(mapRemoteEnvironmentError));
47
+
48
+ return {
49
+ environmentId: descriptor.environmentId,
50
+ label: descriptor.label,
51
+ httpBaseUrl,
52
+ socketUrl,
53
+ httpAuthorization: {
54
+ _tag: "Bearer",
55
+ token: connection.auth.token,
56
+ },
57
+ target: new BearerConnectionTarget({
58
+ environmentId: descriptor.environmentId,
59
+ label: descriptor.label,
60
+ connectionId: descriptor.environmentId,
61
+ }),
62
+ } satisfies PreparedConnection;
63
+ });
64
+
65
+ const makeT3PreparedConnectionProvider = Effect.fn("makeT3PreparedConnectionProvider")(
66
+ function* () {
67
+ const connectionProvider = yield* T3CodeConnectionProvider;
68
+ const httpClient = yield* HttpClient.HttpClient;
69
+ const get = connectionProvider.get.pipe(
70
+ Effect.flatMap((connection) =>
71
+ makePreparedConnection(connection).pipe(
72
+ Effect.provideService(HttpClient.HttpClient, httpClient),
73
+ ),
74
+ ),
75
+ );
76
+ return T3PreparedConnectionProvider.of({ get });
77
+ },
78
+ );
79
+
80
+ export const T3PreparedConnectionProviderLive = Layer.effect(
81
+ T3PreparedConnectionProvider,
82
+ makeT3PreparedConnectionProvider(),
83
+ );
@@ -25,7 +25,8 @@ export const makeT3Orchestration = Effect.fn("makeT3Orchestration")(function* ()
25
25
  client[ORCHESTRATION_WS_METHODS.subscribeShell]({}),
26
26
  )
27
27
  .pipe(
28
- Stream.map((item: OrchestrationShellStreamItem) =>
28
+ Stream.filter((item: OrchestrationShellStreamItem) => item.kind !== "synchronized"),
29
+ Stream.map((item) =>
29
30
  item.kind === "snapshot" ? item.snapshot.snapshotSequence : item.sequence,
30
31
  ),
31
32
  );
package/src/rpc/error.ts CHANGED
@@ -1,21 +1,19 @@
1
- import * as Schema from "effect/Schema";
1
+ import {
2
+ ConnectionBlockedError,
3
+ ConnectionTransientError,
4
+ } from "@t3tools/client-runtime/connection";
2
5
  import {
3
6
  EnvironmentAuthorizationError,
4
7
  KeybindingsConfigError,
5
8
  OrchestrationDispatchCommandError,
6
9
  OrchestrationGetSnapshotError,
7
10
  ServerSettingsError,
8
- TerminalCwdError,
9
- TerminalHistoryError,
10
- TerminalNotRunningError,
11
- TerminalSessionLookupError,
11
+ TerminalError,
12
12
  } from "@t3tools/contracts";
13
- import { HttpClientError } from "effect/unstable/http";
13
+ import * as Schema from "effect/Schema";
14
14
  import { RpcClientError } from "effect/unstable/rpc";
15
15
 
16
- import { AuthTransportError } from "../auth/error.ts";
17
16
  import { T3CodeConnectionError } from "../connection/error.ts";
18
- import { UrlError } from "../config/url/error.ts";
19
17
 
20
18
  const RpcErrorCauseSchema = Schema.Union([
21
19
  RpcClientError.RpcClientError,
@@ -24,15 +22,10 @@ const RpcErrorCauseSchema = Schema.Union([
24
22
  OrchestrationDispatchCommandError,
25
23
  OrchestrationGetSnapshotError,
26
24
  ServerSettingsError,
27
- TerminalCwdError,
28
- TerminalHistoryError,
29
- TerminalNotRunningError,
30
- TerminalSessionLookupError,
31
- AuthTransportError,
25
+ TerminalError,
26
+ ConnectionBlockedError,
27
+ ConnectionTransientError,
32
28
  T3CodeConnectionError,
33
- HttpClientError.HttpClientErrorSchema,
34
- UrlError,
35
- Schema.instanceOf(Schema.SchemaError),
36
29
  ]);
37
30
 
38
31
  export type RpcKnownCause = Schema.Schema.Type<typeof RpcErrorCauseSchema>;
package/src/rpc/index.ts CHANGED
@@ -1,5 +1,6 @@
1
- export { RpcError } from "./error.ts";
1
+ export { RpcError, type OrchestrationError } from "./error.ts";
2
2
  export { makeT3RpcLayer, T3RpcLive } from "./layer.ts";
3
3
  export { T3RpcOperations, T3RpcOperationsLive, makeT3RpcOperations } from "./operation.ts";
4
+ export type { T3RpcOperationsService } from "./operation.ts";
4
5
  export { T3Rpc } from "./service.ts";
5
- export type { WsClient } from "./service.ts";
6
+ export type { T3RpcService, WsClient } from "./service.ts";
package/src/rpc/layer.ts CHANGED
@@ -3,22 +3,22 @@ import * as Effect from "effect/Effect";
3
3
  import * as Exit from "effect/Exit";
4
4
  import * as Layer from "effect/Layer";
5
5
  import * as Option from "effect/Option";
6
+ import * as Predicate from "effect/Predicate";
6
7
  import * as Schedule from "effect/Schedule";
7
8
  import * as Scope from "effect/Scope";
8
9
  import * as SynchronizedRef from "effect/SynchronizedRef";
9
- import { HttpClientRequest } from "effect/unstable/http";
10
- import { RpcClient, RpcSerialization } from "effect/unstable/rpc";
11
- import * as Socket from "effect/unstable/socket/Socket";
12
10
 
13
- import { T3AuthTransport } from "../auth/transport.ts";
14
- import { T3CodeConnectionProvider } from "../connection/service.ts";
15
- import { normalizeHttpBaseUrl, toWebSocketEndpointUrl } from "../config/url/url.ts";
16
- import { CliWsRpcGroup } from "./ws-group.ts";
11
+ import { T3PreparedConnectionProvider } from "../connection/prepared.ts";
17
12
  import { RpcError } from "./error.ts";
13
+ import { T3RpcSessionFactory } from "./session.ts";
18
14
  import { T3Rpc, type WsClient } from "./service.ts";
19
15
 
20
- const makeClient = RpcClient.make(CliWsRpcGroup);
21
- const connectionRetrySchedule = Schedule.exponential("100 millis").pipe(Schedule.take(4));
16
+ const connectionRetrySchedule = Schedule.exponential("100 millis").pipe(
17
+ Schedule.take(4),
18
+ Schedule.collectWhile((metadata: Schedule.Metadata) =>
19
+ Predicate.isTagged(metadata.input, "ConnectionTransientError"),
20
+ ),
21
+ );
22
22
 
23
23
  type Connection = {
24
24
  readonly scope: Scope.Closeable;
@@ -26,23 +26,19 @@ type Connection = {
26
26
  };
27
27
 
28
28
  export const makeT3RpcLayer = Effect.fn("makeT3RpcLayer")(function* () {
29
- const connectionProvider = yield* T3CodeConnectionProvider;
30
- const authTransport = yield* T3AuthTransport;
31
- const webSocketConstructor = yield* Socket.WebSocketConstructor;
29
+ const preparedConnectionProvider = yield* T3PreparedConnectionProvider;
30
+ const sessions = yield* T3RpcSessionFactory;
32
31
  const parentScope = yield* Scope.Scope;
33
32
  const connection = yield* SynchronizedRef.make(Option.none<Connection>());
34
33
  const openConnection = Effect.fn("T3RpcLive.openConnection")(function* () {
35
34
  const scope = yield* Scope.fork(parentScope);
36
35
  return yield* Effect.gen(function* () {
37
- const url = yield* makeWsUrl({ authTransport, connectionProvider });
38
- const protocol = yield* Layer.buildWithScope(
39
- makeProtocolLayer(url, webSocketConstructor),
40
- scope,
41
- );
42
- const client = yield* makeClient.pipe(
43
- Effect.provide(protocol),
44
- Effect.provideService(Scope.Scope, scope),
45
- );
36
+ const prepared = yield* preparedConnectionProvider.get;
37
+ const session = yield* sessions
38
+ .connect(prepared)
39
+ .pipe(Effect.provideService(Scope.Scope, scope));
40
+ yield* session.ready;
41
+ const client: WsClient = session.client;
46
42
  return { scope, client } satisfies Connection;
47
43
  }).pipe(
48
44
  Effect.retry(connectionRetrySchedule),
@@ -74,36 +70,6 @@ export const makeT3RpcLayer = Effect.fn("makeT3RpcLayer")(function* () {
74
70
  };
75
71
  });
76
72
 
77
- const makeWsUrl = Effect.fn("makeWsUrl")(function* (input: {
78
- readonly authTransport: T3AuthTransport["Service"];
79
- readonly connectionProvider: T3CodeConnectionProvider["Service"];
80
- }) {
81
- const connection = yield* input.connectionProvider.get;
82
- const origin = yield* normalizeHttpBaseUrl(connection.origin.url);
83
- const wsTicket = yield* input.authTransport.issueWebSocketTicket({
84
- url: origin,
85
- token: connection.auth.token,
86
- });
87
- const wsUrl = yield* toWebSocketEndpointUrl(origin, "/ws");
88
- const request = HttpClientRequest.get(wsUrl).pipe(
89
- HttpClientRequest.setUrlParam("wsTicket", wsTicket.ticket),
90
- );
91
- return Option.getOrThrow(HttpClientRequest.toUrl(request)).toString();
92
- });
93
-
94
- function makeProtocolLayer(
95
- url: string,
96
- webSocketConstructor: Socket.WebSocketConstructor["Service"],
97
- ) {
98
- const socketLayer = Socket.layerWebSocket(url).pipe(
99
- Layer.provide(Layer.succeed(Socket.WebSocketConstructor, webSocketConstructor)),
100
- );
101
- return RpcClient.layerProtocolSocket({ retryTransientErrors: true }).pipe(
102
- Layer.provide(socketLayer),
103
- Layer.provide(RpcSerialization.layerJson),
104
- );
105
- }
106
-
107
73
  export const T3RpcLive = Layer.effectContext(
108
74
  makeT3RpcLayer().pipe(Effect.map((rpc) => Context.make(T3Rpc, rpc))),
109
75
  );
@@ -1,3 +1,11 @@
1
+ import type {
2
+ EnvironmentAuthorizationError,
3
+ KeybindingsConfigError,
4
+ OrchestrationDispatchCommandError,
5
+ OrchestrationGetSnapshotError,
6
+ ServerSettingsError,
7
+ TerminalError,
8
+ } from "@t3tools/contracts";
1
9
  import * as Context from "effect/Context";
2
10
  import * as Effect from "effect/Effect";
3
11
  import * as Layer from "effect/Layer";
@@ -8,9 +16,15 @@ import { RpcClientError } from "effect/unstable/rpc";
8
16
 
9
17
  import { RpcError } from "./error.ts";
10
18
  import { T3Rpc, type WsClient } from "./service.ts";
11
- import type { CliRpcRequestError } from "./ws-group.ts";
12
19
 
13
- export type CliRpcOperationError = CliRpcRequestError | RpcClientError.RpcClientError;
20
+ export type CliRpcOperationError =
21
+ | EnvironmentAuthorizationError
22
+ | KeybindingsConfigError
23
+ | OrchestrationDispatchCommandError
24
+ | OrchestrationGetSnapshotError
25
+ | RpcClientError.RpcClientError
26
+ | ServerSettingsError
27
+ | TerminalError;
14
28
 
15
29
  export const rpcRetrySchedule = Schedule.exponential("100 millis").pipe(
16
30
  Schedule.take(4),
@@ -1,8 +1,9 @@
1
1
  import * as Context from "effect/Context";
2
2
  import type * as Effect from "effect/Effect";
3
3
  import type { RpcClient, RpcClientError } from "effect/unstable/rpc";
4
- import type { CliWsRpcGroup } from "./ws-group.ts";
4
+
5
5
  import type { RpcError } from "./error.ts";
6
+ import type { CliWsRpcGroup } from "./ws-group.ts";
6
7
 
7
8
  export type WsClient = RpcClient.FromGroup<typeof CliWsRpcGroup, RpcClientError.RpcClientError>;
8
9
 
@@ -0,0 +1,168 @@
1
+ import {
2
+ ConnectionBlockedError,
3
+ type ConnectionAttemptError,
4
+ ConnectionTransientError,
5
+ type PreparedConnection,
6
+ } from "@t3tools/client-runtime/connection";
7
+ import { WS_METHODS } from "@t3tools/contracts";
8
+ import * as Context from "effect/Context";
9
+ import * as Deferred from "effect/Deferred";
10
+ import * as Effect from "effect/Effect";
11
+ import * as Layer from "effect/Layer";
12
+ import * as Schedule from "effect/Schedule";
13
+ import type * as Scope from "effect/Scope";
14
+ import * as RpcClient from "effect/unstable/rpc/RpcClient";
15
+ import * as RpcSerialization from "effect/unstable/rpc/RpcSerialization";
16
+ import * as Socket from "effect/unstable/socket/Socket";
17
+
18
+ import type { WsClient as CliWsClient } from "./service.ts";
19
+ import type { CliServerConfig } from "./ws-group.ts";
20
+ import { CliWsRpcGroup } from "./ws-group.ts";
21
+
22
+ interface T3RpcSession {
23
+ readonly client: CliWsClient;
24
+ readonly initialConfig: Effect.Effect<CliServerConfig, ConnectionAttemptError>;
25
+ readonly ready: Effect.Effect<void, ConnectionAttemptError>;
26
+ readonly probe: Effect.Effect<void, ConnectionAttemptError>;
27
+ readonly closed: Effect.Effect<never, ConnectionTransientError>;
28
+ }
29
+
30
+ export class T3RpcSessionFactory extends Context.Service<
31
+ T3RpcSessionFactory,
32
+ {
33
+ readonly connect: (
34
+ connection: PreparedConnection,
35
+ ) => Effect.Effect<T3RpcSession, ConnectionAttemptError, Scope.Scope>;
36
+ }
37
+ >()("t3cli/T3RpcSessionFactory") {}
38
+
39
+ type SessionRpcError =
40
+ | Effect.Error<ReturnType<CliWsClient[typeof WS_METHODS.serverGetConfig]>>
41
+ | Effect.Error<ReturnType<CliWsClient[typeof WS_METHODS.serverProbe]>>;
42
+
43
+ const makeClient = RpcClient.make(CliWsRpcGroup);
44
+
45
+ const makeT3RpcSessionFactory = Effect.fn("makeT3RpcSessionFactory")(function* () {
46
+ const webSocketConstructor = yield* Socket.WebSocketConstructor;
47
+
48
+ const connect: T3RpcSessionFactory["Service"]["connect"] = Effect.fnUntraced(function* (
49
+ connection: PreparedConnection,
50
+ ) {
51
+ yield* Effect.annotateCurrentSpan({
52
+ "connection.environment.id": connection.environmentId,
53
+ });
54
+
55
+ const connected = yield* Deferred.make<void>();
56
+ const disconnected = yield* Deferred.make<never, ConnectionTransientError>();
57
+ const hooks = RpcClient.ConnectionHooks.of({
58
+ onConnect: Deferred.succeed(connected, undefined).pipe(Effect.asVoid),
59
+ onDisconnect: Deferred.isDone(connected).pipe(
60
+ Effect.flatMap((wasConnected) =>
61
+ Deferred.fail(
62
+ disconnected,
63
+ new ConnectionTransientError({
64
+ reason: "transport",
65
+ detail: wasConnected
66
+ ? `${connection.label} disconnected.`
67
+ : `${connection.label} could not establish a WebSocket connection.`,
68
+ }),
69
+ ),
70
+ ),
71
+ Effect.asVoid,
72
+ ),
73
+ });
74
+ const socketLayer = Socket.layerWebSocket(connection.socketUrl, {
75
+ openTimeout: "15 seconds",
76
+ }).pipe(Layer.provide(Layer.succeed(Socket.WebSocketConstructor, webSocketConstructor)));
77
+ const protocolLayer = Layer.effect(
78
+ RpcClient.Protocol,
79
+ RpcClient.makeProtocolSocket({
80
+ retryTransientErrors: false,
81
+ retryPolicy: Schedule.recurs(0),
82
+ }),
83
+ ).pipe(
84
+ Layer.provide(
85
+ Layer.mergeAll(
86
+ socketLayer,
87
+ RpcSerialization.layerJson,
88
+ Layer.succeed(RpcClient.ConnectionHooks, hooks),
89
+ ),
90
+ ),
91
+ );
92
+ const protocolContext = yield* Layer.build(protocolLayer).pipe(
93
+ Effect.withSpan("environment.websocket.connect"),
94
+ );
95
+ const client = yield* makeClient.pipe(Effect.provide(protocolContext));
96
+ const initialConfig = yield* Effect.cached(
97
+ client[WS_METHODS.serverGetConfig]({}).pipe(
98
+ catchSessionRpcErrors,
99
+ Effect.withSpan("environment.initialSync"),
100
+ ),
101
+ );
102
+ const probe = initialConfig.pipe(
103
+ Effect.flatMap((config) =>
104
+ Effect.gen(function* () {
105
+ if (config.environment.capabilities.connectionProbe) {
106
+ return yield* client[WS_METHODS.serverProbe]({});
107
+ }
108
+ return yield* client[WS_METHODS.serverGetConfig]({});
109
+ }).pipe(catchSessionRpcErrors),
110
+ ),
111
+ Effect.asVoid,
112
+ Effect.withSpan("clientRuntime.connection.rpcSession.probe"),
113
+ );
114
+
115
+ return {
116
+ client,
117
+ initialConfig,
118
+ ready: Deferred.await(connected).pipe(
119
+ Effect.andThen(initialConfig),
120
+ Effect.asVoid,
121
+ Effect.raceFirst(Deferred.await(disconnected)),
122
+ ),
123
+ probe,
124
+ closed: Deferred.await(disconnected),
125
+ } satisfies T3RpcSession;
126
+ });
127
+
128
+ return T3RpcSessionFactory.of({ connect });
129
+ });
130
+
131
+ export const T3RpcSessionFactoryLive = Layer.effect(T3RpcSessionFactory, makeT3RpcSessionFactory());
132
+
133
+ function catchSessionRpcErrors<A, R>(
134
+ effect: Effect.Effect<A, SessionRpcError, R>,
135
+ ): Effect.Effect<A, ConnectionAttemptError, R> {
136
+ return effect.pipe(
137
+ Effect.catchTags({
138
+ EnvironmentAuthorizationError: (error) =>
139
+ Effect.fail(
140
+ new ConnectionBlockedError({
141
+ reason: "permission",
142
+ detail: error.message,
143
+ }),
144
+ ),
145
+ KeybindingsConfigParseError: (error) =>
146
+ Effect.fail(
147
+ new ConnectionTransientError({
148
+ reason: "remote-unavailable",
149
+ detail: error.message,
150
+ }),
151
+ ),
152
+ ServerSettingsError: (error) =>
153
+ Effect.fail(
154
+ new ConnectionTransientError({
155
+ reason: "remote-unavailable",
156
+ detail: error.message,
157
+ }),
158
+ ),
159
+ RpcClientError: (error) =>
160
+ Effect.fail(
161
+ new ConnectionTransientError({
162
+ reason: "transport",
163
+ detail: error.message,
164
+ }),
165
+ ),
166
+ }),
167
+ );
168
+ }
@@ -1,16 +1,14 @@
1
1
  import {
2
2
  EnvironmentAuthorizationError,
3
3
  KeybindingsConfigError,
4
- OrchestrationDispatchCommandError,
5
- OrchestrationGetSnapshotError,
6
- ServerConfig,
7
4
  ServerProviders,
8
5
  ServerSettingsError,
9
- TerminalCwdError,
10
- TerminalHistoryError,
11
- TerminalNotRunningError,
12
- TerminalSessionLookupError,
13
6
  WS_METHODS,
7
+ WsOrchestrationDispatchCommandRpc,
8
+ WsOrchestrationGetArchivedShellSnapshotRpc,
9
+ WsOrchestrationSubscribeShellRpc,
10
+ WsOrchestrationSubscribeThreadRpc,
11
+ WsServerProbeRpc,
14
12
  WsSubscribeTerminalEventsRpc,
15
13
  WsSubscribeTerminalMetadataRpc,
16
14
  WsTerminalAttachRpc,
@@ -18,20 +16,18 @@ import {
18
16
  WsTerminalOpenRpc,
19
17
  WsTerminalResizeRpc,
20
18
  WsTerminalWriteRpc,
21
- WsOrchestrationDispatchCommandRpc,
22
- WsOrchestrationGetArchivedShellSnapshotRpc,
23
- WsOrchestrationSubscribeShellRpc,
24
- WsOrchestrationSubscribeThreadRpc,
25
19
  } from "@t3tools/contracts";
26
20
  import * as Schema from "effect/Schema";
27
21
  import { Rpc, RpcGroup } from "effect/unstable/rpc";
28
22
 
29
- export const FallbackServerConfig = Schema.Struct({
23
+ export const CliServerConfig = Schema.Struct({
24
+ environment: Schema.Struct({
25
+ capabilities: Schema.Struct({
26
+ connectionProbe: Schema.Boolean,
27
+ }),
28
+ }),
30
29
  providers: ServerProviders,
31
30
  });
32
- export type FallbackServerConfig = typeof FallbackServerConfig.Type;
33
-
34
- export const CliServerConfig = Schema.Union([ServerConfig, FallbackServerConfig]);
35
31
  export type CliServerConfig = typeof CliServerConfig.Type;
36
32
 
37
33
  export const WsServerGetConfigRpc = Rpc.make(WS_METHODS.serverGetConfig, {
@@ -52,16 +48,6 @@ export const CliWsRpcGroup = RpcGroup.make(
52
48
  WsOrchestrationGetArchivedShellSnapshotRpc,
53
49
  WsOrchestrationSubscribeShellRpc,
54
50
  WsOrchestrationSubscribeThreadRpc,
51
+ WsServerProbeRpc,
55
52
  WsServerGetConfigRpc,
56
53
  );
57
-
58
- export type CliRpcRequestError =
59
- | EnvironmentAuthorizationError
60
- | KeybindingsConfigError
61
- | OrchestrationDispatchCommandError
62
- | OrchestrationGetSnapshotError
63
- | TerminalCwdError
64
- | TerminalHistoryError
65
- | TerminalNotRunningError
66
- | TerminalSessionLookupError
67
- | ServerSettingsError;
@@ -14,10 +14,12 @@ import * as Config from "../config/config.ts";
14
14
  import * as Credential from "../config/credential/service.ts";
15
15
  import * as Selection from "../config/selection/service.ts";
16
16
  import { T3CodeConnectionError } from "../connection/error.ts";
17
+ import { T3PreparedConnectionProviderLive } from "../connection/prepared.ts";
17
18
  import { T3CodeConnectionProvider, makeT3CodeConnectionProvider } from "../connection/service.ts";
18
19
  import { T3OrchestrationLive } from "../orchestration/layer.ts";
19
20
  import { T3RpcLive } from "../rpc/layer.ts";
20
21
  import { T3RpcOperationsLive } from "../rpc/operation.ts";
22
+ import { T3RpcSessionFactoryLive } from "../rpc/session.ts";
21
23
  import { NodeSqlClientFactoryLive } from "../sql/node-sqlite-client.ts";
22
24
  import { NodeCliPathLayer } from "../cli-path/layer.ts";
23
25
 
@@ -63,9 +65,10 @@ const T3ConfigConnectionProviderLayer = Layer.effect(
63
65
  const T3RpcLayer = T3RpcLive.pipe(
64
66
  Layer.provide(
65
67
  Layer.mergeAll(
66
- T3ConfigConnectionProviderLayer,
67
- T3AuthTransportLayer,
68
- NodeSocket.layerWebSocketConstructor,
68
+ T3PreparedConnectionProviderLive.pipe(
69
+ Layer.provide(Layer.mergeAll(T3ConfigConnectionProviderLayer, NodeHttpClient.layerUndici)),
70
+ ),
71
+ T3RpcSessionFactoryLive.pipe(Layer.provide(NodeSocket.layerWebSocketConstructor)),
69
72
  ),
70
73
  ),
71
74
  );