t3code-cli 0.14.2 → 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.
Files changed (165) hide show
  1. package/README.md +36 -1
  2. package/dist/application.d.ts +2 -2
  3. package/dist/application.js +1 -1
  4. package/dist/auth.d.ts +1 -1
  5. package/dist/auth.js +1 -1
  6. package/dist/bin.js +935 -336
  7. package/dist/cli.d.ts +1 -1
  8. package/dist/cli.js +1 -1
  9. package/dist/client-runtime/authorization.d.ts +1 -1
  10. package/dist/client-runtime/authorization.js +1 -1
  11. package/dist/client-runtime/connection.d.ts +1 -1
  12. package/dist/client-runtime/connection.js +1 -1
  13. package/dist/client-runtime/environment.d.ts +3 -1
  14. package/dist/client-runtime/environment.js +1 -1
  15. package/dist/client-runtime/errors.js +1 -1
  16. package/dist/client-runtime/operations/projects.d.ts +1 -1
  17. package/dist/client-runtime/operations.d.ts +1 -1
  18. package/dist/client-runtime/platform.d.ts +1 -1
  19. package/dist/client-runtime/platform.js +1 -1
  20. package/dist/client-runtime/relay.d.ts +9 -2
  21. package/dist/client-runtime/relay.js +12 -2
  22. package/dist/client-runtime/rpc.d.ts +2 -2
  23. package/dist/client-runtime/rpc.js +2 -2
  24. package/dist/client-runtime/state/assets.d.ts +1 -1
  25. package/dist/client-runtime/state/assets.js +1 -1
  26. package/dist/client-runtime/state/auth.d.ts +1 -1
  27. package/dist/client-runtime/state/auth.js +1 -1
  28. package/dist/client-runtime/state/connections.js +1 -1
  29. package/dist/client-runtime/state/entities.d.ts +1 -1
  30. package/dist/client-runtime/state/filesystem.d.ts +1 -1
  31. package/dist/client-runtime/state/filesystem.js +1 -1
  32. package/dist/client-runtime/state/git.d.ts +2 -1
  33. package/dist/client-runtime/state/git.js +1 -1
  34. package/dist/client-runtime/state/models.d.ts +1 -1
  35. package/dist/client-runtime/state/models.js +1 -1
  36. package/dist/client-runtime/state/orchestration.d.ts +1 -1
  37. package/dist/client-runtime/state/orchestration.js +1 -1
  38. package/dist/client-runtime/state/presentation.d.ts +7 -1
  39. package/dist/client-runtime/state/presentation.js +1 -1
  40. package/dist/client-runtime/state/preview.d.ts +5 -2
  41. package/dist/client-runtime/state/preview.js +3 -2
  42. package/dist/client-runtime/state/project-grouping.d.ts +1 -1
  43. package/dist/client-runtime/state/project-grouping.js +1 -1
  44. package/dist/client-runtime/state/projects.d.ts +1 -1
  45. package/dist/client-runtime/state/pull-requests.d.ts +478 -0
  46. package/dist/client-runtime/state/pull-requests.js +172 -0
  47. package/dist/client-runtime/state/relay.d.ts +1 -1
  48. package/dist/client-runtime/state/relay.js +1 -1
  49. package/dist/client-runtime/state/review.d.ts +1 -1
  50. package/dist/client-runtime/state/review.js +1 -1
  51. package/dist/client-runtime/state/runtime.d.ts +2 -2
  52. package/dist/client-runtime/state/runtime.js +2 -2
  53. package/dist/client-runtime/state/server.d.ts +13 -1
  54. package/dist/client-runtime/state/server.js +1 -1
  55. package/dist/client-runtime/state/session.d.ts +13 -1
  56. package/dist/client-runtime/state/session.js +1 -1
  57. package/dist/client-runtime/state/shell.d.ts +7 -1
  58. package/dist/client-runtime/state/shell.js +1 -1
  59. package/dist/client-runtime/state/source-control.d.ts +1 -1
  60. package/dist/client-runtime/state/source-control.js +1 -1
  61. package/dist/client-runtime/state/subagentRuntime.d.ts +1 -1
  62. package/dist/client-runtime/state/terminal.d.ts +1 -1
  63. package/dist/client-runtime/state/terminal.js +1 -1
  64. package/dist/client-runtime/state/thread-search.d.ts +1 -1
  65. package/dist/client-runtime/state/thread-search.js +1 -1
  66. package/dist/client-runtime/state/thread-settled.d.ts +11 -8
  67. package/dist/client-runtime/state/thread-settled.js +2 -229
  68. package/dist/client-runtime/state/thread-sort.d.ts +1 -1
  69. package/dist/client-runtime/state/thread-sort.js +1 -1
  70. package/dist/client-runtime/state/threads.d.ts +1 -1
  71. package/dist/client-runtime/state/threads.js +1 -1
  72. package/dist/client-runtime/state/vcs.d.ts +1 -1
  73. package/dist/client-runtime/state/vcs.js +1 -1
  74. package/dist/config.d.ts +1 -1
  75. package/dist/config.js +1 -1
  76. package/dist/connection.d.ts +1 -1
  77. package/dist/connection.js +1 -1
  78. package/dist/contracts.d.ts +1 -1
  79. package/dist/contracts.js +1 -1
  80. package/dist/index.d.ts +1 -1
  81. package/dist/index.js +1 -1
  82. package/dist/node.d.ts +1 -1
  83. package/dist/node.js +1 -1
  84. package/dist/orchestration.d.ts +12 -6
  85. package/dist/orchestration.js +2 -2
  86. package/dist/preview.d.ts +1 -1
  87. package/dist/rpc.d.ts +4 -9
  88. package/dist/rpc.js +1 -1
  89. package/dist/runtime.d.ts +1 -1
  90. package/dist/shared/DrainableWorker.js +1 -1
  91. package/dist/shared/KeyedCoalescingWorker.js +1 -1
  92. package/dist/shared/Net.d.ts +6 -0
  93. package/dist/shared/Net.js +2 -1
  94. package/dist/shared/advertisedEndpoint.d.ts +1 -1
  95. package/dist/shared/advertisedEndpoint.js +1 -1
  96. package/dist/shared/agentAwareness.d.ts +1 -1
  97. package/dist/shared/backgroundActivitySettings.d.ts +1 -1
  98. package/dist/shared/connectAuth.d.ts +23 -4
  99. package/dist/shared/connectAuth.js +40 -7
  100. package/dist/shared/devHome.js +1 -1
  101. package/dist/shared/dpop.js +1 -1
  102. package/dist/shared/git.d.ts +1 -1
  103. package/dist/shared/httpObservability.js +1 -1
  104. package/dist/shared/httpReadiness.js +1 -1
  105. package/dist/shared/keybindings.d.ts +1 -1
  106. package/dist/shared/model.d.ts +1 -1
  107. package/dist/shared/oauthScope.js +1 -1
  108. package/dist/shared/observability.js +1 -1
  109. package/dist/shared/preview.js +1 -1
  110. package/dist/shared/previewViewport.d.ts +1 -1
  111. package/dist/shared/previewViewport.js +1 -1
  112. package/dist/shared/projectScripts.d.ts +1 -1
  113. package/dist/shared/relayAuth.js +1 -1
  114. package/dist/shared/relayClient.d.ts +1 -1
  115. package/dist/shared/relayClient.js +1 -1
  116. package/dist/shared/relayJwt.js +1 -1
  117. package/dist/shared/relayTracing.js +1 -1
  118. package/dist/shared/relayUrl.js +1 -1
  119. package/dist/shared/remote.js +1 -1
  120. package/dist/shared/schemaYaml.js +1 -1
  121. package/dist/shared/serverSettings.d.ts +1 -1
  122. package/dist/shared/serverSettings.js +1 -1
  123. package/dist/shared/shell.js +1 -1
  124. package/dist/shared/sourceControl.d.ts +1 -1
  125. package/dist/shared/t3ProjectFile.d.ts +1 -1
  126. package/dist/shared/t3ProjectFile.js +1 -1
  127. package/dist/shared/terminalLabels.d.ts +1 -1
  128. package/dist/shared/threadEnvMode.d.ts +1 -1
  129. package/dist/shared/toolActivity.d.ts +1 -1
  130. package/dist/shared/usageFormat.d.ts +16 -3
  131. package/dist/shared/usageFormat.js +92 -6
  132. package/dist/shared/usageMerge.d.ts +13 -2
  133. package/dist/shared/usageMerge.js +23 -0
  134. package/dist/shared.d.ts +3470 -378
  135. package/dist/shared.js +2434 -617
  136. package/dist/t3tools.d.ts +2 -2
  137. package/dist/t3tools.js +2 -2
  138. package/package.json +2 -2
  139. package/src/application/error.ts +2 -2
  140. package/src/application/index.ts +1 -0
  141. package/src/application/service.ts +38 -4
  142. package/src/application/thread-commands.ts +78 -0
  143. package/src/application/threads.ts +113 -16
  144. package/src/cli/app.ts +2 -0
  145. package/src/cli/ask-lifecycle.ts +331 -0
  146. package/src/cli/ask.ts +390 -0
  147. package/src/cli/error.ts +70 -0
  148. package/src/cli/format/thread.ts +26 -6
  149. package/src/cli/thread.ts +12 -0
  150. package/src/cli/threads/messages.ts +33 -3
  151. package/src/cli/threads/pin.ts +46 -0
  152. package/src/cli/threads/send.ts +5 -1
  153. package/src/cli/threads/settle.ts +46 -0
  154. package/src/cli/threads/snooze.ts +117 -0
  155. package/src/cli/threads/start.ts +6 -1
  156. package/src/cli/threads/unpin.ts +48 -0
  157. package/src/cli/threads/unsettle.ts +48 -0
  158. package/src/cli/threads/unsnooze.ts +48 -0
  159. package/src/connection/prepared.ts +12 -2
  160. package/src/orchestration/error.ts +10 -0
  161. package/src/orchestration/index.ts +1 -0
  162. package/src/orchestration/layer.ts +72 -0
  163. package/src/orchestration/service.ts +11 -3
  164. package/src/rpc/ws-group.ts +1 -0
  165. package/src/runtime/layer.ts +9 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "t3code-cli",
