t3code-cli 0.8.0 → 0.9.1

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