t3code-cli 0.5.1 → 0.6.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 (111) hide show
  1. package/README.md +41 -16
  2. package/dist/Context-DueQ9iMH.js +4916 -0
  3. package/dist/Path-D8WPdPwR.js +11406 -0
  4. package/dist/Schema-DsQxYh6_.js +13581 -0
  5. package/dist/UrlParams-BA6gBvaY.js +205 -0
  6. package/dist/application.js +2 -0
  7. package/dist/auth.js +3 -0
  8. package/dist/base-dir-R12OMDso.js +20 -0
  9. package/dist/bin.js +236 -13526
  10. package/dist/chunk-B5meny8j.js +36 -0
  11. package/dist/cli.js +2 -0
  12. package/dist/config.js +4 -0
  13. package/dist/connection.js +15 -0
  14. package/dist/contracts.js +1 -0
  15. package/dist/error-B2t1bAP9.js +169 -0
  16. package/dist/error-BHRnjLux.js +15 -0
  17. package/dist/error-jwMt3VoW.js +54 -0
  18. package/dist/flags-CM7_iGdA.js +13371 -0
  19. package/dist/index.js +5 -12
  20. package/dist/layer-CfC5qZol.js +1508 -0
  21. package/dist/layer-DHhKS5jd.js +13 -0
  22. package/dist/layer-DIg0RxSO.js +1217 -0
  23. package/dist/layer-DUv99vsS.js +72 -0
  24. package/dist/layer-DvHnKBYj.js +29466 -0
  25. package/dist/layout.js +2 -0
  26. package/dist/orchestration.js +2 -0
  27. package/dist/rpc.js +2 -0
  28. package/dist/runtime.js +3 -0
  29. package/dist/scope-GycYiJ54.js +29 -0
  30. package/dist/scope.js +2 -0
  31. package/dist/service-CLmRO2Dp.js +8 -0
  32. package/dist/service-ybOWV9pL.js +5 -0
  33. package/dist/src/application/index.d.ts +3 -0
  34. package/dist/src/application/layer.d.ts +4 -4
  35. package/dist/src/application/projects.d.ts +1 -1
  36. package/dist/src/application/service.d.ts +1 -1
  37. package/dist/src/application/threads.d.ts +4 -4
  38. package/dist/src/auth/index.d.ts +10 -0
  39. package/dist/src/auth/local-base-dir.d.ts +5 -7
  40. package/dist/src/auth/local-token.d.ts +2 -2
  41. package/dist/src/auth/type.d.ts +1 -0
  42. package/dist/src/cli/flags.d.ts +15 -0
  43. package/dist/src/cli/index.d.ts +1 -0
  44. package/dist/src/cli/output-format.d.ts +9 -0
  45. package/dist/src/config/index.d.ts +5 -0
  46. package/dist/src/config/layer.d.ts +2 -0
  47. package/dist/src/config/service.d.ts +2 -0
  48. package/dist/src/connection/index.d.ts +5 -0
  49. package/dist/src/contracts/index.d.ts +1 -0
  50. package/dist/src/domain/helpers.d.ts +164 -32
  51. package/dist/src/index.d.ts +4 -28
  52. package/dist/src/layout/base-dir.d.ts +12 -0
  53. package/dist/src/layout/index.d.ts +1 -0
  54. package/dist/src/orchestration/index.d.ts +2 -0
  55. package/dist/src/rpc/index.d.ts +1 -0
  56. package/dist/src/runtime/index.d.ts +2 -0
  57. package/dist/src/runtime/layer.d.ts +11 -0
  58. package/dist/src/scope/index.d.ts +1 -0
  59. package/dist/src/scope/resolve.d.ts +19 -0
  60. package/dist/src/t3tools/index.d.ts +1 -0
  61. package/dist/src-KdbHqrex.js +8874 -0
  62. package/dist/t3tools.js +2 -0
  63. package/dist/transport-D3zBdZ1h.js +539 -0
  64. package/dist/url-SlsaG8nY.js +165 -0
  65. package/package.json +50 -1
  66. package/src/application/index.ts +3 -0
  67. package/src/application/service.ts +1 -1
  68. package/src/application/threads.ts +40 -11
  69. package/src/auth/index.ts +28 -0
  70. package/src/auth/layer.ts +13 -6
  71. package/src/auth/local-base-dir.ts +15 -19
  72. package/src/auth/local-origin.ts +4 -1
  73. package/src/auth/local-token.ts +4 -1
  74. package/src/auth/type.ts +1 -0
  75. package/src/bin.ts +1 -1
  76. package/src/cli/app.ts +6 -6
  77. package/src/cli/auth-format.ts +2 -0
  78. package/src/cli/auth.ts +19 -9
  79. package/src/cli/error.ts +7 -0
  80. package/src/cli/flags.ts +51 -0
  81. package/src/cli/index.ts +10 -0
  82. package/src/cli/{models.ts → model.ts} +5 -4
  83. package/src/cli/{projects.ts → project.ts} +8 -7
  84. package/src/cli/require.ts +31 -0
  85. package/src/cli/{threads.ts → thread.ts} +2 -2
  86. package/src/cli/threads/archive.ts +24 -8
  87. package/src/cli/threads/list.ts +12 -5
  88. package/src/cli/threads/messages.ts +20 -5
  89. package/src/cli/threads/send.ts +27 -23
  90. package/src/cli/threads/start.ts +22 -21
  91. package/src/cli/threads/wait.ts +22 -12
  92. package/src/config/index.ts +5 -0
  93. package/src/config/layer.ts +2 -0
  94. package/src/config/service.ts +2 -0
  95. package/src/connection/index.ts +9 -0
  96. package/src/contracts/index.ts +8 -0
  97. package/src/domain/helpers.ts +136 -16
  98. package/src/index.ts +4 -87
  99. package/src/layout/base-dir.ts +35 -0
  100. package/src/layout/index.ts +1 -0
  101. package/src/orchestration/index.ts +7 -0
  102. package/src/rpc/index.ts +1 -0
  103. package/src/runtime/index.ts +12 -0
  104. package/src/{runtime.ts → runtime/layer.ts} +15 -15
  105. package/src/scope/index.ts +6 -0
  106. package/src/scope/resolve.ts +62 -0
  107. package/src/t3tools/index.ts +1 -0
  108. package/dist/runtime-KQVRmRk-.js +0 -71499
  109. package/dist/src/connection.d.ts +0 -5
  110. package/dist/src/runtime.d.ts +0 -10
  111. package/src/connection.ts +0 -9