3
- "version": "0.14.2",
3
+ "version": "0.15.0",
4
4
  "description": "CLI for t3code",
5
5
  "keywords": [
6
6
  "claude",
@@ -124,7 +124,7 @@
124
124
  "typescript": "^7.0.2",
125
125
  "vite-plus": "^0.2.6",
126
126
  "yaml": "^2.9.0",
127
- "@t3tools/contracts": "0.0.32"
127
+ "@t3tools/contracts": "0.0.33"
128
128
  },
129
129
  "engines": {
130
130
  "node": ">=24.0.0"
@@ -1,4 +1,4 @@
1
1
  import type { DomainError } from "../domain/error.ts";
2
- import type { RpcError } from "../rpc/error.ts";
2
+ import type { OrchestrationError } from "../orchestration/service.ts";
3
3
 
4
- export type ApplicationError = DomainError | RpcError;
4
+ export type ApplicationError = DomainError | OrchestrationError;
@@ -23,6 +23,7 @@ export type {
23
23
  ProjectActionRunResult,
24
24
  ProjectActionSelector,
25
25
  SendThreadInput,
26
+ SnoozeThreadInput,
26
27
  StartThreadInput,
27
28
  StartThreadPolicy,
28
29
  T3ActionApplicationService,
@@ -9,6 +9,8 @@ import type {
9
9
  OrchestrationSearchThreadsInput,
10
10
  OrchestrationShellSnapshot,
11
11
  OrchestrationThread,
12
+ OrchestrationThreadDetailSnapshot,
13
+ OrchestrationThreadDetailWindow,
12
14
  OrchestrationThreadShell,
13
15
  ProjectScript,
14
16
  ProjectScriptIcon,
@@ -62,8 +64,18 @@ export type CallbackThreadInput = {
62
64
  readonly prompt: string;
63
65
  };
64
66
 
67
+ export interface SnoozeThreadInput {
68
+ readonly threadId: string;
69
+ readonly snoozedUntil: string;
70
+ }
71
+
65
72
  export type ListThreadsInclude = "active" | "archived" | "all";
66
73
 
74
+ export interface GetThreadMessagesInput {
75
+ readonly threadId: string;
76
+ readonly window?: OrchestrationThreadDetailWindow;
77
+ }
78
+
67
79
  export type UpdateThreadInput = {
68
80
  readonly threadId: string;
69
81
  readonly title?: string;
@@ -74,9 +86,13 @@ export type UpdateThreadInput = {
74
86
  readonly worktreePath?: string | null;
75
87
  };
76
88
 
77
- export type StartThreadPolicy = {
89
+ export interface ThreadDispatchPolicy {
78
90
  readonly until: "dispatch" | "visible" | "complete";
79
- };
91
+ }
92
+
93
+ export interface StartThreadPolicy extends ThreadDispatchPolicy {
94
+ readonly onThreadCreated?: (threadId: string) => Effect.Effect<void>;
95
+ }
80
96
 
81
97
  export type WaitEvent =
82
98
  | { readonly type: "thread"; readonly thread: OrchestrationThread }
@@ -197,6 +213,7 @@ export class T3ProjectApplication extends Context.Service<
197
213
  >()("t3cli/T3ProjectApplication") {}
198
214
 
199
215
  export type T3ThreadApplicationService = {
216
+ readonly awaitShellSequence: (sequence: number) => Effect.Effect<void, ApplicationError>;
200
217
  readonly searchThreads: (
201
218
  input: OrchestrationSearchThreadsInput,
202
219
  ) => Effect.Effect<ReadonlyArray<ThreadSearchResult>, ApplicationError>;
@@ -213,8 +230,11 @@ export type T3ThreadApplicationService = {
213
230
  ApplicationError
214
231
  >;
215
232
  readonly getThreadMessages: (
233
+ input: GetThreadMessagesInput,
234
+ ) => Effect.Effect<OrchestrationThreadDetailSnapshot, ApplicationError>;
235
+ readonly getThreadSummary: (
216
236
  threadId: string,
217
- ) => Effect.Effect<OrchestrationThread, ApplicationError>;
237
+ ) => Effect.Effect<OrchestrationThreadShell, ApplicationError>;
218
238
  readonly showThread: (threadId: string) => Effect.Effect<ThreadShow, ApplicationError>;
219
239
  readonly approveThread: (input: {
220
240
  readonly threadId: string;
@@ -234,7 +254,19 @@ export type T3ThreadApplicationService = {
234
254
  >;
235
255
  readonly archiveThread: (threadId: string) => Effect.Effect<DispatchResult, ApplicationError>;
236
256
  readonly interruptThread: (threadId: string) => Effect.Effect<DispatchResult, ApplicationError>;
257
+ readonly interruptThreadTurn: (
258
+ threadId: string,
259
+ turnId: string,
260
+ ) => Effect.Effect<DispatchResult | undefined, ApplicationError>;
261
+ readonly pinThread: (threadId: string) => Effect.Effect<DispatchResult, ApplicationError>;
262
+ readonly settleThread: (threadId: string) => Effect.Effect<DispatchResult, ApplicationError>;
263
+ readonly snoozeThread: (
264
+ input: SnoozeThreadInput,
265
+ ) => Effect.Effect<DispatchResult, ApplicationError>;
237
266
  readonly unarchiveThread: (threadId: string) => Effect.Effect<DispatchResult, ApplicationError>;
267
+ readonly unpinThread: (threadId: string) => Effect.Effect<DispatchResult, ApplicationError>;
268
+ readonly unsnoozeThread: (threadId: string) => Effect.Effect<DispatchResult, ApplicationError>;
269
+ readonly unsettleThread: (threadId: string) => Effect.Effect<DispatchResult, ApplicationError>;
238
270
  readonly deleteThread: (
239
271
  threadId: string,
240
272
  ) => Effect.Effect<
@@ -250,6 +282,7 @@ export type T3ThreadApplicationService = {
250
282
  ) => Effect.Effect<
251
283
  {
252
284
  readonly dispatch: DispatchResult;
285
+ readonly messageId: string;
253
286
  readonly project: OrchestrationProjectShell;
254
287
  readonly threadId: string;
255
288
  readonly thread?: OrchestrationThread;
@@ -258,10 +291,11 @@ export type T3ThreadApplicationService = {
258
291
  >;
259
292
  readonly sendThread: (
260
293
  input: SendThreadInput,
261
- policy?: StartThreadPolicy,
294
+ policy?: ThreadDispatchPolicy,
262
295
  ) => Effect.Effect<
263
296
  {
264
297
  readonly dispatch: DispatchResult;
298
+ readonly messageId: string;
265
299
  readonly threadId: string;
266
300
  readonly thread?: OrchestrationThread;
267
301
  },
@@ -115,6 +115,84 @@ export const makeThreadUnarchiveCommand = Effect.fn("makeThreadUnarchiveCommand"
115
115
  } satisfies Extract<ClientOrchestrationCommand, { readonly type: "thread.unarchive" }>;
116
116
  });
117
117
 
118
+ export const makeThreadSettleCommand = Effect.fn("makeThreadSettleCommand")(function* (
119
+ threadId: string,
120
+ ) {
121
+ const crypto = yield* Crypto.Crypto;
122
+ return {
123
+ type: "thread.settle",
124
+ commandId: CommandId.make(
125
+ `t3cli:thread-settle:${yield* crypto.randomUUIDv4.pipe(Effect.orDie)}`,
126
+ ),
127
+ threadId: ThreadId.make(threadId),
128
+ } satisfies Extract<ClientOrchestrationCommand, { readonly type: "thread.settle" }>;
129
+ });
130
+
131
+ export const makeThreadUnsettleCommand = Effect.fn("makeThreadUnsettleCommand")(function* (
132
+ threadId: string,
133
+ ) {
134
+ const crypto = yield* Crypto.Crypto;
135
+ return {
136
+ type: "thread.unsettle",
137
+ commandId: CommandId.make(
138
+ `t3cli:thread-unsettle:${yield* crypto.randomUUIDv4.pipe(Effect.orDie)}`,
139
+ ),
140
+ threadId: ThreadId.make(threadId),
141
+ reason: "user",
142
+ } satisfies Extract<ClientOrchestrationCommand, { readonly type: "thread.unsettle" }>;
143
+ });
144
+
145
+ export const makeThreadSnoozeCommand = Effect.fn("makeThreadSnoozeCommand")(function* (input: {
146
+ readonly threadId: string;
147
+ readonly snoozedUntil: string;
148
+ }) {
149
+ const crypto = yield* Crypto.Crypto;
150
+ return {
151
+ type: "thread.snooze",
152
+ commandId: CommandId.make(
153
+ `t3cli:thread-snooze:${yield* crypto.randomUUIDv4.pipe(Effect.orDie)}`,
154
+ ),
155
+ threadId: ThreadId.make(input.threadId),
156
+ snoozedUntil: input.snoozedUntil,
157
+ } satisfies Extract<ClientOrchestrationCommand, { readonly type: "thread.snooze" }>;
158
+ });
159
+
160
+ export const makeThreadUnsnoozeCommand = Effect.fn("makeThreadUnsnoozeCommand")(function* (
161
+ threadId: string,
162
+ ) {
163
+ const crypto = yield* Crypto.Crypto;
164
+ return {
165
+ type: "thread.unsnooze",
166
+ commandId: CommandId.make(
167
+ `t3cli:thread-unsnooze:${yield* crypto.randomUUIDv4.pipe(Effect.orDie)}`,
168
+ ),
169
+ threadId: ThreadId.make(threadId),
170
+ reason: "user",
171
+ } satisfies Extract<ClientOrchestrationCommand, { readonly type: "thread.unsnooze" }>;
172
+ });
173
+
174
+ export const makeThreadPinCommand = Effect.fn("makeThreadPinCommand")(function* (threadId: string) {
175
+ const crypto = yield* Crypto.Crypto;
176
+ return {
177
+ type: "thread.pin",
178
+ commandId: CommandId.make(`t3cli:thread-pin:${yield* crypto.randomUUIDv4.pipe(Effect.orDie)}`),
179
+ threadId: ThreadId.make(threadId),
180
+ } satisfies Extract<ClientOrchestrationCommand, { readonly type: "thread.pin" }>;
181
+ });
182
+
183
+ export const makeThreadUnpinCommand = Effect.fn("makeThreadUnpinCommand")(function* (
184
+ threadId: string,
185
+ ) {
186
+ const crypto = yield* Crypto.Crypto;
187
+ return {
188
+ type: "thread.unpin",
189
+ commandId: CommandId.make(
190
+ `t3cli:thread-unpin:${yield* crypto.randomUUIDv4.pipe(Effect.orDie)}`,
191
+ ),
192
+ threadId: ThreadId.make(threadId),
193
+ } satisfies Extract<ClientOrchestrationCommand, { readonly type: "thread.unpin" }>;
194
+ });
195
+
118
196
  export const makeThreadSessionStopCommand = Effect.fn("makeThreadSessionStopCommand")(function* (
119
197
  threadId: string,
120
198
  ) {
@@ -6,7 +6,14 @@ import { CliRuntime } from "../cli/runtime/service.ts";
6
6
  import { T3Orchestration } from "../orchestration/service.ts";
7
7
  import { ProjectLookupError, ThreadLookupError, ThreadSessionError } from "../domain/error.ts";
8
8
  import { resolveProjectScope } from "../domain/helpers.ts";
9
- import { type ListThreadsInclude, type StartThreadInput } from "./service.ts";
9
+ import {
10
+ type GetThreadMessagesInput,
11
+ type ListThreadsInclude,
12
+ type SnoozeThreadInput,
13
+ type StartThreadInput,
14
+ type StartThreadPolicy,
15
+ type ThreadDispatchPolicy,
16
+ } from "./service.ts";
10
17
  import type { CallbackThreadInput, SendThreadInput } from "./service.ts";
11
18
  import type { T3ThreadApplicationService } from "./service.ts";
12
19
  import type {
@@ -28,10 +35,16 @@ import {
28
35
  makeThreadArchiveCommand,
29
36
  makeThreadDeleteCommand,
30
37
  makeThreadInterruptCommand,
38
+ makeThreadPinCommand,
31
39
  makeThreadSessionStopCommand,
40
+ makeThreadSettleCommand,
41
+ makeThreadSnoozeCommand,
32
42
  makeThreadStartCommands,
33
43
  makeThreadTurnContinueCommand,
34
44
  makeThreadUnarchiveCommand,
45
+ makeThreadUnpinCommand,
46
+ makeThreadUnsnoozeCommand,
47
+ makeThreadUnsettleCommand,
35
48
  makeThreadUserInputRespondCommand,
36
49
  } from "./thread-commands.ts";
37
50
  import { makeUpdateThread } from "./thread-update.ts";
@@ -102,9 +115,26 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
102
115
  });
103
116
  });
104
117
  const getThreadMessages = Effect.fn("T3ApplicationLive.getThreadMessages")(function* (
118
+ input: GetThreadMessagesInput,
119
+ ) {
120
+ return yield* orchestration.getThreadDetailSnapshot(input);
121
+ });
122
+ const getThreadSummary = Effect.fn("T3ApplicationLive.getThreadSummary")(function* (
105
123
  threadId: string,
106
124
  ) {
107
- return yield* orchestration.getThreadSnapshot(threadId);
125
+ const snapshot = yield* loadThreadsSnapshot("all").pipe(
126
+ Effect.provideService(T3Orchestration, orchestration),
127
+ );
128
+ const thread = snapshot.threads.find((item) => item.id === threadId);
129
+ if (thread === undefined) {
130
+ return yield* Effect.fail(
131
+ new ThreadLookupError({
132
+ message: `thread not found: ${threadId}`,
133
+ threadId,
134
+ }),
135
+ );
136
+ }
137
+ return thread;
108
138
  });
109
139
  const showThread = Effect.fn("T3ApplicationLive.showThread")(function* (threadId: string) {
110
140
  const thread = yield* orchestration.getThreadSnapshot(threadId);
@@ -114,7 +144,9 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
114
144
  const command = yield* makeThreadArchiveCommand(threadId).pipe(
115
145
  Effect.provideService(Crypto.Crypto, crypto),
116
146
  );
117
- return yield* orchestration.dispatch(command);
147
+ const dispatch = yield* orchestration.dispatch(command);
148
+ yield* awaitShellSequence(dispatch.sequence);
149
+ return dispatch;
118
150
  });
119
151
  const unarchiveThread = Effect.fn("T3ApplicationLive.unarchiveThread")(function* (
120
152
  threadId: string,
@@ -124,6 +156,48 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
124
156
  );
125
157
  return yield* orchestration.dispatch(command);
126
158
  });
159
+ const settleThread = Effect.fn("T3ApplicationLive.settleThread")(function* (threadId: string) {
160
+ const command = yield* makeThreadSettleCommand(threadId).pipe(
161
+ Effect.provideService(Crypto.Crypto, crypto),
162
+ );
163
+ return yield* orchestration.dispatch(command);
164
+ });
165
+ const unsettleThread = Effect.fn("T3ApplicationLive.unsettleThread")(function* (
166
+ threadId: string,
167
+ ) {
168
+ const command = yield* makeThreadUnsettleCommand(threadId).pipe(
169
+ Effect.provideService(Crypto.Crypto, crypto),
170
+ );
171
+ return yield* orchestration.dispatch(command);
172
+ });
173
+ const snoozeThread = Effect.fn("T3ApplicationLive.snoozeThread")(function* (
174
+ input: SnoozeThreadInput,
175
+ ) {
176
+ const command = yield* makeThreadSnoozeCommand(input).pipe(
177
+ Effect.provideService(Crypto.Crypto, crypto),
178
+ );
179
+ return yield* orchestration.dispatch(command);
180
+ });
181
+ const unsnoozeThread = Effect.fn("T3ApplicationLive.unsnoozeThread")(function* (
182
+ threadId: string,
183
+ ) {
184
+ const command = yield* makeThreadUnsnoozeCommand(threadId).pipe(
185
+ Effect.provideService(Crypto.Crypto, crypto),
186
+ );
187
+ return yield* orchestration.dispatch(command);
188
+ });
189
+ const pinThread = Effect.fn("T3ApplicationLive.pinThread")(function* (threadId: string) {
190
+ const command = yield* makeThreadPinCommand(threadId).pipe(
191
+ Effect.provideService(Crypto.Crypto, crypto),
192
+ );
193
+ return yield* orchestration.dispatch(command);
194
+ });
195
+ const unpinThread = Effect.fn("T3ApplicationLive.unpinThread")(function* (threadId: string) {
196
+ const command = yield* makeThreadUnpinCommand(threadId).pipe(
197
+ Effect.provideService(Crypto.Crypto, crypto),
198
+ );
199
+ return yield* orchestration.dispatch(command);
200
+ });
127
201
  const interruptThread = Effect.fn("T3ApplicationLive.interruptThread")(function* (
128
202
  threadId: string,
129
203
  ) {
@@ -135,6 +209,19 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
135
209
  }).pipe(Effect.provideService(Crypto.Crypto, crypto));
136
210
  return yield* orchestration.dispatch(command);
137
211
  });
212
+ const interruptThreadTurn = Effect.fn("T3ApplicationLive.interruptThreadTurn")(function* (
213
+ threadId: string,
214
+ turnId: string,
215
+ ) {
216
+ const snapshot = yield* orchestration.getThreadSnapshot(threadId);
217
+ if (snapshot.session?.activeTurnId !== turnId) {
218
+ return undefined;
219
+ }
220
+ const command = yield* makeThreadInterruptCommand({ threadId, turnId }).pipe(
221
+ Effect.provideService(Crypto.Crypto, crypto),
222
+ );
223
+ return yield* orchestration.dispatch(command);
224
+ });
138
225
  const deleteThread = Effect.fn("T3ApplicationLive.deleteThread")(function* (threadId: string) {
139
226
  const snapshot = yield* loadThreadsSnapshot("all").pipe(
140
227
  Effect.provideService(T3Orchestration, orchestration),
@@ -167,9 +254,7 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
167
254
  );
168
255
  const startThread = Effect.fn("T3ApplicationLive.startThread")(function* (
169
256
  startInput: StartThreadInput,
170
- policy?: {
171
- readonly until: "dispatch" | "visible" | "complete";
172
- },
257
+ policy?: StartThreadPolicy,
173
258
  ) {
174
259
  const snapshot = yield* orchestration.getShellSnapshot();
175
260
  const projectRef = startInput.projectRef;
@@ -199,13 +284,17 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
199
284
  project: scope.project,
200
285
  serverConfig,
201
286
  }).pipe(Effect.provideService(Crypto.Crypto, crypto));
287
+ const threadId = commands.threadId;
202
288
  const createDispatch = yield* orchestration.dispatch(commands.createCommand);
289
+ if (policy?.onThreadCreated !== undefined) {
290
+ yield* policy.onThreadCreated(threadId);
291
+ }
203
292
  yield* awaitShellSequence(createDispatch.sequence);
204
293
  const dispatch = yield* orchestration.dispatch(commands.turnCommand);
205
- const threadId = commands.threadId;
294
+ const messageId = commands.turnCommand.message.messageId;
206
295
  const until = policy?.until ?? "dispatch";
207
296
  if (until === "dispatch") {
208
- return { dispatch, project: scope.project, threadId };
297
+ return { dispatch, messageId, project: scope.project, threadId };
209
298
  }
210
299
  yield* awaitShellSequence(dispatch.sequence);
211
300
  if (until === "visible") {
@@ -215,17 +304,15 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
215
304
  return opened.snapshot;
216
305
  }),
217
306
  );
218
- return { dispatch, project: scope.project, threadId, thread };
307
+ return { dispatch, messageId, project: scope.project, threadId, thread };
219
308
  }
220
309
  const thread = yield* awaitThreadCompletion(threadId);
221
310
  yield* failIfThreadError(thread);
222
- return { dispatch, project: scope.project, threadId, thread };
311
+ return { dispatch, messageId, project: scope.project, threadId, thread };
223
312
  });
224
313
  const sendThread = Effect.fn("T3ApplicationLive.sendThread")(function* (
225
314
  input: SendThreadInput,
226
- policy?: {
227
- readonly until: "dispatch" | "visible" | "complete";
228
- },
315
+ policy?: ThreadDispatchPolicy,
229
316
  ) {
230
317
  const modelSelection =
231
318
  input.options !== undefined && input.options.length > 0
@@ -239,9 +326,10 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
239
326
  ...(modelSelection !== undefined ? { modelSelection } : {}),
240
327
  }).pipe(Effect.provideService(Crypto.Crypto, crypto));
241
328
  const dispatch = yield* orchestration.dispatch(command);
329
+ const messageId = command.message.messageId;
242
330
  const until = policy?.until ?? "dispatch";
243
331
  if (until === "dispatch") {
244
- return { dispatch, threadId: input.threadId };
332
+ return { dispatch, messageId, threadId: input.threadId };
245
333
  }
246
334
  yield* awaitShellSequence(dispatch.sequence);
247
335
  if (until === "visible") {
@@ -251,11 +339,11 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
251
339
  return opened.snapshot;
252
340
  }),
