t3code-cli 0.14.1 → 0.15.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.
- package/README.md +37 -1
- package/dist/application.d.ts +2 -2
- package/dist/application.js +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +1 -1
- package/dist/bin.js +1305 -424
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/client-runtime/authorization.d.ts +1 -1
- package/dist/client-runtime/authorization.js +1 -1
- package/dist/client-runtime/connection.d.ts +1 -1
- package/dist/client-runtime/connection.js +1 -1
- package/dist/client-runtime/environment.d.ts +7 -1
- package/dist/client-runtime/environment.js +1 -1
- package/dist/client-runtime/errors.js +1 -1
- package/dist/client-runtime/operations/projects.d.ts +2 -2
- package/dist/client-runtime/operations/projects.js +2 -2
- package/dist/client-runtime/operations.d.ts +2 -2
- package/dist/client-runtime/operations.js +2 -2
- package/dist/client-runtime/platform.d.ts +1 -1
- package/dist/client-runtime/platform.js +1 -1
- package/dist/client-runtime/relay.d.ts +13 -2
- package/dist/client-runtime/relay.js +12 -2
- package/dist/client-runtime/rpc.d.ts +2 -2
- package/dist/client-runtime/rpc.js +2 -2
- package/dist/client-runtime/state/assets.d.ts +17 -11
- package/dist/client-runtime/state/assets.js +1 -1
- package/dist/client-runtime/state/auth.d.ts +1 -1
- package/dist/client-runtime/state/auth.js +1 -1
- package/dist/client-runtime/state/connections.js +1 -1
- package/dist/client-runtime/state/entities.d.ts +1 -1
- package/dist/client-runtime/state/entities.js +1 -1
- package/dist/client-runtime/state/filesystem.d.ts +1 -1
- package/dist/client-runtime/state/filesystem.js +1 -1
- package/dist/client-runtime/state/git.d.ts +6 -5
- package/dist/client-runtime/state/git.js +1 -1
- package/dist/client-runtime/state/models.d.ts +1 -1
- package/dist/client-runtime/state/models.js +1 -1
- package/dist/client-runtime/state/orchestration.d.ts +42 -2
- package/dist/client-runtime/state/orchestration.js +13 -1
- package/dist/client-runtime/state/presentation.d.ts +15 -3
- package/dist/client-runtime/state/presentation.js +1 -1
- package/dist/client-runtime/state/preview.d.ts +58 -48
- package/dist/client-runtime/state/preview.js +3 -2
- package/dist/client-runtime/state/project-grouping.d.ts +26 -2
- package/dist/client-runtime/state/project-grouping.js +83 -3
- package/dist/client-runtime/state/projects.d.ts +24 -18
- package/dist/client-runtime/state/projects.js +1 -1
- package/dist/client-runtime/state/pull-requests.d.ts +478 -0
- package/dist/client-runtime/state/pull-requests.js +172 -0
- package/dist/client-runtime/state/relay.d.ts +1 -1
- package/dist/client-runtime/state/relay.js +1 -1
- package/dist/client-runtime/state/review.d.ts +16 -1
- package/dist/client-runtime/state/review.js +27 -6
- package/dist/client-runtime/state/runtime.d.ts +2 -2
- package/dist/client-runtime/state/runtime.js +2 -2
- package/dist/client-runtime/state/server.d.ts +311 -172
- package/dist/client-runtime/state/server.js +192 -16
- package/dist/client-runtime/state/session.d.ts +77 -7
- package/dist/client-runtime/state/session.js +32 -3
- package/dist/client-runtime/state/shell.d.ts +47 -7
- package/dist/client-runtime/state/shell.js +1 -1
- package/dist/client-runtime/state/source-control.d.ts +2 -2
- package/dist/client-runtime/state/source-control.js +1 -1
- package/dist/client-runtime/state/subagentRuntime.d.ts +145 -0
- package/dist/client-runtime/state/subagentRuntime.js +521 -0
- package/dist/client-runtime/state/terminal.d.ts +17 -17
- package/dist/client-runtime/state/terminal.js +1 -1
- package/dist/client-runtime/state/thread-search.d.ts +23 -0
- package/dist/client-runtime/state/thread-search.js +38 -0
- package/dist/client-runtime/state/thread-settled.d.ts +32 -4
- package/dist/client-runtime/state/thread-settled.js +2 -157
- package/dist/client-runtime/state/thread-sort.d.ts +59 -2
- package/dist/client-runtime/state/thread-sort.js +128 -2
- package/dist/client-runtime/state/threads.d.ts +115 -3
- package/dist/client-runtime/state/threads.js +309 -28
- package/dist/client-runtime/state/vcs.d.ts +14 -14
- package/dist/client-runtime/state/vcs.js +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connection.d.ts +1 -1
- package/dist/connection.js +1 -1
- package/dist/contracts.d.ts +1 -1
- package/dist/contracts.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +1 -1
- package/dist/orchestration.d.ts +155 -6
- package/dist/orchestration.js +2 -2
- package/dist/preview.d.ts +1 -1
- package/dist/preview.js +1 -1
- package/dist/rpc.d.ts +887 -360
- package/dist/rpc.js +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +1 -1
- package/dist/shared/DrainableWorker.js +1 -1
- package/dist/shared/KeyedCoalescingWorker.js +1 -1
- package/dist/shared/Net.d.ts +6 -0
- package/dist/shared/Net.js +2 -1
- package/dist/shared/advertisedEndpoint.d.ts +1 -1
- package/dist/shared/advertisedEndpoint.js +1 -1
- package/dist/shared/agentAwareness.d.ts +1 -1
- package/dist/shared/backgroundActivitySettings.d.ts +1 -1
- package/dist/shared/composerInlineTokens.js +1 -1
- package/dist/shared/connectAuth.d.ts +23 -4
- package/dist/shared/connectAuth.js +40 -7
- package/dist/shared/devHome.js +1 -1
- package/dist/shared/dpop.js +1 -1
- package/dist/shared/git.d.ts +1 -1
- package/dist/shared/httpObservability.js +1 -1
- package/dist/shared/httpReadiness.js +1 -1
- package/dist/shared/keybindings.d.ts +2 -2
- package/dist/shared/keybindings.js +15 -1
- package/dist/shared/model.d.ts +1 -1
- package/dist/shared/oauthScope.js +1 -1
- package/dist/shared/observability.d.ts +8 -1
- package/dist/shared/observability.js +49 -5
- package/dist/shared/path.js +1 -1
- package/dist/shared/preview.js +1 -1
- package/dist/shared/previewViewport.d.ts +1 -1
- package/dist/shared/previewViewport.js +1 -1
- package/dist/shared/projectFavicon.d.ts +2 -1
- package/dist/shared/projectFavicon.js +13 -1
- package/dist/shared/projectScripts.d.ts +1 -1
- package/dist/shared/relayAuth.js +1 -1
- package/dist/shared/relayClient.d.ts +1 -1
- package/dist/shared/relayClient.js +1 -1
- package/dist/shared/relayJwt.js +1 -1
- package/dist/shared/relayTracing.js +1 -1
- package/dist/shared/relayUrl.js +1 -1
- package/dist/shared/remote.js +1 -1
- package/dist/shared/schemaYaml.js +3 -3
- package/dist/shared/semver.js +1 -1
- package/dist/shared/serverSettings.d.ts +1 -1
- package/dist/shared/serverSettings.js +1 -1
- package/dist/shared/shell.d.ts +6 -1
- package/dist/shared/shell.js +42 -4
- package/dist/shared/sourceControl.d.ts +1 -1
- package/dist/shared/t3ProjectFile.d.ts +9 -1
- package/dist/shared/t3ProjectFile.js +12 -2
- package/dist/shared/terminalLabels.d.ts +1 -1
- package/dist/shared/threadEnvMode.d.ts +29 -0
- package/dist/shared/threadEnvMode.js +24 -0
- package/dist/shared/toolActivity.d.ts +1 -1
- package/dist/shared/usageFormat.d.ts +34 -0
- package/dist/shared/usageFormat.js +176 -0
- package/dist/shared/usageMerge.d.ts +78 -0
- package/dist/shared/usageMerge.js +241 -0
- package/dist/shared.d.ts +8268 -1372
- package/dist/shared.js +22185 -19774
- package/dist/t3tools.d.ts +2 -2
- package/dist/t3tools.js +2 -2
- package/package.json +5 -5
- package/src/application/error.ts +2 -2
- package/src/application/index.ts +2 -0
- package/src/application/service.ts +43 -5
- package/src/application/thread-commands.ts +78 -0
- package/src/application/threads.ts +156 -17
- package/src/cli/app.ts +4 -0
- package/src/cli/ask-lifecycle.ts +331 -0
- package/src/cli/ask.ts +390 -0
- package/src/cli/error.ts +70 -0
- package/src/cli/format/thread.ts +49 -7
- package/src/cli/search.ts +48 -0
- package/src/cli/thread.ts +12 -0
- package/src/cli/threads/messages.ts +33 -3
- package/src/cli/threads/pin.ts +46 -0
- package/src/cli/threads/send.ts +5 -1
- package/src/cli/threads/settle.ts +46 -0
- package/src/cli/threads/snooze.ts +117 -0
- package/src/cli/threads/start.ts +6 -1
- package/src/cli/threads/unpin.ts +48 -0
- package/src/cli/threads/unsettle.ts +48 -0
- package/src/cli/threads/unsnooze.ts +48 -0
- package/src/config/persist/schema.ts +1 -1
- package/src/connection/prepared.ts +12 -2
- package/src/orchestration/error.ts +10 -0
- package/src/orchestration/index.ts +1 -0
- package/src/orchestration/layer.ts +78 -0
- package/src/orchestration/service.ts +16 -3
- package/src/rpc/error.ts +2 -0
- package/src/rpc/operation.ts +2 -0
- package/src/rpc/ws-group.ts +3 -0
- package/src/runtime/layer.ts +9 -4
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Option from "effect/Option";
|
|
3
|
+
import { Command } from "effect/unstable/cli";
|
|
4
|
+
|
|
5
|
+
import { T3Application } from "../../application/service.ts";
|
|
6
|
+
import { loadT3CliEnv } from "../../config/env/env.ts";
|
|
7
|
+
import { MissingThreadError } from "../error.ts";
|
|
8
|
+
import { extraArgsConfig } from "../extra-args.ts";
|
|
9
|
+
import { formatFlag, threadFlag } from "../flags.ts";
|
|
10
|
+
import { resolveOutputFormat } from "../format/output.ts";
|
|
11
|
+
import { T3Output } from "../output/service.ts";
|
|
12
|
+
import { CliRuntime } from "../runtime/service.ts";
|
|
13
|
+
import { resolveThreadId } from "../scope/index.ts";
|
|
14
|
+
|
|
15
|
+
export const pinThreadCommand = Command.make(
|
|
16
|
+
"pin",
|
|
17
|
+
{
|
|
18
|
+
thread: threadFlag,
|
|
19
|
+
format: formatFlag,
|
|
20
|
+
...extraArgsConfig,
|
|
21
|
+
},
|
|
22
|
+
({ thread, format }) =>
|
|
23
|
+
Effect.gen(function* () {
|
|
24
|
+
const application = yield* T3Application;
|
|
25
|
+
const cliRuntime = yield* CliRuntime;
|
|
26
|
+
const t3CliEnv = yield* loadT3CliEnv;
|
|
27
|
+
const output = yield* T3Output;
|
|
28
|
+
const threadId = resolveThreadId({
|
|
29
|
+
value: Option.getOrUndefined(thread),
|
|
30
|
+
scope: t3CliEnv.scope,
|
|
31
|
+
});
|
|
32
|
+
if (threadId === undefined) {
|
|
33
|
+
return yield* Effect.fail(
|
|
34
|
+
new MissingThreadError({
|
|
35
|
+
message: "thread id is required: pass --thread or set T3CODE_THREAD_ID",
|
|
36
|
+
}),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const resolvedFormat = resolveOutputFormat(format, cliRuntime, t3CliEnv, "json");
|
|
40
|
+
const dispatch = yield* application.pinThread(threadId);
|
|
41
|
+
if (resolvedFormat === "json") {
|
|
42
|
+
return yield* output.printJson(dispatch);
|
|
43
|
+
}
|
|
44
|
+
return yield* output.printInfo(`thread pinned: ${threadId} (sequence ${dispatch.sequence})`);
|
|
45
|
+
}),
|
|
46
|
+
).pipe(Command.withDescription("pin thread"));
|
package/src/cli/threads/send.ts
CHANGED
|
@@ -118,7 +118,11 @@ export const sendThreadCommand = Command.make(
|
|
|
118
118
|
|
|
119
119
|
const result = yield* application.sendThread(input, { until: "visible" });
|
|
120
120
|
if (resolvedFormat === "json") {
|
|
121
|
-
return yield* output.printJson(
|
|
121
|
+
return yield* output.printJson({
|
|
122
|
+
dispatch: result.dispatch,
|
|
123
|
+
threadId: result.threadId,
|
|
124
|
+
thread: result.thread,
|
|
125
|
+
});
|
|
122
126
|
}
|
|
123
127
|
return yield* output.printInfo(`message sent: ${result.threadId}`);
|
|
124
128
|
}),
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Option from "effect/Option";
|
|
3
|
+
import { Command } from "effect/unstable/cli";
|
|
4
|
+
|
|
5
|
+
import { T3Application } from "../../application/service.ts";
|
|
6
|
+
import { loadT3CliEnv } from "../../config/env/env.ts";
|
|
7
|
+
import { MissingThreadError } from "../error.ts";
|
|
8
|
+
import { extraArgsConfig } from "../extra-args.ts";
|
|
9
|
+
import { formatFlag, threadFlag } from "../flags.ts";
|
|
10
|
+
import { resolveOutputFormat } from "../format/output.ts";
|
|
11
|
+
import { T3Output } from "../output/service.ts";
|
|
12
|
+
import { CliRuntime } from "../runtime/service.ts";
|
|
13
|
+
import { resolveThreadId } from "../scope/index.ts";
|
|
14
|
+
|
|
15
|
+
export const settleThreadCommand = Command.make(
|
|
16
|
+
"settle",
|
|
17
|
+
{
|
|
18
|
+
thread: threadFlag,
|
|
19
|
+
format: formatFlag,
|
|
20
|
+
...extraArgsConfig,
|
|
21
|
+
},
|
|
22
|
+
({ thread, format }) =>
|
|
23
|
+
Effect.gen(function* () {
|
|
24
|
+
const application = yield* T3Application;
|
|
25
|
+
const cliRuntime = yield* CliRuntime;
|
|
26
|
+
const t3CliEnv = yield* loadT3CliEnv;
|
|
27
|
+
const output = yield* T3Output;
|
|
28
|
+
const threadId = resolveThreadId({
|
|
29
|
+
value: Option.getOrUndefined(thread),
|
|
30
|
+
scope: t3CliEnv.scope,
|
|
31
|
+
});
|
|
32
|
+
if (threadId === undefined) {
|
|
33
|
+
return yield* Effect.fail(
|
|
34
|
+
new MissingThreadError({
|
|
35
|
+
message: "thread id is required: pass --thread or set T3CODE_THREAD_ID",
|
|
36
|
+
}),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const resolvedFormat = resolveOutputFormat(format, cliRuntime, t3CliEnv, "json");
|
|
40
|
+
const dispatch = yield* application.settleThread(threadId);
|
|
41
|
+
if (resolvedFormat === "json") {
|
|
42
|
+
return yield* output.printJson(dispatch);
|
|
43
|
+
}
|
|
44
|
+
return yield* output.printInfo(`thread settled: ${threadId} (sequence ${dispatch.sequence})`);
|
|
45
|
+
}),
|
|
46
|
+
).pipe(Command.withDescription("settle thread"));
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as DateTime from "effect/DateTime";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Option from "effect/Option";
|
|
4
|
+
import * as Schema from "effect/Schema";
|
|
5
|
+
import { Command, Flag } from "effect/unstable/cli";
|
|
6
|
+
import {
|
|
7
|
+
resolveSnoozePresets,
|
|
8
|
+
type SnoozePresetId,
|
|
9
|
+
} from "@t3tools/client-runtime/state/thread-settled";
|
|
10
|
+
|
|
11
|
+
import { T3Application } from "../../application/service.ts";
|
|
12
|
+
import { loadT3CliEnv } from "../../config/env/env.ts";
|
|
13
|
+
import {
|
|
14
|
+
InvalidFlagCombinationError,
|
|
15
|
+
InvalidSnoozeUntilError,
|
|
16
|
+
MissingThreadError,
|
|
17
|
+
UnavailableSnoozePresetError,
|
|
18
|
+
} from "../error.ts";
|
|
19
|
+
import { extraArgsConfig } from "../extra-args.ts";
|
|
20
|
+
import { formatFlag, threadFlag } from "../flags.ts";
|
|
21
|
+
import { resolveOutputFormat } from "../format/output.ts";
|
|
22
|
+
import { T3Output } from "../output/service.ts";
|
|
23
|
+
import { CliRuntime } from "../runtime/service.ts";
|
|
24
|
+
import { resolveThreadId } from "../scope/index.ts";
|
|
25
|
+
|
|
26
|
+
const snoozePresetChoices = [
|
|
27
|
+
"hour",
|
|
28
|
+
"evening",
|
|
29
|
+
"tomorrow",
|
|
30
|
+
"next-week",
|
|
31
|
+
] as const satisfies ReadonlyArray<SnoozePresetId>;
|
|
32
|
+
|
|
33
|
+
export const snoozeThreadCommand = Command.make(
|
|
34
|
+
"snooze",
|
|
35
|
+
{
|
|
36
|
+
thread: threadFlag,
|
|
37
|
+
until: Flag.string("until").pipe(Flag.optional),
|
|
38
|
+
preset: Flag.choice("preset", snoozePresetChoices).pipe(Flag.optional),
|
|
39
|
+
format: formatFlag,
|
|
40
|
+
...extraArgsConfig,
|
|
41
|
+
},
|
|
42
|
+
({ thread, until, preset, format }) =>
|
|
43
|
+
Effect.gen(function* () {
|
|
44
|
+
const application = yield* T3Application;
|
|
45
|
+
const cliRuntime = yield* CliRuntime;
|
|
46
|
+
const t3CliEnv = yield* loadT3CliEnv;
|
|
47
|
+
const output = yield* T3Output;
|
|
48
|
+
const threadId = resolveThreadId({
|
|
49
|
+
value: Option.getOrUndefined(thread),
|
|
50
|
+
scope: t3CliEnv.scope,
|
|
51
|
+
});
|
|
52
|
+
if (threadId === undefined) {
|
|
53
|
+
return yield* Effect.fail(
|
|
54
|
+
new MissingThreadError({
|
|
55
|
+
message: "thread id is required: pass --thread or set T3CODE_THREAD_ID",
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const untilValue = Option.getOrUndefined(until);
|
|
61
|
+
const presetValue = Option.getOrUndefined(preset);
|
|
62
|
+
if (untilValue !== undefined && presetValue !== undefined) {
|
|
63
|
+
return yield* Effect.fail(
|
|
64
|
+
new InvalidFlagCombinationError({
|
|
65
|
+
message: "exactly one of --until or --preset is required",
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let snoozedUntil: string;
|
|
71
|
+
if (untilValue !== undefined) {
|
|
72
|
+
snoozedUntil = yield* Schema.decodeUnknownEffect(Schema.DateTimeUtcFromString)(
|
|
73
|
+
untilValue,
|
|
74
|
+
).pipe(
|
|
75
|
+
Effect.map(DateTime.formatIso),
|
|
76
|
+
Effect.mapError(
|
|
77
|
+
() =>
|
|
78
|
+
new InvalidSnoozeUntilError({
|
|
79
|
+
message: `invalid ISO-8601 snooze time: ${untilValue}`,
|
|
80
|
+
value: untilValue,
|
|
81
|
+
}),
|
|
82
|
+
),
|
|
83
|
+
);
|
|
84
|
+
} else if (presetValue !== undefined) {
|
|
85
|
+
snoozedUntil = yield* resolveSnoozePreset(presetValue);
|
|
86
|
+
} else {
|
|
87
|
+
return yield* Effect.fail(
|
|
88
|
+
new InvalidFlagCombinationError({
|
|
89
|
+
message: "exactly one of --until or --preset is required",
|
|
90
|
+
}),
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const resolvedFormat = resolveOutputFormat(format, cliRuntime, t3CliEnv, "json");
|
|
95
|
+
const dispatch = yield* application.snoozeThread({ threadId, snoozedUntil });
|
|
96
|
+
if (resolvedFormat === "json") {
|
|
97
|
+
return yield* output.printJson(dispatch);
|
|
98
|
+
}
|
|
99
|
+
return yield* output.printInfo(
|
|
100
|
+
`thread snoozed: ${threadId} until ${snoozedUntil} (sequence ${dispatch.sequence})`,
|
|
101
|
+
);
|
|
102
|
+
}),
|
|
103
|
+
).pipe(Command.withDescription("snooze thread"));
|
|
104
|
+
|
|
105
|
+
const resolveSnoozePreset = Effect.fn("resolveSnoozePreset")(function* (presetId: SnoozePresetId) {
|
|
106
|
+
const now = yield* DateTime.nowAsDate;
|
|
107
|
+
const preset = resolveSnoozePresets(now).find((candidate) => candidate.id === presetId);
|
|
108
|
+
if (preset === undefined) {
|
|
109
|
+
return yield* Effect.fail(
|
|
110
|
+
new UnavailableSnoozePresetError({
|
|
111
|
+
message: `snooze preset is not available at this time: ${presetId}`,
|
|
112
|
+
preset: presetId,
|
|
113
|
+
}),
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
return preset.snoozedUntil;
|
|
117
|
+
});
|
package/src/cli/threads/start.ts
CHANGED
|
@@ -129,7 +129,12 @@ export const startThreadCommand = Command.make(
|
|
|
129
129
|
|
|
130
130
|
const result = yield* application.startThread(input, { until: "visible" });
|
|
131
131
|
if (resolvedFormat === "json") {
|
|
132
|
-
yield* output.printJson(
|
|
132
|
+
yield* output.printJson({
|
|
133
|
+
dispatch: result.dispatch,
|
|
134
|
+
project: result.project,
|
|
135
|
+
threadId: result.threadId,
|
|
136
|
+
thread: result.thread,
|
|
137
|
+
});
|
|
133
138
|
} else {
|
|
134
139
|
yield* output.printInfo(
|
|
135
140
|
formatThreadStartedHuman({
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Option from "effect/Option";
|
|
3
|
+
import { Command } from "effect/unstable/cli";
|
|
4
|
+
|
|
5
|
+
import { T3Application } from "../../application/service.ts";
|
|
6
|
+
import { loadT3CliEnv } from "../../config/env/env.ts";
|
|
7
|
+
import { MissingThreadError } from "../error.ts";
|
|
8
|
+
import { extraArgsConfig } from "../extra-args.ts";
|
|
9
|
+
import { formatFlag, threadFlag } from "../flags.ts";
|
|
10
|
+
import { resolveOutputFormat } from "../format/output.ts";
|
|
11
|
+
import { T3Output } from "../output/service.ts";
|
|
12
|
+
import { CliRuntime } from "../runtime/service.ts";
|
|
13
|
+
import { resolveThreadId } from "../scope/index.ts";
|
|
14
|
+
|
|
15
|
+
export const unpinThreadCommand = Command.make(
|
|
16
|
+
"unpin",
|
|
17
|
+
{
|
|
18
|
+
thread: threadFlag,
|
|
19
|
+
format: formatFlag,
|
|
20
|
+
...extraArgsConfig,
|
|
21
|
+
},
|
|
22
|
+
({ thread, format }) =>
|
|
23
|
+
Effect.gen(function* () {
|
|
24
|
+
const application = yield* T3Application;
|
|
25
|
+
const cliRuntime = yield* CliRuntime;
|
|
26
|
+
const t3CliEnv = yield* loadT3CliEnv;
|
|
27
|
+
const output = yield* T3Output;
|
|
28
|
+
const threadId = resolveThreadId({
|
|
29
|
+
value: Option.getOrUndefined(thread),
|
|
30
|
+
scope: t3CliEnv.scope,
|
|
31
|
+
});
|
|
32
|
+
if (threadId === undefined) {
|
|
33
|
+
return yield* Effect.fail(
|
|
34
|
+
new MissingThreadError({
|
|
35
|
+
message: "thread id is required: pass --thread or set T3CODE_THREAD_ID",
|
|
36
|
+
}),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const resolvedFormat = resolveOutputFormat(format, cliRuntime, t3CliEnv, "json");
|
|
40
|
+
const dispatch = yield* application.unpinThread(threadId);
|
|
41
|
+
if (resolvedFormat === "json") {
|
|
42
|
+
return yield* output.printJson(dispatch);
|
|
43
|
+
}
|
|
44
|
+
return yield* output.printInfo(
|
|
45
|
+
`thread unpinned: ${threadId} (sequence ${dispatch.sequence})`,
|
|
46
|
+
);
|
|
47
|
+
}),
|
|
48
|
+
).pipe(Command.withDescription("unpin thread"));
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Option from "effect/Option";
|
|
3
|
+
import { Command } from "effect/unstable/cli";
|
|
4
|
+
|
|
5
|
+
import { T3Application } from "../../application/service.ts";
|
|
6
|
+
import { loadT3CliEnv } from "../../config/env/env.ts";
|
|
7
|
+
import { MissingThreadError } from "../error.ts";
|
|
8
|
+
import { extraArgsConfig } from "../extra-args.ts";
|
|
9
|
+
import { formatFlag, threadFlag } from "../flags.ts";
|
|
10
|
+
import { resolveOutputFormat } from "../format/output.ts";
|
|
11
|
+
import { T3Output } from "../output/service.ts";
|
|
12
|
+
import { CliRuntime } from "../runtime/service.ts";
|
|
13
|
+
import { resolveThreadId } from "../scope/index.ts";
|
|
14
|
+
|
|
15
|
+
export const unsettleThreadCommand = Command.make(
|
|
16
|
+
"unsettle",
|
|
17
|
+
{
|
|
18
|
+
thread: threadFlag,
|
|
19
|
+
format: formatFlag,
|
|
20
|
+
...extraArgsConfig,
|
|
21
|
+
},
|
|
22
|
+
({ thread, format }) =>
|
|
23
|
+
Effect.gen(function* () {
|
|
24
|
+
const application = yield* T3Application;
|
|
25
|
+
const cliRuntime = yield* CliRuntime;
|
|
26
|
+
const t3CliEnv = yield* loadT3CliEnv;
|
|
27
|
+
const output = yield* T3Output;
|
|
28
|
+
const threadId = resolveThreadId({
|
|
29
|
+
value: Option.getOrUndefined(thread),
|
|
30
|
+
scope: t3CliEnv.scope,
|
|
31
|
+
});
|
|
32
|
+
if (threadId === undefined) {
|
|
33
|
+
return yield* Effect.fail(
|
|
34
|
+
new MissingThreadError({
|
|
35
|
+
message: "thread id is required: pass --thread or set T3CODE_THREAD_ID",
|
|
36
|
+
}),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const resolvedFormat = resolveOutputFormat(format, cliRuntime, t3CliEnv, "json");
|
|
40
|
+
const dispatch = yield* application.unsettleThread(threadId);
|
|
41
|
+
if (resolvedFormat === "json") {
|
|
42
|
+
return yield* output.printJson(dispatch);
|
|
43
|
+
}
|
|
44
|
+
return yield* output.printInfo(
|
|
45
|
+
`thread unsettled: ${threadId} (sequence ${dispatch.sequence})`,
|
|
46
|
+
);
|
|
47
|
+
}),
|
|
48
|
+
).pipe(Command.withDescription("unsettle thread"));
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Option from "effect/Option";
|
|
3
|
+
import { Command } from "effect/unstable/cli";
|
|
4
|
+
|
|
5
|
+
import { T3Application } from "../../application/service.ts";
|
|
6
|
+
import { loadT3CliEnv } from "../../config/env/env.ts";
|
|
7
|
+
import { MissingThreadError } from "../error.ts";
|
|
8
|
+
import { extraArgsConfig } from "../extra-args.ts";
|
|
9
|
+
import { formatFlag, threadFlag } from "../flags.ts";
|
|
10
|
+
import { resolveOutputFormat } from "../format/output.ts";
|
|
11
|
+
import { T3Output } from "../output/service.ts";
|
|
12
|
+
import { CliRuntime } from "../runtime/service.ts";
|
|
13
|
+
import { resolveThreadId } from "../scope/index.ts";
|
|
14
|
+
|
|
15
|
+
export const unsnoozeThreadCommand = Command.make(
|
|
16
|
+
"unsnooze",
|
|
17
|
+
{
|
|
18
|
+
thread: threadFlag,
|
|
19
|
+
format: formatFlag,
|
|
20
|
+
...extraArgsConfig,
|
|
21
|
+
},
|
|
22
|
+
({ thread, format }) =>
|
|
23
|
+
Effect.gen(function* () {
|
|
24
|
+
const application = yield* T3Application;
|
|
25
|
+
const cliRuntime = yield* CliRuntime;
|
|
26
|
+
const t3CliEnv = yield* loadT3CliEnv;
|
|
27
|
+
const output = yield* T3Output;
|
|
28
|
+
const threadId = resolveThreadId({
|
|
29
|
+
value: Option.getOrUndefined(thread),
|
|
30
|
+
scope: t3CliEnv.scope,
|
|
31
|
+
});
|
|
32
|
+
if (threadId === undefined) {
|
|
33
|
+
return yield* Effect.fail(
|
|
34
|
+
new MissingThreadError({
|
|
35
|
+
message: "thread id is required: pass --thread or set T3CODE_THREAD_ID",
|
|
36
|
+
}),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const resolvedFormat = resolveOutputFormat(format, cliRuntime, t3CliEnv, "json");
|
|
40
|
+
const dispatch = yield* application.unsnoozeThread(threadId);
|
|
41
|
+
if (resolvedFormat === "json") {
|
|
42
|
+
return yield* output.printJson(dispatch);
|
|
43
|
+
}
|
|
44
|
+
return yield* output.printInfo(
|
|
45
|
+
`thread unsnoozed: ${threadId} (sequence ${dispatch.sequence})`,
|
|
46
|
+
);
|
|
47
|
+
}),
|
|
48
|
+
).pipe(Command.withDescription("unsnooze thread"));
|
|
@@ -34,4 +34,4 @@ export type StoredConfigV1File = Schema.Schema.Type<typeof StoredConfigV1FileSch
|
|
|
34
34
|
|
|
35
35
|
export const StoredConfigV1FileJson = Schema.fromJsonString(StoredConfigV1FileSchema);
|
|
36
36
|
export const StoredConfigV2FileJson = Schema.fromJsonString(StoredConfigV2FileSchema);
|
|
37
|
-
export const UnknownConfigFileJson = Schema.
|
|
37
|
+
export const UnknownConfigFileJson = Schema.fromJsonString(Schema.Unknown);
|
|
@@ -16,10 +16,20 @@ import { T3CodeConnectionError } from "./error.ts";
|
|
|
16
16
|
import { T3CodeConnectionProvider } from "./service.ts";
|
|
17
17
|
import type { T3CodeConnection } from "./type.ts";
|
|
18
18
|
|
|
19
|
+
export interface T3PreparedConnection extends PreparedConnection {
|
|
20
|
+
readonly httpAuthorization: {
|
|
21
|
+
readonly _tag: "Bearer";
|
|
22
|
+
readonly token: string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
19
26
|
export class T3PreparedConnectionProvider extends Context.Service<
|
|
20
27
|
T3PreparedConnectionProvider,
|
|
21
28
|
{
|
|
22
|
-
readonly get: Effect.Effect<
|
|
29
|
+
readonly get: Effect.Effect<
|
|
30
|
+
T3PreparedConnection,
|
|
31
|
+
ConnectionAttemptError | T3CodeConnectionError
|
|
32
|
+
>;
|
|
23
33
|
}
|
|
24
34
|
>()("t3cli/T3PreparedConnectionProvider") {}
|
|
25
35
|
|
|
@@ -59,7 +69,7 @@ const makePreparedConnection = Effect.fn("makePreparedConnection")(function* (
|
|
|
59
69
|
label: descriptor.label,
|
|
60
70
|
connectionId: descriptor.environmentId,
|
|
61
71
|
}),
|
|
62
|
-
} satisfies
|
|
72
|
+
} satisfies T3PreparedConnection;
|
|
63
73
|
});
|
|
64
74
|
|
|
65
75
|
const makeT3PreparedConnectionProvider = Effect.fn("makeT3PreparedConnectionProvider")(
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
|
|
3
|
+
export class ThreadSnapshotRequestError extends Schema.TaggedErrorClass<ThreadSnapshotRequestError>()(
|
|
4
|
+
"ThreadSnapshotRequestError",
|
|
5
|
+
{
|
|
6
|
+
message: Schema.String,
|
|
7
|
+
threadId: Schema.String,
|
|
8
|
+
cause: Schema.Defect(),
|
|
9
|
+
},
|
|
10
|
+
) {}
|
|
@@ -3,6 +3,7 @@ import * as Layer from "effect/Layer";
|
|
|
3
3
|
import * as Option from "effect/Option";
|
|
4
4
|
import * as Sink from "effect/Sink";
|
|
5
5
|
import * as Stream from "effect/Stream";
|
|
6
|
+
import { HttpClient } from "effect/unstable/http";
|
|
6
7
|
import {
|
|
7
8
|
ORCHESTRATION_WS_METHODS,
|
|
8
9
|
ThreadId,
|
|
@@ -12,14 +13,25 @@ import {
|
|
|
12
13
|
type OrchestrationShellStreamItem,
|
|
13
14
|
type OrchestrationThreadStreamItem,
|
|
14
15
|
} from "@t3tools/contracts";
|
|
16
|
+
import { environmentEndpointUrl } from "@t3tools/client-runtime/environment";
|
|
17
|
+
import {
|
|
18
|
+
executeEnvironmentHttpRequest,
|
|
19
|
+
makeEnvironmentHttpApiClient,
|
|
20
|
+
} from "@t3tools/client-runtime/rpc";
|
|
15
21
|
import { applyShellStreamEvent } from "@t3tools/client-runtime/state/shell";
|
|
16
22
|
|
|
23
|
+
import { T3PreparedConnectionProvider } from "../connection/prepared.ts";
|
|
17
24
|
import { RpcError } from "../rpc/error.ts";
|
|
18
25
|
import { T3RpcOperations } from "../rpc/operation.ts";
|
|
26
|
+
import { ThreadSnapshotRequestError } from "./error.ts";
|
|
19
27
|
import { T3Orchestration, type OpenThread, type Orchestration } from "./service.ts";
|
|
20
28
|
|
|
29
|
+
const THREAD_SNAPSHOT_TIMEOUT_MS = 30_000;
|
|
30
|
+
|
|
21
31
|
export const makeT3Orchestration = Effect.fn("makeT3Orchestration")(function* () {
|
|
22
32
|
const rpc = yield* T3RpcOperations;
|
|
33
|
+
const preparedConnectionProvider = yield* T3PreparedConnectionProvider;
|
|
34
|
+
const httpClient = yield* HttpClient.HttpClient;
|
|
23
35
|
|
|
24
36
|
const watchShellSnapshots: Orchestration["watchShellSnapshots"] = () =>
|
|
25
37
|
rpc
|
|
@@ -107,6 +119,11 @@ export const makeT3Orchestration = Effect.fn("makeT3Orchestration")(function* ()
|
|
|
107
119
|
);
|
|
108
120
|
},
|
|
109
121
|
);
|
|
122
|
+
const searchThreads = Effect.fn("T3OrchestrationLive.searchThreads")(function* (input) {
|
|
123
|
+
return yield* rpc.run(ORCHESTRATION_WS_METHODS.searchThreads, (client) =>
|
|
124
|
+
client[ORCHESTRATION_WS_METHODS.searchThreads](input),
|
|
125
|
+
);
|
|
126
|
+
});
|
|
110
127
|
const getThreadSnapshot = Effect.fn("T3OrchestrationLive.getThreadSnapshot")(function* (
|
|
111
128
|
threadId: string,
|
|
112
129
|
) {
|
|
@@ -128,6 +145,65 @@ export const makeT3Orchestration = Effect.fn("makeT3Orchestration")(function* ()
|
|
|
128
145
|
}
|
|
129
146
|
return value.snapshot.thread;
|
|
130
147
|
});
|
|
148
|
+
const getThreadDetailSnapshot: Orchestration["getThreadDetailSnapshot"] = Effect.fn(
|
|
149
|
+
"T3OrchestrationLive.getThreadDetailSnapshot",
|
|
150
|
+
)(function* (input) {
|
|
151
|
+
const paginationSupported =
|
|
152
|
+
input.window === undefined
|
|
153
|
+
? true
|
|
154
|
+
: (yield* getServerConfig()).threadSnapshotPagination === true;
|
|
155
|
+
const window = paginationSupported ? input.window : undefined;
|
|
156
|
+
const prepared = yield* preparedConnectionProvider.get.pipe(
|
|
157
|
+
Effect.mapError(
|
|
158
|
+
(cause) =>
|
|
159
|
+
new ThreadSnapshotRequestError({
|
|
160
|
+
message: "failed to prepare the thread snapshot request",
|
|
161
|
+
threadId: input.threadId,
|
|
162
|
+
cause,
|
|
163
|
+
}),
|
|
164
|
+
),
|
|
165
|
+
);
|
|
166
|
+
const threadId = ThreadId.make(input.threadId);
|
|
167
|
+
const requestUrl = environmentEndpointUrl(
|
|
168
|
+
prepared.httpBaseUrl,
|
|
169
|
+
`/api/orchestration/threads/${threadId}`,
|
|
170
|
+
);
|
|
171
|
+
const client = yield* makeEnvironmentHttpApiClient(prepared.httpBaseUrl).pipe(
|
|
172
|
+
Effect.provideService(HttpClient.HttpClient, httpClient),
|
|
173
|
+
Effect.mapError(
|
|
174
|
+
(cause) =>
|
|
175
|
+
new ThreadSnapshotRequestError({
|
|
176
|
+
message: "failed to create the thread snapshot client",
|
|
177
|
+
threadId: input.threadId,
|
|
178
|
+
cause,
|
|
179
|
+
}),
|
|
180
|
+
),
|
|
181
|
+
);
|
|
182
|
+
return yield* executeEnvironmentHttpRequest(
|
|
183
|
+
requestUrl,
|
|
184
|
+
THREAD_SNAPSHOT_TIMEOUT_MS,
|
|
185
|
+
client.orchestration.threadSnapshot({
|
|
186
|
+
params: { threadId },
|
|
187
|
+
payload: {
|
|
188
|
+
...(window !== undefined ? { turnLimit: window.turnLimit } : {}),
|
|
189
|
+
...(window?.beforeCursor !== undefined ? { beforeCursor: window.beforeCursor } : {}),
|
|
190
|
+
},
|
|
191
|
+
headers: {
|
|
192
|
+
authorization: `Bearer ${prepared.httpAuthorization.token}`,
|
|
193
|
+
},
|
|
194
|
+
}),
|
|
195
|
+
).pipe(
|
|
196
|
+
Effect.provideService(HttpClient.HttpClient, httpClient),
|
|
197
|
+
Effect.mapError(
|
|
198
|
+
(cause) =>
|
|
199
|
+
new ThreadSnapshotRequestError({
|
|
200
|
+
message: "failed to load the thread snapshot",
|
|
201
|
+
threadId: input.threadId,
|
|
202
|
+
cause,
|
|
203
|
+
}),
|
|
204
|
+
),
|
|
205
|
+
);
|
|
206
|
+
});
|
|
131
207
|
const openThread = Effect.fn("T3OrchestrationLive.openThread")(function* (threadId: string) {
|
|
132
208
|
return yield* watchThreadItems(threadId).pipe(
|
|
133
209
|
Stream.peel(Sink.head<OrchestrationThreadStreamItem>()),
|
|
@@ -160,7 +236,9 @@ export const makeT3Orchestration = Effect.fn("makeT3Orchestration")(function* ()
|
|
|
160
236
|
getServerConfig,
|
|
161
237
|
getShellSnapshot,
|
|
162
238
|
getArchivedShellSnapshot,
|
|
239
|
+
searchThreads,
|
|
163
240
|
getThreadSnapshot,
|
|
241
|
+
getThreadDetailSnapshot,
|
|
164
242
|
watchShellSnapshots,
|
|
165
243
|
watchShellSequence,
|
|
166
244
|
watchThreadItems,
|
|
@@ -7,23 +7,29 @@ import type {
|
|
|
7
7
|
DispatchResult,
|
|
8
8
|
OrchestrationEvent,
|
|
9
9
|
OrchestrationShellSnapshot,
|
|
10
|
+
OrchestrationSearchThreadsInput,
|
|
11
|
+
OrchestrationSearchThreadsResult,
|
|
10
12
|
OrchestrationThread,
|
|
13
|
+
OrchestrationThreadDetailSnapshot,
|
|
14
|
+
OrchestrationThreadDetailWindow,
|
|
11
15
|
OrchestrationThreadStreamItem,
|
|
12
16
|
ServerProviders,
|
|
13
17
|
} from "@t3tools/contracts";
|
|
14
18
|
|
|
19
|
+
import type { ThreadSnapshotRequestError } from "./error.ts";
|
|
15
20
|
import type { RpcError } from "../rpc/error.ts";
|
|
16
21
|
|
|
17
|
-
export type OrchestrationError = RpcError;
|
|
22
|
+
export type OrchestrationError = RpcError | ThreadSnapshotRequestError;
|
|
18
23
|
|
|
19
24
|
export type OpenThread = {
|
|
20
25
|
readonly snapshot: OrchestrationThread;
|
|
21
26
|
readonly events: Stream.Stream<OrchestrationEvent, OrchestrationError>;
|
|
22
27
|
};
|
|
23
28
|
|
|
24
|
-
export
|
|
29
|
+
export interface ServerConfigForCli {
|
|
25
30
|
readonly providers: ServerProviders;
|
|
26
|
-
|
|
31
|
+
readonly threadSnapshotPagination?: boolean;
|
|
32
|
+
}
|
|
27
33
|
|
|
28
34
|
export type Orchestration = {
|
|
29
35
|
readonly dispatch: (
|
|
@@ -35,9 +41,16 @@ export type Orchestration = {
|
|
|
35
41
|
OrchestrationShellSnapshot,
|
|
36
42
|
OrchestrationError
|
|
37
43
|
>;
|
|
44
|
+
readonly searchThreads: (
|
|
45
|
+
input: OrchestrationSearchThreadsInput,
|
|
46
|
+
) => Effect.Effect<OrchestrationSearchThreadsResult, OrchestrationError>;
|
|
38
47
|
readonly getThreadSnapshot: (
|
|
39
48
|
threadId: string,
|
|
40
49
|
) => Effect.Effect<OrchestrationThread, OrchestrationError>;
|
|
50
|
+
readonly getThreadDetailSnapshot: (input: {
|
|
51
|
+
readonly threadId: string;
|
|
52
|
+
readonly window?: OrchestrationThreadDetailWindow;
|
|
53
|
+
}) => Effect.Effect<OrchestrationThreadDetailSnapshot, OrchestrationError>;
|
|
41
54
|
readonly watchShellSnapshots: () => Stream.Stream<
|
|
42
55
|
OrchestrationShellSnapshot,
|
|
43
56
|
OrchestrationError,
|
package/src/rpc/error.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
KeybindingsConfigError,
|
|
8
8
|
OrchestrationDispatchCommandError,
|
|
9
9
|
OrchestrationGetSnapshotError,
|
|
10
|
+
OrchestrationSearchThreadsError,
|
|
10
11
|
PreviewAutomationError,
|
|
11
12
|
ServerSettingsError,
|
|
12
13
|
TerminalError,
|
|
@@ -22,6 +23,7 @@ const RpcErrorCauseSchema = Schema.Union([
|
|
|
22
23
|
KeybindingsConfigError,
|
|
23
24
|
OrchestrationDispatchCommandError,
|
|
24
25
|
OrchestrationGetSnapshotError,
|
|
26
|
+
OrchestrationSearchThreadsError,
|
|
25
27
|
PreviewAutomationError,
|
|
26
28
|
ServerSettingsError,
|
|
27
29
|
TerminalError,
|
package/src/rpc/operation.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
KeybindingsConfigError,
|
|
4
4
|
OrchestrationDispatchCommandError,
|
|
5
5
|
OrchestrationGetSnapshotError,
|
|
6
|
+
OrchestrationSearchThreadsError,
|
|
6
7
|
PreviewAutomationError,
|
|
7
8
|
ServerSettingsError,
|
|
8
9
|
TerminalError,
|
|
@@ -23,6 +24,7 @@ export type CliRpcOperationError =
|
|
|
23
24
|
| KeybindingsConfigError
|
|
24
25
|
| OrchestrationDispatchCommandError
|
|
25
26
|
| OrchestrationGetSnapshotError
|
|
27
|
+
| OrchestrationSearchThreadsError
|
|
26
28
|
| PreviewAutomationError
|
|
27
29
|
| RpcClientError.RpcClientError
|
|
28
30
|
| ServerSettingsError
|
package/src/rpc/ws-group.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
WS_METHODS,
|
|
7
7
|
WsOrchestrationDispatchCommandRpc,
|
|
8
8
|
WsOrchestrationGetArchivedShellSnapshotRpc,
|
|
9
|
+
WsOrchestrationSearchThreadsRpc,
|
|
9
10
|
WsOrchestrationSubscribeShellRpc,
|
|
10
11
|
WsOrchestrationSubscribeThreadRpc,
|
|
11
12
|
WsPreviewAutomationConnectRpc,
|
|
@@ -30,6 +31,7 @@ export const CliServerConfig = Schema.Struct({
|
|
|
30
31
|
}),
|
|
31
32
|
}),
|
|
32
33
|
providers: ServerProviders,
|
|
34
|
+
threadSnapshotPagination: Schema.optionalKey(Schema.Boolean),
|
|
33
35
|
});
|
|
34
36
|
export type CliServerConfig = typeof CliServerConfig.Type;
|
|
35
37
|
|
|
@@ -49,6 +51,7 @@ export const CliWsRpcGroup = RpcGroup.make(
|
|
|
49
51
|
WsSubscribeTerminalMetadataRpc,
|
|
50
52
|
WsOrchestrationDispatchCommandRpc,
|
|
51
53
|
WsOrchestrationGetArchivedShellSnapshotRpc,
|
|
54
|
+
WsOrchestrationSearchThreadsRpc,
|
|
52
55
|
WsOrchestrationSubscribeShellRpc,
|
|
53
56
|
WsOrchestrationSubscribeThreadRpc,
|
|
54
57
|
WsPreviewAutomationConnectRpc,
|