@@ -0,0 +1,1217 @@
1
+ import { An as identity, C as isNone, S as getOrUndefined, T as isSome, an as hasProperty, n as Service } from "./Context-DueQ9iMH.js";
2
+ import { $ as mapError, Fn as succeed$1, It as try_, Mn as mergeAll, Mt as tapError, Nn as provide$1, P as fn, Tt as succeed, U as gen, Vt as void_, X as map, Yt as exponential, Zt as take, b as catchTags, bt as scope, dt as provideService, j as flatMap, k as fail, kn as effect, kt as sync, lt as provide, mt as retry, qt as collectWhile, st as orDie, t as Path, xt as scoped, zn as addFinalizer } from "./Path-D8WPdPwR.js";
3
+ import { $ as optional, $t as tapError$1, At as map$1, Ct as flatMap$1, Et as fromIterableEffect, F as decodeUnknownSync, Ft as peel, Gt as runHead, Kt as runLast, Ln as formatIso, Rn as now, Rt as retry$1, St as filter, T as Union, Tt as fromIterable, Zt as takeUntil, _t as catchTags$1, a as Defect, g as Number, nn as unwrap, qt as scoped$1, sn as head, x as TaggedErrorClass, xt as fail$1, y as String } from "./Schema-DsQxYh6_.js";
4
+ import { n as T3AuthTransportLive } from "./transport-D3zBdZ1h.js";
5
+ import { a as makeT3CodeConnectionProvider, n as T3Rpc, o as layerWebSocketConstructor, r as T3CodeConnectionProvider, s as layerUndici, t as T3RpcLive } from "./layer-DvHnKBYj.js";
6
+ import { S as Crypto, _ as layer, c as T3LocalAuthLive, d as T3LocalAuthTokenLive, g as makeCompilerSqlite, h as defaultTransforms, i as T3AuthPairingLive, m as make, p as SqlClientFactory, t as T3AuthLive, y as T3LocalAuthOriginLive } from "./layer-CfC5qZol.js";
7
+ import { $c as ProviderInstanceId, Gu as MessageId, Vu as CommandId, Yu as ProjectId, is as ORCHESTRATION_WS_METHODS, rs as ModelSelection, t as WS_METHODS, td as ThreadId, ws as OrchestrationMessage } from "./src-KdbHqrex.js";
8
+ import { n as T3Config, t as Environment } from "./service-CLmRO2Dp.js";
9
+ import { t as T3Application } from "./service-ybOWV9pL.js";
10
+ import { i as RpcClientError, n as T3CodeConnectionError, t as RpcError } from "./error-B2t1bAP9.js";
11
+ import { t as T3ConfigLive } from "./layer-DUv99vsS.js";
12
+ import { DatabaseSync } from "node:sqlite";
13
+ //#region src/domain/error.ts
14
+ var ProjectLookupError = class extends TaggedErrorClass()("ProjectLookupError", {
15
+ message: String,
16
+ ref: String
17
+ }) {};
18
+ var ModelSelectionError = class extends TaggedErrorClass()("ModelSelectionError", { message: String }) {};
19
+ TaggedErrorClass()("ThreadEventError", { message: String });
20
+ var ThreadSessionError = class extends TaggedErrorClass()("ThreadSessionError", {
21
+ message: String,
22
+ threadId: String
23
+ }) {};
24
+ var ProjectCreateVisibilityError = class extends TaggedErrorClass()("ProjectCreateVisibilityError", {
25
+ message: String,
26
+ projectId: String
27
+ }) {};
28
+ //#endregion
29
+ //#region src/domain/thread-lifecycle.ts
30
+ function isThreadActive(thread) {
31
+ return thread.session?.status === "starting" || thread.session?.status === "running" || thread.latestTurn?.state === "running" || isPendingStart(thread);
32
+ }
33
+ function threadStatus(thread) {
34
+ if (isPendingStart(thread)) return "pending";
35
+ return thread.session?.status ?? thread.latestTurn?.state ?? "unknown";
36
+ }
37
+ function latestAssistantMessage(thread) {
38
+ return thread.messages.toReversed().find((message) => message.role === "assistant");
39
+ }
40
+ function isThreadCompleteEnough(thread) {
41
+ if (thread.session?.status === "error" || thread.session?.status === "interrupted") return true;
42
+ const lastUserIndex = thread.messages.findLastIndex((message) => message.role === "user");
43
+ if (lastUserIndex === -1) return true;
44
+ return thread.messages.slice(lastUserIndex + 1).some((message) => message.role === "assistant");
45
+ }
46
+ function applyThreadEvent(current, event, messages) {
47
+ const message = messageFromEvent(event, messages);
48
+ if (message !== null) {
49
+ messages.set(messageKey(message), message);
50
+ return {
51
+ ...current,
52
+ messages: [...messages.values()]
53
+ };
54
+ }
55
+ if (event.type === "thread.session-set") return {
56
+ ...current,
57
+ session: event.payload.session
58
+ };
59
+ return current;
60
+ }
61
+ function messageFromEvent(event, existingMessages = /* @__PURE__ */ new Map()) {
62
+ if (event.type !== "thread.message-sent") return null;
63
+ const payload = event.payload;
64
+ const id = payload.messageId;
65
+ const previous = existingMessages.get(id);
66
+ const text = payload.text;
67
+ return decodeUnknownSync(OrchestrationMessage)({
68
+ id,
69
+ role: payload.role,
70
+ text: text.length > 0 || previous === void 0 ? text : previous.text,
71
+ turnId: payload.turnId,
72
+ streaming: payload.streaming,
73
+ createdAt: payload.createdAt,
74
+ updatedAt: payload.updatedAt
75
+ });
76
+ }
77
+ function messageKey(message) {
78
+ return message.id;
79
+ }
80
+ function isPendingStart(thread) {
81
+ if (thread.session !== null || thread.latestTurn !== null || !("messages" in thread)) return false;
82
+ return thread.messages.at(-1)?.role === "user";
83
+ }
84
+ //#endregion
85
+ //#region src/domain/model-config.ts
86
+ function isSelectableProvider(provider) {
87
+ return provider.status === "ready" && provider.models.length > 0;
88
+ }
89
+ function firstSelectableProvider(providers) {
90
+ return providers.find(isSelectableProvider);
91
+ }
92
+ function firstSelectableModel(provider) {
93
+ return provider.models[0];
94
+ }
95
+ function findSelectableProvider(providers, instanceId) {
96
+ return providers.find((provider) => provider.instanceId === instanceId && isSelectableProvider(provider));
97
+ }
98
+ function filterProvidersForModelListing(input) {
99
+ return input.providers.filter((provider) => input.provider === void 0 || provider.instanceId === input.provider).flatMap((provider) => {
100
+ if (input.all) return [provider];
101
+ if (!isSelectableProvider(provider)) return [];
102
+ return [provider];
103
+ });
104
+ }
105
+ //#endregion
106
+ //#region src/orchestration/service.ts
107
+ var T3Orchestration = class extends Service()("t3cli/T3Orchestration") {};
108
+ //#endregion
109
+ //#region src/application/models.ts
110
+ const makeModelsApplication = fn("makeModelsApplication")(function* () {
111
+ const orchestration = yield* T3Orchestration;
112
+ return { listModels: fn("T3Application.listModels")(function* (input) {
113
+ return filterProvidersForModelListing({
114
+ providers: (yield* orchestration.getServerConfig()).providers,
115
+ all: input.all === true,
116
+ ...input.provider !== void 0 && input.provider.length > 0 ? { provider: input.provider } : {}
117
+ });
118
+ }) };
119
+ });
120
+ //#endregion
121
+ //#region src/domain/helpers.ts
122
+ const resolveProjectScope = fn("resolveProjectScope")(function* (snapshot, input) {
123
+ const absoluteRef = yield* resolveAbsolutePath(input.ref, input.cwd);
124
+ const byId = findProjectById(snapshot, input.ref);
125
+ if (byId !== null) return { project: byId };
126
+ const byExactPath = yield* findProjectByWorkspaceRoot(snapshot, absoluteRef, input.cwd);
127
+ if (byExactPath !== void 0) return { project: byExactPath };
128
+ const byAncestor = yield* findProjectByAncestorPath(snapshot, absoluteRef, input.cwd);
129
+ if (byAncestor !== void 0) return byAncestor;
130
+ return yield* findProjectByKnownWorktreePath(snapshot, absoluteRef, input.cwd);
131
+ });
132
+ function findProjectById(snapshot, projectId) {
133
+ return snapshot.projects.find((project) => project.id === projectId) ?? null;
134
+ }
135
+ const resolveAbsolutePath = fn("resolveAbsolutePath")(function* (ref, cwd) {
136
+ const path = yield* Path;
137
+ return path.isAbsolute(ref) ? path.normalize(ref) : path.normalize(path.resolve(cwd, ref));
138
+ });
139
+ const isDescendantPath = fn("isDescendantPath")(function* (parent, child) {
140
+ const path = yield* Path;
141
+ if (child === parent) return true;
142
+ const relative = path.relative(parent, child);
143
+ return relative.length > 0 && !relative.startsWith("..") && !path.isAbsolute(relative);
144
+ });
145
+ const findProjectByWorkspaceRoot = fn("findProjectByWorkspaceRoot")(function* (snapshot, absolutePath, cwd) {
146
+ for (const project of snapshot.projects) if ((yield* resolveAbsolutePath(project.workspaceRoot, cwd)) === absolutePath) return project;
147
+ });
148
+ const findProjectByAncestorPath = fn("findProjectByAncestorPath")(function* (snapshot, absolutePath, cwd) {
149
+ let bestProject;
150
+ let bestWorkspaceRoot = "";
151
+ for (const project of snapshot.projects) {
152
+ const workspaceRoot = yield* resolveAbsolutePath(project.workspaceRoot, cwd);
153
+ if (!(yield* isDescendantPath(workspaceRoot, absolutePath))) continue;
154
+ if (workspaceRoot.length > bestWorkspaceRoot.length) {
155
+ bestProject = project;
156
+ bestWorkspaceRoot = workspaceRoot;
157
+ }
158
+ }
159
+ if (bestProject === void 0) return;
160
+ if (absolutePath === bestWorkspaceRoot) return { project: bestProject };
161
+ return {
162
+ project: bestProject,
163
+ inferredWorktreePath: absolutePath
164
+ };
165
+ });
166
+ const findProjectByKnownWorktreePath = fn("findProjectByKnownWorktreePath")(function* (snapshot, absolutePath, cwd) {
167
+ const projectsById = new Map(snapshot.projects.map((project) => [project.id, project]));
168
+ let bestProject;
169
+ let bestKnownPath = "";
170
+ for (const thread of snapshot.threads) {
171
+ if (thread.worktreePath === null) continue;
172
+ const project = projectsById.get(thread.projectId);
173
+ if (project === void 0) continue;
174
+ const knownPath = yield* resolveAbsolutePath(thread.worktreePath, cwd);
175
+ if (!(yield* isDescendantPath(knownPath, absolutePath))) continue;
176
+ if (knownPath.length > bestKnownPath.length) {
177
+ bestProject = project;
178
+ bestKnownPath = knownPath;
179
+ }
180
+ }
181
+ if (bestProject === void 0) return;
182
+ const workspaceRoot = yield* resolveAbsolutePath(bestProject.workspaceRoot, cwd);
183
+ if (absolutePath === workspaceRoot) return { project: bestProject };
184
+ if (absolutePath === bestKnownPath) return bestKnownPath === workspaceRoot ? { project: bestProject } : {
185
+ project: bestProject,
186
+ inferredWorktreePath: bestKnownPath
187
+ };
188
+ return {
189
+ project: bestProject,
190
+ inferredWorktreePath: absolutePath
191
+ };
192
+ });
193
+ //#endregion
194
+ //#region src/application/project-commands.ts
195
+ const makeProjectCreateCommand = fn("makeProjectCreateCommand")(function* (input) {
196
+ const path = yield* Path;
197
+ const crypto = yield* Crypto;
198
+ const environment = yield* Environment;
199
+ const workspaceRoot = path.resolve(environment.cwd, input.path);
200
+ const projectId = ProjectId.make(yield* crypto.randomUUIDv4.pipe(orDie));
201
+ const title = input.title?.trim();
202
+ const createdAt = formatIso(yield* now);
203
+ return {
204
+ type: "project.create",
205
+ commandId: CommandId.make(`t3cli:project-create:${yield* crypto.randomUUIDv4.pipe(orDie)}`),
206
+ projectId,
207
+ title: title !== void 0 && title.length > 0 ? title : path.basename(workspaceRoot),
208
+ workspaceRoot,
209
+ createdAt
210
+ };
211
+ });
212
+ //#endregion
213
+ //#region src/application/shell-sequence.ts
214
+ function waitForShellSequence(input) {
215
+ return gen(function* () {
216
+ if (isNone(yield* input.orchestration.watchShellSequence().pipe(filter((snapshotSequence) => snapshotSequence >= input.sequence), runHead, scoped))) return yield* fail(new RpcError({
217
+ message: `shell stream ended before sequence ${input.sequence}`,
218
+ method: ORCHESTRATION_WS_METHODS.subscribeShell
219
+ }));
220
+ return yield* input.orchestration.getShellSnapshot();
221
+ });
222
+ }
223
+ //#endregion
224
+ //#region src/application/projects.ts
225
+ const makeProjectApplication = fn("makeProjectApplication")(function* () {
226
+ const orchestration = yield* T3Orchestration;
227
+ const crypto = yield* Crypto;
228
+ const path = yield* Path;
229
+ const environment = yield* Environment;
230
+ return {
231
+ loadShell: fn("T3ApplicationLive.loadShell")(function* () {
232
+ return yield* orchestration.getShellSnapshot();
233
+ }),
234
+ addProject: fn("T3ApplicationLive.addProject")(function* (projectInput) {
235
+ const command = yield* makeProjectCreateCommand(projectInput).pipe(provideService(Path, path), provideService(Crypto, crypto), provideService(Environment, environment));
236
+ const dispatch = yield* orchestration.dispatch(command);
237
+ const project = findProjectById(yield* waitForShellSequence({
238
+ orchestration,
239
+ sequence: dispatch.sequence
240
+ }), command.projectId);
241
+ if (project === null) return yield* fail(new ProjectCreateVisibilityError({
242
+ message: `project created but not visible in shell snapshot: ${command.projectId}`,
243
+ projectId: command.projectId
244
+ }));
245
+ return {
246
+ dispatch,
247
+ project
248
+ };
249
+ })
250
+ };
251
+ });
252
+ //#endregion
253
+ //#region src/application/model-selection.ts
254
+ function resolveModelSelection(input) {
255
+ return gen(function* () {
256
+ if (input.start.provider !== void 0 && input.start.model !== void 0) return withModelOptions(input.start, {
257
+ instanceId: ProviderInstanceId.make(input.start.provider),
258
+ model: input.start.model
259
+ });
260
+ if (input.start.provider !== void 0) {
261
+ const model = firstSelectableModel(yield* findProvider(input.serverConfig, input.start.provider));
262
+ if (model === void 0) return yield* failNoAvailableModel();
263
+ return withModelOptions(input.start, {
264
+ instanceId: ProviderInstanceId.make(input.start.provider),
265
+ model: model.slug
266
+ });
267
+ }
268
+ if (input.start.model !== void 0) {
269
+ const provider = yield* firstAvailableModel(input.serverConfig);
270
+ return withModelOptions(input.start, {
271
+ instanceId: provider.instanceId,
272
+ model: input.start.model
273
+ });
274
+ }
275
+ if (input.project.defaultModelSelection !== null) return withModelOptions(input.start, input.project.defaultModelSelection);
276
+ const provider = yield* firstAvailableModel(input.serverConfig);
277
+ const model = firstSelectableModel(provider);
278
+ if (model === void 0) return yield* failNoAvailableModel();
279
+ return withModelOptions(input.start, {
280
+ instanceId: provider.instanceId,
281
+ model: model.slug
282
+ });
283
+ });
284
+ }
285
+ function mergeModelOptions(selection, options) {
286
+ if (options.length === 0) return selection;
287
+ const optionsById = new Map((selection.options ?? []).map((option) => [option.id, option]));
288
+ for (const option of options) optionsById.set(option.id, option);
289
+ return decodeUnknownSync(ModelSelection)({
290
+ ...selection,
291
+ options: [...optionsById.values()]
292
+ });
293
+ }
294
+ function withModelOptions(input, selection) {
295
+ if (input.options === void 0 || input.options.length === 0) return selection;
296
+ return mergeModelOptions(selection, input.options);
297
+ }
298
+ function firstAvailableModel(serverConfig) {
299
+ const providers = serverConfig.providers;
300
+ const provider = firstSelectableProvider(providers);
301
+ if (provider === void 0) return failNoAvailableModel();
302
+ return succeed(provider);
303
+ }
304
+ function findProvider(serverConfig, instanceId) {
305
+ const provider = findSelectableProvider(serverConfig.providers, instanceId);
306
+ if (provider === void 0) return failNoAvailableModel();
307
+ return succeed(provider);
308
+ }
309
+ function failNoAvailableModel() {
310
+ return fail(new ModelSelectionError({ message: "no available provider model found; pass --provider and --model" }));
311
+ }
312
+ //#endregion
313
+ //#region src/application/thread-commands.ts
314
+ const makeThreadStartCommands = fn("makeThreadStartCommands")(function* (input) {
315
+ const crypto = yield* Crypto;
316
+ const threadId = ThreadId.make(yield* crypto.randomUUIDv4.pipe(orDie));
317
+ const createdAt = formatIso(yield* now);
318
+ const modelSelection = yield* resolveModelSelection(input);
319
+ const inputTitle = input.start.title?.trim();
320
+ const messageTitle = input.start.message.trim().split(/\s+/).slice(0, 8).join(" ");
321
+ const title = inputTitle !== void 0 && inputTitle.length > 0 ? inputTitle : messageTitle;
322
+ return {
323
+ createCommand: {
324
+ type: "thread.create",
325
+ commandId: CommandId.make(`t3cli:thread-create:${yield* crypto.randomUUIDv4.pipe(orDie)}`),
326
+ threadId,
327
+ projectId: input.project.id,
328
+ title: title.length > 0 ? title : "New thread",
329
+ modelSelection,
330
+ runtimeMode: "full-access",
331
+ interactionMode: "default",
332
+ branch: null,
333
+ worktreePath: input.start.worktreePath ?? null,
334
+ createdAt
335
+ },
336
+ turnCommand: {
337
+ type: "thread.turn.start",
338
+ commandId: CommandId.make(`t3cli:thread-start:${yield* crypto.randomUUIDv4.pipe(orDie)}`),
339
+ threadId,
340
+ message: {
341
+ messageId: MessageId.make(yield* crypto.randomUUIDv4.pipe(orDie)),
342
+ role: "user",
343
+ text: input.start.message,
344
+ attachments: []
345
+ },
346
+ modelSelection,
347
+ titleSeed: title,
348
+ runtimeMode: "full-access",
349
+ interactionMode: "default",
350
+ createdAt
351
+ },
352
+ threadId
353
+ };
354
+ });
355
+ const makeThreadTurnContinueCommand = fn("makeThreadTurnContinueCommand")(function* (input) {
356
+ const crypto = yield* Crypto;
357
+ const createdAt = formatIso(yield* now);
358
+ return {
359
+ type: "thread.turn.start",
360
+ commandId: CommandId.make(`t3cli:thread-start:${yield* crypto.randomUUIDv4.pipe(orDie)}`),
361
+ threadId: ThreadId.make(input.threadId),
362
+ message: {
363
+ messageId: MessageId.make(yield* crypto.randomUUIDv4.pipe(orDie)),
364
+ role: "user",
365
+ text: input.message,
366
+ attachments: []
367
+ },
368
+ runtimeMode: "full-access",
369
+ interactionMode: "default",
370
+ ...input.modelSelection !== void 0 ? { modelSelection: input.modelSelection } : {},
371
+ createdAt
372
+ };
373
+ });
374
+ const makeThreadArchiveCommand = fn("makeThreadArchiveCommand")(function* (threadId) {
375
+ const crypto = yield* Crypto;
376
+ return {
377
+ type: "thread.archive",
378
+ commandId: CommandId.make(`t3cli:thread-archive:${yield* crypto.randomUUIDv4.pipe(orDie)}`),
379
+ threadId: ThreadId.make(threadId)
380
+ };
381
+ });
382
+ //#endregion
383
+ //#region src/application/thread-wait.ts
384
+ function watchThread(input) {
385
+ let current;
386
+ let currentMessages;
387
+ return scoped$1(input.orchestration.watchThreadItems(input.threadId).pipe(flatMap$1((item) => {
388
+ if (item.kind === "snapshot") {
389
+ const messages = /* @__PURE__ */ new Map();
390
+ for (const message of item.snapshot.thread.messages) messages.set(messageKey(message), message);
391
+ current = item.snapshot.thread;
392
+ currentMessages = messages;
393
+ const events = [{
394
+ type: "thread",
395
+ thread: current
396
+ }, {
397
+ type: "status",
398
+ status: threadStatus(current),
399
+ threadId: current.id
400
+ }];
401
+ if (!isThreadActive(current) && isThreadCompleteEnough(current)) events.push({
402
+ type: "done",
403
+ thread: current
404
+ });
405
+ return fromIterable(events);
406
+ }
407
+ if (current === void 0 || currentMessages === void 0) return fail$1(new ThreadSessionError({
408
+ message: `thread stream event received before snapshot: ${input.threadId}`,
409
+ threadId: input.threadId
410
+ }));
411
+ current = applyThreadEvent(current, item.event, currentMessages);
412
+ const message = messageFromEvent(item.event, currentMessages);
413
+ const events = message !== null ? [{
414
+ type: "message",
415
+ message
416
+ }] : [];
417
+ events.push({
418
+ type: "status",
419
+ status: threadStatus(current),
420
+ threadId: current.id
421
+ });
422
+ if (!isThreadActive(current) && isThreadCompleteEnough(current)) events.push({
423
+ type: "done",
424
+ thread: current
425
+ });
426
+ return fromIterable(events);
427
+ }), takeUntil((event) => event.type === "done")));
428
+ }
429
+ function waitForThread(input) {
430
+ return watchThread(input).pipe(runLast, flatMap((event) => {
431
+ if (isSome(event) && event.value.type === "done") return succeed(event.value.thread);
432
+ return fail(new ThreadSessionError({
433
+ message: `thread wait ended without done event: ${input.threadId}`,
434
+ threadId: input.threadId
435
+ }));
436
+ }));
437
+ }
438
+ //#endregion
439
+ //#region src/application/threads.ts
440
+ const makeThreadApplication = fn("makeThreadApplication")(function* () {
441
+ const orchestration = yield* T3Orchestration;
442
+ const crypto = yield* Crypto;
443
+ const path = yield* Path;
444
+ const environment = yield* Environment;
445
+ const listThreads = fn("T3ApplicationLive.listThreads")(function* (projectRef) {
446
+ const snapshot = yield* orchestration.getShellSnapshot();
447
+ const scope = yield* resolveProjectScope(snapshot, {
448
+ ref: projectRef,
449
+ cwd: environment.cwd
450
+ }).pipe(provideService(Path, path));
451
+ if (scope === void 0) return yield* fail(new ProjectLookupError({
452
+ message: `project not found: ${projectRef}`,
453
+ ref: projectRef
454
+ }));
455
+ return {
456
+ project: scope.project,
457
+ threads: snapshot.threads.filter((thread) => thread.projectId === scope.project.id)
458
+ };
459
+ });
460
+ const getThreadMessages = fn("T3ApplicationLive.getThreadMessages")(function* (threadId) {
461
+ return yield* orchestration.getThreadSnapshot(threadId);
462
+ });
463
+ const archiveThread = fn("T3ApplicationLive.archiveThread")(function* (threadId) {
464
+ const command = yield* makeThreadArchiveCommand(threadId).pipe(provideService(Crypto, crypto));
465
+ return yield* orchestration.dispatch(command);
466
+ });
467
+ const startThread = fn("T3ApplicationLive.startThread")(function* (startInput, policy) {
468
+ const snapshot = yield* orchestration.getShellSnapshot();
469
+ const projectRef = startInput.projectRef;
470
+ if (projectRef === void 0) return yield* fail(new ProjectLookupError({
471
+ message: "project is required",
472
+ ref: environment.cwd
473
+ }));
474
+ const scope = yield* resolveProjectScope(snapshot, {
475
+ ref: projectRef,
476
+ cwd: environment.cwd
477
+ }).pipe(provideService(Path, path));
478
+ if (scope === void 0) return yield* fail(new ProjectLookupError({
479
+ message: `project not found: ${projectRef}`,
480
+ ref: projectRef
481
+ }));
482
+ const worktreePath = startInput.worktreePath ?? scope.inferredWorktreePath;
483
+ const serverConfig = yield* orchestration.getServerConfig();
484
+ const commands = yield* makeThreadStartCommands({
485
+ start: {
486
+ ...startInput,
487
+ ...worktreePath !== void 0 ? { worktreePath } : {}
488
+ },
489
+ project: scope.project,
490
+ serverConfig
491
+ }).pipe(provideService(Crypto, crypto));
492
+ yield* waitForShellSequence({
493
+ orchestration,
494
+ sequence: (yield* orchestration.dispatch(commands.createCommand)).sequence
495
+ });
496
+ const dispatch = yield* orchestration.dispatch(commands.turnCommand);
497
+ const threadId = commands.threadId;
498
+ const until = policy?.until ?? "dispatch";
499
+ if (until === "dispatch") return {
500
+ dispatch,
501
+ project: scope.project,
502
+ threadId
503
+ };
504
+ yield* waitForShellSequence({
505
+ orchestration,
506
+ sequence: dispatch.sequence
507
+ });
508
+ if (until === "visible") {
509
+ const thread = yield* scoped(gen(function* () {
510
+ return (yield* orchestration.openThread(threadId)).snapshot;
511
+ }));
512
+ return {
513
+ dispatch,
514
+ project: scope.project,
515
+ threadId,
516
+ thread
517
+ };
518
+ }
519
+ const thread = yield* waitForThread({
520
+ orchestration,
521
+ threadId
522
+ });
523
+ yield* failIfThreadError(thread);
524
+ return {
525
+ dispatch,
526
+ project: scope.project,
527
+ threadId,
528
+ thread
529
+ };
530
+ });
531
+ const sendThread = fn("T3ApplicationLive.sendThread")(function* (input, policy) {
532
+ const modelSelection = input.options !== void 0 && input.options.length > 0 ? mergeModelOptions((yield* orchestration.getThreadSnapshot(input.threadId)).modelSelection, input.options) : void 0;
533
+ const command = yield* makeThreadTurnContinueCommand({
534
+ ...input,
535
+ ...modelSelection !== void 0 ? { modelSelection } : {}
536
+ }).pipe(provideService(Crypto, crypto));
537
+ const dispatch = yield* orchestration.dispatch(command);
538
+ const until = policy?.until ?? "dispatch";
539
+ if (until === "dispatch") return {
540
+ dispatch,
541
+ threadId: input.threadId
542
+ };
543
+ yield* waitForShellSequence({
544
+ orchestration,
545
+ sequence: dispatch.sequence
546
+ });
547
+ if (until === "visible") {
548
+ const thread = yield* scoped(gen(function* () {
549
+ return (yield* orchestration.openThread(input.threadId)).snapshot;
550
+ }));
551
+ return {
552
+ dispatch,
553
+ threadId: input.threadId,
554
+ thread
555
+ };
556
+ }
557
+ const thread = yield* waitForThread({
558
+ orchestration,
559
+ threadId: input.threadId
560
+ });
561
+ yield* failIfThreadError(thread);
562
+ return {
563
+ dispatch,
564
+ threadId: input.threadId,
565
+ thread
566
+ };
567
+ });
568
+ const watchThread$1 = (threadId) => watchThread({
569
+ orchestration,
570
+ threadId
571
+ });
572
+ return {
573
+ archiveThread,
574
+ listThreads,
575
+ getThreadMessages,
576
+ sendThread,
577
+ startThread,
578
+ watchThread: watchThread$1,
579
+ waitForThread: fn("T3ApplicationLive.waitForThread")(function* (threadId) {
580
+ const thread = yield* waitForThread({
581
+ orchestration,
582
+ threadId
583
+ });
584
+ yield* failIfThreadError(thread);
585
+ return thread;
586
+ })
587
+ };
588
+ });
589
+ function failIfThreadError(thread) {
590
+ if (thread.session?.status !== "error") return void_;
591
+ return fail(new ThreadSessionError({
592
+ threadId: thread.id,
593
+ message: thread.session.lastError ?? "thread ended with error"
594
+ }));
595
+ }
596
+ const T3ApplicationLive = effect(T3Application, fn("makeT3Application")(function* () {
597
+ const models = yield* makeModelsApplication();
598
+ const projects = yield* makeProjectApplication();
599
+ const threads = yield* makeThreadApplication();
600
+ return {
601
+ ...models,
602
+ ...projects,
603
+ ...threads
604
+ };
605
+ })());
606
+ //#endregion
607
+ //#region src/orchestration/layer.ts
608
+ const rpcRetrySchedule = exponential("100 millis").pipe(take(4), collectWhile((metadata) => metadata.input instanceof RpcClientError));
609
+ function runRpc(rpc, method, f) {
610
+ return gen(function* () {
611
+ return yield* f(yield* rpc.getClient);
612
+ }).pipe(tapError((error) => error instanceof RpcClientError ? rpc.disconnect : void_), retry(rpcRetrySchedule), catchTags({
613
+ RpcError: (error) => fail(error),
614
+ EnvironmentAuthorizationError: (error) => fail(toRpcRequestError(error, method)),
615
+ RpcClientError: (error) => fail(toRpcRequestError(error, method)),
616
+ KeybindingsConfigParseError: (error) => fail(toRpcRequestError(error, method)),
617
+ OrchestrationDispatchCommandError: (error) => fail(toRpcRequestError(error, method)),
618
+ OrchestrationGetSnapshotError: (error) => fail(toRpcRequestError(error, method)),
619
+ ServerSettingsError: (error) => fail(toRpcRequestError(error, method))
620
+ }));
621
+ }
622
+ function subscribeRpc(rpc, method, f) {
623
+ return unwrap(map(rpc.getClient, f)).pipe(tapError$1((error) => error instanceof RpcClientError ? rpc.disconnect : void_), retry$1(rpcRetrySchedule), catchTags$1({
624
+ RpcError: (error) => fail$1(error),
625
+ EnvironmentAuthorizationError: (error) => fail$1(toRpcRequestError(error, method)),
626
+ RpcClientError: (error) => fail$1(toRpcRequestError(error, method)),
627
+ KeybindingsConfigParseError: (error) => fail$1(toRpcRequestError(error, method)),
628
+ OrchestrationDispatchCommandError: (error) => fail$1(toRpcRequestError(error, method)),
629
+ OrchestrationGetSnapshotError: (error) => fail$1(toRpcRequestError(error, method)),
630
+ ServerSettingsError: (error) => fail$1(toRpcRequestError(error, method))
631
+ }));
632
+ }
633
+ const T3OrchestrationLive = effect(T3Orchestration, fn("makeT3Orchestration")(function* () {
634
+ const rpc = yield* T3Rpc;
635
+ const dispatch = fn("T3OrchestrationLive.dispatch")(function* (command) {
636
+ return yield* runRpc(rpc, ORCHESTRATION_WS_METHODS.dispatchCommand, (client) => client[ORCHESTRATION_WS_METHODS.dispatchCommand](command));
637
+ });
638
+ const getServerConfig = fn("T3OrchestrationLive.getServerConfig")(function* () {
639
+ return yield* runRpc(rpc, WS_METHODS.serverGetConfig, (client) => client[WS_METHODS.serverGetConfig]({}));
640
+ });
641
+ const getShellSnapshot = fn("T3OrchestrationLive.getShellSnapshot")(function* () {
642
+ const value = getOrUndefined(yield* runHead(subscribeRpc(rpc, ORCHESTRATION_WS_METHODS.subscribeShell, (client) => client[ORCHESTRATION_WS_METHODS.subscribeShell]({}))));
643
+ if (value === void 0 || value.kind !== "snapshot") return yield* fail(new RpcError({
644
+ message: "server did not return shell snapshot",
645
+ method: ORCHESTRATION_WS_METHODS.subscribeShell
646
+ }));
647
+ return value.snapshot;
648
+ });
649
+ const getThreadSnapshot = fn("T3OrchestrationLive.getThreadSnapshot")(function* (threadId) {
650
+ const value = getOrUndefined(yield* runHead(subscribeRpc(rpc, ORCHESTRATION_WS_METHODS.subscribeThread, (client) => client[ORCHESTRATION_WS_METHODS.subscribeThread]({ threadId: ThreadId.make(threadId) }))));
651
+ if (value === void 0 || value.kind !== "snapshot") return yield* fail(new RpcError({
652
+ message: `thread ${threadId} not found`,
653
+ method: ORCHESTRATION_WS_METHODS.subscribeThread
654
+ }));
655
+ return value.snapshot.thread;
656
+ });
657
+ const watchShellSequence = () => subscribeRpc(rpc, ORCHESTRATION_WS_METHODS.subscribeShell, (client) => client[ORCHESTRATION_WS_METHODS.subscribeShell]({})).pipe(map$1((item) => item.kind === "snapshot" ? item.snapshot.snapshotSequence : item.sequence));
658
+ const watchThreadItems = (threadId) => subscribeRpc(rpc, ORCHESTRATION_WS_METHODS.subscribeThread, (client) => client[ORCHESTRATION_WS_METHODS.subscribeThread]({ threadId: ThreadId.make(threadId) }));
659
+ return {
660
+ dispatch,
661
+ getServerConfig,
662
+ getShellSnapshot,
663
+ getThreadSnapshot,
664
+ watchShellSequence,
665
+ watchThreadItems,
666
+ openThread: fn("T3OrchestrationLive.openThread")(function* (threadId) {
667
+ return yield* watchThreadItems(threadId).pipe(peel(head()), flatMap(([item, rest]) => {
668
+ const value = getOrUndefined(item);
669
+ if (value === void 0 || value.kind !== "snapshot") return fail(new RpcError({
670
+ message: `thread ${threadId} not found`,
671
+ method: ORCHESTRATION_WS_METHODS.subscribeThread
672
+ }));
673
+ return succeed({
674
+ snapshot: value.snapshot.thread,
675
+ events: rest.pipe(filter((next) => next.kind === "event"), map$1((next) => next.event))
676
+ });
677
+ }));
678
+ })
679
+ };
680
+ })());
681
+ function toRpcRequestError(error, method) {
682
+ return new RpcError({
683
+ message: error.message,
684
+ method,
685
+ cause: error
686
+ });
687
+ }
688
+ //#endregion
689
+ //#region node_modules/.pnpm/effect@4.0.0-beta.78/node_modules/effect/dist/unstable/sql/SqlError.js
690
+ /**
691
+ * Structured SQL failures for unstable SQL clients and driver integrations.
692
+ *
693
+ * This module provides the top-level `SqlError` wrapper, the concrete
694
+ * `SqlErrorReason` variants used by adapters, schemas for encoding or decoding
695
+ * those errors, guards for recognizing them, and a SQLite classifier for native
696
+ * driver causes. The model keeps query mistakes, authentication and
697
+ * authorization failures, constraint violations, connection failures, lock
698
+ * waits, deadlocks, serialization conflicts, statement timeouts, and unknown
699
+ * failures distinguishable in the Effect error channel.
700
+ *
701
+ * **Mental model**
702
+ *
703
+ * `SqlError` wraps exactly one reason. Its `message`, `cause`, and
704
+ * `isRetryable` values are delegated to that reason, so recovery code can branch
705
+ * on either the reason tag or the retryability flag without losing the original
706
+ * native cause. Reasons are intentionally driver-neutral; adapters translate
707
+ * database-specific error codes into this shared vocabulary.
708
+ *
709
+ * **Common tasks**
710
+ *
711
+ * Construct a reason when adapting a driver failure, wrap it in `SqlError` for
712
+ * client APIs, use `isSqlError` or `isSqlErrorReason` at boundaries that receive
713
+ * unknown failures, and use `classifySqliteError` when mapping SQLite `code` or
714
+ * `errno` values.
715
+ *
716
+ * **Gotchas**
717
+ *
718
+ * Preserve the native `cause` and `operation` metadata when constructing these
719
+ * errors; they are often the only way to diagnose dialect-specific failures.
720
+ * Retryable reasons represent transient infrastructure or concurrency problems,
721
+ * while syntax, credential, permission, and constraint failures generally need a
722
+ * changed query, configuration, or data set. SQLite unique violations include a
723
+ * best-effort constraint name when one can be extracted.
724
+ *
725
+ * @since 4.0.0
726
+ */
727
+ const TypeId = "~effect/sql/SqlError";
728
+ const ReasonTypeId = "~effect/sql/SqlError/Reason";
729
+ const ReasonFields = {
730
+ cause: /*#__PURE__*/ Defect(),
731
+ message: /*#__PURE__*/ optional(String),
732
+ operation: /*#__PURE__*/ optional(String)
733
+ };
734
+ /**
735
+ * SQL error reason for connection or open failures; marked retryable.
736
+ *
737
+ * @category errors
738
+ * @since 4.0.0
739
+ */
740
+ var ConnectionError = class extends TaggedErrorClass("effect/sql/SqlError/ConnectionError")("ConnectionError", ReasonFields) {
741
+ /**
742
+ * Marks this value as a structured SQL error reason for runtime guards.
743
+ *
744
+ * @since 4.0.0
745
+ */
746
+ [ReasonTypeId] = ReasonTypeId;
747
+ /**
748
+ * Indicates whether retrying the failed SQL operation may succeed.
749
+ *
750
+ * @since 4.0.0
751
+ */
752
+ get isRetryable() {
753
+ return true;
754
+ }
755
+ };
756
+ /**
757
+ * SQL error reason for authentication failures such as invalid credentials; not
758
+ * marked retryable.
759
+ *
760
+ * @category errors
761
+ * @since 4.0.0
762
+ */
763
+ var AuthenticationError = class extends TaggedErrorClass("effect/sql/SqlError/AuthenticationError")("AuthenticationError", ReasonFields) {
764
+ /**
765
+ * Marks this value as a structured SQL error reason for runtime guards.
766
+ *
767
+ * @since 4.0.0
768
+ */
769
+ [ReasonTypeId] = ReasonTypeId;
770
+ /**
771
+ * Indicates whether retrying the failed SQL operation may succeed.
772
+ *
773
+ * @since 4.0.0
774
+ */
775
+ get isRetryable() {
776
+ return false;
777
+ }
778
+ };
779
+ /**
780
+ * SQL error reason for authorization or permission failures; not marked
781
+ * retryable.
782
+ *
783
+ * @category errors
784
+ * @since 4.0.0
785
+ */
786
+ var AuthorizationError = class extends TaggedErrorClass("effect/sql/SqlError/AuthorizationError")("AuthorizationError", ReasonFields) {
787
+ /**
788
+ * Marks this value as a structured SQL error reason for runtime guards.
789
+ *
790
+ * @since 4.0.0
791
+ */
792
+ [ReasonTypeId] = ReasonTypeId;
793
+ /**
794
+ * Indicates whether retrying the failed SQL operation may succeed.
795
+ *
796
+ * @since 4.0.0
797
+ */
798
+ get isRetryable() {
799
+ return false;
800
+ }
801
+ };
802
+ /**
803
+ * SQL error reason for invalid SQL syntax; not marked retryable.
804
+ *
805
+ * @category errors
806
+ * @since 4.0.0
807
+ */
808
+ var SqlSyntaxError = class extends TaggedErrorClass("effect/sql/SqlError/SqlSyntaxError")("SqlSyntaxError", ReasonFields) {
809
+ /**
810
+ * Marks this value as a structured SQL error reason for runtime guards.
811
+ *
812
+ * @since 4.0.0
813
+ */
814
+ [ReasonTypeId] = ReasonTypeId;
815
+ /**
816
+ * Indicates whether retrying the failed SQL operation may succeed.
817
+ *
818
+ * @since 4.0.0
819
+ */
820
+ get isRetryable() {
821
+ return false;
822
+ }
823
+ };
824
+ const UniqueViolationFields = {
825
+ ...ReasonFields,
826
+ constraint: String
827
+ };
828
+ /**
829
+ * SQL error reason for a unique constraint violation, including the violated
830
+ * constraint identifier; not marked retryable.
831
+ *
832
+ * @category errors
833
+ * @since 4.0.0
834
+ */
835
+ var UniqueViolation = class extends TaggedErrorClass("effect/sql/SqlError/UniqueViolation")("UniqueViolation", UniqueViolationFields) {
836
+ /**
837
+ * Marks this value as a structured SQL error reason for runtime guards.
838
+ *
839
+ * @since 4.0.0
840
+ */
841
+ [ReasonTypeId] = ReasonTypeId;
842
+ /**
843
+ * Indicates whether retrying the failed SQL operation may succeed.
844
+ *
845
+ * @since 4.0.0
846
+ */
847
+ get isRetryable() {
848
+ return false;
849
+ }
850
+ };
851
+ /**
852
+ * SQL error reason for a non-unique constraint violation; not marked retryable.
853
+ *
854
+ * @category errors
855
+ * @since 4.0.0
856
+ */
857
+ var ConstraintError = class extends TaggedErrorClass("effect/sql/SqlError/ConstraintError")("ConstraintError", ReasonFields) {
858
+ /**
859
+ * Marks this value as a structured SQL error reason for runtime guards.
860
+ *
861
+ * @since 4.0.0
862
+ */
863
+ [ReasonTypeId] = ReasonTypeId;
864
+ /**
865
+ * Indicates whether retrying the failed SQL operation may succeed.
866
+ *
867
+ * @since 4.0.0
868
+ */
869
+ get isRetryable() {
870
+ return false;
871
+ }
872
+ };
873
+ /**
874
+ * SQL error reason for a database deadlock; marked retryable.
875
+ *
876
+ * @category errors
877
+ * @since 4.0.0
878
+ */
879
+ var DeadlockError = class extends TaggedErrorClass("effect/sql/SqlError/DeadlockError")("DeadlockError", ReasonFields) {
880
+ /**
881
+ * Marks this value as a structured SQL error reason for runtime guards.
882
+ *
883
+ * @since 4.0.0
884
+ */
885
+ [ReasonTypeId] = ReasonTypeId;
886
+ /**
887
+ * Indicates whether retrying the failed SQL operation may succeed.
888
+ *
889
+ * @since 4.0.0
890
+ */
891
+ get isRetryable() {
892
+ return true;
893
+ }
894
+ };
895
+ /**
896
+ * SQL error reason for a transaction serialization or isolation conflict;
897
+ * marked retryable.
898
+ *
899
+ * @category errors
900
+ * @since 4.0.0
901
+ */
902
+ var SerializationError = class extends TaggedErrorClass("effect/sql/SqlError/SerializationError")("SerializationError", ReasonFields) {
903
+ /**
904
+ * Marks this value as a structured SQL error reason for runtime guards.
905
+ *
906
+ * @since 4.0.0
907
+ */
908
+ [ReasonTypeId] = ReasonTypeId;
909
+ /**
910
+ * Indicates whether retrying the failed SQL operation may succeed.
911
+ *
912
+ * @since 4.0.0
913
+ */
914
+ get isRetryable() {
915
+ return true;
916
+ }
917
+ };
918
+ /**
919
+ * SQL error reason for timing out while waiting on a database lock; marked
920
+ * retryable.
921
+ *
922
+ * @category errors
923
+ * @since 4.0.0
924
+ */
925
+ var LockTimeoutError = class extends TaggedErrorClass("effect/sql/SqlError/LockTimeoutError")("LockTimeoutError", ReasonFields) {
926
+ /**
927
+ * Marks this value as a structured SQL error reason for runtime guards.
928
+ *
929
+ * @since 4.0.0
930
+ */
931
+ [ReasonTypeId] = ReasonTypeId;
932
+ /**
933
+ * Indicates whether retrying the failed SQL operation may succeed.
934
+ *
935
+ * @since 4.0.0
936
+ */
937
+ get isRetryable() {
938
+ return true;
939
+ }
940
+ };
941
+ /**
942
+ * SQL error reason for a statement or query timeout; marked retryable.
943
+ *
944
+ * @category errors
945
+ * @since 4.0.0
946
+ */
947
+ var StatementTimeoutError = class extends TaggedErrorClass("effect/sql/SqlError/StatementTimeoutError")("StatementTimeoutError", ReasonFields) {
948
+ /**
949
+ * Marks this value as a structured SQL error reason for runtime guards.
950
+ *
951
+ * @since 4.0.0
952
+ */
953
+ [ReasonTypeId] = ReasonTypeId;
954
+ /**
955
+ * Indicates whether retrying the failed SQL operation may succeed.
956
+ *
957
+ * @since 4.0.0
958
+ */
959
+ get isRetryable() {
960
+ return true;
961
+ }
962
+ };
963
+ /**
964
+ * SQL error reason for an unclassified database failure; not marked retryable.
965
+ *
966
+ * @category errors
967
+ * @since 4.0.0
968
+ */
969
+ var UnknownError = class extends TaggedErrorClass("effect/sql/SqlError/UnknownError")("UnknownError", ReasonFields) {
970
+ /**
971
+ * Marks this value as a structured SQL error reason for runtime guards.
972
+ *
973
+ * @since 4.0.0
974
+ */
975
+ [ReasonTypeId] = ReasonTypeId;
976
+ /**
977
+ * Indicates whether retrying the failed SQL operation may succeed.
978
+ *
979
+ * @since 4.0.0
980
+ */
981
+ get isRetryable() {
982
+ return false;
983
+ }
984
+ };
985
+ /**
986
+ * Schema for encoding and decoding SQL error reasons.
987
+ *
988
+ * @category schemas
989
+ * @since 4.0.0
990
+ */
991
+ const SqlErrorReason = /*#__PURE__*/ Union([
992
+ ConnectionError,
993
+ AuthenticationError,
994
+ AuthorizationError,
995
+ SqlSyntaxError,
996
+ UniqueViolation,
997
+ ConstraintError,
998
+ DeadlockError,
999
+ SerializationError,
1000
+ LockTimeoutError,
1001
+ StatementTimeoutError,
1002
+ UnknownError
1003
+ ]);
1004
+ /**
1005
+ * Error wrapper for SQL failures whose `message`, `cause`, and `isRetryable`
1006
+ * values are derived from its `SqlErrorReason`.
1007
+ *
1008
+ * @category errors
1009
+ * @since 4.0.0
1010
+ */
1011
+ var SqlError = class extends TaggedErrorClass("effect/sql/SqlError")("SqlError", { reason: SqlErrorReason }) {
1012
+ /**
1013
+ * Marks this value as the top-level SQL error wrapper for runtime guards.
1014
+ *
1015
+ * @since 4.0.0
1016
+ */
1017
+ [TypeId] = TypeId;
1018
+ /**
1019
+ * Exposes the structured SQL reason as the JavaScript error cause.
1020
+ *
1021
+ * @since 4.0.0
1022
+ */
1023
+ cause = this.reason;
1024
+ /**
1025
+ * Uses the reason message when present, otherwise falls back to the reason tag.
1026
+ *
1027
+ * @since 4.0.0
1028
+ */
1029
+ get message() {
1030
+ return this.reason.message || this.reason._tag;
1031
+ }
1032
+ /**
1033
+ * Delegates retryability to the underlying SQL error reason.
1034
+ *
1035
+ * @since 4.0.0
1036
+ */
1037
+ get isRetryable() {
1038
+ return this.reason.isRetryable;
1039
+ }
1040
+ };
1041
+ const sqliteCodeFromCause = (cause) => {
1042
+ if (!hasProperty(cause, "code")) return;
1043
+ const code = cause.code;
1044
+ return typeof code === "string" || typeof code === "number" ? code : void 0;
1045
+ };
1046
+ const sqliteNumericCodeFromCause = (cause) => {
1047
+ const code = sqliteCodeFromCause(cause);
1048
+ if (typeof code === "number") return code;
1049
+ if (!hasProperty(cause, "errno")) return;
1050
+ const errno = cause.errno;
1051
+ return typeof errno === "number" ? errno : void 0;
1052
+ };
1053
+ const matchesSqliteNumericCode = (cause, expected) => {
1054
+ if (sqliteCodeFromCause(cause) === expected) return true;
1055
+ if (!hasProperty(cause, "errno")) return false;
1056
+ return cause.errno === expected;
1057
+ };
1058
+ const matchesSqliteCode = (code, expected) => code === expected || code.startsWith(expected + "_");
1059
+ const UNKNOWN_CONSTRAINT = "unknown";
1060
+ const SQLITE_CONSTRAINT_UNIQUE = "SQLITE_CONSTRAINT_UNIQUE";
1061
+ const SQLITE_CONSTRAINT_UNIQUE_CODE = 2067;
1062
+ const normalizeConstraintIdentifier = (identifier) => {
1063
+ if (typeof identifier !== "string") return UNKNOWN_CONSTRAINT;
1064
+ const trimmed = identifier.trim();
1065
+ return trimmed.length === 0 ? UNKNOWN_CONSTRAINT : trimmed;
1066
+ };
1067
+ const sqliteUniqueConstraintFromCause = (cause) => {
1068
+ if (hasProperty(cause, "constraint")) return normalizeConstraintIdentifier(cause.constraint);
1069
+ if (!hasProperty(cause, "message")) return UNKNOWN_CONSTRAINT;
1070
+ const message = cause.message;
1071
+ if (typeof message !== "string") return UNKNOWN_CONSTRAINT;
1072
+ const index = message.indexOf("UNIQUE constraint failed:");
1073
+ return index === -1 ? UNKNOWN_CONSTRAINT : normalizeConstraintIdentifier(message.slice(index + 25));
1074
+ };
1075
+ /**
1076
+ * Classifies a native SQLite error cause into a `SqlErrorReason` using its
1077
+ * `code` or `errno`, with optional message and operation metadata.
1078
+ *
1079
+ * @category converting
1080
+ * @since 4.0.0
1081
+ */
1082
+ const classifySqliteError = (cause, { message, operation } = {}) => {
1083
+ const props = {
1084
+ cause,
1085
+ message,
1086
+ operation
1087
+ };
1088
+ const code = sqliteCodeFromCause(cause);
1089
+ const numericCode = sqliteNumericCodeFromCause(cause);
1090
+ if (code === SQLITE_CONSTRAINT_UNIQUE || matchesSqliteNumericCode(cause, SQLITE_CONSTRAINT_UNIQUE_CODE)) return new UniqueViolation({
1091
+ ...props,
1092
+ constraint: sqliteUniqueConstraintFromCause(cause)
1093
+ });
1094
+ if (typeof code === "string") {
1095
+ if (matchesSqliteCode(code, "SQLITE_AUTH")) return new AuthenticationError(props);
1096
+ if (matchesSqliteCode(code, "SQLITE_PERM")) return new AuthorizationError(props);
1097
+ if (matchesSqliteCode(code, "SQLITE_CONSTRAINT")) return new ConstraintError(props);
1098
+ if (matchesSqliteCode(code, "SQLITE_BUSY") || matchesSqliteCode(code, "SQLITE_LOCKED")) return new LockTimeoutError(props);
1099
+ if (matchesSqliteCode(code, "SQLITE_CANTOPEN")) return new ConnectionError(props);
1100
+ }
1101
+ if (typeof numericCode === "number") switch (numericCode & 255) {
1102
+ case 23: return new AuthenticationError(props);
1103
+ case 3: return new AuthorizationError(props);
1104
+ case 19: return new ConstraintError(props);
1105
+ case 5:
1106
+ case 6: return new LockTimeoutError(props);
1107
+ case 14: return new ConnectionError(props);
1108
+ default: return new UnknownError(props);
1109
+ }
1110
+ return new UnknownError(props);
1111
+ };
1112
+ TaggedErrorClass("effect/sql/ResultLengthMismatch")("ResultLengthMismatch", {
1113
+ expected: Number,
1114
+ actual: Number
1115
+ });
1116
+ //#endregion
1117
+ //#region src/sql/node-sqlite-client.ts
1118
+ const ATTR_DB_SYSTEM_NAME = "db.system.name";
1119
+ const classifyError = (cause, message, operation) => classifySqliteError(cause, {
1120
+ message,
1121
+ operation
1122
+ });
1123
+ const makeNodeSqliteClient = fn("makeNodeSqliteClient")(function* (config) {
1124
+ const compiler = makeCompilerSqlite(config.transformQueryNames);
1125
+ const transformRows = config.transformResultNames === void 0 ? void 0 : defaultTransforms(config.transformResultNames).array;
1126
+ const scope$1 = yield* scope;
1127
+ const db = yield* try_({
1128
+ try: () => new DatabaseSync(config.filename),
1129
+ catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to open sqlite database", "connect") })
1130
+ });
1131
+ yield* addFinalizer(scope$1, sync(() => {
1132
+ try {
1133
+ db.close();
1134
+ } catch {}
1135
+ }));
1136
+ const runRows = (sql, params) => try_({
1137
+ try: () => {
1138
+ const statement = db.prepare(sql);
1139
+ const bound = params.map(toSqlInputValue);
1140
+ if (statement.columns().length > 0) return statement.all(...bound);
1141
+ statement.run(...bound);
1142
+ return [];
1143
+ },
1144
+ catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to execute sqlite statement", "execute") })
1145
+ });
1146
+ const runRaw = (sql, params) => try_({
1147
+ try: () => {
1148
+ const statement = db.prepare(sql);
1149
+ const bound = params.map(toSqlInputValue);
1150
+ return statement.columns().length > 0 ? statement.all(...bound) : statement.run(...bound);
1151
+ },
1152
+ catch: (cause) => new SqlError({ reason: classifyError(cause, "Failed to execute sqlite statement", "execute") })
1153
+ });
1154
+ const runValues = (sql, params) => map(runRows(sql, params), (rows) => rows.map((row) => Object.values(row)));
1155
+ return yield* make({
1156
+ acquirer: succeed(identity({
1157
+ execute(sql, params, rowTransform) {
1158
+ const effect = runRows(sql, params);
1159
+ return rowTransform === void 0 ? effect : map(effect, rowTransform);
1160
+ },
1161
+ executeRaw(sql, params) {
1162
+ return runRaw(sql, params);
1163
+ },
1164
+ executeValues(sql, params) {
1165
+ return runValues(sql, params);
1166
+ },
1167
+ executeUnprepared(sql, params, rowTransform) {
1168
+ const effect = runRows(sql, params);
1169
+ return rowTransform === void 0 ? effect : map(effect, rowTransform);
1170
+ },
1171
+ executeStream(sql, params, rowTransform) {
1172
+ return fromIterableEffect(this.execute(sql, params, rowTransform));
1173
+ }
1174
+ })),
1175
+ compiler,
1176
+ spanAttributes: [[ATTR_DB_SYSTEM_NAME, "sqlite"]],
1177
+ transformRows
1178
+ });
1179
+ });
1180
+ const NodeSqlClientFactoryLive = succeed$1(SqlClientFactory, { sqliteClient: (config) => makeNodeSqliteClient(config).pipe(provide(layer)) });
1181
+ function toSqlInputValue(value) {
1182
+ if (value === void 0 || value === null) return null;
1183
+ if (typeof value === "string" || typeof value === "number" || typeof value === "bigint") return value;
1184
+ if (typeof value === "boolean") return value ? 1 : 0;
1185
+ if (value instanceof Date) return value.toISOString();
1186
+ if (ArrayBuffer.isView(value)) {
1187
+ const bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
1188
+ const copy = new Uint8Array(bytes.byteLength);
1189
+ copy.set(bytes);
1190
+ return copy;
1191
+ }
1192
+ return JSON.stringify(value) ?? null;
1193
+ }
1194
+ //#endregion
1195
+ //#region src/runtime/layer.ts
1196
+ const T3AuthTransportLayer = T3AuthTransportLive.pipe(provide$1(layerUndici));
1197
+ const T3LocalAuthOriginLayer = T3LocalAuthOriginLive;
1198
+ const T3LocalAuthTokenLayer = T3LocalAuthTokenLive.pipe(provide$1(NodeSqlClientFactoryLive));
1199
+ const T3LocalAuthLayer = T3LocalAuthLive.pipe(provide$1(mergeAll(T3LocalAuthOriginLayer, T3LocalAuthTokenLayer)));
1200
+ const T3AuthPairingLayer = T3AuthPairingLive.pipe(provide$1(T3AuthTransportLayer));
1201
+ const T3AuthLayer = T3AuthLive.pipe(provide$1(mergeAll(T3ConfigLive, T3AuthTransportLayer, T3LocalAuthLayer, T3AuthPairingLayer)));
1202
+ const T3ConfigConnectionProviderLayer = effect(T3CodeConnectionProvider, gen(function* () {
1203
+ return makeT3CodeConnectionProvider((yield* T3Config).resolve().pipe(map((resolved) => ({
1204
+ origin: { url: resolved.url },
1205
+ auth: { token: resolved.token }
1206
+ })), mapError((error) => new T3CodeConnectionError({
1207
+ message: "failed to resolve T3 Code connection from CLI config",
1208
+ cause: error
1209
+ }))));
1210
+ })).pipe(provide$1(T3ConfigLive));
1211
+ const T3RpcLayer = T3RpcLive.pipe(provide$1(mergeAll(T3ConfigConnectionProviderLayer, T3AuthTransportLayer, layerWebSocketConstructor)));
1212
+ const T3OrchestrationLayer = T3OrchestrationLive.pipe(provide$1(T3RpcLayer));
1213
+ const T3ApplicationLayer = T3ApplicationLive.pipe(provide$1(T3OrchestrationLayer));
1214
+ const AuthAppLayer = mergeAll(T3ConfigLive, T3AuthLayer);
1215
+ const AppLayer = mergeAll(T3ConfigLive, T3AuthLayer, T3RpcLayer, T3OrchestrationLayer, T3ApplicationLayer);
1216
+ //#endregion
1217
+ export { T3AuthTransportLayer as a, T3LocalAuthTokenLayer as c, latestAssistantMessage as d, threadStatus as f, T3AuthPairingLayer as i, T3OrchestrationLayer as l, ThreadSessionError as m, AuthAppLayer as n, T3LocalAuthLayer as o, ProjectLookupError as p, T3AuthLayer as r, T3LocalAuthOriginLayer as s, AppLayer as t, T3Orchestration as u };