253
341
  );
254
- return { dispatch, threadId: input.threadId, thread };
342
+ return { dispatch, messageId, threadId: input.threadId, thread };
255
343
  }
256
344
  const thread = yield* awaitThreadCompletion(input.threadId);
257
345
  yield* failIfThreadError(thread);
258
- return { dispatch, threadId: input.threadId, thread };
346
+ return { dispatch, messageId, threadId: input.threadId, thread };
259
347
  });
260
348
  const watchThread = (threadId: string) => streamThreadEvents(threadId);
261
349
  const waitForThread = Effect.fn("T3ApplicationLive.waitForThread")(function* (threadId: string) {
@@ -299,13 +387,22 @@ export const makeThreadApplication = Effect.fn("makeThreadApplication")(function
299
387
  return {
300
388
  approveThread,
301
389
  archiveThread,
390
+ awaitShellSequence,
302
391
  deleteThread,
303
392
  interruptThread,
393
+ interruptThreadTurn,
394
+ pinThread,
395
+ settleThread,
396
+ snoozeThread,
304
397
  updateThread,
305
398
  unarchiveThread,
399
+ unpinThread,
400
+ unsnoozeThread,
401
+ unsettleThread,
306
402
  listThreads,
307
403
  searchThreads,
308
404
  getThreadMessages,
405
+ getThreadSummary,
309
406
  respondToThread,
310
407
  sendThread,
311
408
  showThread,
package/src/cli/app.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Command } from "effect/unstable/cli";
2
2
 
3
3
  import { createActionCommand } from "./action.ts";
4
+ import { askCommand } from "./ask.ts";
4
5
  import { createAuthCommand } from "./auth.ts";
5
6
  import { createEnvCommand } from "./env.ts";
6
7
  import { cliEnvironmentSetting } from "./env/flag.ts";
@@ -22,6 +23,7 @@ export function createCliCommand() {
22
23
  Command.withGlobalFlags([cliEnvironmentSetting]),
23
24
  Command.withSubcommands([
24
25
  createActionCommand(),
26
+ askCommand,
25
27
  createAuthCommand(),
26
28
  createEnvCommand(),
27
29
  listThreadsCommand,