@kimuson/claude-code-viewer 0.4.5 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +1804 -815
- package/dist/main.js.map +4 -4
- package/dist/static/assets/index-C-6yHKgK.css +1 -0
- package/dist/static/assets/{index-D1IPE4nC.js → index-CEfL1559.js} +22 -22
- package/dist/static/assets/index-ChVcZMuL.js +6 -0
- package/dist/static/assets/index-CsvC5pl6.js +1 -0
- package/dist/static/assets/{label-l0et4hNL.js → label-D9NP5l7d.js} +3 -3
- package/dist/static/assets/{index-BuR5pLkN.js → session-B4u9RwAC.js} +64 -58
- package/dist/static/assets/{index-BwRuqrVH.js → session-aPiwqPra.js} +1 -1
- package/dist/static/index.html +2 -2
- package/package.json +4 -4
- package/dist/static/assets/index-BHWHZ-91.js +0 -1
- package/dist/static/assets/index-CYLe5Tc7.js +0 -1
- package/dist/static/assets/index-DovipUdR.js +0 -6
- package/dist/static/assets/index-sJq6n11H.js +0 -1
- package/dist/static/assets/index-tkMROyMY.css +0 -1
package/dist/main.js
CHANGED
|
@@ -6,33 +6,380 @@ import { resolve as resolve6 } from "node:path";
|
|
|
6
6
|
import { NodeContext as NodeContext2 } from "@effect/platform-node";
|
|
7
7
|
import { serve } from "@hono/node-server";
|
|
8
8
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
9
|
-
import { Effect as
|
|
9
|
+
import { Effect as Effect42 } from "effect";
|
|
10
|
+
|
|
11
|
+
// src/server/core/agent-session/index.ts
|
|
12
|
+
import { Layer as Layer3 } from "effect";
|
|
13
|
+
|
|
14
|
+
// src/server/core/agent-session/infrastructure/AgentSessionRepository.ts
|
|
15
|
+
import { FileSystem, Path } from "@effect/platform";
|
|
16
|
+
import { Context, Effect, Layer } from "effect";
|
|
17
|
+
|
|
18
|
+
// src/lib/conversation-schema/index.ts
|
|
19
|
+
import { z as z16 } from "zod";
|
|
20
|
+
|
|
21
|
+
// src/lib/conversation-schema/entry/AssistantEntrySchema.ts
|
|
22
|
+
import { z as z8 } from "zod";
|
|
23
|
+
|
|
24
|
+
// src/lib/conversation-schema/message/AssistantMessageSchema.ts
|
|
25
|
+
import { z as z6 } from "zod";
|
|
26
|
+
|
|
27
|
+
// src/lib/conversation-schema/content/TextContentSchema.ts
|
|
28
|
+
import { z } from "zod";
|
|
29
|
+
var TextContentSchema = z.object({
|
|
30
|
+
type: z.literal("text"),
|
|
31
|
+
text: z.string()
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// src/lib/conversation-schema/content/ThinkingContentSchema.ts
|
|
35
|
+
import { z as z2 } from "zod";
|
|
36
|
+
var ThinkingContentSchema = z2.object({
|
|
37
|
+
type: z2.literal("thinking"),
|
|
38
|
+
thinking: z2.string(),
|
|
39
|
+
signature: z2.string().optional()
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// src/lib/conversation-schema/content/ToolResultContentSchema.ts
|
|
43
|
+
import { z as z4 } from "zod";
|
|
44
|
+
|
|
45
|
+
// src/lib/conversation-schema/content/ImageContentSchema.ts
|
|
46
|
+
import { z as z3 } from "zod";
|
|
47
|
+
var ImageContentSchema = z3.object({
|
|
48
|
+
type: z3.literal("image"),
|
|
49
|
+
source: z3.object({
|
|
50
|
+
type: z3.literal("base64"),
|
|
51
|
+
data: z3.string(),
|
|
52
|
+
media_type: z3.enum(["image/png", "image/jpeg", "image/gif", "image/webp"])
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// src/lib/conversation-schema/content/ToolResultContentSchema.ts
|
|
57
|
+
var ToolResultContentSchema = z4.object({
|
|
58
|
+
type: z4.literal("tool_result"),
|
|
59
|
+
tool_use_id: z4.string(),
|
|
60
|
+
content: z4.union([
|
|
61
|
+
z4.string(),
|
|
62
|
+
z4.array(z4.union([TextContentSchema, ImageContentSchema]))
|
|
63
|
+
]),
|
|
64
|
+
is_error: z4.boolean().optional()
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// src/lib/conversation-schema/content/ToolUseContentSchema.ts
|
|
68
|
+
import { z as z5 } from "zod";
|
|
69
|
+
var ToolUseContentSchema = z5.object({
|
|
70
|
+
type: z5.literal("tool_use"),
|
|
71
|
+
id: z5.string(),
|
|
72
|
+
name: z5.string(),
|
|
73
|
+
input: z5.record(z5.string(), z5.unknown())
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// src/lib/conversation-schema/message/AssistantMessageSchema.ts
|
|
77
|
+
var AssistantMessageContentSchema = z6.union([
|
|
78
|
+
ThinkingContentSchema,
|
|
79
|
+
TextContentSchema,
|
|
80
|
+
ToolUseContentSchema,
|
|
81
|
+
ToolResultContentSchema
|
|
82
|
+
]);
|
|
83
|
+
var AssistantMessageSchema = z6.object({
|
|
84
|
+
id: z6.string(),
|
|
85
|
+
container: z6.null().optional(),
|
|
86
|
+
type: z6.literal("message"),
|
|
87
|
+
role: z6.literal("assistant"),
|
|
88
|
+
model: z6.string(),
|
|
89
|
+
content: z6.array(AssistantMessageContentSchema),
|
|
90
|
+
stop_reason: z6.string().nullable(),
|
|
91
|
+
stop_sequence: z6.string().nullable(),
|
|
92
|
+
usage: z6.object({
|
|
93
|
+
input_tokens: z6.number(),
|
|
94
|
+
cache_creation_input_tokens: z6.number().optional(),
|
|
95
|
+
cache_read_input_tokens: z6.number().optional(),
|
|
96
|
+
cache_creation: z6.object({
|
|
97
|
+
ephemeral_5m_input_tokens: z6.number(),
|
|
98
|
+
ephemeral_1h_input_tokens: z6.number()
|
|
99
|
+
}).optional(),
|
|
100
|
+
output_tokens: z6.number(),
|
|
101
|
+
service_tier: z6.string().nullable().optional(),
|
|
102
|
+
server_tool_use: z6.object({
|
|
103
|
+
web_search_requests: z6.number()
|
|
104
|
+
}).optional()
|
|
105
|
+
})
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// src/lib/conversation-schema/entry/BaseEntrySchema.ts
|
|
109
|
+
import { z as z7 } from "zod";
|
|
110
|
+
var BaseEntrySchema = z7.object({
|
|
111
|
+
// required
|
|
112
|
+
isSidechain: z7.boolean(),
|
|
113
|
+
userType: z7.enum(["external"]),
|
|
114
|
+
cwd: z7.string(),
|
|
115
|
+
sessionId: z7.string(),
|
|
116
|
+
version: z7.string(),
|
|
117
|
+
uuid: z7.uuid(),
|
|
118
|
+
timestamp: z7.string(),
|
|
119
|
+
// nullable
|
|
120
|
+
parentUuid: z7.uuid().nullable(),
|
|
121
|
+
// optional
|
|
122
|
+
isMeta: z7.boolean().optional(),
|
|
123
|
+
toolUseResult: z7.unknown().optional(),
|
|
124
|
+
// スキーマがツールごとに異なりすぎるし利用もしなそうなので unknown
|
|
125
|
+
gitBranch: z7.string().optional(),
|
|
126
|
+
isCompactSummary: z7.boolean().optional()
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// src/lib/conversation-schema/entry/AssistantEntrySchema.ts
|
|
130
|
+
var AssistantEntrySchema = BaseEntrySchema.extend({
|
|
131
|
+
// discriminator
|
|
132
|
+
type: z8.literal("assistant"),
|
|
133
|
+
// required
|
|
134
|
+
message: AssistantMessageSchema,
|
|
135
|
+
// optional
|
|
136
|
+
requestId: z8.string().optional(),
|
|
137
|
+
isApiErrorMessage: z8.boolean().optional()
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// src/lib/conversation-schema/entry/FileHIstorySnapshotEntrySchema.ts
|
|
141
|
+
import { z as z9 } from "zod";
|
|
142
|
+
var FileHistorySnapshotEntrySchema = z9.object({
|
|
143
|
+
// discriminator
|
|
144
|
+
type: z9.literal("file-history-snapshot"),
|
|
145
|
+
// required
|
|
146
|
+
messageId: z9.string(),
|
|
147
|
+
snapshot: z9.object({
|
|
148
|
+
messageId: z9.string(),
|
|
149
|
+
trackedFileBackups: z9.record(z9.string(), z9.unknown()),
|
|
150
|
+
timestamp: z9.string()
|
|
151
|
+
}),
|
|
152
|
+
isSnapshotUpdate: z9.boolean()
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// src/lib/conversation-schema/entry/QueueOperationEntrySchema.ts
|
|
156
|
+
import { z as z11 } from "zod";
|
|
157
|
+
|
|
158
|
+
// src/lib/conversation-schema/content/DocumentContentSchema.ts
|
|
159
|
+
import { z as z10 } from "zod";
|
|
160
|
+
var DocumentContentSchema = z10.object({
|
|
161
|
+
type: z10.literal("document"),
|
|
162
|
+
source: z10.union([
|
|
163
|
+
z10.object({
|
|
164
|
+
media_type: z10.literal("text/plain"),
|
|
165
|
+
type: z10.literal("text"),
|
|
166
|
+
data: z10.string()
|
|
167
|
+
}),
|
|
168
|
+
z10.object({
|
|
169
|
+
media_type: z10.enum(["application/pdf"]),
|
|
170
|
+
type: z10.literal("base64"),
|
|
171
|
+
data: z10.string()
|
|
172
|
+
})
|
|
173
|
+
])
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// src/lib/conversation-schema/entry/QueueOperationEntrySchema.ts
|
|
177
|
+
var QueueOperationContentSchema = z11.union([
|
|
178
|
+
z11.string(),
|
|
179
|
+
TextContentSchema,
|
|
180
|
+
ToolResultContentSchema,
|
|
181
|
+
ImageContentSchema,
|
|
182
|
+
DocumentContentSchema
|
|
183
|
+
]);
|
|
184
|
+
var QueueOperationEntrySchema = z11.union([
|
|
185
|
+
z11.object({
|
|
186
|
+
type: z11.literal("queue-operation"),
|
|
187
|
+
operation: z11.literal("enqueue"),
|
|
188
|
+
content: z11.union([
|
|
189
|
+
z11.string(),
|
|
190
|
+
z11.array(z11.union([z11.string(), QueueOperationContentSchema]))
|
|
191
|
+
]),
|
|
192
|
+
sessionId: z11.string(),
|
|
193
|
+
timestamp: z11.iso.datetime()
|
|
194
|
+
}),
|
|
195
|
+
z11.object({
|
|
196
|
+
type: z11.literal("queue-operation"),
|
|
197
|
+
operation: z11.literal("dequeue"),
|
|
198
|
+
sessionId: z11.string(),
|
|
199
|
+
timestamp: z11.iso.datetime()
|
|
200
|
+
})
|
|
201
|
+
]);
|
|
202
|
+
|
|
203
|
+
// src/lib/conversation-schema/entry/SummaryEntrySchema.ts
|
|
204
|
+
import { z as z12 } from "zod";
|
|
205
|
+
var SummaryEntrySchema = z12.object({
|
|
206
|
+
type: z12.literal("summary"),
|
|
207
|
+
summary: z12.string(),
|
|
208
|
+
leafUuid: z12.string().uuid()
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// src/lib/conversation-schema/entry/SystemEntrySchema.ts
|
|
212
|
+
import { z as z13 } from "zod";
|
|
213
|
+
var SystemEntrySchema = BaseEntrySchema.extend({
|
|
214
|
+
// discriminator
|
|
215
|
+
type: z13.literal("system"),
|
|
216
|
+
// required
|
|
217
|
+
content: z13.string(),
|
|
218
|
+
toolUseID: z13.string(),
|
|
219
|
+
level: z13.enum(["info"])
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// src/lib/conversation-schema/entry/UserEntrySchema.ts
|
|
223
|
+
import { z as z15 } from "zod";
|
|
224
|
+
|
|
225
|
+
// src/lib/conversation-schema/message/UserMessageSchema.ts
|
|
226
|
+
import { z as z14 } from "zod";
|
|
227
|
+
var UserMessageContentSchema = z14.union([
|
|
228
|
+
z14.string(),
|
|
229
|
+
TextContentSchema,
|
|
230
|
+
ToolResultContentSchema,
|
|
231
|
+
ImageContentSchema,
|
|
232
|
+
DocumentContentSchema
|
|
233
|
+
]);
|
|
234
|
+
var UserMessageSchema = z14.object({
|
|
235
|
+
role: z14.literal("user"),
|
|
236
|
+
content: z14.union([
|
|
237
|
+
z14.string(),
|
|
238
|
+
z14.array(z14.union([z14.string(), UserMessageContentSchema]))
|
|
239
|
+
])
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// src/lib/conversation-schema/entry/UserEntrySchema.ts
|
|
243
|
+
var UserEntrySchema = BaseEntrySchema.extend({
|
|
244
|
+
// discriminator
|
|
245
|
+
type: z15.literal("user"),
|
|
246
|
+
// required
|
|
247
|
+
message: UserMessageSchema
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// src/lib/conversation-schema/index.ts
|
|
251
|
+
var ConversationSchema = z16.union([
|
|
252
|
+
UserEntrySchema,
|
|
253
|
+
AssistantEntrySchema,
|
|
254
|
+
SummaryEntrySchema,
|
|
255
|
+
SystemEntrySchema,
|
|
256
|
+
FileHistorySnapshotEntrySchema,
|
|
257
|
+
QueueOperationEntrySchema
|
|
258
|
+
]);
|
|
259
|
+
|
|
260
|
+
// src/server/core/claude-code/functions/parseJsonl.ts
|
|
261
|
+
var parseJsonl = (content) => {
|
|
262
|
+
const lines = content.trim().split("\n").filter((line) => line.trim() !== "");
|
|
263
|
+
return lines.map((line, index) => {
|
|
264
|
+
const parsed = ConversationSchema.safeParse(JSON.parse(line));
|
|
265
|
+
if (!parsed.success) {
|
|
266
|
+
const errorData = {
|
|
267
|
+
type: "x-error",
|
|
268
|
+
line,
|
|
269
|
+
lineNumber: index + 1
|
|
270
|
+
};
|
|
271
|
+
return errorData;
|
|
272
|
+
}
|
|
273
|
+
return parsed.data;
|
|
274
|
+
});
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// src/server/core/project/functions/id.ts
|
|
278
|
+
import { dirname } from "node:path";
|
|
279
|
+
var encodeProjectId = (fullPath) => {
|
|
280
|
+
return Buffer.from(fullPath).toString("base64url");
|
|
281
|
+
};
|
|
282
|
+
var decodeProjectId = (id) => {
|
|
283
|
+
return Buffer.from(id, "base64url").toString("utf-8");
|
|
284
|
+
};
|
|
285
|
+
var encodeProjectIdFromSessionFilePath = (sessionFilePath) => {
|
|
286
|
+
return encodeProjectId(dirname(sessionFilePath));
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// src/server/core/agent-session/infrastructure/AgentSessionRepository.ts
|
|
290
|
+
var LayerImpl = Effect.gen(function* () {
|
|
291
|
+
const fs = yield* FileSystem.FileSystem;
|
|
292
|
+
const path = yield* Path.Path;
|
|
293
|
+
const getAgentSessionByAgentId = (projectId, agentId) => Effect.gen(function* () {
|
|
294
|
+
const projectPath = decodeProjectId(projectId);
|
|
295
|
+
const agentFilePath = path.resolve(projectPath, `agent-${agentId}.jsonl`);
|
|
296
|
+
const exists = yield* fs.exists(agentFilePath);
|
|
297
|
+
if (!exists) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
const content = yield* fs.readFileString(agentFilePath);
|
|
301
|
+
const conversations = parseJsonl(content);
|
|
302
|
+
return conversations;
|
|
303
|
+
});
|
|
304
|
+
return {
|
|
305
|
+
getAgentSessionByAgentId
|
|
306
|
+
};
|
|
307
|
+
});
|
|
308
|
+
var AgentSessionRepository = class extends Context.Tag(
|
|
309
|
+
"AgentSessionRepository"
|
|
310
|
+
)() {
|
|
311
|
+
static {
|
|
312
|
+
this.Live = Layer.effect(this, LayerImpl);
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
// src/server/core/agent-session/presentation/AgentSessionController.ts
|
|
317
|
+
import { Context as Context2, Effect as Effect2, Layer as Layer2 } from "effect";
|
|
318
|
+
var LayerImpl2 = Effect2.gen(function* () {
|
|
319
|
+
const repository = yield* AgentSessionRepository;
|
|
320
|
+
const getAgentSession = (params) => Effect2.gen(function* () {
|
|
321
|
+
const { projectId, agentId } = params;
|
|
322
|
+
const conversations = yield* repository.getAgentSessionByAgentId(
|
|
323
|
+
projectId,
|
|
324
|
+
agentId
|
|
325
|
+
);
|
|
326
|
+
if (conversations === null) {
|
|
327
|
+
return {
|
|
328
|
+
status: 200,
|
|
329
|
+
response: {
|
|
330
|
+
agentSessionId: null,
|
|
331
|
+
conversations: []
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
status: 200,
|
|
337
|
+
response: {
|
|
338
|
+
agentSessionId: agentId,
|
|
339
|
+
conversations
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
});
|
|
343
|
+
return {
|
|
344
|
+
getAgentSession
|
|
345
|
+
};
|
|
346
|
+
});
|
|
347
|
+
var AgentSessionController = class extends Context2.Tag(
|
|
348
|
+
"AgentSessionController"
|
|
349
|
+
)() {
|
|
350
|
+
static {
|
|
351
|
+
this.Live = Layer2.effect(this, LayerImpl2);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
// src/server/core/agent-session/index.ts
|
|
356
|
+
var AgentSessionLayer = Layer3.mergeAll(AgentSessionRepository.Live);
|
|
10
357
|
|
|
11
358
|
// src/server/core/claude-code/presentation/ClaudeCodeController.ts
|
|
12
|
-
import { FileSystem as
|
|
13
|
-
import { Context as
|
|
359
|
+
import { FileSystem as FileSystem6, Path as Path8 } from "@effect/platform";
|
|
360
|
+
import { Context as Context9, Effect as Effect12, Layer as Layer11 } from "effect";
|
|
14
361
|
|
|
15
362
|
// src/server/core/platform/services/ApplicationContext.ts
|
|
16
363
|
import { homedir } from "node:os";
|
|
17
|
-
import { Path } from "@effect/platform";
|
|
18
|
-
import { Effect as
|
|
364
|
+
import { Path as Path2 } from "@effect/platform";
|
|
365
|
+
import { Effect as Effect4, Context as EffectContext, Layer as Layer5 } from "effect";
|
|
19
366
|
|
|
20
367
|
// src/server/core/platform/services/EnvService.ts
|
|
21
|
-
import { Context, Effect, Layer, Ref } from "effect";
|
|
368
|
+
import { Context as Context3, Effect as Effect3, Layer as Layer4, Ref } from "effect";
|
|
22
369
|
|
|
23
370
|
// src/server/core/platform/schema.ts
|
|
24
|
-
import { z } from "zod";
|
|
25
|
-
var envSchema =
|
|
26
|
-
NODE_ENV:
|
|
27
|
-
CLAUDE_CODE_VIEWER_CC_EXECUTABLE_PATH:
|
|
28
|
-
GLOBAL_CLAUDE_DIR:
|
|
29
|
-
NEXT_PHASE:
|
|
30
|
-
PORT:
|
|
31
|
-
PATH:
|
|
371
|
+
import { z as z17 } from "zod";
|
|
372
|
+
var envSchema = z17.object({
|
|
373
|
+
NODE_ENV: z17.enum(["development", "production", "test"]).optional().default("development"),
|
|
374
|
+
CLAUDE_CODE_VIEWER_CC_EXECUTABLE_PATH: z17.string().optional(),
|
|
375
|
+
GLOBAL_CLAUDE_DIR: z17.string().optional(),
|
|
376
|
+
NEXT_PHASE: z17.string().optional(),
|
|
377
|
+
PORT: z17.string().optional().default("3000").transform((val) => parseInt(val, 10)),
|
|
378
|
+
PATH: z17.string().optional()
|
|
32
379
|
});
|
|
33
380
|
|
|
34
381
|
// src/server/core/platform/services/EnvService.ts
|
|
35
|
-
var
|
|
382
|
+
var LayerImpl3 = Effect3.gen(function* () {
|
|
36
383
|
const envRef = yield* Ref.make(void 0);
|
|
37
384
|
const parseEnv = () => {
|
|
38
385
|
const parsed = envSchema.safeParse(process.env);
|
|
@@ -43,7 +390,7 @@ var LayerImpl = Effect.gen(function* () {
|
|
|
43
390
|
return parsed.data;
|
|
44
391
|
};
|
|
45
392
|
const getEnv = (key) => {
|
|
46
|
-
return
|
|
393
|
+
return Effect3.gen(function* () {
|
|
47
394
|
yield* Ref.update(envRef, (existingEnv) => {
|
|
48
395
|
if (existingEnv === void 0) {
|
|
49
396
|
return parseEnv();
|
|
@@ -63,18 +410,18 @@ var LayerImpl = Effect.gen(function* () {
|
|
|
63
410
|
getEnv
|
|
64
411
|
};
|
|
65
412
|
});
|
|
66
|
-
var EnvService = class extends
|
|
413
|
+
var EnvService = class extends Context3.Tag("EnvService")() {
|
|
67
414
|
static {
|
|
68
|
-
this.Live =
|
|
415
|
+
this.Live = Layer4.effect(this, LayerImpl3);
|
|
69
416
|
}
|
|
70
417
|
};
|
|
71
418
|
|
|
72
419
|
// src/server/core/platform/services/ApplicationContext.ts
|
|
73
|
-
var
|
|
74
|
-
const path = yield*
|
|
420
|
+
var LayerImpl4 = Effect4.gen(function* () {
|
|
421
|
+
const path = yield* Path2.Path;
|
|
75
422
|
const envService = yield* EnvService;
|
|
76
423
|
const globalClaudeDirectoryPath = yield* envService.getEnv("GLOBAL_CLAUDE_DIR").pipe(
|
|
77
|
-
|
|
424
|
+
Effect4.map(
|
|
78
425
|
(envVar) => envVar === void 0 ? path.resolve(homedir(), ".claude") : path.resolve(envVar)
|
|
79
426
|
)
|
|
80
427
|
);
|
|
@@ -89,38 +436,26 @@ var LayerImpl2 = Effect2.gen(function* () {
|
|
|
89
436
|
});
|
|
90
437
|
var ApplicationContext = class extends EffectContext.Tag("ApplicationContext")() {
|
|
91
438
|
static {
|
|
92
|
-
this.Live =
|
|
439
|
+
this.Live = Layer5.effect(this, LayerImpl4);
|
|
93
440
|
}
|
|
94
441
|
};
|
|
95
442
|
|
|
96
443
|
// src/server/core/project/infrastructure/ProjectRepository.ts
|
|
97
|
-
import { FileSystem as
|
|
98
|
-
import { Context as
|
|
99
|
-
|
|
100
|
-
// src/server/core/project/functions/id.ts
|
|
101
|
-
import { dirname } from "node:path";
|
|
102
|
-
var encodeProjectId = (fullPath) => {
|
|
103
|
-
return Buffer.from(fullPath).toString("base64url");
|
|
104
|
-
};
|
|
105
|
-
var decodeProjectId = (id) => {
|
|
106
|
-
return Buffer.from(id, "base64url").toString("utf-8");
|
|
107
|
-
};
|
|
108
|
-
var encodeProjectIdFromSessionFilePath = (sessionFilePath) => {
|
|
109
|
-
return encodeProjectId(dirname(sessionFilePath));
|
|
110
|
-
};
|
|
444
|
+
import { FileSystem as FileSystem4, Path as Path5 } from "@effect/platform";
|
|
445
|
+
import { Context as Context7, Effect as Effect8, Layer as Layer9, Option as Option2 } from "effect";
|
|
111
446
|
|
|
112
447
|
// src/server/core/project/services/ProjectMetaService.ts
|
|
113
|
-
import { FileSystem as
|
|
114
|
-
import { Context as
|
|
448
|
+
import { FileSystem as FileSystem3, Path as Path4 } from "@effect/platform";
|
|
449
|
+
import { Context as Context6, Effect as Effect7, Layer as Layer8, Option, Ref as Ref3 } from "effect";
|
|
115
450
|
import { z as z19 } from "zod";
|
|
116
451
|
|
|
117
452
|
// src/server/lib/storage/FileCacheStorage/index.ts
|
|
118
|
-
import { Context as
|
|
453
|
+
import { Context as Context5, Effect as Effect6, Layer as Layer7, Ref as Ref2, Runtime } from "effect";
|
|
119
454
|
|
|
120
455
|
// src/server/lib/storage/FileCacheStorage/PersistentService.ts
|
|
121
|
-
import { FileSystem, Path as
|
|
122
|
-
import { Context as
|
|
123
|
-
import { z as
|
|
456
|
+
import { FileSystem as FileSystem2, Path as Path3 } from "@effect/platform";
|
|
457
|
+
import { Context as Context4, Effect as Effect5, Layer as Layer6 } from "effect";
|
|
458
|
+
import { z as z18 } from "zod";
|
|
124
459
|
|
|
125
460
|
// src/server/lib/config/paths.ts
|
|
126
461
|
import { homedir as homedir2 } from "node:os";
|
|
@@ -132,14 +467,14 @@ var claudeCodeViewerCacheDirPath = resolve(
|
|
|
132
467
|
);
|
|
133
468
|
|
|
134
469
|
// src/server/lib/storage/FileCacheStorage/PersistentService.ts
|
|
135
|
-
var saveSchema =
|
|
136
|
-
var
|
|
137
|
-
const path = yield*
|
|
470
|
+
var saveSchema = z18.array(z18.tuple([z18.string(), z18.unknown()]));
|
|
471
|
+
var LayerImpl5 = Effect5.gen(function* () {
|
|
472
|
+
const path = yield* Path3.Path;
|
|
138
473
|
const getCacheFilePath = (key) => path.resolve(claudeCodeViewerCacheDirPath, `${key}.json`);
|
|
139
474
|
const load = (key) => {
|
|
140
475
|
const cacheFilePath = getCacheFilePath(key);
|
|
141
|
-
return
|
|
142
|
-
const fs = yield*
|
|
476
|
+
return Effect5.gen(function* () {
|
|
477
|
+
const fs = yield* FileSystem2.FileSystem;
|
|
143
478
|
if (!(yield* fs.exists(claudeCodeViewerCacheDirPath))) {
|
|
144
479
|
yield* fs.makeDirectory(claudeCodeViewerCacheDirPath, {
|
|
145
480
|
recursive: true
|
|
@@ -169,8 +504,8 @@ var LayerImpl3 = Effect3.gen(function* () {
|
|
|
169
504
|
};
|
|
170
505
|
const save = (key, entries) => {
|
|
171
506
|
const cacheFilePath = getCacheFilePath(key);
|
|
172
|
-
return
|
|
173
|
-
const fs = yield*
|
|
507
|
+
return Effect5.gen(function* () {
|
|
508
|
+
const fs = yield* FileSystem2.FileSystem;
|
|
174
509
|
yield* fs.writeFileString(cacheFilePath, JSON.stringify(entries));
|
|
175
510
|
});
|
|
176
511
|
};
|
|
@@ -179,20 +514,20 @@ var LayerImpl3 = Effect3.gen(function* () {
|
|
|
179
514
|
save
|
|
180
515
|
};
|
|
181
516
|
});
|
|
182
|
-
var PersistentService = class extends
|
|
517
|
+
var PersistentService = class extends Context4.Tag("PersistentService")() {
|
|
183
518
|
static {
|
|
184
|
-
this.Live =
|
|
519
|
+
this.Live = Layer6.effect(this, LayerImpl5);
|
|
185
520
|
}
|
|
186
521
|
};
|
|
187
522
|
|
|
188
523
|
// src/server/lib/storage/FileCacheStorage/index.ts
|
|
189
|
-
var FileCacheStorage = () =>
|
|
190
|
-
var makeFileCacheStorageLayer = (storageKey, schema) =>
|
|
524
|
+
var FileCacheStorage = () => Context5.GenericTag("FileCacheStorage");
|
|
525
|
+
var makeFileCacheStorageLayer = (storageKey, schema) => Layer7.effect(
|
|
191
526
|
FileCacheStorage(),
|
|
192
|
-
|
|
527
|
+
Effect6.gen(function* () {
|
|
193
528
|
const persistentService = yield* PersistentService;
|
|
194
|
-
const runtime = yield*
|
|
195
|
-
const storageRef = yield*
|
|
529
|
+
const runtime = yield* Effect6.runtime();
|
|
530
|
+
const storageRef = yield* Effect6.gen(function* () {
|
|
196
531
|
const persistedData = yield* persistentService.load(storageKey);
|
|
197
532
|
const initialMap = /* @__PURE__ */ new Map();
|
|
198
533
|
for (const [key, value] of persistedData) {
|
|
@@ -207,11 +542,11 @@ var makeFileCacheStorageLayer = (storageKey, schema) => Layer4.effect(
|
|
|
207
542
|
Runtime.runFork(runtime)(persistentService.save(storageKey, entries));
|
|
208
543
|
};
|
|
209
544
|
return {
|
|
210
|
-
get: (key) =>
|
|
545
|
+
get: (key) => Effect6.gen(function* () {
|
|
211
546
|
const storage = yield* Ref2.get(storageRef);
|
|
212
547
|
return storage.get(key);
|
|
213
548
|
}),
|
|
214
|
-
set: (key, value) =>
|
|
549
|
+
set: (key, value) => Effect6.gen(function* () {
|
|
215
550
|
const before = yield* Ref2.get(storageRef);
|
|
216
551
|
const beforeString = JSON.stringify(Array.from(before.entries()));
|
|
217
552
|
yield* Ref2.update(storageRef, (map) => {
|
|
@@ -224,7 +559,7 @@ var makeFileCacheStorageLayer = (storageKey, schema) => Layer4.effect(
|
|
|
224
559
|
syncToFile(Array.from(after.entries()));
|
|
225
560
|
}
|
|
226
561
|
}),
|
|
227
|
-
invalidate: (key) =>
|
|
562
|
+
invalidate: (key) => Effect6.gen(function* () {
|
|
228
563
|
const before = yield* Ref2.get(storageRef);
|
|
229
564
|
if (!before.has(key)) {
|
|
230
565
|
return;
|
|
@@ -236,7 +571,7 @@ var makeFileCacheStorageLayer = (storageKey, schema) => Layer4.effect(
|
|
|
236
571
|
const after = yield* Ref2.get(storageRef);
|
|
237
572
|
syncToFile(Array.from(after.entries()));
|
|
238
573
|
}),
|
|
239
|
-
getAll: () =>
|
|
574
|
+
getAll: () => Effect6.gen(function* () {
|
|
240
575
|
const storage = yield* Ref2.get(storageRef);
|
|
241
576
|
return new Map(storage);
|
|
242
577
|
})
|
|
@@ -244,263 +579,14 @@ var makeFileCacheStorageLayer = (storageKey, schema) => Layer4.effect(
|
|
|
244
579
|
})
|
|
245
580
|
);
|
|
246
581
|
|
|
247
|
-
// src/lib/conversation-schema/index.ts
|
|
248
|
-
import { z as z18 } from "zod";
|
|
249
|
-
|
|
250
|
-
// src/lib/conversation-schema/entry/AssistantEntrySchema.ts
|
|
251
|
-
import { z as z10 } from "zod";
|
|
252
|
-
|
|
253
|
-
// src/lib/conversation-schema/message/AssistantMessageSchema.ts
|
|
254
|
-
import { z as z8 } from "zod";
|
|
255
|
-
|
|
256
|
-
// src/lib/conversation-schema/content/TextContentSchema.ts
|
|
257
|
-
import { z as z3 } from "zod";
|
|
258
|
-
var TextContentSchema = z3.object({
|
|
259
|
-
type: z3.literal("text"),
|
|
260
|
-
text: z3.string()
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
// src/lib/conversation-schema/content/ThinkingContentSchema.ts
|
|
264
|
-
import { z as z4 } from "zod";
|
|
265
|
-
var ThinkingContentSchema = z4.object({
|
|
266
|
-
type: z4.literal("thinking"),
|
|
267
|
-
thinking: z4.string(),
|
|
268
|
-
signature: z4.string().optional()
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
// src/lib/conversation-schema/content/ToolResultContentSchema.ts
|
|
272
|
-
import { z as z6 } from "zod";
|
|
273
|
-
|
|
274
|
-
// src/lib/conversation-schema/content/ImageContentSchema.ts
|
|
275
|
-
import { z as z5 } from "zod";
|
|
276
|
-
var ImageContentSchema = z5.object({
|
|
277
|
-
type: z5.literal("image"),
|
|
278
|
-
source: z5.object({
|
|
279
|
-
type: z5.literal("base64"),
|
|
280
|
-
data: z5.string(),
|
|
281
|
-
media_type: z5.enum(["image/png", "image/jpeg", "image/gif", "image/webp"])
|
|
282
|
-
})
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
// src/lib/conversation-schema/content/ToolResultContentSchema.ts
|
|
286
|
-
var ToolResultContentSchema = z6.object({
|
|
287
|
-
type: z6.literal("tool_result"),
|
|
288
|
-
tool_use_id: z6.string(),
|
|
289
|
-
content: z6.union([
|
|
290
|
-
z6.string(),
|
|
291
|
-
z6.array(z6.union([TextContentSchema, ImageContentSchema]))
|
|
292
|
-
]),
|
|
293
|
-
is_error: z6.boolean().optional()
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
// src/lib/conversation-schema/content/ToolUseContentSchema.ts
|
|
297
|
-
import { z as z7 } from "zod";
|
|
298
|
-
var ToolUseContentSchema = z7.object({
|
|
299
|
-
type: z7.literal("tool_use"),
|
|
300
|
-
id: z7.string(),
|
|
301
|
-
name: z7.string(),
|
|
302
|
-
input: z7.record(z7.string(), z7.unknown())
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
// src/lib/conversation-schema/message/AssistantMessageSchema.ts
|
|
306
|
-
var AssistantMessageContentSchema = z8.union([
|
|
307
|
-
ThinkingContentSchema,
|
|
308
|
-
TextContentSchema,
|
|
309
|
-
ToolUseContentSchema,
|
|
310
|
-
ToolResultContentSchema
|
|
311
|
-
]);
|
|
312
|
-
var AssistantMessageSchema = z8.object({
|
|
313
|
-
id: z8.string(),
|
|
314
|
-
container: z8.null().optional(),
|
|
315
|
-
type: z8.literal("message"),
|
|
316
|
-
role: z8.literal("assistant"),
|
|
317
|
-
model: z8.string(),
|
|
318
|
-
content: z8.array(AssistantMessageContentSchema),
|
|
319
|
-
stop_reason: z8.string().nullable(),
|
|
320
|
-
stop_sequence: z8.string().nullable(),
|
|
321
|
-
usage: z8.object({
|
|
322
|
-
input_tokens: z8.number(),
|
|
323
|
-
cache_creation_input_tokens: z8.number().optional(),
|
|
324
|
-
cache_read_input_tokens: z8.number().optional(),
|
|
325
|
-
cache_creation: z8.object({
|
|
326
|
-
ephemeral_5m_input_tokens: z8.number(),
|
|
327
|
-
ephemeral_1h_input_tokens: z8.number()
|
|
328
|
-
}).optional(),
|
|
329
|
-
output_tokens: z8.number(),
|
|
330
|
-
service_tier: z8.string().nullable().optional(),
|
|
331
|
-
server_tool_use: z8.object({
|
|
332
|
-
web_search_requests: z8.number()
|
|
333
|
-
}).optional()
|
|
334
|
-
})
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
// src/lib/conversation-schema/entry/BaseEntrySchema.ts
|
|
338
|
-
import { z as z9 } from "zod";
|
|
339
|
-
var BaseEntrySchema = z9.object({
|
|
340
|
-
// required
|
|
341
|
-
isSidechain: z9.boolean(),
|
|
342
|
-
userType: z9.enum(["external"]),
|
|
343
|
-
cwd: z9.string(),
|
|
344
|
-
sessionId: z9.string(),
|
|
345
|
-
version: z9.string(),
|
|
346
|
-
uuid: z9.uuid(),
|
|
347
|
-
timestamp: z9.string(),
|
|
348
|
-
// nullable
|
|
349
|
-
parentUuid: z9.uuid().nullable(),
|
|
350
|
-
// optional
|
|
351
|
-
isMeta: z9.boolean().optional(),
|
|
352
|
-
toolUseResult: z9.unknown().optional(),
|
|
353
|
-
// スキーマがツールごとに異なりすぎるし利用もしなそうなので unknown
|
|
354
|
-
gitBranch: z9.string().optional(),
|
|
355
|
-
isCompactSummary: z9.boolean().optional()
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
// src/lib/conversation-schema/entry/AssistantEntrySchema.ts
|
|
359
|
-
var AssistantEntrySchema = BaseEntrySchema.extend({
|
|
360
|
-
// discriminator
|
|
361
|
-
type: z10.literal("assistant"),
|
|
362
|
-
// required
|
|
363
|
-
message: AssistantMessageSchema,
|
|
364
|
-
// optional
|
|
365
|
-
requestId: z10.string().optional(),
|
|
366
|
-
isApiErrorMessage: z10.boolean().optional()
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
// src/lib/conversation-schema/entry/FileHIstorySnapshotEntrySchema.ts
|
|
370
|
-
import { z as z11 } from "zod";
|
|
371
|
-
var FileHistorySnapshotEntrySchema = z11.object({
|
|
372
|
-
// discriminator
|
|
373
|
-
type: z11.literal("file-history-snapshot"),
|
|
374
|
-
// required
|
|
375
|
-
messageId: z11.string(),
|
|
376
|
-
snapshot: z11.object({
|
|
377
|
-
messageId: z11.string(),
|
|
378
|
-
trackedFileBackups: z11.record(z11.string(), z11.unknown()),
|
|
379
|
-
timestamp: z11.string()
|
|
380
|
-
}),
|
|
381
|
-
isSnapshotUpdate: z11.boolean()
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
// src/lib/conversation-schema/entry/QueueOperationEntrySchema.ts
|
|
385
|
-
import { z as z12 } from "zod";
|
|
386
|
-
var QueueOperationEntrySchema = z12.union([
|
|
387
|
-
z12.object({
|
|
388
|
-
type: z12.literal("queue-operation"),
|
|
389
|
-
operation: z12.literal("enqueue"),
|
|
390
|
-
content: z12.string(),
|
|
391
|
-
sessionId: z12.string(),
|
|
392
|
-
timestamp: z12.iso.datetime()
|
|
393
|
-
}),
|
|
394
|
-
z12.object({
|
|
395
|
-
type: z12.literal("queue-operation"),
|
|
396
|
-
operation: z12.literal("dequeue"),
|
|
397
|
-
sessionId: z12.string(),
|
|
398
|
-
timestamp: z12.iso.datetime()
|
|
399
|
-
})
|
|
400
|
-
]);
|
|
401
|
-
|
|
402
|
-
// src/lib/conversation-schema/entry/SummaryEntrySchema.ts
|
|
403
|
-
import { z as z13 } from "zod";
|
|
404
|
-
var SummaryEntrySchema = z13.object({
|
|
405
|
-
type: z13.literal("summary"),
|
|
406
|
-
summary: z13.string(),
|
|
407
|
-
leafUuid: z13.string().uuid()
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
// src/lib/conversation-schema/entry/SystemEntrySchema.ts
|
|
411
|
-
import { z as z14 } from "zod";
|
|
412
|
-
var SystemEntrySchema = BaseEntrySchema.extend({
|
|
413
|
-
// discriminator
|
|
414
|
-
type: z14.literal("system"),
|
|
415
|
-
// required
|
|
416
|
-
content: z14.string(),
|
|
417
|
-
toolUseID: z14.string(),
|
|
418
|
-
level: z14.enum(["info"])
|
|
419
|
-
});
|
|
420
|
-
|
|
421
|
-
// src/lib/conversation-schema/entry/UserEntrySchema.ts
|
|
422
|
-
import { z as z17 } from "zod";
|
|
423
|
-
|
|
424
|
-
// src/lib/conversation-schema/message/UserMessageSchema.ts
|
|
425
|
-
import { z as z16 } from "zod";
|
|
426
|
-
|
|
427
|
-
// src/lib/conversation-schema/content/DocumentContentSchema.ts
|
|
428
|
-
import { z as z15 } from "zod";
|
|
429
|
-
var DocumentContentSchema = z15.object({
|
|
430
|
-
type: z15.literal("document"),
|
|
431
|
-
source: z15.union([
|
|
432
|
-
z15.object({
|
|
433
|
-
media_type: z15.literal("text/plain"),
|
|
434
|
-
type: z15.literal("text"),
|
|
435
|
-
data: z15.string()
|
|
436
|
-
}),
|
|
437
|
-
z15.object({
|
|
438
|
-
media_type: z15.enum(["application/pdf"]),
|
|
439
|
-
type: z15.literal("base64"),
|
|
440
|
-
data: z15.string()
|
|
441
|
-
})
|
|
442
|
-
])
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
// src/lib/conversation-schema/message/UserMessageSchema.ts
|
|
446
|
-
var UserMessageContentSchema = z16.union([
|
|
447
|
-
z16.string(),
|
|
448
|
-
TextContentSchema,
|
|
449
|
-
ToolResultContentSchema,
|
|
450
|
-
ImageContentSchema,
|
|
451
|
-
DocumentContentSchema
|
|
452
|
-
]);
|
|
453
|
-
var UserMessageSchema = z16.object({
|
|
454
|
-
role: z16.literal("user"),
|
|
455
|
-
content: z16.union([
|
|
456
|
-
z16.string(),
|
|
457
|
-
z16.array(z16.union([z16.string(), UserMessageContentSchema]))
|
|
458
|
-
])
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
// src/lib/conversation-schema/entry/UserEntrySchema.ts
|
|
462
|
-
var UserEntrySchema = BaseEntrySchema.extend({
|
|
463
|
-
// discriminator
|
|
464
|
-
type: z17.literal("user"),
|
|
465
|
-
// required
|
|
466
|
-
message: UserMessageSchema
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
// src/lib/conversation-schema/index.ts
|
|
470
|
-
var ConversationSchema = z18.union([
|
|
471
|
-
UserEntrySchema,
|
|
472
|
-
AssistantEntrySchema,
|
|
473
|
-
SummaryEntrySchema,
|
|
474
|
-
SystemEntrySchema,
|
|
475
|
-
FileHistorySnapshotEntrySchema,
|
|
476
|
-
QueueOperationEntrySchema
|
|
477
|
-
]);
|
|
478
|
-
|
|
479
|
-
// src/server/core/claude-code/functions/parseJsonl.ts
|
|
480
|
-
var parseJsonl = (content) => {
|
|
481
|
-
const lines = content.trim().split("\n").filter((line) => line.trim() !== "");
|
|
482
|
-
return lines.map((line, index) => {
|
|
483
|
-
const parsed = ConversationSchema.safeParse(JSON.parse(line));
|
|
484
|
-
if (!parsed.success) {
|
|
485
|
-
const errorData = {
|
|
486
|
-
type: "x-error",
|
|
487
|
-
line,
|
|
488
|
-
lineNumber: index + 1
|
|
489
|
-
};
|
|
490
|
-
return errorData;
|
|
491
|
-
}
|
|
492
|
-
return parsed.data;
|
|
493
|
-
});
|
|
494
|
-
};
|
|
495
|
-
|
|
496
582
|
// src/server/core/project/services/ProjectMetaService.ts
|
|
497
583
|
var ProjectPathSchema = z19.string().nullable();
|
|
498
|
-
var
|
|
499
|
-
const fs = yield*
|
|
500
|
-
const path = yield*
|
|
584
|
+
var LayerImpl6 = Effect7.gen(function* () {
|
|
585
|
+
const fs = yield* FileSystem3.FileSystem;
|
|
586
|
+
const path = yield* Path4.Path;
|
|
501
587
|
const projectPathCache = yield* FileCacheStorage();
|
|
502
588
|
const projectMetaCacheRef = yield* Ref3.make(/* @__PURE__ */ new Map());
|
|
503
|
-
const extractProjectPathFromJsonl = (filePath) =>
|
|
589
|
+
const extractProjectPathFromJsonl = (filePath) => Effect7.gen(function* () {
|
|
504
590
|
const cached = yield* projectPathCache.get(filePath);
|
|
505
591
|
if (cached !== void 0) {
|
|
506
592
|
return cached;
|
|
@@ -521,7 +607,7 @@ var LayerImpl4 = Effect5.gen(function* () {
|
|
|
521
607
|
}
|
|
522
608
|
return cwd;
|
|
523
609
|
});
|
|
524
|
-
const getProjectMeta = (projectId) =>
|
|
610
|
+
const getProjectMeta = (projectId) => Effect7.gen(function* () {
|
|
525
611
|
const metaCache = yield* Ref3.get(projectMetaCacheRef);
|
|
526
612
|
const cached = metaCache.get(projectId);
|
|
527
613
|
if (cached !== void 0) {
|
|
@@ -529,9 +615,9 @@ var LayerImpl4 = Effect5.gen(function* () {
|
|
|
529
615
|
}
|
|
530
616
|
const claudeProjectPath = decodeProjectId(projectId);
|
|
531
617
|
const dirents = yield* fs.readDirectory(claudeProjectPath);
|
|
532
|
-
const fileEntries = yield*
|
|
618
|
+
const fileEntries = yield* Effect7.all(
|
|
533
619
|
dirents.filter((name) => name.endsWith(".jsonl")).map(
|
|
534
|
-
(name) =>
|
|
620
|
+
(name) => Effect7.gen(function* () {
|
|
535
621
|
const fullPath = path.resolve(claudeProjectPath, name);
|
|
536
622
|
const stat = yield* fs.stat(fullPath);
|
|
537
623
|
const mtime = Option.getOrElse(stat.mtime, () => /* @__PURE__ */ new Date(0));
|
|
@@ -565,7 +651,7 @@ var LayerImpl4 = Effect5.gen(function* () {
|
|
|
565
651
|
});
|
|
566
652
|
return projectMeta;
|
|
567
653
|
});
|
|
568
|
-
const invalidateProject = (projectId) =>
|
|
654
|
+
const invalidateProject = (projectId) => Effect7.gen(function* () {
|
|
569
655
|
yield* Ref3.update(projectMetaCacheRef, (cache) => {
|
|
570
656
|
cache.delete(projectId);
|
|
571
657
|
return cache;
|
|
@@ -576,28 +662,28 @@ var LayerImpl4 = Effect5.gen(function* () {
|
|
|
576
662
|
invalidateProject
|
|
577
663
|
};
|
|
578
664
|
});
|
|
579
|
-
var ProjectMetaService = class extends
|
|
665
|
+
var ProjectMetaService = class extends Context6.Tag("ProjectMetaService")() {
|
|
580
666
|
static {
|
|
581
|
-
this.Live =
|
|
582
|
-
|
|
667
|
+
this.Live = Layer8.effect(this, LayerImpl6).pipe(
|
|
668
|
+
Layer8.provide(
|
|
583
669
|
makeFileCacheStorageLayer("project-path-cache", ProjectPathSchema)
|
|
584
670
|
),
|
|
585
|
-
|
|
671
|
+
Layer8.provide(PersistentService.Live)
|
|
586
672
|
);
|
|
587
673
|
}
|
|
588
674
|
};
|
|
589
675
|
|
|
590
676
|
// src/server/core/project/infrastructure/ProjectRepository.ts
|
|
591
|
-
var
|
|
592
|
-
const fs = yield*
|
|
593
|
-
const path = yield*
|
|
677
|
+
var LayerImpl7 = Effect8.gen(function* () {
|
|
678
|
+
const fs = yield* FileSystem4.FileSystem;
|
|
679
|
+
const path = yield* Path5.Path;
|
|
594
680
|
const projectMetaService = yield* ProjectMetaService;
|
|
595
681
|
const context = yield* ApplicationContext;
|
|
596
|
-
const getProject = (projectId) =>
|
|
682
|
+
const getProject = (projectId) => Effect8.gen(function* () {
|
|
597
683
|
const fullPath = decodeProjectId(projectId);
|
|
598
684
|
const exists = yield* fs.exists(fullPath);
|
|
599
685
|
if (!exists) {
|
|
600
|
-
return yield*
|
|
686
|
+
return yield* Effect8.fail(new Error("Project not found"));
|
|
601
687
|
}
|
|
602
688
|
const stat = yield* fs.stat(fullPath);
|
|
603
689
|
const meta = yield* projectMetaService.getProjectMeta(projectId);
|
|
@@ -610,7 +696,7 @@ var LayerImpl5 = Effect6.gen(function* () {
|
|
|
610
696
|
}
|
|
611
697
|
};
|
|
612
698
|
});
|
|
613
|
-
const getProjects = () =>
|
|
699
|
+
const getProjects = () => Effect8.gen(function* () {
|
|
614
700
|
const dirExists = yield* fs.exists(
|
|
615
701
|
context.claudeCodePaths.claudeProjectsDirPath
|
|
616
702
|
);
|
|
@@ -624,14 +710,14 @@ var LayerImpl5 = Effect6.gen(function* () {
|
|
|
624
710
|
context.claudeCodePaths.claudeProjectsDirPath
|
|
625
711
|
);
|
|
626
712
|
const projectEffects = entries.map(
|
|
627
|
-
(entry) =>
|
|
713
|
+
(entry) => Effect8.gen(function* () {
|
|
628
714
|
const fullPath = path.resolve(
|
|
629
715
|
context.claudeCodePaths.claudeProjectsDirPath,
|
|
630
716
|
entry
|
|
631
717
|
);
|
|
632
|
-
const stat = yield*
|
|
633
|
-
() => fs.stat(fullPath).pipe(
|
|
634
|
-
).pipe(
|
|
718
|
+
const stat = yield* Effect8.tryPromise(
|
|
719
|
+
() => fs.stat(fullPath).pipe(Effect8.runPromise)
|
|
720
|
+
).pipe(Effect8.catchAll(() => Effect8.succeed(null)));
|
|
635
721
|
if (!stat || stat.type !== "Directory") {
|
|
636
722
|
return null;
|
|
637
723
|
}
|
|
@@ -645,7 +731,7 @@ var LayerImpl5 = Effect6.gen(function* () {
|
|
|
645
731
|
};
|
|
646
732
|
})
|
|
647
733
|
);
|
|
648
|
-
const projectsWithNulls = yield*
|
|
734
|
+
const projectsWithNulls = yield* Effect8.all(projectEffects, {
|
|
649
735
|
concurrency: "unbounded"
|
|
650
736
|
});
|
|
651
737
|
const projects = projectsWithNulls.filter(
|
|
@@ -661,12 +747,57 @@ var LayerImpl5 = Effect6.gen(function* () {
|
|
|
661
747
|
getProjects
|
|
662
748
|
};
|
|
663
749
|
});
|
|
664
|
-
var ProjectRepository = class extends
|
|
750
|
+
var ProjectRepository = class extends Context7.Tag("ProjectRepository")() {
|
|
665
751
|
static {
|
|
666
|
-
this.Live =
|
|
752
|
+
this.Live = Layer9.effect(this, LayerImpl7);
|
|
667
753
|
}
|
|
668
754
|
};
|
|
669
755
|
|
|
756
|
+
// src/server/core/claude-code/functions/scanCommandFiles.ts
|
|
757
|
+
import { FileSystem as FileSystem5, Path as Path6 } from "@effect/platform";
|
|
758
|
+
import { Effect as Effect9 } from "effect";
|
|
759
|
+
var pathToCommandName = (filePath, baseDir) => {
|
|
760
|
+
const normalizedBaseDir = baseDir.endsWith("/") ? baseDir.slice(0, -1) : baseDir;
|
|
761
|
+
const relativePath = filePath.startsWith(normalizedBaseDir) ? filePath.slice(normalizedBaseDir.length + 1) : filePath;
|
|
762
|
+
return relativePath.replace(/\.md$/, "").replace(/\//g, ":");
|
|
763
|
+
};
|
|
764
|
+
var scanCommandFilesRecursively = (dirPath) => Effect9.gen(function* () {
|
|
765
|
+
const fs = yield* FileSystem5.FileSystem;
|
|
766
|
+
const path = yield* Path6.Path;
|
|
767
|
+
const scanDirectory = (currentPath) => Effect9.gen(function* () {
|
|
768
|
+
const exists = yield* fs.exists(currentPath);
|
|
769
|
+
if (!exists) {
|
|
770
|
+
return [];
|
|
771
|
+
}
|
|
772
|
+
const items = yield* fs.readDirectory(currentPath);
|
|
773
|
+
const results = yield* Effect9.forEach(
|
|
774
|
+
items,
|
|
775
|
+
(item) => Effect9.gen(function* () {
|
|
776
|
+
if (item.startsWith(".")) {
|
|
777
|
+
return [];
|
|
778
|
+
}
|
|
779
|
+
const itemPath = path.join(currentPath, item);
|
|
780
|
+
const info = yield* fs.stat(itemPath);
|
|
781
|
+
if (info.type === "Directory") {
|
|
782
|
+
return yield* scanDirectory(itemPath);
|
|
783
|
+
}
|
|
784
|
+
if (info.type === "File" && item.endsWith(".md")) {
|
|
785
|
+
return [pathToCommandName(itemPath, dirPath)];
|
|
786
|
+
}
|
|
787
|
+
return [];
|
|
788
|
+
}),
|
|
789
|
+
{ concurrency: "unbounded" }
|
|
790
|
+
);
|
|
791
|
+
return results.flat();
|
|
792
|
+
});
|
|
793
|
+
return yield* scanDirectory(dirPath).pipe(
|
|
794
|
+
Effect9.match({
|
|
795
|
+
onSuccess: (items) => items,
|
|
796
|
+
onFailure: () => []
|
|
797
|
+
})
|
|
798
|
+
);
|
|
799
|
+
});
|
|
800
|
+
|
|
670
801
|
// src/server/core/claude-code/models/ClaudeCodeVersion.ts
|
|
671
802
|
import { z as z20 } from "zod";
|
|
672
803
|
var versionRegex = /^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/;
|
|
@@ -694,7 +825,7 @@ var greaterThan = (a, b) => a.major > b.major || a.major === b.major && (a.minor
|
|
|
694
825
|
var greaterThanOrEqual = (a, b) => equals(a, b) || greaterThan(a, b);
|
|
695
826
|
|
|
696
827
|
// src/server/core/claude-code/services/ClaudeCodeService.ts
|
|
697
|
-
import { Context as
|
|
828
|
+
import { Context as Context8, Data as Data2, Effect as Effect11, Layer as Layer10 } from "effect";
|
|
698
829
|
|
|
699
830
|
// src/server/core/claude-code/functions/parseMcpListOutput.ts
|
|
700
831
|
var parseMcpListOutput = (output) => {
|
|
@@ -722,14 +853,14 @@ import { query as agentSdkQuery } from "@anthropic-ai/claude-agent-sdk";
|
|
|
722
853
|
import {
|
|
723
854
|
query as claudeCodeQuery
|
|
724
855
|
} from "@anthropic-ai/claude-code";
|
|
725
|
-
import { Command, Path as
|
|
726
|
-
import { Data, Effect as
|
|
856
|
+
import { Command, Path as Path7 } from "@effect/platform";
|
|
857
|
+
import { Data, Effect as Effect10 } from "effect";
|
|
727
858
|
var ClaudeCodePathNotFoundError = class extends Data.TaggedError(
|
|
728
859
|
"ClaudeCodePathNotFoundError"
|
|
729
860
|
) {
|
|
730
861
|
};
|
|
731
|
-
var resolveClaudeCodePath =
|
|
732
|
-
const path = yield*
|
|
862
|
+
var resolveClaudeCodePath = Effect10.gen(function* () {
|
|
863
|
+
const path = yield* Path7.Path;
|
|
733
864
|
const envService = yield* EnvService;
|
|
734
865
|
const specifiedExecutablePath = yield* envService.getEnv(
|
|
735
866
|
"CLAUDE_CODE_VIEWER_CC_EXECUTABLE_PATH"
|
|
@@ -746,15 +877,15 @@ var resolveClaudeCodePath = Effect7.gen(function* () {
|
|
|
746
877
|
Command.runInShell(true)
|
|
747
878
|
)
|
|
748
879
|
).pipe(
|
|
749
|
-
|
|
750
|
-
|
|
880
|
+
Effect10.map((output) => output.trim()),
|
|
881
|
+
Effect10.map((output) => output === "" ? null : output),
|
|
751
882
|
// 存在しない時、空文字になる模様
|
|
752
|
-
|
|
883
|
+
Effect10.catchAll(() => Effect10.succeed(null))
|
|
753
884
|
);
|
|
754
885
|
if (whichClaude !== null) {
|
|
755
886
|
return whichClaude;
|
|
756
887
|
}
|
|
757
|
-
const projectClaudeCode = yield*
|
|
888
|
+
const projectClaudeCode = yield* Effect10.try(() => {
|
|
758
889
|
const parts = __dirname.split("/");
|
|
759
890
|
const packagePath = parts.slice(0, parts.indexOf("claude-code-viewer") + 1).join("/");
|
|
760
891
|
return path.join(
|
|
@@ -765,8 +896,8 @@ var resolveClaudeCodePath = Effect7.gen(function* () {
|
|
|
765
896
|
"cli.js"
|
|
766
897
|
);
|
|
767
898
|
}).pipe(
|
|
768
|
-
|
|
769
|
-
return
|
|
899
|
+
Effect10.catchAll(() => {
|
|
900
|
+
return Effect10.fail(
|
|
770
901
|
new ClaudeCodePathNotFoundError({
|
|
771
902
|
message: "Claude Code CLI not found in any location"
|
|
772
903
|
})
|
|
@@ -775,7 +906,7 @@ var resolveClaudeCodePath = Effect7.gen(function* () {
|
|
|
775
906
|
);
|
|
776
907
|
return projectClaudeCode;
|
|
777
908
|
});
|
|
778
|
-
var Config =
|
|
909
|
+
var Config = Effect10.gen(function* () {
|
|
779
910
|
const claudeCodeExecutablePath = yield* resolveClaudeCodePath;
|
|
780
911
|
const claudeCodeVersion = fromCLIString(
|
|
781
912
|
yield* Command.string(Command.make(claudeCodeExecutablePath, "--version"))
|
|
@@ -785,7 +916,7 @@ var Config = Effect7.gen(function* () {
|
|
|
785
916
|
claudeCodeVersion
|
|
786
917
|
};
|
|
787
918
|
});
|
|
788
|
-
var getMcpListOutput = (projectCwd) =>
|
|
919
|
+
var getMcpListOutput = (projectCwd) => Effect10.gen(function* () {
|
|
789
920
|
const { claudeCodeExecutablePath } = yield* Config;
|
|
790
921
|
const output = yield* Command.string(
|
|
791
922
|
Command.make(
|
|
@@ -815,11 +946,17 @@ var getAvailableFeatures = (claudeCodeVersion) => ({
|
|
|
815
946
|
minor: 0,
|
|
816
947
|
patch: 125
|
|
817
948
|
// ClaudeCodeAgentSDK is available since v1.0.125
|
|
949
|
+
}) : false,
|
|
950
|
+
sidechainSeparation: claudeCodeVersion !== null ? greaterThanOrEqual(claudeCodeVersion, {
|
|
951
|
+
major: 2,
|
|
952
|
+
minor: 0,
|
|
953
|
+
patch: 28
|
|
954
|
+
// Sidechain conversations stored in agent-*.jsonl since v2.0.28
|
|
818
955
|
}) : false
|
|
819
956
|
});
|
|
820
957
|
var query = (prompt, options) => {
|
|
821
958
|
const { canUseTool, permissionMode, ...baseOptions } = options;
|
|
822
|
-
return
|
|
959
|
+
return Effect10.gen(function* () {
|
|
823
960
|
const { claudeCodeExecutablePath, claudeCodeVersion } = yield* Config;
|
|
824
961
|
const availableFeatures = getAvailableFeatures(claudeCodeVersion);
|
|
825
962
|
const options2 = {
|
|
@@ -869,23 +1006,23 @@ var ProjectPathNotFoundError = class extends Data2.TaggedError(
|
|
|
869
1006
|
"ProjectPathNotFoundError"
|
|
870
1007
|
) {
|
|
871
1008
|
};
|
|
872
|
-
var
|
|
1009
|
+
var LayerImpl8 = Effect11.gen(function* () {
|
|
873
1010
|
const projectRepository = yield* ProjectRepository;
|
|
874
|
-
const getClaudeCodeMeta = () =>
|
|
1011
|
+
const getClaudeCodeMeta = () => Effect11.gen(function* () {
|
|
875
1012
|
const config = yield* Config;
|
|
876
1013
|
return config;
|
|
877
1014
|
});
|
|
878
|
-
const getAvailableFeatures2 = () =>
|
|
1015
|
+
const getAvailableFeatures2 = () => Effect11.gen(function* () {
|
|
879
1016
|
const config = yield* Config;
|
|
880
1017
|
const features = getAvailableFeatures(
|
|
881
1018
|
config.claudeCodeVersion
|
|
882
1019
|
);
|
|
883
1020
|
return features;
|
|
884
1021
|
});
|
|
885
|
-
const getMcpList = (projectId) =>
|
|
1022
|
+
const getMcpList = (projectId) => Effect11.gen(function* () {
|
|
886
1023
|
const { project } = yield* projectRepository.getProject(projectId);
|
|
887
1024
|
if (project.meta.projectPath === null) {
|
|
888
|
-
return yield*
|
|
1025
|
+
return yield* Effect11.fail(new ProjectPathNotFoundError({ projectId }));
|
|
889
1026
|
}
|
|
890
1027
|
const output = yield* getMcpListOutput(
|
|
891
1028
|
project.meta.projectPath
|
|
@@ -898,47 +1035,27 @@ var LayerImpl6 = Effect8.gen(function* () {
|
|
|
898
1035
|
getAvailableFeatures: getAvailableFeatures2
|
|
899
1036
|
};
|
|
900
1037
|
});
|
|
901
|
-
var ClaudeCodeService = class extends
|
|
1038
|
+
var ClaudeCodeService = class extends Context8.Tag("ClaudeCodeService")() {
|
|
902
1039
|
static {
|
|
903
|
-
this.Live =
|
|
1040
|
+
this.Live = Layer10.effect(this, LayerImpl8);
|
|
904
1041
|
}
|
|
905
1042
|
};
|
|
906
1043
|
|
|
907
1044
|
// src/server/core/claude-code/presentation/ClaudeCodeController.ts
|
|
908
|
-
var
|
|
1045
|
+
var LayerImpl9 = Effect12.gen(function* () {
|
|
909
1046
|
const projectRepository = yield* ProjectRepository;
|
|
910
1047
|
const claudeCodeService = yield* ClaudeCodeService;
|
|
911
1048
|
const context = yield* ApplicationContext;
|
|
912
|
-
|
|
913
|
-
const path = yield*
|
|
914
|
-
const getClaudeCommands = (options) =>
|
|
1049
|
+
yield* FileSystem6.FileSystem;
|
|
1050
|
+
const path = yield* Path8.Path;
|
|
1051
|
+
const getClaudeCommands = (options) => Effect12.gen(function* () {
|
|
915
1052
|
const { projectId } = options;
|
|
916
1053
|
const { project } = yield* projectRepository.getProject(projectId);
|
|
917
|
-
const globalCommands = yield*
|
|
918
|
-
|
|
919
|
-
(items) => items.filter((item) => item.endsWith(".md")).map((item) => item.replace(/\.md$/, ""))
|
|
920
|
-
)
|
|
921
|
-
).pipe(
|
|
922
|
-
Effect9.match({
|
|
923
|
-
onSuccess: (items) => items,
|
|
924
|
-
onFailure: () => {
|
|
925
|
-
return [];
|
|
926
|
-
}
|
|
927
|
-
})
|
|
1054
|
+
const globalCommands = yield* scanCommandFilesRecursively(
|
|
1055
|
+
context.claudeCodePaths.claudeCommandsDirPath
|
|
928
1056
|
);
|
|
929
|
-
const projectCommands = project.meta.projectPath === null ? [] : yield*
|
|
1057
|
+
const projectCommands = project.meta.projectPath === null ? [] : yield* scanCommandFilesRecursively(
|
|
930
1058
|
path.resolve(project.meta.projectPath, ".claude", "commands")
|
|
931
|
-
).pipe(
|
|
932
|
-
Effect9.map(
|
|
933
|
-
(items) => items.filter((item) => item.endsWith(".md")).map((item) => item.replace(/\.md$/, ""))
|
|
934
|
-
)
|
|
935
|
-
).pipe(
|
|
936
|
-
Effect9.match({
|
|
937
|
-
onSuccess: (items) => items,
|
|
938
|
-
onFailure: () => {
|
|
939
|
-
return [];
|
|
940
|
-
}
|
|
941
|
-
})
|
|
942
1059
|
);
|
|
943
1060
|
return {
|
|
944
1061
|
response: {
|
|
@@ -949,7 +1066,7 @@ var LayerImpl7 = Effect9.gen(function* () {
|
|
|
949
1066
|
status: 200
|
|
950
1067
|
};
|
|
951
1068
|
});
|
|
952
|
-
const getMcpListRoute = (options) =>
|
|
1069
|
+
const getMcpListRoute = (options) => Effect12.gen(function* () {
|
|
953
1070
|
const { projectId } = options;
|
|
954
1071
|
const servers = yield* claudeCodeService.getMcpList(projectId);
|
|
955
1072
|
return {
|
|
@@ -957,7 +1074,7 @@ var LayerImpl7 = Effect9.gen(function* () {
|
|
|
957
1074
|
status: 200
|
|
958
1075
|
};
|
|
959
1076
|
});
|
|
960
|
-
const getClaudeCodeMeta = () =>
|
|
1077
|
+
const getClaudeCodeMeta = () => Effect12.gen(function* () {
|
|
961
1078
|
const config = yield* claudeCodeService.getClaudeCodeMeta();
|
|
962
1079
|
return {
|
|
963
1080
|
response: {
|
|
@@ -967,7 +1084,7 @@ var LayerImpl7 = Effect9.gen(function* () {
|
|
|
967
1084
|
status: 200
|
|
968
1085
|
};
|
|
969
1086
|
});
|
|
970
|
-
const getAvailableFeatures2 = () =>
|
|
1087
|
+
const getAvailableFeatures2 = () => Effect12.gen(function* () {
|
|
971
1088
|
const features = yield* claudeCodeService.getAvailableFeatures();
|
|
972
1089
|
const featuresList = Object.entries(features).flatMap(([key, value]) => {
|
|
973
1090
|
return [
|
|
@@ -989,22 +1106,22 @@ var LayerImpl7 = Effect9.gen(function* () {
|
|
|
989
1106
|
getAvailableFeatures: getAvailableFeatures2
|
|
990
1107
|
};
|
|
991
1108
|
});
|
|
992
|
-
var ClaudeCodeController = class extends
|
|
1109
|
+
var ClaudeCodeController = class extends Context9.Tag("ClaudeCodeController")() {
|
|
993
1110
|
static {
|
|
994
|
-
this.Live =
|
|
1111
|
+
this.Live = Layer11.effect(this, LayerImpl9);
|
|
995
1112
|
}
|
|
996
1113
|
};
|
|
997
1114
|
|
|
998
1115
|
// src/server/core/claude-code/presentation/ClaudeCodePermissionController.ts
|
|
999
|
-
import { Context as
|
|
1116
|
+
import { Context as Context12, Effect as Effect15, Layer as Layer14 } from "effect";
|
|
1000
1117
|
|
|
1001
1118
|
// src/server/core/claude-code/services/ClaudeCodePermissionService.ts
|
|
1002
|
-
import { Context as
|
|
1119
|
+
import { Context as Context11, Effect as Effect14, Layer as Layer13, Ref as Ref4 } from "effect";
|
|
1003
1120
|
import { ulid } from "ulid";
|
|
1004
1121
|
|
|
1005
1122
|
// src/server/core/events/services/EventBus.ts
|
|
1006
|
-
import { Context as
|
|
1007
|
-
var layerImpl =
|
|
1123
|
+
import { Context as Context10, Effect as Effect13, Layer as Layer12 } from "effect";
|
|
1124
|
+
var layerImpl = Effect13.gen(function* () {
|
|
1008
1125
|
const listenersMap = /* @__PURE__ */ new Map();
|
|
1009
1126
|
const getListeners = (event) => {
|
|
1010
1127
|
if (!listenersMap.has(event)) {
|
|
@@ -1012,7 +1129,7 @@ var layerImpl = Effect10.gen(function* () {
|
|
|
1012
1129
|
}
|
|
1013
1130
|
return listenersMap.get(event);
|
|
1014
1131
|
};
|
|
1015
|
-
const emit = (event, data) =>
|
|
1132
|
+
const emit = (event, data) => Effect13.gen(function* () {
|
|
1016
1133
|
const listeners = getListeners(event);
|
|
1017
1134
|
void Promise.allSettled(
|
|
1018
1135
|
Array.from(listeners).map(async (listener) => {
|
|
@@ -1020,11 +1137,11 @@ var layerImpl = Effect10.gen(function* () {
|
|
|
1020
1137
|
})
|
|
1021
1138
|
);
|
|
1022
1139
|
});
|
|
1023
|
-
const on = (event, listener) =>
|
|
1140
|
+
const on = (event, listener) => Effect13.sync(() => {
|
|
1024
1141
|
const listeners = getListeners(event);
|
|
1025
1142
|
listeners.add(listener);
|
|
1026
1143
|
});
|
|
1027
|
-
const off = (event, listener) =>
|
|
1144
|
+
const off = (event, listener) => Effect13.sync(() => {
|
|
1028
1145
|
const listeners = getListeners(event);
|
|
1029
1146
|
listeners.delete(listener);
|
|
1030
1147
|
});
|
|
@@ -1034,18 +1151,18 @@ var layerImpl = Effect10.gen(function* () {
|
|
|
1034
1151
|
off
|
|
1035
1152
|
};
|
|
1036
1153
|
});
|
|
1037
|
-
var EventBus = class extends
|
|
1154
|
+
var EventBus = class extends Context10.Tag("EventBus")() {
|
|
1038
1155
|
static {
|
|
1039
|
-
this.Live =
|
|
1156
|
+
this.Live = Layer12.effect(this, layerImpl);
|
|
1040
1157
|
}
|
|
1041
1158
|
};
|
|
1042
1159
|
|
|
1043
1160
|
// src/server/core/claude-code/services/ClaudeCodePermissionService.ts
|
|
1044
|
-
var
|
|
1161
|
+
var LayerImpl10 = Effect14.gen(function* () {
|
|
1045
1162
|
const pendingPermissionRequestsRef = yield* Ref4.make(/* @__PURE__ */ new Map());
|
|
1046
1163
|
const permissionResponsesRef = yield* Ref4.make(/* @__PURE__ */ new Map());
|
|
1047
1164
|
const eventBus = yield* EventBus;
|
|
1048
|
-
const waitPermissionResponse = (request, options) =>
|
|
1165
|
+
const waitPermissionResponse = (request, options) => Effect14.gen(function* () {
|
|
1049
1166
|
yield* Ref4.update(pendingPermissionRequestsRef, (requests) => {
|
|
1050
1167
|
requests.set(request.id, request);
|
|
1051
1168
|
return requests;
|
|
@@ -1061,14 +1178,14 @@ var LayerImpl8 = Effect11.gen(function* () {
|
|
|
1061
1178
|
if (response !== null) {
|
|
1062
1179
|
break;
|
|
1063
1180
|
}
|
|
1064
|
-
yield*
|
|
1181
|
+
yield* Effect14.sleep(1e3);
|
|
1065
1182
|
passedMs += 1e3;
|
|
1066
1183
|
}
|
|
1067
1184
|
return response;
|
|
1068
1185
|
});
|
|
1069
1186
|
const createCanUseToolRelatedOptions = (options) => {
|
|
1070
1187
|
const { taskId, userConfig, sessionId } = options;
|
|
1071
|
-
return
|
|
1188
|
+
return Effect14.gen(function* () {
|
|
1072
1189
|
const claudeCodeConfig = yield* Config;
|
|
1073
1190
|
if (!getAvailableFeatures(claudeCodeConfig.claudeCodeVersion).canUseTool) {
|
|
1074
1191
|
return {
|
|
@@ -1097,7 +1214,7 @@ var LayerImpl8 = Effect11.gen(function* () {
|
|
|
1097
1214
|
toolInput,
|
|
1098
1215
|
timestamp: Date.now()
|
|
1099
1216
|
};
|
|
1100
|
-
const response = await
|
|
1217
|
+
const response = await Effect14.runPromise(
|
|
1101
1218
|
waitPermissionResponse(permissionRequest, { timeoutMs: 6e4 })
|
|
1102
1219
|
);
|
|
1103
1220
|
if (response === null) {
|
|
@@ -1124,7 +1241,7 @@ var LayerImpl8 = Effect11.gen(function* () {
|
|
|
1124
1241
|
};
|
|
1125
1242
|
});
|
|
1126
1243
|
};
|
|
1127
|
-
const respondToPermissionRequest = (response) =>
|
|
1244
|
+
const respondToPermissionRequest = (response) => Effect14.gen(function* () {
|
|
1128
1245
|
yield* Ref4.update(permissionResponsesRef, (responses) => {
|
|
1129
1246
|
responses.set(response.permissionRequestId, response);
|
|
1130
1247
|
return responses;
|
|
@@ -1139,20 +1256,20 @@ var LayerImpl8 = Effect11.gen(function* () {
|
|
|
1139
1256
|
respondToPermissionRequest
|
|
1140
1257
|
};
|
|
1141
1258
|
});
|
|
1142
|
-
var ClaudeCodePermissionService = class extends
|
|
1259
|
+
var ClaudeCodePermissionService = class extends Context11.Tag(
|
|
1143
1260
|
"ClaudeCodePermissionService"
|
|
1144
1261
|
)() {
|
|
1145
1262
|
static {
|
|
1146
|
-
this.Live =
|
|
1263
|
+
this.Live = Layer13.effect(this, LayerImpl10);
|
|
1147
1264
|
}
|
|
1148
1265
|
};
|
|
1149
1266
|
|
|
1150
1267
|
// src/server/core/claude-code/presentation/ClaudeCodePermissionController.ts
|
|
1151
|
-
var
|
|
1268
|
+
var LayerImpl11 = Effect15.gen(function* () {
|
|
1152
1269
|
const claudeCodePermissionService = yield* ClaudeCodePermissionService;
|
|
1153
|
-
const permissionResponse = (options) =>
|
|
1270
|
+
const permissionResponse = (options) => Effect15.sync(() => {
|
|
1154
1271
|
const { permissionResponse: permissionResponse2 } = options;
|
|
1155
|
-
|
|
1272
|
+
Effect15.runFork(
|
|
1156
1273
|
claudeCodePermissionService.respondToPermissionRequest(
|
|
1157
1274
|
permissionResponse2
|
|
1158
1275
|
)
|
|
@@ -1168,19 +1285,19 @@ var LayerImpl9 = Effect12.gen(function* () {
|
|
|
1168
1285
|
permissionResponse
|
|
1169
1286
|
};
|
|
1170
1287
|
});
|
|
1171
|
-
var ClaudeCodePermissionController = class extends
|
|
1288
|
+
var ClaudeCodePermissionController = class extends Context12.Tag(
|
|
1172
1289
|
"ClaudeCodePermissionController"
|
|
1173
1290
|
)() {
|
|
1174
1291
|
static {
|
|
1175
|
-
this.Live =
|
|
1292
|
+
this.Live = Layer14.effect(this, LayerImpl11);
|
|
1176
1293
|
}
|
|
1177
1294
|
};
|
|
1178
1295
|
|
|
1179
1296
|
// src/server/core/claude-code/presentation/ClaudeCodeSessionProcessController.ts
|
|
1180
|
-
import { Context as
|
|
1297
|
+
import { Context as Context19, Effect as Effect23, Layer as Layer21 } from "effect";
|
|
1181
1298
|
|
|
1182
1299
|
// src/server/core/platform/services/UserConfigService.ts
|
|
1183
|
-
import { Context as
|
|
1300
|
+
import { Context as Context13, Effect as Effect16, Layer as Layer15, Ref as Ref5 } from "effect";
|
|
1184
1301
|
|
|
1185
1302
|
// src/lib/i18n/localeDetection.ts
|
|
1186
1303
|
var DEFAULT_LOCALE = "en";
|
|
@@ -1232,7 +1349,7 @@ var detectLocaleFromAcceptLanguage = (header) => {
|
|
|
1232
1349
|
};
|
|
1233
1350
|
|
|
1234
1351
|
// src/server/core/platform/services/UserConfigService.ts
|
|
1235
|
-
var
|
|
1352
|
+
var LayerImpl12 = Effect16.gen(function* () {
|
|
1236
1353
|
const configRef = yield* Ref5.make({
|
|
1237
1354
|
hideNoUserMessageSession: true,
|
|
1238
1355
|
unifySameTitleSession: false,
|
|
@@ -1241,10 +1358,10 @@ var LayerImpl10 = Effect13.gen(function* () {
|
|
|
1241
1358
|
locale: DEFAULT_LOCALE,
|
|
1242
1359
|
theme: "system"
|
|
1243
1360
|
});
|
|
1244
|
-
const setUserConfig = (newConfig) =>
|
|
1361
|
+
const setUserConfig = (newConfig) => Effect16.gen(function* () {
|
|
1245
1362
|
yield* Ref5.update(configRef, () => newConfig);
|
|
1246
1363
|
});
|
|
1247
|
-
const getUserConfig = () =>
|
|
1364
|
+
const getUserConfig = () => Effect16.gen(function* () {
|
|
1248
1365
|
const config = yield* Ref5.get(configRef);
|
|
1249
1366
|
return config;
|
|
1250
1367
|
});
|
|
@@ -1253,14 +1370,14 @@ var LayerImpl10 = Effect13.gen(function* () {
|
|
|
1253
1370
|
setUserConfig
|
|
1254
1371
|
};
|
|
1255
1372
|
});
|
|
1256
|
-
var UserConfigService = class extends
|
|
1373
|
+
var UserConfigService = class extends Context13.Tag("UserConfigService")() {
|
|
1257
1374
|
static {
|
|
1258
|
-
this.Live =
|
|
1375
|
+
this.Live = Layer15.effect(this, LayerImpl12);
|
|
1259
1376
|
}
|
|
1260
1377
|
};
|
|
1261
1378
|
|
|
1262
1379
|
// src/server/core/claude-code/services/ClaudeCodeLifeCycleService.ts
|
|
1263
|
-
import { Context as
|
|
1380
|
+
import { Context as Context18, Effect as Effect22, Layer as Layer20, Runtime as Runtime2 } from "effect";
|
|
1264
1381
|
import { ulid as ulid2 } from "ulid";
|
|
1265
1382
|
|
|
1266
1383
|
// src/lib/controllablePromise.ts
|
|
@@ -1290,8 +1407,8 @@ var controllablePromise = () => {
|
|
|
1290
1407
|
};
|
|
1291
1408
|
|
|
1292
1409
|
// src/server/core/session/infrastructure/SessionRepository.ts
|
|
1293
|
-
import { FileSystem as
|
|
1294
|
-
import { Context as
|
|
1410
|
+
import { FileSystem as FileSystem8, Path as Path9 } from "@effect/platform";
|
|
1411
|
+
import { Context as Context16, Effect as Effect19, Layer as Layer18, Option as Option3 } from "effect";
|
|
1295
1412
|
|
|
1296
1413
|
// src/server/core/claude-code/functions/parseUserMessage.ts
|
|
1297
1414
|
import { z as z21 } from "zod";
|
|
@@ -1367,29 +1484,32 @@ var decodeSessionId = (projectId, sessionId) => {
|
|
|
1367
1484
|
return resolve2(projectPath, `${sessionId}.jsonl`);
|
|
1368
1485
|
};
|
|
1369
1486
|
|
|
1487
|
+
// src/server/core/session/functions/isRegularSessionFile.ts
|
|
1488
|
+
var isRegularSessionFile = (filename) => filename.endsWith(".jsonl") && !filename.startsWith("agent-");
|
|
1489
|
+
|
|
1370
1490
|
// src/server/core/session/infrastructure/VirtualConversationDatabase.ts
|
|
1371
|
-
import { Context as
|
|
1372
|
-
var VirtualConversationDatabase = class extends
|
|
1491
|
+
import { Context as Context14, Effect as Effect17, Layer as Layer16, Ref as Ref6 } from "effect";
|
|
1492
|
+
var VirtualConversationDatabase = class extends Context14.Tag(
|
|
1373
1493
|
"VirtualConversationDatabase"
|
|
1374
1494
|
)() {
|
|
1375
1495
|
static {
|
|
1376
|
-
this.Live =
|
|
1496
|
+
this.Live = Layer16.effect(
|
|
1377
1497
|
this,
|
|
1378
|
-
|
|
1498
|
+
Effect17.gen(function* () {
|
|
1379
1499
|
const storageRef = yield* Ref6.make([]);
|
|
1380
|
-
const getProjectVirtualConversations = (projectId) =>
|
|
1500
|
+
const getProjectVirtualConversations = (projectId) => Effect17.gen(function* () {
|
|
1381
1501
|
const conversations = yield* Ref6.get(storageRef);
|
|
1382
1502
|
return conversations.filter(
|
|
1383
1503
|
(conversation) => conversation.projectId === projectId
|
|
1384
1504
|
);
|
|
1385
1505
|
});
|
|
1386
|
-
const getSessionVirtualConversation = (sessionId) =>
|
|
1506
|
+
const getSessionVirtualConversation = (sessionId) => Effect17.gen(function* () {
|
|
1387
1507
|
const conversations = yield* Ref6.get(storageRef);
|
|
1388
1508
|
return conversations.find(
|
|
1389
1509
|
(conversation) => conversation.sessionId === sessionId
|
|
1390
1510
|
) ?? null;
|
|
1391
1511
|
});
|
|
1392
|
-
const createVirtualConversation2 = (projectId, sessionId, createConversations) =>
|
|
1512
|
+
const createVirtualConversation2 = (projectId, sessionId, createConversations) => Effect17.gen(function* () {
|
|
1393
1513
|
yield* Ref6.update(storageRef, (conversations) => {
|
|
1394
1514
|
const existingRecord = conversations.find(
|
|
1395
1515
|
(record) => record.projectId === projectId && record.sessionId === sessionId
|
|
@@ -1408,7 +1528,7 @@ var VirtualConversationDatabase = class extends Context12.Tag(
|
|
|
1408
1528
|
return conversations;
|
|
1409
1529
|
});
|
|
1410
1530
|
});
|
|
1411
|
-
const deleteVirtualConversations = (sessionId) =>
|
|
1531
|
+
const deleteVirtualConversations = (sessionId) => Effect17.gen(function* () {
|
|
1412
1532
|
yield* Ref6.update(storageRef, (conversations) => {
|
|
1413
1533
|
return conversations.filter((c) => c.sessionId !== sessionId);
|
|
1414
1534
|
});
|
|
@@ -1425,8 +1545,8 @@ var VirtualConversationDatabase = class extends Context12.Tag(
|
|
|
1425
1545
|
};
|
|
1426
1546
|
|
|
1427
1547
|
// src/server/core/session/services/SessionMetaService.ts
|
|
1428
|
-
import { FileSystem as
|
|
1429
|
-
import { Context as
|
|
1548
|
+
import { FileSystem as FileSystem7 } from "@effect/platform";
|
|
1549
|
+
import { Context as Context15, Effect as Effect18, Layer as Layer17, Ref as Ref7 } from "effect";
|
|
1430
1550
|
|
|
1431
1551
|
// src/server/core/session/constants/pricing.ts
|
|
1432
1552
|
var MODEL_PRICING = {
|
|
@@ -1572,17 +1692,17 @@ var extractFirstUserMessage = (conversation) => {
|
|
|
1572
1692
|
|
|
1573
1693
|
// src/server/core/session/services/SessionMetaService.ts
|
|
1574
1694
|
var parsedUserMessageOrNullSchema = parsedUserMessageSchema.nullable();
|
|
1575
|
-
var SessionMetaService = class extends
|
|
1695
|
+
var SessionMetaService = class extends Context15.Tag("SessionMetaService")() {
|
|
1576
1696
|
static {
|
|
1577
|
-
this.Live =
|
|
1697
|
+
this.Live = Layer17.effect(
|
|
1578
1698
|
this,
|
|
1579
|
-
|
|
1580
|
-
const fs = yield*
|
|
1699
|
+
Effect18.gen(function* () {
|
|
1700
|
+
const fs = yield* FileSystem7.FileSystem;
|
|
1581
1701
|
const firstUserMessageCache = yield* FileCacheStorage();
|
|
1582
1702
|
const sessionMetaCacheRef = yield* Ref7.make(
|
|
1583
1703
|
/* @__PURE__ */ new Map()
|
|
1584
1704
|
);
|
|
1585
|
-
const getFirstUserMessage = (jsonlFilePath, lines) =>
|
|
1705
|
+
const getFirstUserMessage = (jsonlFilePath, lines) => Effect18.gen(function* () {
|
|
1586
1706
|
const cached = yield* firstUserMessageCache.get(jsonlFilePath);
|
|
1587
1707
|
if (cached !== void 0) {
|
|
1588
1708
|
return cached;
|
|
@@ -1667,7 +1787,7 @@ var SessionMetaService = class extends Context13.Tag("SessionMetaService")() {
|
|
|
1667
1787
|
modelName: lastModelName
|
|
1668
1788
|
};
|
|
1669
1789
|
};
|
|
1670
|
-
const getSessionMeta = (projectId, sessionId) =>
|
|
1790
|
+
const getSessionMeta = (projectId, sessionId) => Effect18.gen(function* () {
|
|
1671
1791
|
const metaCache = yield* Ref7.get(sessionMetaCacheRef);
|
|
1672
1792
|
const cached = metaCache.get(sessionId);
|
|
1673
1793
|
if (cached !== void 0) {
|
|
@@ -1696,7 +1816,7 @@ var SessionMetaService = class extends Context13.Tag("SessionMetaService")() {
|
|
|
1696
1816
|
});
|
|
1697
1817
|
return sessionMeta;
|
|
1698
1818
|
});
|
|
1699
|
-
const invalidateSession = (_projectId, sessionId) =>
|
|
1819
|
+
const invalidateSession = (_projectId, sessionId) => Effect18.gen(function* () {
|
|
1700
1820
|
yield* Ref7.update(sessionMetaCacheRef, (cache) => {
|
|
1701
1821
|
cache.delete(sessionId);
|
|
1702
1822
|
return cache;
|
|
@@ -1708,30 +1828,30 @@ var SessionMetaService = class extends Context13.Tag("SessionMetaService")() {
|
|
|
1708
1828
|
};
|
|
1709
1829
|
})
|
|
1710
1830
|
).pipe(
|
|
1711
|
-
|
|
1831
|
+
Layer17.provide(
|
|
1712
1832
|
makeFileCacheStorageLayer(
|
|
1713
1833
|
"first-user-message-cache",
|
|
1714
1834
|
parsedUserMessageOrNullSchema
|
|
1715
1835
|
)
|
|
1716
1836
|
),
|
|
1717
|
-
|
|
1837
|
+
Layer17.provide(PersistentService.Live)
|
|
1718
1838
|
);
|
|
1719
1839
|
}
|
|
1720
1840
|
};
|
|
1721
1841
|
|
|
1722
1842
|
// src/server/core/session/infrastructure/SessionRepository.ts
|
|
1723
|
-
var
|
|
1724
|
-
const fs = yield*
|
|
1725
|
-
const path = yield*
|
|
1843
|
+
var LayerImpl13 = Effect19.gen(function* () {
|
|
1844
|
+
const fs = yield* FileSystem8.FileSystem;
|
|
1845
|
+
const path = yield* Path9.Path;
|
|
1726
1846
|
const sessionMetaService = yield* SessionMetaService;
|
|
1727
1847
|
const virtualConversationDatabase = yield* VirtualConversationDatabase;
|
|
1728
|
-
const getSession = (projectId, sessionId) =>
|
|
1848
|
+
const getSession = (projectId, sessionId) => Effect19.gen(function* () {
|
|
1729
1849
|
const sessionPath = decodeSessionId(projectId, sessionId);
|
|
1730
1850
|
const virtualConversation = yield* virtualConversationDatabase.getSessionVirtualConversation(
|
|
1731
1851
|
sessionId
|
|
1732
1852
|
);
|
|
1733
1853
|
const exists = yield* fs.exists(sessionPath);
|
|
1734
|
-
const sessionDetail = yield* exists ?
|
|
1854
|
+
const sessionDetail = yield* exists ? Effect19.gen(function* () {
|
|
1735
1855
|
const content = yield* fs.readFileString(sessionPath);
|
|
1736
1856
|
const allLines = content.split("\n").filter((line) => line.trim());
|
|
1737
1857
|
const conversations = parseJsonl(allLines.join("\n"));
|
|
@@ -1769,7 +1889,7 @@ var LayerImpl11 = Effect16.gen(function* () {
|
|
|
1769
1889
|
return sessionDetail2;
|
|
1770
1890
|
}) : (() => {
|
|
1771
1891
|
if (virtualConversation === null) {
|
|
1772
|
-
return
|
|
1892
|
+
return Effect19.succeed(null);
|
|
1773
1893
|
}
|
|
1774
1894
|
const lastConversation = virtualConversation.conversations.filter(
|
|
1775
1895
|
(conversation) => conversation.type === "user" || conversation.type === "assistant" || conversation.type === "system"
|
|
@@ -1799,13 +1919,13 @@ var LayerImpl11 = Effect16.gen(function* () {
|
|
|
1799
1919
|
conversations: virtualConversation.conversations,
|
|
1800
1920
|
lastModifiedAt: lastConversation !== void 0 ? new Date(lastConversation.timestamp) : /* @__PURE__ */ new Date()
|
|
1801
1921
|
};
|
|
1802
|
-
return
|
|
1922
|
+
return Effect19.succeed(virtualSession);
|
|
1803
1923
|
})();
|
|
1804
1924
|
return {
|
|
1805
1925
|
session: sessionDetail
|
|
1806
1926
|
};
|
|
1807
1927
|
});
|
|
1808
|
-
const getSessions = (projectId, options) =>
|
|
1928
|
+
const getSessions = (projectId, options) => Effect19.gen(function* () {
|
|
1809
1929
|
const { maxCount = 20, cursor } = options ?? {};
|
|
1810
1930
|
const claudeProjectPath = decodeProjectId(projectId);
|
|
1811
1931
|
const dirExists = yield* fs.exists(claudeProjectPath);
|
|
@@ -1813,8 +1933,8 @@ var LayerImpl11 = Effect16.gen(function* () {
|
|
|
1813
1933
|
console.warn(`Project directory not found at ${claudeProjectPath}`);
|
|
1814
1934
|
return { sessions: [] };
|
|
1815
1935
|
}
|
|
1816
|
-
const dirents = yield*
|
|
1817
|
-
try: () => fs.readDirectory(claudeProjectPath).pipe(
|
|
1936
|
+
const dirents = yield* Effect19.tryPromise({
|
|
1937
|
+
try: () => fs.readDirectory(claudeProjectPath).pipe(Effect19.runPromise),
|
|
1818
1938
|
catch: (error) => {
|
|
1819
1939
|
console.warn(
|
|
1820
1940
|
`Failed to read sessions for project ${projectId}:`,
|
|
@@ -1822,14 +1942,14 @@ var LayerImpl11 = Effect16.gen(function* () {
|
|
|
1822
1942
|
);
|
|
1823
1943
|
return new Error("Failed to read directory");
|
|
1824
1944
|
}
|
|
1825
|
-
}).pipe(
|
|
1826
|
-
const sessionEffects = dirents.filter(
|
|
1827
|
-
(entry) =>
|
|
1945
|
+
}).pipe(Effect19.catchAll(() => Effect19.succeed([])));
|
|
1946
|
+
const sessionEffects = dirents.filter(isRegularSessionFile).map(
|
|
1947
|
+
(entry) => Effect19.gen(function* () {
|
|
1828
1948
|
const fullPath = path.resolve(claudeProjectPath, entry);
|
|
1829
1949
|
const sessionId = encodeSessionId(fullPath);
|
|
1830
|
-
const stat = yield*
|
|
1831
|
-
() => fs.stat(fullPath).pipe(
|
|
1832
|
-
).pipe(
|
|
1950
|
+
const stat = yield* Effect19.tryPromise(
|
|
1951
|
+
() => fs.stat(fullPath).pipe(Effect19.runPromise)
|
|
1952
|
+
).pipe(Effect19.catchAll(() => Effect19.succeed(null)));
|
|
1833
1953
|
if (!stat) {
|
|
1834
1954
|
return null;
|
|
1835
1955
|
}
|
|
@@ -1840,7 +1960,7 @@ var LayerImpl11 = Effect16.gen(function* () {
|
|
|
1840
1960
|
};
|
|
1841
1961
|
})
|
|
1842
1962
|
);
|
|
1843
|
-
const sessionsWithNulls = yield*
|
|
1963
|
+
const sessionsWithNulls = yield* Effect19.all(sessionEffects, {
|
|
1844
1964
|
concurrency: "unbounded"
|
|
1845
1965
|
});
|
|
1846
1966
|
const sessions = sessionsWithNulls.filter((s) => s !== null).sort(
|
|
@@ -1855,9 +1975,9 @@ var LayerImpl11 = Effect16.gen(function* () {
|
|
|
1855
1975
|
index + 1,
|
|
1856
1976
|
Math.min(index + 1 + maxCount, sessions.length)
|
|
1857
1977
|
);
|
|
1858
|
-
const sessionsWithMeta2 = yield*
|
|
1978
|
+
const sessionsWithMeta2 = yield* Effect19.all(
|
|
1859
1979
|
sessionsToReturn2.map(
|
|
1860
|
-
(item) =>
|
|
1980
|
+
(item) => Effect19.gen(function* () {
|
|
1861
1981
|
const meta = yield* sessionMetaService.getSessionMeta(
|
|
1862
1982
|
projectId,
|
|
1863
1983
|
item.id
|
|
@@ -1920,9 +2040,9 @@ var LayerImpl11 = Effect16.gen(function* () {
|
|
|
1920
2040
|
0,
|
|
1921
2041
|
Math.min(maxCount, sessions.length)
|
|
1922
2042
|
);
|
|
1923
|
-
const sessionsWithMeta = yield*
|
|
2043
|
+
const sessionsWithMeta = yield* Effect19.all(
|
|
1924
2044
|
sessionsToReturn.map(
|
|
1925
|
-
(item) =>
|
|
2045
|
+
(item) => Effect19.gen(function* () {
|
|
1926
2046
|
const meta = yield* sessionMetaService.getSessionMeta(
|
|
1927
2047
|
projectId,
|
|
1928
2048
|
item.id
|
|
@@ -1944,9 +2064,9 @@ var LayerImpl11 = Effect16.gen(function* () {
|
|
|
1944
2064
|
getSessions
|
|
1945
2065
|
};
|
|
1946
2066
|
});
|
|
1947
|
-
var SessionRepository = class extends
|
|
2067
|
+
var SessionRepository = class extends Context16.Tag("SessionRepository")() {
|
|
1948
2068
|
static {
|
|
1949
|
-
this.Live =
|
|
2069
|
+
this.Live = Layer18.effect(this, LayerImpl13);
|
|
1950
2070
|
}
|
|
1951
2071
|
};
|
|
1952
2072
|
|
|
@@ -2046,7 +2166,7 @@ var fallbackSdkMessage = (message) => {
|
|
|
2046
2166
|
};
|
|
2047
2167
|
|
|
2048
2168
|
// src/server/core/claude-code/models/CCSessionProcess.ts
|
|
2049
|
-
import { Effect as
|
|
2169
|
+
import { Effect as Effect20 } from "effect";
|
|
2050
2170
|
var isPublic = (process2) => {
|
|
2051
2171
|
return process2.type === "initialized" || process2.type === "file_created" || process2.type === "paused";
|
|
2052
2172
|
};
|
|
@@ -2057,7 +2177,7 @@ var getAliveTasks = (process2) => {
|
|
|
2057
2177
|
};
|
|
2058
2178
|
var createVirtualConversation = (process2, ctx) => {
|
|
2059
2179
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2060
|
-
return
|
|
2180
|
+
return Effect20.gen(function* () {
|
|
2061
2181
|
const config = yield* Config;
|
|
2062
2182
|
const virtualConversation = {
|
|
2063
2183
|
type: "user",
|
|
@@ -2079,7 +2199,7 @@ var createVirtualConversation = (process2, ctx) => {
|
|
|
2079
2199
|
};
|
|
2080
2200
|
|
|
2081
2201
|
// src/server/core/claude-code/services/ClaudeCodeSessionProcessService.ts
|
|
2082
|
-
import { Context as
|
|
2202
|
+
import { Context as Context17, Data as Data3, Effect as Effect21, Layer as Layer19, Ref as Ref8 } from "effect";
|
|
2083
2203
|
var SessionProcessNotFoundError = class extends Data3.TaggedError(
|
|
2084
2204
|
"SessionProcessNotFoundError"
|
|
2085
2205
|
) {
|
|
@@ -2098,12 +2218,12 @@ var IllegalStateChangeError = class extends Data3.TaggedError(
|
|
|
2098
2218
|
};
|
|
2099
2219
|
var TaskNotFoundError = class extends Data3.TaggedError("TaskNotFoundError") {
|
|
2100
2220
|
};
|
|
2101
|
-
var
|
|
2221
|
+
var LayerImpl14 = Effect21.gen(function* () {
|
|
2102
2222
|
const processesRef = yield* Ref8.make([]);
|
|
2103
2223
|
const eventBus = yield* EventBus;
|
|
2104
2224
|
const startSessionProcess = (options) => {
|
|
2105
2225
|
const { sessionDef, taskDef } = options;
|
|
2106
|
-
return
|
|
2226
|
+
return Effect21.gen(function* () {
|
|
2107
2227
|
const task = {
|
|
2108
2228
|
def: taskDef,
|
|
2109
2229
|
status: "pending"
|
|
@@ -2126,10 +2246,10 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2126
2246
|
};
|
|
2127
2247
|
const continueSessionProcess = (options) => {
|
|
2128
2248
|
const { sessionProcessId } = options;
|
|
2129
|
-
return
|
|
2249
|
+
return Effect21.gen(function* () {
|
|
2130
2250
|
const process2 = yield* getSessionProcess(sessionProcessId);
|
|
2131
2251
|
if (process2.type !== "paused") {
|
|
2132
|
-
return yield*
|
|
2252
|
+
return yield* Effect21.fail(
|
|
2133
2253
|
new SessionProcessNotPausedError({
|
|
2134
2254
|
sessionProcessId
|
|
2135
2255
|
})
|
|
@@ -2137,7 +2257,7 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2137
2257
|
}
|
|
2138
2258
|
const [firstAliveTask] = getAliveTasks(process2);
|
|
2139
2259
|
if (firstAliveTask !== void 0) {
|
|
2140
|
-
return yield*
|
|
2260
|
+
return yield* Effect21.fail(
|
|
2141
2261
|
new SessionProcessAlreadyAliveError({
|
|
2142
2262
|
sessionProcessId,
|
|
2143
2263
|
aliveTaskId: firstAliveTask.def.taskId,
|
|
@@ -2167,13 +2287,13 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2167
2287
|
});
|
|
2168
2288
|
};
|
|
2169
2289
|
const getSessionProcess = (sessionProcessId) => {
|
|
2170
|
-
return
|
|
2290
|
+
return Effect21.gen(function* () {
|
|
2171
2291
|
const processes = yield* Ref8.get(processesRef);
|
|
2172
2292
|
const result = processes.find(
|
|
2173
2293
|
(p) => p.def.sessionProcessId === sessionProcessId
|
|
2174
2294
|
);
|
|
2175
2295
|
if (result === void 0) {
|
|
2176
|
-
return yield*
|
|
2296
|
+
return yield* Effect21.fail(
|
|
2177
2297
|
new SessionProcessNotFoundError({ sessionProcessId })
|
|
2178
2298
|
);
|
|
2179
2299
|
}
|
|
@@ -2181,13 +2301,13 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2181
2301
|
});
|
|
2182
2302
|
};
|
|
2183
2303
|
const getSessionProcesses = () => {
|
|
2184
|
-
return
|
|
2304
|
+
return Effect21.gen(function* () {
|
|
2185
2305
|
const processes = yield* Ref8.get(processesRef);
|
|
2186
2306
|
return processes;
|
|
2187
2307
|
});
|
|
2188
2308
|
};
|
|
2189
2309
|
const getTask = (taskId) => {
|
|
2190
|
-
return
|
|
2310
|
+
return Effect21.gen(function* () {
|
|
2191
2311
|
const processes = yield* Ref8.get(processesRef);
|
|
2192
2312
|
const result = processes.flatMap((p) => {
|
|
2193
2313
|
const found = p.tasks.find((t) => t.def.taskId === taskId);
|
|
@@ -2202,14 +2322,14 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2202
2322
|
];
|
|
2203
2323
|
}).at(0);
|
|
2204
2324
|
if (result === void 0) {
|
|
2205
|
-
return yield*
|
|
2325
|
+
return yield* Effect21.fail(new TaskNotFoundError({ taskId }));
|
|
2206
2326
|
}
|
|
2207
2327
|
return result;
|
|
2208
2328
|
});
|
|
2209
2329
|
};
|
|
2210
2330
|
const dangerouslyChangeProcessState = (options) => {
|
|
2211
2331
|
const { sessionProcessId, nextState } = options;
|
|
2212
|
-
return
|
|
2332
|
+
return Effect21.gen(function* () {
|
|
2213
2333
|
const processes = yield* Ref8.get(processesRef);
|
|
2214
2334
|
const targetProcess = processes.find(
|
|
2215
2335
|
(p) => p.def.sessionProcessId === sessionProcessId
|
|
@@ -2238,7 +2358,7 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2238
2358
|
};
|
|
2239
2359
|
const changeTaskState = (options) => {
|
|
2240
2360
|
const { sessionProcessId, taskId, nextTask } = options;
|
|
2241
|
-
return
|
|
2361
|
+
return Effect21.gen(function* () {
|
|
2242
2362
|
const { task } = yield* getTask(taskId);
|
|
2243
2363
|
yield* Ref8.update(processesRef, (processes) => {
|
|
2244
2364
|
return processes.map(
|
|
@@ -2259,10 +2379,10 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2259
2379
|
};
|
|
2260
2380
|
const toNotInitializedState = (options) => {
|
|
2261
2381
|
const { sessionProcessId, rawUserMessage } = options;
|
|
2262
|
-
return
|
|
2382
|
+
return Effect21.gen(function* () {
|
|
2263
2383
|
const currentProcess = yield* getSessionProcess(sessionProcessId);
|
|
2264
2384
|
if (currentProcess.type !== "pending") {
|
|
2265
|
-
return yield*
|
|
2385
|
+
return yield* Effect21.fail(
|
|
2266
2386
|
new IllegalStateChangeError({
|
|
2267
2387
|
from: currentProcess.type,
|
|
2268
2388
|
to: "not_initialized"
|
|
@@ -2295,10 +2415,10 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2295
2415
|
};
|
|
2296
2416
|
const toInitializedState = (options) => {
|
|
2297
2417
|
const { sessionProcessId, initContext } = options;
|
|
2298
|
-
return
|
|
2418
|
+
return Effect21.gen(function* () {
|
|
2299
2419
|
const currentProcess = yield* getSessionProcess(sessionProcessId);
|
|
2300
2420
|
if (currentProcess.type !== "not_initialized") {
|
|
2301
|
-
return yield*
|
|
2421
|
+
return yield* Effect21.fail(
|
|
2302
2422
|
new IllegalStateChangeError({
|
|
2303
2423
|
from: currentProcess.type,
|
|
2304
2424
|
to: "initialized"
|
|
@@ -2324,10 +2444,10 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2324
2444
|
};
|
|
2325
2445
|
const toFileCreatedState = (options) => {
|
|
2326
2446
|
const { sessionProcessId } = options;
|
|
2327
|
-
return
|
|
2447
|
+
return Effect21.gen(function* () {
|
|
2328
2448
|
const currentProcess = yield* getSessionProcess(sessionProcessId);
|
|
2329
2449
|
if (currentProcess.type !== "initialized") {
|
|
2330
|
-
return yield*
|
|
2450
|
+
return yield* Effect21.fail(
|
|
2331
2451
|
new IllegalStateChangeError({
|
|
2332
2452
|
from: currentProcess.type,
|
|
2333
2453
|
to: "file_created"
|
|
@@ -2353,10 +2473,10 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2353
2473
|
};
|
|
2354
2474
|
const toPausedState = (options) => {
|
|
2355
2475
|
const { sessionProcessId, resultMessage } = options;
|
|
2356
|
-
return
|
|
2476
|
+
return Effect21.gen(function* () {
|
|
2357
2477
|
const currentProcess = yield* getSessionProcess(sessionProcessId);
|
|
2358
2478
|
if (currentProcess.type !== "file_created") {
|
|
2359
|
-
return yield*
|
|
2479
|
+
return yield* Effect21.fail(
|
|
2360
2480
|
new IllegalStateChangeError({
|
|
2361
2481
|
from: currentProcess.type,
|
|
2362
2482
|
to: "paused"
|
|
@@ -2390,7 +2510,7 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2390
2510
|
};
|
|
2391
2511
|
const toCompletedState = (options) => {
|
|
2392
2512
|
const { sessionProcessId, error } = options;
|
|
2393
|
-
return
|
|
2513
|
+
return Effect21.gen(function* () {
|
|
2394
2514
|
const currentProcess = yield* getSessionProcess(sessionProcessId);
|
|
2395
2515
|
const currentTask = currentProcess.type === "not_initialized" || currentProcess.type === "initialized" || currentProcess.type === "file_created" ? currentProcess.currentTask : void 0;
|
|
2396
2516
|
const newTask = currentTask !== void 0 ? error !== void 0 ? {
|
|
@@ -2443,25 +2563,25 @@ var LayerImpl12 = Effect18.gen(function* () {
|
|
|
2443
2563
|
changeTaskState
|
|
2444
2564
|
};
|
|
2445
2565
|
});
|
|
2446
|
-
var ClaudeCodeSessionProcessService = class extends
|
|
2566
|
+
var ClaudeCodeSessionProcessService = class extends Context17.Tag(
|
|
2447
2567
|
"ClaudeCodeSessionProcessService"
|
|
2448
2568
|
)() {
|
|
2449
2569
|
static {
|
|
2450
|
-
this.Live =
|
|
2570
|
+
this.Live = Layer19.effect(this, LayerImpl14);
|
|
2451
2571
|
}
|
|
2452
2572
|
};
|
|
2453
2573
|
|
|
2454
2574
|
// src/server/core/claude-code/services/ClaudeCodeLifeCycleService.ts
|
|
2455
|
-
var
|
|
2575
|
+
var LayerImpl15 = Effect22.gen(function* () {
|
|
2456
2576
|
const eventBusService = yield* EventBus;
|
|
2457
2577
|
const sessionRepository = yield* SessionRepository;
|
|
2458
2578
|
const sessionProcessService = yield* ClaudeCodeSessionProcessService;
|
|
2459
2579
|
const virtualConversationDatabase = yield* VirtualConversationDatabase;
|
|
2460
2580
|
const permissionService = yield* ClaudeCodePermissionService;
|
|
2461
|
-
const runtime = yield*
|
|
2581
|
+
const runtime = yield* Effect22.runtime();
|
|
2462
2582
|
const continueTask = (options) => {
|
|
2463
2583
|
const { sessionProcessId, baseSessionId, input } = options;
|
|
2464
|
-
return
|
|
2584
|
+
return Effect22.gen(function* () {
|
|
2465
2585
|
const { sessionProcess, task } = yield* sessionProcessService.continueSessionProcess({
|
|
2466
2586
|
sessionProcessId,
|
|
2467
2587
|
taskDef: {
|
|
@@ -2489,7 +2609,7 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2489
2609
|
};
|
|
2490
2610
|
const startTask = (options) => {
|
|
2491
2611
|
const { baseSession, input, userConfig } = options;
|
|
2492
|
-
return
|
|
2612
|
+
return Effect22.gen(function* () {
|
|
2493
2613
|
const {
|
|
2494
2614
|
generateMessages,
|
|
2495
2615
|
setNextMessage,
|
|
@@ -2517,7 +2637,7 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2517
2637
|
const sessionFileCreatedPromise = controllablePromise();
|
|
2518
2638
|
setMessageGeneratorHooks({
|
|
2519
2639
|
onNewUserMessageResolved: async (input2) => {
|
|
2520
|
-
|
|
2640
|
+
Effect22.runFork(
|
|
2521
2641
|
sessionProcessService.toNotInitializedState({
|
|
2522
2642
|
sessionProcessId: sessionProcess.def.sessionProcessId,
|
|
2523
2643
|
rawUserMessage: input2.text
|
|
@@ -2525,7 +2645,7 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2525
2645
|
);
|
|
2526
2646
|
}
|
|
2527
2647
|
});
|
|
2528
|
-
const handleMessage = (message) =>
|
|
2648
|
+
const handleMessage = (message) => Effect22.gen(function* () {
|
|
2529
2649
|
const processState = yield* sessionProcessService.getSessionProcess(
|
|
2530
2650
|
sessionProcess.def.sessionProcessId
|
|
2531
2651
|
);
|
|
@@ -2533,7 +2653,7 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2533
2653
|
return "break";
|
|
2534
2654
|
}
|
|
2535
2655
|
if (processState.type === "paused") {
|
|
2536
|
-
yield*
|
|
2656
|
+
yield* Effect22.die(
|
|
2537
2657
|
new Error("Illegal state: paused is not expected")
|
|
2538
2658
|
);
|
|
2539
2659
|
}
|
|
@@ -2605,7 +2725,7 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2605
2725
|
});
|
|
2606
2726
|
const handleSessionProcessDaemon = async () => {
|
|
2607
2727
|
const messageIter = await Runtime2.runPromise(runtime)(
|
|
2608
|
-
|
|
2728
|
+
Effect22.gen(function* () {
|
|
2609
2729
|
const permissionOptions = yield* permissionService.createCanUseToolRelatedOptions({
|
|
2610
2730
|
taskId: task.def.taskId,
|
|
2611
2731
|
userConfig,
|
|
@@ -2626,7 +2746,7 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2626
2746
|
const result = await Runtime2.runPromise(runtime)(
|
|
2627
2747
|
handleMessage(fallbackMessage)
|
|
2628
2748
|
).catch((error) => {
|
|
2629
|
-
|
|
2749
|
+
Effect22.runFork(
|
|
2630
2750
|
sessionProcessService.changeTaskState({
|
|
2631
2751
|
sessionProcessId: sessionProcess.def.sessionProcessId,
|
|
2632
2752
|
taskId: task.def.taskId,
|
|
@@ -2657,7 +2777,7 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2657
2777
|
if (sessionFileCreatedPromise.status === "pending") {
|
|
2658
2778
|
sessionFileCreatedPromise.reject(error);
|
|
2659
2779
|
}
|
|
2660
|
-
await
|
|
2780
|
+
await Effect22.runPromise(
|
|
2661
2781
|
sessionProcessService.changeTaskState({
|
|
2662
2782
|
sessionProcessId: sessionProcess.def.sessionProcessId,
|
|
2663
2783
|
taskId: task.def.taskId,
|
|
@@ -2680,8 +2800,8 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2680
2800
|
}
|
|
2681
2801
|
throw error;
|
|
2682
2802
|
}).finally(() => {
|
|
2683
|
-
|
|
2684
|
-
|
|
2803
|
+
Effect22.runFork(
|
|
2804
|
+
Effect22.gen(function* () {
|
|
2685
2805
|
const currentProcess = yield* sessionProcessService.getSessionProcess(
|
|
2686
2806
|
sessionProcess.def.sessionProcessId
|
|
2687
2807
|
);
|
|
@@ -2697,16 +2817,16 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2697
2817
|
daemonPromise,
|
|
2698
2818
|
awaitSessionInitialized: async () => await sessionInitializedPromise.promise,
|
|
2699
2819
|
awaitSessionFileCreated: async () => await sessionFileCreatedPromise.promise,
|
|
2700
|
-
yieldSessionInitialized: () =>
|
|
2701
|
-
yieldSessionFileCreated: () =>
|
|
2820
|
+
yieldSessionInitialized: () => Effect22.promise(() => sessionInitializedPromise.promise),
|
|
2821
|
+
yieldSessionFileCreated: () => Effect22.promise(() => sessionFileCreatedPromise.promise)
|
|
2702
2822
|
};
|
|
2703
2823
|
});
|
|
2704
2824
|
};
|
|
2705
|
-
const getPublicSessionProcesses = () =>
|
|
2825
|
+
const getPublicSessionProcesses = () => Effect22.gen(function* () {
|
|
2706
2826
|
const processes = yield* sessionProcessService.getSessionProcesses();
|
|
2707
2827
|
return processes.filter((process2) => isPublic(process2));
|
|
2708
2828
|
});
|
|
2709
|
-
const abortTask = (sessionProcessId) =>
|
|
2829
|
+
const abortTask = (sessionProcessId) => Effect22.gen(function* () {
|
|
2710
2830
|
const currentProcess = yield* sessionProcessService.getSessionProcess(sessionProcessId);
|
|
2711
2831
|
currentProcess.def.abortController.abort();
|
|
2712
2832
|
yield* sessionProcessService.toCompletedState({
|
|
@@ -2714,7 +2834,7 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2714
2834
|
error: new Error("Task aborted")
|
|
2715
2835
|
});
|
|
2716
2836
|
});
|
|
2717
|
-
const abortAllTasks = () =>
|
|
2837
|
+
const abortAllTasks = () => Effect22.gen(function* () {
|
|
2718
2838
|
const processes = yield* sessionProcessService.getSessionProcesses();
|
|
2719
2839
|
for (const process2 of processes) {
|
|
2720
2840
|
yield* sessionProcessService.toCompletedState({
|
|
@@ -2731,20 +2851,20 @@ var LayerImpl13 = Effect19.gen(function* () {
|
|
|
2731
2851
|
getPublicSessionProcesses
|
|
2732
2852
|
};
|
|
2733
2853
|
});
|
|
2734
|
-
var ClaudeCodeLifeCycleService = class extends
|
|
2854
|
+
var ClaudeCodeLifeCycleService = class extends Context18.Tag(
|
|
2735
2855
|
"ClaudeCodeLifeCycleService"
|
|
2736
2856
|
)() {
|
|
2737
2857
|
static {
|
|
2738
|
-
this.Live =
|
|
2858
|
+
this.Live = Layer20.effect(this, LayerImpl15);
|
|
2739
2859
|
}
|
|
2740
2860
|
};
|
|
2741
2861
|
|
|
2742
2862
|
// src/server/core/claude-code/presentation/ClaudeCodeSessionProcessController.ts
|
|
2743
|
-
var
|
|
2863
|
+
var LayerImpl16 = Effect23.gen(function* () {
|
|
2744
2864
|
const projectRepository = yield* ProjectRepository;
|
|
2745
2865
|
const claudeCodeLifeCycleService = yield* ClaudeCodeLifeCycleService;
|
|
2746
2866
|
const userConfigService = yield* UserConfigService;
|
|
2747
|
-
const getSessionProcesses = () =>
|
|
2867
|
+
const getSessionProcesses = () => Effect23.gen(function* () {
|
|
2748
2868
|
const publicSessionProcesses = yield* claudeCodeLifeCycleService.getPublicSessionProcesses();
|
|
2749
2869
|
return {
|
|
2750
2870
|
response: {
|
|
@@ -2760,7 +2880,7 @@ var LayerImpl14 = Effect20.gen(function* () {
|
|
|
2760
2880
|
status: 200
|
|
2761
2881
|
};
|
|
2762
2882
|
});
|
|
2763
|
-
const createSessionProcess = (options) =>
|
|
2883
|
+
const createSessionProcess = (options) => Effect23.gen(function* () {
|
|
2764
2884
|
const { projectId, input, baseSessionId } = options;
|
|
2765
2885
|
const { project } = yield* projectRepository.getProject(projectId);
|
|
2766
2886
|
const userConfig = yield* userConfigService.getUserConfig();
|
|
@@ -2791,7 +2911,7 @@ var LayerImpl14 = Effect20.gen(function* () {
|
|
|
2791
2911
|
}
|
|
2792
2912
|
};
|
|
2793
2913
|
});
|
|
2794
|
-
const continueSessionProcess = (options) =>
|
|
2914
|
+
const continueSessionProcess = (options) => Effect23.gen(function* () {
|
|
2795
2915
|
const { projectId, input, baseSessionId, sessionProcessId } = options;
|
|
2796
2916
|
const { project } = yield* projectRepository.getProject(projectId);
|
|
2797
2917
|
if (project.meta.projectPath === null) {
|
|
@@ -2822,16 +2942,16 @@ var LayerImpl14 = Effect20.gen(function* () {
|
|
|
2822
2942
|
continueSessionProcess
|
|
2823
2943
|
};
|
|
2824
2944
|
});
|
|
2825
|
-
var ClaudeCodeSessionProcessController = class extends
|
|
2945
|
+
var ClaudeCodeSessionProcessController = class extends Context19.Tag(
|
|
2826
2946
|
"ClaudeCodeSessionProcessController"
|
|
2827
2947
|
)() {
|
|
2828
2948
|
static {
|
|
2829
|
-
this.Live =
|
|
2949
|
+
this.Live = Layer21.effect(this, LayerImpl16);
|
|
2830
2950
|
}
|
|
2831
2951
|
};
|
|
2832
2952
|
|
|
2833
2953
|
// src/server/core/events/presentation/SSEController.ts
|
|
2834
|
-
import { Context as
|
|
2954
|
+
import { Context as Context21, Effect as Effect25, Layer as Layer23 } from "effect";
|
|
2835
2955
|
|
|
2836
2956
|
// src/server/core/events/functions/adaptInternalEventToSSE.ts
|
|
2837
2957
|
var adaptInternalEventToSSE = (rawStream, options) => {
|
|
@@ -2858,12 +2978,12 @@ var adaptInternalEventToSSE = (rawStream, options) => {
|
|
|
2858
2978
|
};
|
|
2859
2979
|
|
|
2860
2980
|
// src/server/core/events/functions/typeSafeSSE.ts
|
|
2861
|
-
import { Context as
|
|
2981
|
+
import { Context as Context20, Effect as Effect24, Layer as Layer22 } from "effect";
|
|
2862
2982
|
import { ulid as ulid3 } from "ulid";
|
|
2863
|
-
var TypeSafeSSE = class extends
|
|
2983
|
+
var TypeSafeSSE = class extends Context20.Tag("TypeSafeSSE")() {
|
|
2864
2984
|
static {
|
|
2865
|
-
this.make = (stream) =>
|
|
2866
|
-
writeSSE: (event, data) =>
|
|
2985
|
+
this.make = (stream) => Layer22.succeed(this, {
|
|
2986
|
+
writeSSE: (event, data) => Effect24.tryPromise({
|
|
2867
2987
|
try: async () => {
|
|
2868
2988
|
const id = ulid3();
|
|
2869
2989
|
await stream.writeSSE({
|
|
@@ -2888,44 +3008,52 @@ var TypeSafeSSE = class extends Context18.Tag("TypeSafeSSE")() {
|
|
|
2888
3008
|
};
|
|
2889
3009
|
|
|
2890
3010
|
// src/server/core/events/presentation/SSEController.ts
|
|
2891
|
-
var
|
|
3011
|
+
var LayerImpl17 = Effect25.gen(function* () {
|
|
2892
3012
|
const eventBus = yield* EventBus;
|
|
2893
|
-
const handleSSE = (rawStream) =>
|
|
3013
|
+
const handleSSE = (rawStream) => Effect25.gen(function* () {
|
|
2894
3014
|
const typeSafeSSE = yield* TypeSafeSSE;
|
|
2895
3015
|
yield* typeSafeSSE.writeSSE("connect", {
|
|
2896
3016
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2897
3017
|
});
|
|
2898
3018
|
const onHeartbeat = () => {
|
|
2899
|
-
|
|
3019
|
+
Effect25.runFork(
|
|
2900
3020
|
typeSafeSSE.writeSSE("heartbeat", {
|
|
2901
3021
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2902
3022
|
})
|
|
2903
3023
|
);
|
|
2904
3024
|
};
|
|
2905
3025
|
const onSessionListChanged = (event) => {
|
|
2906
|
-
|
|
3026
|
+
Effect25.runFork(
|
|
2907
3027
|
typeSafeSSE.writeSSE("sessionListChanged", {
|
|
2908
3028
|
projectId: event.projectId
|
|
2909
3029
|
})
|
|
2910
3030
|
);
|
|
2911
3031
|
};
|
|
2912
3032
|
const onSessionChanged = (event) => {
|
|
2913
|
-
|
|
3033
|
+
Effect25.runFork(
|
|
2914
3034
|
typeSafeSSE.writeSSE("sessionChanged", {
|
|
2915
3035
|
projectId: event.projectId,
|
|
2916
3036
|
sessionId: event.sessionId
|
|
2917
3037
|
})
|
|
2918
3038
|
);
|
|
2919
3039
|
};
|
|
3040
|
+
const onAgentSessionChanged = (event) => {
|
|
3041
|
+
Effect25.runFork(
|
|
3042
|
+
typeSafeSSE.writeSSE("agentSessionChanged", {
|
|
3043
|
+
projectId: event.projectId,
|
|
3044
|
+
agentSessionId: event.agentSessionId
|
|
3045
|
+
})
|
|
3046
|
+
);
|
|
3047
|
+
};
|
|
2920
3048
|
const onSessionProcessChanged = (event) => {
|
|
2921
|
-
|
|
3049
|
+
Effect25.runFork(
|
|
2922
3050
|
typeSafeSSE.writeSSE("sessionProcessChanged", {
|
|
2923
3051
|
processes: event.processes
|
|
2924
3052
|
})
|
|
2925
3053
|
);
|
|
2926
3054
|
};
|
|
2927
3055
|
const onPermissionRequested = (event) => {
|
|
2928
|
-
|
|
3056
|
+
Effect25.runFork(
|
|
2929
3057
|
typeSafeSSE.writeSSE("permissionRequested", {
|
|
2930
3058
|
permissionRequest: event.permissionRequest
|
|
2931
3059
|
})
|
|
@@ -2933,16 +3061,18 @@ var LayerImpl15 = Effect22.gen(function* () {
|
|
|
2933
3061
|
};
|
|
2934
3062
|
yield* eventBus.on("sessionListChanged", onSessionListChanged);
|
|
2935
3063
|
yield* eventBus.on("sessionChanged", onSessionChanged);
|
|
3064
|
+
yield* eventBus.on("agentSessionChanged", onAgentSessionChanged);
|
|
2936
3065
|
yield* eventBus.on("sessionProcessChanged", onSessionProcessChanged);
|
|
2937
3066
|
yield* eventBus.on("heartbeat", onHeartbeat);
|
|
2938
3067
|
yield* eventBus.on("permissionRequested", onPermissionRequested);
|
|
2939
3068
|
const { connectionPromise } = adaptInternalEventToSSE(rawStream, {
|
|
2940
3069
|
timeout: 5 * 60 * 1e3,
|
|
2941
3070
|
cleanUp: async () => {
|
|
2942
|
-
await
|
|
2943
|
-
|
|
3071
|
+
await Effect25.runPromise(
|
|
3072
|
+
Effect25.gen(function* () {
|
|
2944
3073
|
yield* eventBus.off("sessionListChanged", onSessionListChanged);
|
|
2945
3074
|
yield* eventBus.off("sessionChanged", onSessionChanged);
|
|
3075
|
+
yield* eventBus.off("agentSessionChanged", onAgentSessionChanged);
|
|
2946
3076
|
yield* eventBus.off(
|
|
2947
3077
|
"sessionProcessChanged",
|
|
2948
3078
|
onSessionProcessChanged
|
|
@@ -2953,34 +3083,64 @@ var LayerImpl15 = Effect22.gen(function* () {
|
|
|
2953
3083
|
);
|
|
2954
3084
|
}
|
|
2955
3085
|
});
|
|
2956
|
-
yield*
|
|
3086
|
+
yield* Effect25.promise(() => connectionPromise);
|
|
2957
3087
|
});
|
|
2958
3088
|
return {
|
|
2959
3089
|
handleSSE
|
|
2960
3090
|
};
|
|
2961
3091
|
});
|
|
2962
|
-
var SSEController = class extends
|
|
3092
|
+
var SSEController = class extends Context21.Tag("SSEController")() {
|
|
2963
3093
|
static {
|
|
2964
|
-
this.Live =
|
|
3094
|
+
this.Live = Layer23.effect(this, LayerImpl17);
|
|
2965
3095
|
}
|
|
2966
3096
|
};
|
|
2967
3097
|
|
|
2968
3098
|
// src/server/core/events/services/fileWatcher.ts
|
|
2969
3099
|
import { watch } from "node:fs";
|
|
2970
|
-
import { Path as
|
|
2971
|
-
import { Context as
|
|
3100
|
+
import { Path as Path10 } from "@effect/platform";
|
|
3101
|
+
import { Context as Context22, Effect as Effect26, Layer as Layer24, Ref as Ref9 } from "effect";
|
|
3102
|
+
|
|
3103
|
+
// src/server/core/events/functions/parseSessionFilePath.ts
|
|
2972
3104
|
import z22 from "zod";
|
|
2973
|
-
var
|
|
2974
|
-
var
|
|
3105
|
+
var sessionFileRegExp = /(?<projectId>.*?)\/(?<sessionId>.*?)\.jsonl$/;
|
|
3106
|
+
var agentFileRegExp = /(?<projectId>.*?)\/agent-(?<agentSessionId>.*?)\.jsonl$/;
|
|
3107
|
+
var sessionFileGroupSchema = z22.object({
|
|
2975
3108
|
projectId: z22.string(),
|
|
2976
3109
|
sessionId: z22.string()
|
|
2977
3110
|
});
|
|
2978
|
-
var
|
|
3111
|
+
var agentFileGroupSchema = z22.object({
|
|
3112
|
+
projectId: z22.string(),
|
|
3113
|
+
agentSessionId: z22.string()
|
|
3114
|
+
});
|
|
3115
|
+
var parseSessionFilePath = (filePath) => {
|
|
3116
|
+
const agentMatch = filePath.match(agentFileRegExp);
|
|
3117
|
+
const agentGroups = agentFileGroupSchema.safeParse(agentMatch?.groups);
|
|
3118
|
+
if (agentGroups.success) {
|
|
3119
|
+
return {
|
|
3120
|
+
type: "agent",
|
|
3121
|
+
projectId: agentGroups.data.projectId,
|
|
3122
|
+
agentSessionId: agentGroups.data.agentSessionId
|
|
3123
|
+
};
|
|
3124
|
+
}
|
|
3125
|
+
const sessionMatch = filePath.match(sessionFileRegExp);
|
|
3126
|
+
const sessionGroups = sessionFileGroupSchema.safeParse(sessionMatch?.groups);
|
|
3127
|
+
if (sessionGroups.success) {
|
|
3128
|
+
return {
|
|
3129
|
+
type: "session",
|
|
3130
|
+
projectId: sessionGroups.data.projectId,
|
|
3131
|
+
sessionId: sessionGroups.data.sessionId
|
|
3132
|
+
};
|
|
3133
|
+
}
|
|
3134
|
+
return null;
|
|
3135
|
+
};
|
|
3136
|
+
|
|
3137
|
+
// src/server/core/events/services/fileWatcher.ts
|
|
3138
|
+
var FileWatcherService = class extends Context22.Tag("FileWatcherService")() {
|
|
2979
3139
|
static {
|
|
2980
|
-
this.Live =
|
|
3140
|
+
this.Live = Layer24.effect(
|
|
2981
3141
|
this,
|
|
2982
|
-
|
|
2983
|
-
const path = yield*
|
|
3142
|
+
Effect26.gen(function* () {
|
|
3143
|
+
const path = yield* Path10.Path;
|
|
2984
3144
|
const eventBus = yield* EventBus;
|
|
2985
3145
|
const context = yield* ApplicationContext;
|
|
2986
3146
|
const isWatchingRef = yield* Ref9.make(false);
|
|
@@ -2989,11 +3149,11 @@ var FileWatcherService = class extends Context20.Tag("FileWatcherService")() {
|
|
|
2989
3149
|
/* @__PURE__ */ new Map()
|
|
2990
3150
|
);
|
|
2991
3151
|
const debounceTimersRef = yield* Ref9.make(/* @__PURE__ */ new Map());
|
|
2992
|
-
const startWatching = () =>
|
|
3152
|
+
const startWatching = () => Effect26.gen(function* () {
|
|
2993
3153
|
const isWatching = yield* Ref9.get(isWatchingRef);
|
|
2994
3154
|
if (isWatching) return;
|
|
2995
3155
|
yield* Ref9.set(isWatchingRef, true);
|
|
2996
|
-
yield*
|
|
3156
|
+
yield* Effect26.tryPromise({
|
|
2997
3157
|
try: async () => {
|
|
2998
3158
|
console.log(
|
|
2999
3159
|
"Starting file watcher on:",
|
|
@@ -3004,38 +3164,44 @@ var FileWatcherService = class extends Context20.Tag("FileWatcherService")() {
|
|
|
3004
3164
|
{ persistent: false, recursive: true },
|
|
3005
3165
|
(_eventType, filename) => {
|
|
3006
3166
|
if (!filename) return;
|
|
3007
|
-
const
|
|
3008
|
-
|
|
3009
|
-
);
|
|
3010
|
-
if (!groups.success) return;
|
|
3011
|
-
const { sessionId } = groups.data;
|
|
3167
|
+
const fileMatch = parseSessionFilePath(filename);
|
|
3168
|
+
if (fileMatch === null) return;
|
|
3012
3169
|
const fullPath = path.join(
|
|
3013
3170
|
context.claudeCodePaths.claudeProjectsDirPath,
|
|
3014
3171
|
filename
|
|
3015
3172
|
);
|
|
3016
3173
|
const encodedProjectId = encodeProjectIdFromSessionFilePath(fullPath);
|
|
3017
|
-
const debounceKey = `${encodedProjectId}/${sessionId}`;
|
|
3018
|
-
|
|
3019
|
-
|
|
3174
|
+
const debounceKey = fileMatch.type === "agent" ? `${encodedProjectId}/agent-${fileMatch.agentSessionId}` : `${encodedProjectId}/${fileMatch.sessionId}`;
|
|
3175
|
+
Effect26.runPromise(
|
|
3176
|
+
Effect26.gen(function* () {
|
|
3020
3177
|
const timers = yield* Ref9.get(debounceTimersRef);
|
|
3021
3178
|
const existingTimer = timers.get(debounceKey);
|
|
3022
3179
|
if (existingTimer) {
|
|
3023
3180
|
clearTimeout(existingTimer);
|
|
3024
3181
|
}
|
|
3025
3182
|
const newTimer = setTimeout(() => {
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3183
|
+
if (fileMatch.type === "agent") {
|
|
3184
|
+
Effect26.runFork(
|
|
3185
|
+
eventBus.emit("agentSessionChanged", {
|
|
3186
|
+
projectId: encodedProjectId,
|
|
3187
|
+
agentSessionId: fileMatch.agentSessionId
|
|
3188
|
+
})
|
|
3189
|
+
);
|
|
3190
|
+
} else {
|
|
3191
|
+
Effect26.runFork(
|
|
3192
|
+
eventBus.emit("sessionChanged", {
|
|
3193
|
+
projectId: encodedProjectId,
|
|
3194
|
+
sessionId: fileMatch.sessionId
|
|
3195
|
+
})
|
|
3196
|
+
);
|
|
3197
|
+
Effect26.runFork(
|
|
3198
|
+
eventBus.emit("sessionListChanged", {
|
|
3199
|
+
projectId: encodedProjectId
|
|
3200
|
+
})
|
|
3201
|
+
);
|
|
3202
|
+
}
|
|
3203
|
+
Effect26.runPromise(
|
|
3204
|
+
Effect26.gen(function* () {
|
|
3039
3205
|
const currentTimers = yield* Ref9.get(debounceTimersRef);
|
|
3040
3206
|
currentTimers.delete(debounceKey);
|
|
3041
3207
|
yield* Ref9.set(debounceTimersRef, currentTimers);
|
|
@@ -3048,7 +3214,7 @@ var FileWatcherService = class extends Context20.Tag("FileWatcherService")() {
|
|
|
3048
3214
|
);
|
|
3049
3215
|
}
|
|
3050
3216
|
);
|
|
3051
|
-
await
|
|
3217
|
+
await Effect26.runPromise(Ref9.set(watcherRef, watcher));
|
|
3052
3218
|
console.log("File watcher initialization completed");
|
|
3053
3219
|
},
|
|
3054
3220
|
catch: (error) => {
|
|
@@ -3059,10 +3225,10 @@ var FileWatcherService = class extends Context20.Tag("FileWatcherService")() {
|
|
|
3059
3225
|
}
|
|
3060
3226
|
}).pipe(
|
|
3061
3227
|
// エラーが発生しても続行する
|
|
3062
|
-
|
|
3228
|
+
Effect26.catchAll(() => Effect26.void)
|
|
3063
3229
|
);
|
|
3064
3230
|
});
|
|
3065
|
-
const stop = () =>
|
|
3231
|
+
const stop = () => Effect26.gen(function* () {
|
|
3066
3232
|
const timers = yield* Ref9.get(debounceTimersRef);
|
|
3067
3233
|
for (const [, timer] of timers) {
|
|
3068
3234
|
clearTimeout(timer);
|
|
@@ -3070,12 +3236,12 @@ var FileWatcherService = class extends Context20.Tag("FileWatcherService")() {
|
|
|
3070
3236
|
yield* Ref9.set(debounceTimersRef, /* @__PURE__ */ new Map());
|
|
3071
3237
|
const watcher = yield* Ref9.get(watcherRef);
|
|
3072
3238
|
if (watcher) {
|
|
3073
|
-
yield*
|
|
3239
|
+
yield* Effect26.sync(() => watcher.close());
|
|
3074
3240
|
yield* Ref9.set(watcherRef, null);
|
|
3075
3241
|
}
|
|
3076
3242
|
const projectWatchers = yield* Ref9.get(projectWatchersRef);
|
|
3077
3243
|
for (const [, projectWatcher] of projectWatchers) {
|
|
3078
|
-
yield*
|
|
3244
|
+
yield* Effect26.sync(() => projectWatcher.close());
|
|
3079
3245
|
}
|
|
3080
3246
|
yield* Ref9.set(projectWatchersRef, /* @__PURE__ */ new Map());
|
|
3081
3247
|
yield* Ref9.set(isWatchingRef, false);
|
|
@@ -3090,10 +3256,10 @@ var FileWatcherService = class extends Context20.Tag("FileWatcherService")() {
|
|
|
3090
3256
|
};
|
|
3091
3257
|
|
|
3092
3258
|
// src/server/core/feature-flag/presentation/FeatureFlagController.ts
|
|
3093
|
-
import { Context as
|
|
3094
|
-
var
|
|
3259
|
+
import { Context as Context23, Effect as Effect27, Layer as Layer25 } from "effect";
|
|
3260
|
+
var LayerImpl18 = Effect27.gen(function* () {
|
|
3095
3261
|
const claudeCodeService = yield* ClaudeCodeService;
|
|
3096
|
-
const getFlags = () =>
|
|
3262
|
+
const getFlags = () => Effect27.gen(function* () {
|
|
3097
3263
|
const claudeCodeFeatures = yield* claudeCodeService.getAvailableFeatures();
|
|
3098
3264
|
return {
|
|
3099
3265
|
response: {
|
|
@@ -3105,6 +3271,10 @@ var LayerImpl16 = Effect24.gen(function* () {
|
|
|
3105
3271
|
{
|
|
3106
3272
|
name: "agent-sdk",
|
|
3107
3273
|
enabled: claudeCodeFeatures.agentSdk
|
|
3274
|
+
},
|
|
3275
|
+
{
|
|
3276
|
+
name: "sidechain-separation",
|
|
3277
|
+
enabled: claudeCodeFeatures.sidechainSeparation
|
|
3108
3278
|
}
|
|
3109
3279
|
]
|
|
3110
3280
|
},
|
|
@@ -3115,15 +3285,15 @@ var LayerImpl16 = Effect24.gen(function* () {
|
|
|
3115
3285
|
getFlags
|
|
3116
3286
|
};
|
|
3117
3287
|
});
|
|
3118
|
-
var FeatureFlagController = class extends
|
|
3288
|
+
var FeatureFlagController = class extends Context23.Tag("FeatureFlagController")() {
|
|
3119
3289
|
static {
|
|
3120
|
-
this.Live =
|
|
3290
|
+
this.Live = Layer25.effect(this, LayerImpl18);
|
|
3121
3291
|
}
|
|
3122
3292
|
};
|
|
3123
3293
|
|
|
3124
3294
|
// src/server/core/file-system/presentation/FileSystemController.ts
|
|
3125
3295
|
import { homedir as homedir3 } from "node:os";
|
|
3126
|
-
import { Context as
|
|
3296
|
+
import { Context as Context24, Effect as Effect28, Layer as Layer26 } from "effect";
|
|
3127
3297
|
|
|
3128
3298
|
// src/server/core/file-system/functions/getDirectoryListing.ts
|
|
3129
3299
|
import { existsSync } from "node:fs";
|
|
@@ -3256,9 +3426,9 @@ var getFileCompletion = async (projectPath, basePath = "/") => {
|
|
|
3256
3426
|
};
|
|
3257
3427
|
|
|
3258
3428
|
// src/server/core/file-system/presentation/FileSystemController.ts
|
|
3259
|
-
var
|
|
3429
|
+
var LayerImpl19 = Effect28.gen(function* () {
|
|
3260
3430
|
const projectRepository = yield* ProjectRepository;
|
|
3261
|
-
const getFileCompletionRoute = (options) =>
|
|
3431
|
+
const getFileCompletionRoute = (options) => Effect28.gen(function* () {
|
|
3262
3432
|
const { projectId, basePath } = options;
|
|
3263
3433
|
const { project } = yield* projectRepository.getProject(projectId);
|
|
3264
3434
|
if (project.meta.projectPath === null) {
|
|
@@ -3269,7 +3439,7 @@ var LayerImpl17 = Effect25.gen(function* () {
|
|
|
3269
3439
|
}
|
|
3270
3440
|
const projectPath = project.meta.projectPath;
|
|
3271
3441
|
try {
|
|
3272
|
-
const result = yield*
|
|
3442
|
+
const result = yield* Effect28.promise(
|
|
3273
3443
|
() => getFileCompletion(projectPath, basePath)
|
|
3274
3444
|
);
|
|
3275
3445
|
return {
|
|
@@ -3284,7 +3454,7 @@ var LayerImpl17 = Effect25.gen(function* () {
|
|
|
3284
3454
|
};
|
|
3285
3455
|
}
|
|
3286
3456
|
});
|
|
3287
|
-
const getDirectoryListingRoute = (options) =>
|
|
3457
|
+
const getDirectoryListingRoute = (options) => Effect28.promise(async () => {
|
|
3288
3458
|
const { currentPath, showHidden = false } = options;
|
|
3289
3459
|
const rootPath = "/";
|
|
3290
3460
|
const defaultPath = homedir3();
|
|
@@ -3313,14 +3483,14 @@ var LayerImpl17 = Effect25.gen(function* () {
|
|
|
3313
3483
|
getDirectoryListingRoute
|
|
3314
3484
|
};
|
|
3315
3485
|
});
|
|
3316
|
-
var FileSystemController = class extends
|
|
3486
|
+
var FileSystemController = class extends Context24.Tag("FileSystemController")() {
|
|
3317
3487
|
static {
|
|
3318
|
-
this.Live =
|
|
3488
|
+
this.Live = Layer26.effect(this, LayerImpl19);
|
|
3319
3489
|
}
|
|
3320
3490
|
};
|
|
3321
3491
|
|
|
3322
3492
|
// src/server/core/git/presentation/GitController.ts
|
|
3323
|
-
import { Context as
|
|
3493
|
+
import { Context as Context26, Effect as Effect30, Either as Either2, Layer as Layer28 } from "effect";
|
|
3324
3494
|
|
|
3325
3495
|
// src/server/core/git/functions/getDiff.ts
|
|
3326
3496
|
import { readFile } from "node:fs/promises";
|
|
@@ -3659,8 +3829,8 @@ var getDiff = async (cwd, fromRefText, toRefText) => {
|
|
|
3659
3829
|
};
|
|
3660
3830
|
|
|
3661
3831
|
// src/server/core/git/services/GitService.ts
|
|
3662
|
-
import { Command as Command2, FileSystem as
|
|
3663
|
-
import { Context as
|
|
3832
|
+
import { Command as Command2, FileSystem as FileSystem9, Path as Path11 } from "@effect/platform";
|
|
3833
|
+
import { Context as Context25, Data as Data4, Duration, Effect as Effect29, Either, Layer as Layer27 } from "effect";
|
|
3664
3834
|
|
|
3665
3835
|
// src/server/core/git/functions/parseGitBranchesOutput.ts
|
|
3666
3836
|
var parseGitBranchesOutput = (output) => {
|
|
@@ -3737,14 +3907,14 @@ var GitCommandError = class extends Data4.TaggedError("GitCommandError") {
|
|
|
3737
3907
|
};
|
|
3738
3908
|
var DetachedHeadError = class extends Data4.TaggedError("DetachedHeadError") {
|
|
3739
3909
|
};
|
|
3740
|
-
var
|
|
3741
|
-
const fs = yield*
|
|
3742
|
-
const path = yield*
|
|
3910
|
+
var LayerImpl20 = Effect29.gen(function* () {
|
|
3911
|
+
const fs = yield* FileSystem9.FileSystem;
|
|
3912
|
+
const path = yield* Path11.Path;
|
|
3743
3913
|
const envService = yield* EnvService;
|
|
3744
|
-
const execGitCommand = (args, cwd) =>
|
|
3914
|
+
const execGitCommand = (args, cwd) => Effect29.gen(function* () {
|
|
3745
3915
|
const absoluteCwd = path.resolve(cwd);
|
|
3746
3916
|
if (!(yield* fs.exists(absoluteCwd))) {
|
|
3747
|
-
return yield*
|
|
3917
|
+
return yield* Effect29.fail(
|
|
3748
3918
|
new NotARepositoryError({ cwd: absoluteCwd })
|
|
3749
3919
|
);
|
|
3750
3920
|
}
|
|
@@ -3754,9 +3924,9 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3754
3924
|
PATH: yield* envService.getEnv("PATH")
|
|
3755
3925
|
})
|
|
3756
3926
|
);
|
|
3757
|
-
const result = yield*
|
|
3927
|
+
const result = yield* Effect29.either(Command2.string(command));
|
|
3758
3928
|
if (Either.isLeft(result)) {
|
|
3759
|
-
return yield*
|
|
3929
|
+
return yield* Effect29.fail(
|
|
3760
3930
|
new GitCommandError({
|
|
3761
3931
|
cwd: absoluteCwd,
|
|
3762
3932
|
command: `git ${args.join(" ")}`
|
|
@@ -3765,22 +3935,22 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3765
3935
|
}
|
|
3766
3936
|
return result.right;
|
|
3767
3937
|
});
|
|
3768
|
-
const getBranches = (cwd) =>
|
|
3938
|
+
const getBranches = (cwd) => Effect29.gen(function* () {
|
|
3769
3939
|
const result = yield* execGitCommand(["branch", "-vv", "--all"], cwd);
|
|
3770
3940
|
return parseGitBranchesOutput(result);
|
|
3771
3941
|
});
|
|
3772
|
-
const getCurrentBranch = (cwd) =>
|
|
3942
|
+
const getCurrentBranch = (cwd) => Effect29.gen(function* () {
|
|
3773
3943
|
const currentBranch = yield* execGitCommand(
|
|
3774
3944
|
["branch", "--show-current"],
|
|
3775
3945
|
cwd
|
|
3776
|
-
).pipe(
|
|
3946
|
+
).pipe(Effect29.map((result) => result.trim()));
|
|
3777
3947
|
if (currentBranch === "") {
|
|
3778
|
-
return yield*
|
|
3948
|
+
return yield* Effect29.fail(new DetachedHeadError({ cwd }));
|
|
3779
3949
|
}
|
|
3780
3950
|
return currentBranch;
|
|
3781
3951
|
});
|
|
3782
|
-
const branchExists = (cwd, branchName) =>
|
|
3783
|
-
const result = yield*
|
|
3952
|
+
const branchExists = (cwd, branchName) => Effect29.gen(function* () {
|
|
3953
|
+
const result = yield* Effect29.either(
|
|
3784
3954
|
execGitCommand(["branch", "--exists", branchName], cwd)
|
|
3785
3955
|
);
|
|
3786
3956
|
if (Either.isLeft(result)) {
|
|
@@ -3788,7 +3958,7 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3788
3958
|
}
|
|
3789
3959
|
return true;
|
|
3790
3960
|
});
|
|
3791
|
-
const getCommits = (cwd) =>
|
|
3961
|
+
const getCommits = (cwd) => Effect29.gen(function* () {
|
|
3792
3962
|
const result = yield* execGitCommand(
|
|
3793
3963
|
[
|
|
3794
3964
|
"log",
|
|
@@ -3802,9 +3972,9 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3802
3972
|
);
|
|
3803
3973
|
return parseGitCommitsOutput(result);
|
|
3804
3974
|
});
|
|
3805
|
-
const stageFiles = (cwd, files) =>
|
|
3975
|
+
const stageFiles = (cwd, files) => Effect29.gen(function* () {
|
|
3806
3976
|
if (files.length === 0) {
|
|
3807
|
-
return yield*
|
|
3977
|
+
return yield* Effect29.fail(
|
|
3808
3978
|
new GitCommandError({
|
|
3809
3979
|
cwd,
|
|
3810
3980
|
command: "git add (no files)"
|
|
@@ -3814,10 +3984,10 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3814
3984
|
const result = yield* execGitCommand(["add", ...files], cwd);
|
|
3815
3985
|
return result;
|
|
3816
3986
|
});
|
|
3817
|
-
const commit = (cwd, message) =>
|
|
3987
|
+
const commit = (cwd, message) => Effect29.gen(function* () {
|
|
3818
3988
|
const trimmedMessage = message.trim();
|
|
3819
3989
|
if (trimmedMessage.length === 0) {
|
|
3820
|
-
return yield*
|
|
3990
|
+
return yield* Effect29.fail(
|
|
3821
3991
|
new GitCommandError({
|
|
3822
3992
|
cwd,
|
|
3823
3993
|
command: "git commit (empty message)"
|
|
@@ -3854,7 +4024,7 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3854
4024
|
);
|
|
3855
4025
|
return sha.trim();
|
|
3856
4026
|
});
|
|
3857
|
-
const push = (cwd) =>
|
|
4027
|
+
const push = (cwd) => Effect29.gen(function* () {
|
|
3858
4028
|
const branch = yield* getCurrentBranch(cwd);
|
|
3859
4029
|
const absoluteCwd = path.resolve(cwd);
|
|
3860
4030
|
const command = Command2.make("git", "push", "origin", "HEAD").pipe(
|
|
@@ -3863,12 +4033,12 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3863
4033
|
PATH: yield* envService.getEnv("PATH")
|
|
3864
4034
|
})
|
|
3865
4035
|
);
|
|
3866
|
-
const exitCodeResult = yield*
|
|
3867
|
-
Command2.exitCode(command).pipe(
|
|
4036
|
+
const exitCodeResult = yield* Effect29.either(
|
|
4037
|
+
Command2.exitCode(command).pipe(Effect29.timeout(Duration.seconds(60)))
|
|
3868
4038
|
);
|
|
3869
4039
|
if (Either.isLeft(exitCodeResult)) {
|
|
3870
4040
|
console.log("[GitService.push] Command failed or timeout");
|
|
3871
|
-
return yield*
|
|
4041
|
+
return yield* Effect29.fail(
|
|
3872
4042
|
new GitCommandError({
|
|
3873
4043
|
cwd: absoluteCwd,
|
|
3874
4044
|
command: "git push origin HEAD (timeout after 60s)"
|
|
@@ -3886,10 +4056,10 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3886
4056
|
}),
|
|
3887
4057
|
Command2.stderr("inherit")
|
|
3888
4058
|
)
|
|
3889
|
-
).pipe(
|
|
4059
|
+
).pipe(Effect29.orElse(() => Effect29.succeed([])));
|
|
3890
4060
|
const stderr = Array.from(stderrLines).join("\n");
|
|
3891
4061
|
console.log("[GitService.push] Failed with stderr:", stderr);
|
|
3892
|
-
return yield*
|
|
4062
|
+
return yield* Effect29.fail(
|
|
3893
4063
|
new GitCommandError({
|
|
3894
4064
|
cwd: absoluteCwd,
|
|
3895
4065
|
command: `git push origin HEAD - ${stderr}`
|
|
@@ -3899,20 +4069,20 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3899
4069
|
console.log("[GitService.push] Push succeeded");
|
|
3900
4070
|
return { branch, output: "success" };
|
|
3901
4071
|
});
|
|
3902
|
-
const getBranchHash = (cwd, branchName) =>
|
|
4072
|
+
const getBranchHash = (cwd, branchName) => Effect29.gen(function* () {
|
|
3903
4073
|
const result = yield* execGitCommand(["rev-parse", branchName], cwd).pipe(
|
|
3904
|
-
|
|
4074
|
+
Effect29.map((output) => output.trim().split("\n")[0] ?? null)
|
|
3905
4075
|
);
|
|
3906
4076
|
return result;
|
|
3907
4077
|
});
|
|
3908
|
-
const getBranchNamesByCommitHash = (cwd, hash) =>
|
|
4078
|
+
const getBranchNamesByCommitHash = (cwd, hash) => Effect29.gen(function* () {
|
|
3909
4079
|
const result = yield* execGitCommand(
|
|
3910
4080
|
["branch", "--contains", hash, "--format=%(refname:short)"],
|
|
3911
4081
|
cwd
|
|
3912
4082
|
);
|
|
3913
4083
|
return result.split("\n").map((line) => line.trim()).filter((line) => line !== "");
|
|
3914
4084
|
});
|
|
3915
|
-
const compareCommitHash = (cwd, targetHash, compareHash) =>
|
|
4085
|
+
const compareCommitHash = (cwd, targetHash, compareHash) => Effect29.gen(function* () {
|
|
3916
4086
|
const aheadResult = yield* execGitCommand(
|
|
3917
4087
|
["rev-list", `${targetHash}..${compareHash}`],
|
|
3918
4088
|
cwd
|
|
@@ -3934,7 +4104,7 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3934
4104
|
}
|
|
3935
4105
|
return "un-related";
|
|
3936
4106
|
});
|
|
3937
|
-
const getCommitsWithParent = (cwd, options) =>
|
|
4107
|
+
const getCommitsWithParent = (cwd, options) => Effect29.gen(function* () {
|
|
3938
4108
|
const { offset, limit } = options;
|
|
3939
4109
|
const result = yield* execGitCommand(
|
|
3940
4110
|
[
|
|
@@ -3961,7 +4131,7 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3961
4131
|
}
|
|
3962
4132
|
return commits;
|
|
3963
4133
|
});
|
|
3964
|
-
const findBaseBranch = (cwd, targetBranch) =>
|
|
4134
|
+
const findBaseBranch = (cwd, targetBranch) => Effect29.gen(function* () {
|
|
3965
4135
|
let offset = 0;
|
|
3966
4136
|
const limit = 20;
|
|
3967
4137
|
while (offset < 100) {
|
|
@@ -3995,7 +4165,7 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
3995
4165
|
}
|
|
3996
4166
|
return null;
|
|
3997
4167
|
});
|
|
3998
|
-
const getCommitsBetweenBranches = (cwd, baseBranch, targetBranch) =>
|
|
4168
|
+
const getCommitsBetweenBranches = (cwd, baseBranch, targetBranch) => Effect29.gen(function* () {
|
|
3999
4169
|
const result = yield* execGitCommand(
|
|
4000
4170
|
[
|
|
4001
4171
|
"log",
|
|
@@ -4023,17 +4193,17 @@ var LayerImpl18 = Effect26.gen(function* () {
|
|
|
4023
4193
|
getCommitsBetweenBranches
|
|
4024
4194
|
};
|
|
4025
4195
|
});
|
|
4026
|
-
var GitService = class extends
|
|
4196
|
+
var GitService = class extends Context25.Tag("GitService")() {
|
|
4027
4197
|
static {
|
|
4028
|
-
this.Live =
|
|
4198
|
+
this.Live = Layer27.effect(this, LayerImpl20);
|
|
4029
4199
|
}
|
|
4030
4200
|
};
|
|
4031
4201
|
|
|
4032
4202
|
// src/server/core/git/presentation/GitController.ts
|
|
4033
|
-
var
|
|
4203
|
+
var LayerImpl21 = Effect30.gen(function* () {
|
|
4034
4204
|
const gitService = yield* GitService;
|
|
4035
4205
|
const projectRepository = yield* ProjectRepository;
|
|
4036
|
-
const getGitDiff = (options) =>
|
|
4206
|
+
const getGitDiff = (options) => Effect30.gen(function* () {
|
|
4037
4207
|
const { projectId, fromRef, toRef } = options;
|
|
4038
4208
|
const { project } = yield* projectRepository.getProject(projectId);
|
|
4039
4209
|
try {
|
|
@@ -4044,7 +4214,7 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4044
4214
|
};
|
|
4045
4215
|
}
|
|
4046
4216
|
const projectPath = project.meta.projectPath;
|
|
4047
|
-
const result = yield*
|
|
4217
|
+
const result = yield* Effect30.promise(
|
|
4048
4218
|
() => getDiff(projectPath, fromRef, toRef)
|
|
4049
4219
|
);
|
|
4050
4220
|
return {
|
|
@@ -4065,7 +4235,7 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4065
4235
|
};
|
|
4066
4236
|
}
|
|
4067
4237
|
});
|
|
4068
|
-
const commitFiles = (options) =>
|
|
4238
|
+
const commitFiles = (options) => Effect30.gen(function* () {
|
|
4069
4239
|
const { projectId, files, message } = options;
|
|
4070
4240
|
const { project } = yield* projectRepository.getProject(projectId);
|
|
4071
4241
|
if (project.meta.projectPath === null) {
|
|
@@ -4078,7 +4248,7 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4078
4248
|
const projectPath = project.meta.projectPath;
|
|
4079
4249
|
console.log("[GitController.commitFiles] Project path:", projectPath);
|
|
4080
4250
|
console.log("[GitController.commitFiles] Staging files...");
|
|
4081
|
-
const stageResult = yield*
|
|
4251
|
+
const stageResult = yield* Effect30.either(
|
|
4082
4252
|
gitService.stageFiles(projectPath, files)
|
|
4083
4253
|
);
|
|
4084
4254
|
if (Either2.isLeft(stageResult)) {
|
|
@@ -4098,7 +4268,7 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4098
4268
|
}
|
|
4099
4269
|
console.log("[GitController.commitFiles] Stage succeeded");
|
|
4100
4270
|
console.log("[GitController.commitFiles] Committing...");
|
|
4101
|
-
const commitResult = yield*
|
|
4271
|
+
const commitResult = yield* Effect30.either(
|
|
4102
4272
|
gitService.commit(projectPath, message)
|
|
4103
4273
|
);
|
|
4104
4274
|
if (Either2.isLeft(commitResult)) {
|
|
@@ -4133,7 +4303,7 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4133
4303
|
status: 200
|
|
4134
4304
|
};
|
|
4135
4305
|
});
|
|
4136
|
-
const pushCommits = (options) =>
|
|
4306
|
+
const pushCommits = (options) => Effect30.gen(function* () {
|
|
4137
4307
|
const { projectId } = options;
|
|
4138
4308
|
console.log("[GitController.pushCommits] Request:", { projectId });
|
|
4139
4309
|
const { project } = yield* projectRepository.getProject(projectId);
|
|
@@ -4147,7 +4317,7 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4147
4317
|
const projectPath = project.meta.projectPath;
|
|
4148
4318
|
console.log("[GitController.pushCommits] Project path:", projectPath);
|
|
4149
4319
|
console.log("[GitController.pushCommits] Pushing...");
|
|
4150
|
-
const pushResult = yield*
|
|
4320
|
+
const pushResult = yield* Effect30.either(gitService.push(projectPath));
|
|
4151
4321
|
if (Either2.isLeft(pushResult)) {
|
|
4152
4322
|
console.log(
|
|
4153
4323
|
"[GitController.pushCommits] Push failed:",
|
|
@@ -4176,7 +4346,7 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4176
4346
|
status: 200
|
|
4177
4347
|
};
|
|
4178
4348
|
});
|
|
4179
|
-
const commitAndPush = (options) =>
|
|
4349
|
+
const commitAndPush = (options) => Effect30.gen(function* () {
|
|
4180
4350
|
const { projectId, files, message } = options;
|
|
4181
4351
|
console.log("[GitController.commitAndPush] Request:", {
|
|
4182
4352
|
projectId,
|
|
@@ -4227,7 +4397,7 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4227
4397
|
status: 200
|
|
4228
4398
|
};
|
|
4229
4399
|
});
|
|
4230
|
-
const getCurrentRevisions = (options) =>
|
|
4400
|
+
const getCurrentRevisions = (options) => Effect30.gen(function* () {
|
|
4231
4401
|
const { projectId } = options;
|
|
4232
4402
|
const { project } = yield* projectRepository.getProject(projectId);
|
|
4233
4403
|
if (project.meta.projectPath === null) {
|
|
@@ -4237,7 +4407,7 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4237
4407
|
};
|
|
4238
4408
|
}
|
|
4239
4409
|
const projectPath = project.meta.projectPath;
|
|
4240
|
-
const currentBranchResult = yield*
|
|
4410
|
+
const currentBranchResult = yield* Effect30.either(
|
|
4241
4411
|
gitService.getCurrentBranch(projectPath)
|
|
4242
4412
|
);
|
|
4243
4413
|
if (Either2.isLeft(currentBranchResult)) {
|
|
@@ -4249,10 +4419,10 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4249
4419
|
};
|
|
4250
4420
|
}
|
|
4251
4421
|
const currentBranch = currentBranchResult.right;
|
|
4252
|
-
const baseBranchResult = yield*
|
|
4422
|
+
const baseBranchResult = yield* Effect30.either(
|
|
4253
4423
|
gitService.findBaseBranch(projectPath, currentBranch)
|
|
4254
4424
|
);
|
|
4255
|
-
const allBranchesResult = yield*
|
|
4425
|
+
const allBranchesResult = yield* Effect30.either(
|
|
4256
4426
|
gitService.getBranches(projectPath)
|
|
4257
4427
|
);
|
|
4258
4428
|
if (Either2.isLeft(allBranchesResult)) {
|
|
@@ -4277,7 +4447,7 @@ var LayerImpl19 = Effect27.gen(function* () {
|
|
|
4277
4447
|
let commits = [];
|
|
4278
4448
|
if (Either2.isRight(baseBranchResult) && baseBranchResult.right !== null) {
|
|
4279
4449
|
const baseBranchHash = baseBranchResult.right.hash;
|
|
4280
|
-
const commitsResult = yield*
|
|
4450
|
+
const commitsResult = yield* Effect30.either(
|
|
4281
4451
|
gitService.getCommitsBetweenBranches(
|
|
4282
4452
|
projectPath,
|
|
4283
4453
|
baseBranchHash,
|
|
@@ -4340,21 +4510,21 @@ function getPushErrorMessage(code) {
|
|
|
4340
4510
|
};
|
|
4341
4511
|
return messages[code];
|
|
4342
4512
|
}
|
|
4343
|
-
var GitController = class extends
|
|
4513
|
+
var GitController = class extends Context26.Tag("GitController")() {
|
|
4344
4514
|
static {
|
|
4345
|
-
this.Live =
|
|
4515
|
+
this.Live = Layer28.effect(this, LayerImpl21);
|
|
4346
4516
|
}
|
|
4347
4517
|
};
|
|
4348
4518
|
|
|
4349
4519
|
// src/server/core/project/presentation/ProjectController.ts
|
|
4350
|
-
import { FileSystem as
|
|
4351
|
-
import { Context as
|
|
4520
|
+
import { FileSystem as FileSystem10, Path as Path13 } from "@effect/platform";
|
|
4521
|
+
import { Context as Context27, Effect as Effect32, Layer as Layer29 } from "effect";
|
|
4352
4522
|
|
|
4353
4523
|
// src/server/core/claude-code/functions/computeClaudeProjectFilePath.ts
|
|
4354
|
-
import { Path as
|
|
4355
|
-
import { Effect as
|
|
4356
|
-
var computeClaudeProjectFilePath = (options) =>
|
|
4357
|
-
const path = yield*
|
|
4524
|
+
import { Path as Path12 } from "@effect/platform";
|
|
4525
|
+
import { Effect as Effect31 } from "effect";
|
|
4526
|
+
var computeClaudeProjectFilePath = (options) => Effect31.gen(function* () {
|
|
4527
|
+
const path = yield* Path12.Path;
|
|
4358
4528
|
const { projectPath, claudeProjectsDirPath } = options;
|
|
4359
4529
|
return path.join(
|
|
4360
4530
|
claudeProjectsDirPath,
|
|
@@ -4363,22 +4533,22 @@ var computeClaudeProjectFilePath = (options) => Effect28.gen(function* () {
|
|
|
4363
4533
|
});
|
|
4364
4534
|
|
|
4365
4535
|
// src/server/core/project/presentation/ProjectController.ts
|
|
4366
|
-
var
|
|
4536
|
+
var LayerImpl22 = Effect32.gen(function* () {
|
|
4367
4537
|
const projectRepository = yield* ProjectRepository;
|
|
4368
4538
|
const claudeCodeLifeCycleService = yield* ClaudeCodeLifeCycleService;
|
|
4369
4539
|
const userConfigService = yield* UserConfigService;
|
|
4370
4540
|
const sessionRepository = yield* SessionRepository;
|
|
4371
4541
|
const context = yield* ApplicationContext;
|
|
4372
|
-
const fileSystem = yield*
|
|
4373
|
-
const path = yield*
|
|
4374
|
-
const getProjects = () =>
|
|
4542
|
+
const fileSystem = yield* FileSystem10.FileSystem;
|
|
4543
|
+
const path = yield* Path13.Path;
|
|
4544
|
+
const getProjects = () => Effect32.gen(function* () {
|
|
4375
4545
|
const { projects } = yield* projectRepository.getProjects();
|
|
4376
4546
|
return {
|
|
4377
4547
|
status: 200,
|
|
4378
4548
|
response: { projects }
|
|
4379
4549
|
};
|
|
4380
4550
|
});
|
|
4381
|
-
const getProject = (options) =>
|
|
4551
|
+
const getProject = (options) => Effect32.gen(function* () {
|
|
4382
4552
|
const { projectId, cursor } = options;
|
|
4383
4553
|
const userConfig = yield* userConfigService.getUserConfig();
|
|
4384
4554
|
const { project } = yield* projectRepository.getProject(projectId);
|
|
@@ -4432,7 +4602,7 @@ var LayerImpl20 = Effect29.gen(function* () {
|
|
|
4432
4602
|
}
|
|
4433
4603
|
};
|
|
4434
4604
|
});
|
|
4435
|
-
const getProjectLatestSession = (options) =>
|
|
4605
|
+
const getProjectLatestSession = (options) => Effect32.gen(function* () {
|
|
4436
4606
|
const { projectId } = options;
|
|
4437
4607
|
const { sessions } = yield* sessionRepository.getSessions(projectId, {
|
|
4438
4608
|
maxCount: 1
|
|
@@ -4444,7 +4614,7 @@ var LayerImpl20 = Effect29.gen(function* () {
|
|
|
4444
4614
|
}
|
|
4445
4615
|
};
|
|
4446
4616
|
});
|
|
4447
|
-
const createProject = (options) =>
|
|
4617
|
+
const createProject = (options) => Effect32.gen(function* () {
|
|
4448
4618
|
const { projectPath } = options;
|
|
4449
4619
|
const claudeProjectFilePath = yield* computeClaudeProjectFilePath({
|
|
4450
4620
|
projectPath,
|
|
@@ -4481,16 +4651,16 @@ var LayerImpl20 = Effect29.gen(function* () {
|
|
|
4481
4651
|
createProject
|
|
4482
4652
|
};
|
|
4483
4653
|
});
|
|
4484
|
-
var ProjectController = class extends
|
|
4654
|
+
var ProjectController = class extends Context27.Tag("ProjectController")() {
|
|
4485
4655
|
static {
|
|
4486
|
-
this.Live =
|
|
4656
|
+
this.Live = Layer29.effect(this, LayerImpl22);
|
|
4487
4657
|
}
|
|
4488
4658
|
};
|
|
4489
4659
|
|
|
4490
4660
|
// src/server/core/scheduler/config.ts
|
|
4491
4661
|
import { homedir as homedir4 } from "node:os";
|
|
4492
|
-
import { FileSystem as
|
|
4493
|
-
import { Context as
|
|
4662
|
+
import { FileSystem as FileSystem11, Path as Path14 } from "@effect/platform";
|
|
4663
|
+
import { Context as Context28, Data as Data5, Effect as Effect33, Layer as Layer30 } from "effect";
|
|
4494
4664
|
|
|
4495
4665
|
// src/server/core/scheduler/schema.ts
|
|
4496
4666
|
import { z as z23 } from "zod";
|
|
@@ -4551,29 +4721,29 @@ var ConfigParseError = class extends Data5.TaggedError("ConfigParseError") {
|
|
|
4551
4721
|
};
|
|
4552
4722
|
var CONFIG_DIR = "scheduler";
|
|
4553
4723
|
var CONFIG_FILE = "schedules.json";
|
|
4554
|
-
var SchedulerConfigBaseDir = class extends
|
|
4724
|
+
var SchedulerConfigBaseDir = class extends Context28.Tag(
|
|
4555
4725
|
"SchedulerConfigBaseDir"
|
|
4556
4726
|
)() {
|
|
4557
4727
|
static {
|
|
4558
|
-
this.Live =
|
|
4728
|
+
this.Live = Layer30.succeed(this, `${homedir4()}/.claude-code-viewer`);
|
|
4559
4729
|
}
|
|
4560
4730
|
};
|
|
4561
|
-
var getConfigPath =
|
|
4562
|
-
const path = yield*
|
|
4731
|
+
var getConfigPath = Effect33.gen(function* () {
|
|
4732
|
+
const path = yield* Path14.Path;
|
|
4563
4733
|
const baseDir = yield* SchedulerConfigBaseDir;
|
|
4564
4734
|
return path.join(baseDir, CONFIG_DIR, CONFIG_FILE);
|
|
4565
4735
|
});
|
|
4566
|
-
var readConfig =
|
|
4567
|
-
const fs = yield*
|
|
4736
|
+
var readConfig = Effect33.gen(function* () {
|
|
4737
|
+
const fs = yield* FileSystem11.FileSystem;
|
|
4568
4738
|
const configPath = yield* getConfigPath;
|
|
4569
4739
|
const exists = yield* fs.exists(configPath);
|
|
4570
4740
|
if (!exists) {
|
|
4571
|
-
return yield*
|
|
4741
|
+
return yield* Effect33.fail(
|
|
4572
4742
|
new ConfigFileNotFoundError({ path: configPath })
|
|
4573
4743
|
);
|
|
4574
4744
|
}
|
|
4575
4745
|
const content = yield* fs.readFileString(configPath);
|
|
4576
|
-
const jsonResult = yield*
|
|
4746
|
+
const jsonResult = yield* Effect33.try({
|
|
4577
4747
|
try: () => JSON.parse(content),
|
|
4578
4748
|
catch: (error) => new ConfigParseError({
|
|
4579
4749
|
path: configPath,
|
|
@@ -4582,7 +4752,7 @@ var readConfig = Effect30.gen(function* () {
|
|
|
4582
4752
|
});
|
|
4583
4753
|
const parsed = schedulerConfigSchema.safeParse(jsonResult);
|
|
4584
4754
|
if (!parsed.success) {
|
|
4585
|
-
return yield*
|
|
4755
|
+
return yield* Effect33.fail(
|
|
4586
4756
|
new ConfigParseError({
|
|
4587
4757
|
path: configPath,
|
|
4588
4758
|
cause: parsed.error
|
|
@@ -4591,24 +4761,24 @@ var readConfig = Effect30.gen(function* () {
|
|
|
4591
4761
|
}
|
|
4592
4762
|
return parsed.data;
|
|
4593
4763
|
});
|
|
4594
|
-
var writeConfig = (config) =>
|
|
4595
|
-
const fs = yield*
|
|
4596
|
-
const path = yield*
|
|
4764
|
+
var writeConfig = (config) => Effect33.gen(function* () {
|
|
4765
|
+
const fs = yield* FileSystem11.FileSystem;
|
|
4766
|
+
const path = yield* Path14.Path;
|
|
4597
4767
|
const configPath = yield* getConfigPath;
|
|
4598
4768
|
const configDir = path.dirname(configPath);
|
|
4599
4769
|
yield* fs.makeDirectory(configDir, { recursive: true });
|
|
4600
4770
|
const content = JSON.stringify(config, null, 2);
|
|
4601
4771
|
yield* fs.writeFileString(configPath, content);
|
|
4602
4772
|
});
|
|
4603
|
-
var initializeConfig =
|
|
4773
|
+
var initializeConfig = Effect33.gen(function* () {
|
|
4604
4774
|
const result = yield* readConfig.pipe(
|
|
4605
|
-
|
|
4606
|
-
ConfigFileNotFoundError: () =>
|
|
4775
|
+
Effect33.catchTags({
|
|
4776
|
+
ConfigFileNotFoundError: () => Effect33.gen(function* () {
|
|
4607
4777
|
const initialConfig = { jobs: [] };
|
|
4608
4778
|
yield* writeConfig(initialConfig);
|
|
4609
4779
|
return initialConfig;
|
|
4610
4780
|
}),
|
|
4611
|
-
ConfigParseError: () =>
|
|
4781
|
+
ConfigParseError: () => Effect33.gen(function* () {
|
|
4612
4782
|
const initialConfig = { jobs: [] };
|
|
4613
4783
|
yield* writeConfig(initialConfig);
|
|
4614
4784
|
return initialConfig;
|
|
@@ -4620,21 +4790,21 @@ var initializeConfig = Effect30.gen(function* () {
|
|
|
4620
4790
|
|
|
4621
4791
|
// src/server/core/scheduler/domain/Scheduler.ts
|
|
4622
4792
|
import {
|
|
4623
|
-
Context as
|
|
4793
|
+
Context as Context29,
|
|
4624
4794
|
Cron,
|
|
4625
4795
|
Data as Data6,
|
|
4626
4796
|
Duration as Duration2,
|
|
4627
|
-
Effect as
|
|
4797
|
+
Effect as Effect35,
|
|
4628
4798
|
Fiber,
|
|
4629
|
-
Layer as
|
|
4799
|
+
Layer as Layer31,
|
|
4630
4800
|
Ref as Ref10,
|
|
4631
4801
|
Schedule
|
|
4632
4802
|
} from "effect";
|
|
4633
4803
|
import { ulid as ulid4 } from "ulid";
|
|
4634
4804
|
|
|
4635
4805
|
// src/server/core/scheduler/domain/Job.ts
|
|
4636
|
-
import { Effect as
|
|
4637
|
-
var executeJob = (job) =>
|
|
4806
|
+
import { Effect as Effect34 } from "effect";
|
|
4807
|
+
var executeJob = (job) => Effect34.gen(function* () {
|
|
4638
4808
|
const lifeCycleService = yield* ClaudeCodeLifeCycleService;
|
|
4639
4809
|
const projectRepository = yield* ProjectRepository;
|
|
4640
4810
|
const userConfigService = yield* UserConfigService;
|
|
@@ -4642,7 +4812,7 @@ var executeJob = (job) => Effect31.gen(function* () {
|
|
|
4642
4812
|
const { project } = yield* projectRepository.getProject(message.projectId);
|
|
4643
4813
|
const userConfig = yield* userConfigService.getUserConfig();
|
|
4644
4814
|
if (project.meta.projectPath === null) {
|
|
4645
|
-
return yield*
|
|
4815
|
+
return yield* Effect34.fail(
|
|
4646
4816
|
new Error(`Project path not found for projectId: ${message.projectId}`)
|
|
4647
4817
|
);
|
|
4648
4818
|
}
|
|
@@ -4676,15 +4846,15 @@ var InvalidCronExpressionError = class extends Data6.TaggedError(
|
|
|
4676
4846
|
"InvalidCronExpressionError"
|
|
4677
4847
|
) {
|
|
4678
4848
|
};
|
|
4679
|
-
var
|
|
4849
|
+
var LayerImpl23 = Effect35.gen(function* () {
|
|
4680
4850
|
const fibersRef = yield* Ref10.make(/* @__PURE__ */ new Map());
|
|
4681
4851
|
const runningJobsRef = yield* Ref10.make(/* @__PURE__ */ new Set());
|
|
4682
|
-
const startJob = (job) =>
|
|
4852
|
+
const startJob = (job) => Effect35.gen(function* () {
|
|
4683
4853
|
const now = /* @__PURE__ */ new Date();
|
|
4684
4854
|
if (job.schedule.type === "cron") {
|
|
4685
4855
|
const cronResult = Cron.parse(job.schedule.expression);
|
|
4686
4856
|
if (cronResult._tag === "Left") {
|
|
4687
|
-
return yield*
|
|
4857
|
+
return yield* Effect35.fail(
|
|
4688
4858
|
new InvalidCronExpressionError({
|
|
4689
4859
|
expression: job.schedule.expression,
|
|
4690
4860
|
cause: cronResult.left
|
|
@@ -4692,12 +4862,12 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4692
4862
|
);
|
|
4693
4863
|
}
|
|
4694
4864
|
const cronSchedule = Schedule.cron(cronResult.right);
|
|
4695
|
-
const fiber = yield*
|
|
4865
|
+
const fiber = yield* Effect35.gen(function* () {
|
|
4696
4866
|
const nextTime = Cron.next(cronResult.right, /* @__PURE__ */ new Date());
|
|
4697
4867
|
const nextDelay = Math.max(0, nextTime.getTime() - Date.now());
|
|
4698
|
-
yield*
|
|
4699
|
-
yield*
|
|
4700
|
-
}).pipe(
|
|
4868
|
+
yield* Effect35.sleep(Duration2.millis(nextDelay));
|
|
4869
|
+
yield* Effect35.repeat(runJobWithConcurrencyControl(job), cronSchedule);
|
|
4870
|
+
}).pipe(Effect35.forkDaemon);
|
|
4701
4871
|
yield* Ref10.update(
|
|
4702
4872
|
fibersRef,
|
|
4703
4873
|
(fibers) => new Map(fibers).set(job.id, fiber)
|
|
@@ -4708,17 +4878,17 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4708
4878
|
}
|
|
4709
4879
|
const delay = calculateReservedDelay(job, now);
|
|
4710
4880
|
const delayDuration = Duration2.millis(delay);
|
|
4711
|
-
const fiber = yield*
|
|
4881
|
+
const fiber = yield* Effect35.delay(
|
|
4712
4882
|
runJobWithConcurrencyControl(job),
|
|
4713
4883
|
delayDuration
|
|
4714
|
-
).pipe(
|
|
4884
|
+
).pipe(Effect35.forkDaemon);
|
|
4715
4885
|
yield* Ref10.update(
|
|
4716
4886
|
fibersRef,
|
|
4717
4887
|
(fibers) => new Map(fibers).set(job.id, fiber)
|
|
4718
4888
|
);
|
|
4719
4889
|
}
|
|
4720
4890
|
});
|
|
4721
|
-
const runJobWithConcurrencyControl = (job) =>
|
|
4891
|
+
const runJobWithConcurrencyControl = (job) => Effect35.gen(function* () {
|
|
4722
4892
|
if (job.schedule.type === "cron" && job.schedule.concurrencyPolicy === "skip") {
|
|
4723
4893
|
const runningJobs = yield* Ref10.get(runningJobsRef);
|
|
4724
4894
|
if (runningJobs.has(job.id)) {
|
|
@@ -4728,9 +4898,9 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4728
4898
|
yield* Ref10.update(runningJobsRef, (jobs) => new Set(jobs).add(job.id));
|
|
4729
4899
|
if (job.schedule.type === "reserved") {
|
|
4730
4900
|
const result2 = yield* executeJob(job).pipe(
|
|
4731
|
-
|
|
4732
|
-
onSuccess: () =>
|
|
4733
|
-
onFailure: () =>
|
|
4901
|
+
Effect35.matchEffect({
|
|
4902
|
+
onSuccess: () => Effect35.void,
|
|
4903
|
+
onFailure: () => Effect35.void
|
|
4734
4904
|
})
|
|
4735
4905
|
);
|
|
4736
4906
|
yield* Ref10.update(runningJobsRef, (jobs) => {
|
|
@@ -4739,18 +4909,18 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4739
4909
|
return newJobs;
|
|
4740
4910
|
});
|
|
4741
4911
|
yield* deleteJobFromConfig(job.id).pipe(
|
|
4742
|
-
|
|
4912
|
+
Effect35.catchAll((error) => {
|
|
4743
4913
|
console.error(
|
|
4744
4914
|
`[Scheduler] Failed to delete reserved job ${job.id}:`,
|
|
4745
4915
|
error
|
|
4746
4916
|
);
|
|
4747
|
-
return
|
|
4917
|
+
return Effect35.void;
|
|
4748
4918
|
})
|
|
4749
4919
|
);
|
|
4750
4920
|
return result2;
|
|
4751
4921
|
}
|
|
4752
4922
|
const result = yield* executeJob(job).pipe(
|
|
4753
|
-
|
|
4923
|
+
Effect35.matchEffect({
|
|
4754
4924
|
onSuccess: () => updateJobStatus(job.id, "success", (/* @__PURE__ */ new Date()).toISOString()),
|
|
4755
4925
|
onFailure: () => updateJobStatus(job.id, "failed", (/* @__PURE__ */ new Date()).toISOString())
|
|
4756
4926
|
})
|
|
@@ -4762,7 +4932,7 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4762
4932
|
});
|
|
4763
4933
|
return result;
|
|
4764
4934
|
});
|
|
4765
|
-
const updateJobStatus = (jobId, status, runAt) =>
|
|
4935
|
+
const updateJobStatus = (jobId, status, runAt) => Effect35.gen(function* () {
|
|
4766
4936
|
const config = yield* readConfig;
|
|
4767
4937
|
const job = config.jobs.find((j) => j.id === jobId);
|
|
4768
4938
|
if (job === void 0) {
|
|
@@ -4778,7 +4948,7 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4778
4948
|
};
|
|
4779
4949
|
yield* writeConfig(updatedConfig);
|
|
4780
4950
|
});
|
|
4781
|
-
const stopJob = (jobId) =>
|
|
4951
|
+
const stopJob = (jobId) => Effect35.gen(function* () {
|
|
4782
4952
|
const fibers = yield* Ref10.get(fibersRef);
|
|
4783
4953
|
const fiber = fibers.get(jobId);
|
|
4784
4954
|
if (fiber !== void 0) {
|
|
@@ -4790,7 +4960,7 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4790
4960
|
});
|
|
4791
4961
|
}
|
|
4792
4962
|
});
|
|
4793
|
-
const startScheduler =
|
|
4963
|
+
const startScheduler = Effect35.gen(function* () {
|
|
4794
4964
|
yield* initializeConfig;
|
|
4795
4965
|
const config = yield* readConfig;
|
|
4796
4966
|
for (const job of config.jobs) {
|
|
@@ -4799,27 +4969,27 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4799
4969
|
}
|
|
4800
4970
|
}
|
|
4801
4971
|
});
|
|
4802
|
-
const stopScheduler =
|
|
4972
|
+
const stopScheduler = Effect35.gen(function* () {
|
|
4803
4973
|
const fibers = yield* Ref10.get(fibersRef);
|
|
4804
4974
|
for (const fiber of fibers.values()) {
|
|
4805
4975
|
yield* Fiber.interrupt(fiber);
|
|
4806
4976
|
}
|
|
4807
4977
|
yield* Ref10.set(fibersRef, /* @__PURE__ */ new Map());
|
|
4808
4978
|
});
|
|
4809
|
-
const getJobs = () =>
|
|
4979
|
+
const getJobs = () => Effect35.gen(function* () {
|
|
4810
4980
|
const config = yield* readConfig.pipe(
|
|
4811
|
-
|
|
4812
|
-
ConfigFileNotFoundError: () => initializeConfig.pipe(
|
|
4813
|
-
ConfigParseError: () => initializeConfig.pipe(
|
|
4981
|
+
Effect35.catchTags({
|
|
4982
|
+
ConfigFileNotFoundError: () => initializeConfig.pipe(Effect35.map(() => ({ jobs: [] }))),
|
|
4983
|
+
ConfigParseError: () => initializeConfig.pipe(Effect35.map(() => ({ jobs: [] })))
|
|
4814
4984
|
})
|
|
4815
4985
|
);
|
|
4816
4986
|
return config.jobs;
|
|
4817
4987
|
});
|
|
4818
|
-
const addJob = (newJob) =>
|
|
4988
|
+
const addJob = (newJob) => Effect35.gen(function* () {
|
|
4819
4989
|
const config = yield* readConfig.pipe(
|
|
4820
|
-
|
|
4821
|
-
ConfigFileNotFoundError: () => initializeConfig.pipe(
|
|
4822
|
-
ConfigParseError: () => initializeConfig.pipe(
|
|
4990
|
+
Effect35.catchTags({
|
|
4991
|
+
ConfigFileNotFoundError: () => initializeConfig.pipe(Effect35.map(() => ({ jobs: [] }))),
|
|
4992
|
+
ConfigParseError: () => initializeConfig.pipe(Effect35.map(() => ({ jobs: [] })))
|
|
4823
4993
|
})
|
|
4824
4994
|
);
|
|
4825
4995
|
const job = {
|
|
@@ -4838,16 +5008,16 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4838
5008
|
}
|
|
4839
5009
|
return job;
|
|
4840
5010
|
});
|
|
4841
|
-
const updateJob = (jobId, updates) =>
|
|
5011
|
+
const updateJob = (jobId, updates) => Effect35.gen(function* () {
|
|
4842
5012
|
const config = yield* readConfig.pipe(
|
|
4843
|
-
|
|
4844
|
-
ConfigFileNotFoundError: () => initializeConfig.pipe(
|
|
4845
|
-
ConfigParseError: () => initializeConfig.pipe(
|
|
5013
|
+
Effect35.catchTags({
|
|
5014
|
+
ConfigFileNotFoundError: () => initializeConfig.pipe(Effect35.map(() => ({ jobs: [] }))),
|
|
5015
|
+
ConfigParseError: () => initializeConfig.pipe(Effect35.map(() => ({ jobs: [] })))
|
|
4846
5016
|
})
|
|
4847
5017
|
);
|
|
4848
5018
|
const job = config.jobs.find((j) => j.id === jobId);
|
|
4849
5019
|
if (job === void 0) {
|
|
4850
|
-
return yield*
|
|
5020
|
+
return yield* Effect35.fail(new SchedulerJobNotFoundError({ jobId }));
|
|
4851
5021
|
}
|
|
4852
5022
|
yield* stopJob(jobId);
|
|
4853
5023
|
const updatedJob = {
|
|
@@ -4863,32 +5033,32 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4863
5033
|
}
|
|
4864
5034
|
return updatedJob;
|
|
4865
5035
|
});
|
|
4866
|
-
const deleteJobFromConfig = (jobId) =>
|
|
5036
|
+
const deleteJobFromConfig = (jobId) => Effect35.gen(function* () {
|
|
4867
5037
|
const config = yield* readConfig.pipe(
|
|
4868
|
-
|
|
4869
|
-
ConfigFileNotFoundError: () => initializeConfig.pipe(
|
|
4870
|
-
ConfigParseError: () => initializeConfig.pipe(
|
|
5038
|
+
Effect35.catchTags({
|
|
5039
|
+
ConfigFileNotFoundError: () => initializeConfig.pipe(Effect35.map(() => ({ jobs: [] }))),
|
|
5040
|
+
ConfigParseError: () => initializeConfig.pipe(Effect35.map(() => ({ jobs: [] })))
|
|
4871
5041
|
})
|
|
4872
5042
|
);
|
|
4873
5043
|
const job = config.jobs.find((j) => j.id === jobId);
|
|
4874
5044
|
if (job === void 0) {
|
|
4875
|
-
return yield*
|
|
5045
|
+
return yield* Effect35.fail(new SchedulerJobNotFoundError({ jobId }));
|
|
4876
5046
|
}
|
|
4877
5047
|
const updatedConfig = {
|
|
4878
5048
|
jobs: config.jobs.filter((j) => j.id !== jobId)
|
|
4879
5049
|
};
|
|
4880
5050
|
yield* writeConfig(updatedConfig);
|
|
4881
5051
|
});
|
|
4882
|
-
const deleteJob = (jobId) =>
|
|
5052
|
+
const deleteJob = (jobId) => Effect35.gen(function* () {
|
|
4883
5053
|
const config = yield* readConfig.pipe(
|
|
4884
|
-
|
|
4885
|
-
ConfigFileNotFoundError: () => initializeConfig.pipe(
|
|
4886
|
-
ConfigParseError: () => initializeConfig.pipe(
|
|
5054
|
+
Effect35.catchTags({
|
|
5055
|
+
ConfigFileNotFoundError: () => initializeConfig.pipe(Effect35.map(() => ({ jobs: [] }))),
|
|
5056
|
+
ConfigParseError: () => initializeConfig.pipe(Effect35.map(() => ({ jobs: [] })))
|
|
4887
5057
|
})
|
|
4888
5058
|
);
|
|
4889
5059
|
const job = config.jobs.find((j) => j.id === jobId);
|
|
4890
5060
|
if (job === void 0) {
|
|
4891
|
-
return yield*
|
|
5061
|
+
return yield* Effect35.fail(new SchedulerJobNotFoundError({ jobId }));
|
|
4892
5062
|
}
|
|
4893
5063
|
yield* stopJob(jobId);
|
|
4894
5064
|
yield* deleteJobFromConfig(jobId);
|
|
@@ -4902,24 +5072,24 @@ var LayerImpl21 = Effect32.gen(function* () {
|
|
|
4902
5072
|
deleteJob
|
|
4903
5073
|
};
|
|
4904
5074
|
});
|
|
4905
|
-
var SchedulerService = class extends
|
|
5075
|
+
var SchedulerService = class extends Context29.Tag("SchedulerService")() {
|
|
4906
5076
|
static {
|
|
4907
|
-
this.Live =
|
|
5077
|
+
this.Live = Layer31.effect(this, LayerImpl23);
|
|
4908
5078
|
}
|
|
4909
5079
|
};
|
|
4910
5080
|
|
|
4911
5081
|
// src/server/core/scheduler/presentation/SchedulerController.ts
|
|
4912
|
-
import { Context as
|
|
4913
|
-
var
|
|
5082
|
+
import { Context as Context30, Effect as Effect36, Layer as Layer32 } from "effect";
|
|
5083
|
+
var LayerImpl24 = Effect36.gen(function* () {
|
|
4914
5084
|
const schedulerService = yield* SchedulerService;
|
|
4915
|
-
const getJobs = () =>
|
|
5085
|
+
const getJobs = () => Effect36.gen(function* () {
|
|
4916
5086
|
const jobs = yield* schedulerService.getJobs();
|
|
4917
5087
|
return {
|
|
4918
5088
|
response: jobs,
|
|
4919
5089
|
status: 200
|
|
4920
5090
|
};
|
|
4921
5091
|
});
|
|
4922
|
-
const addJob = (options) =>
|
|
5092
|
+
const addJob = (options) => Effect36.gen(function* () {
|
|
4923
5093
|
const { job } = options;
|
|
4924
5094
|
const result = yield* schedulerService.addJob(job);
|
|
4925
5095
|
return {
|
|
@@ -4927,12 +5097,12 @@ var LayerImpl22 = Effect33.gen(function* () {
|
|
|
4927
5097
|
status: 201
|
|
4928
5098
|
};
|
|
4929
5099
|
});
|
|
4930
|
-
const updateJob = (options) =>
|
|
5100
|
+
const updateJob = (options) => Effect36.gen(function* () {
|
|
4931
5101
|
const { id, job } = options;
|
|
4932
5102
|
const result = yield* schedulerService.updateJob(id, job).pipe(
|
|
4933
|
-
|
|
5103
|
+
Effect36.catchTag(
|
|
4934
5104
|
"SchedulerJobNotFoundError",
|
|
4935
|
-
() =>
|
|
5105
|
+
() => Effect36.succeed(null)
|
|
4936
5106
|
)
|
|
4937
5107
|
);
|
|
4938
5108
|
if (result === null) {
|
|
@@ -4946,14 +5116,14 @@ var LayerImpl22 = Effect33.gen(function* () {
|
|
|
4946
5116
|
status: 200
|
|
4947
5117
|
};
|
|
4948
5118
|
});
|
|
4949
|
-
const deleteJob = (options) =>
|
|
5119
|
+
const deleteJob = (options) => Effect36.gen(function* () {
|
|
4950
5120
|
const { id } = options;
|
|
4951
5121
|
const result = yield* schedulerService.deleteJob(id).pipe(
|
|
4952
|
-
|
|
5122
|
+
Effect36.catchTag(
|
|
4953
5123
|
"SchedulerJobNotFoundError",
|
|
4954
|
-
() =>
|
|
5124
|
+
() => Effect36.succeed(false)
|
|
4955
5125
|
),
|
|
4956
|
-
|
|
5126
|
+
Effect36.map(() => true)
|
|
4957
5127
|
);
|
|
4958
5128
|
if (!result) {
|
|
4959
5129
|
return {
|
|
@@ -4973,17 +5143,798 @@ var LayerImpl22 = Effect33.gen(function* () {
|
|
|
4973
5143
|
deleteJob
|
|
4974
5144
|
};
|
|
4975
5145
|
});
|
|
4976
|
-
var SchedulerController = class extends
|
|
5146
|
+
var SchedulerController = class extends Context30.Tag("SchedulerController")() {
|
|
4977
5147
|
static {
|
|
4978
|
-
this.Live =
|
|
5148
|
+
this.Live = Layer32.effect(this, LayerImpl24);
|
|
5149
|
+
}
|
|
5150
|
+
};
|
|
5151
|
+
|
|
5152
|
+
// src/server/core/session/presentation/SessionController.ts
|
|
5153
|
+
import { Context as Context31, Effect as Effect38, Layer as Layer33 } from "effect";
|
|
5154
|
+
|
|
5155
|
+
// src/server/core/session/services/ExportService.ts
|
|
5156
|
+
import { Effect as Effect37 } from "effect";
|
|
5157
|
+
var escapeHtml = (text) => {
|
|
5158
|
+
const map = {
|
|
5159
|
+
"&": "&",
|
|
5160
|
+
"<": "<",
|
|
5161
|
+
">": ">",
|
|
5162
|
+
'"': """,
|
|
5163
|
+
"'": "'"
|
|
5164
|
+
};
|
|
5165
|
+
return text.replace(/[&<>"']/g, (char) => map[char] ?? char);
|
|
5166
|
+
};
|
|
5167
|
+
var formatJsonWithNewlines = (obj) => {
|
|
5168
|
+
const jsonString = JSON.stringify(obj, null, 2);
|
|
5169
|
+
return jsonString.replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\r/g, "\r");
|
|
5170
|
+
};
|
|
5171
|
+
var formatTimestamp = (timestamp) => {
|
|
5172
|
+
const date = new Date(timestamp);
|
|
5173
|
+
return date.toLocaleString("en-US", {
|
|
5174
|
+
year: "numeric",
|
|
5175
|
+
month: "short",
|
|
5176
|
+
day: "numeric",
|
|
5177
|
+
hour: "2-digit",
|
|
5178
|
+
minute: "2-digit",
|
|
5179
|
+
second: "2-digit"
|
|
5180
|
+
});
|
|
5181
|
+
};
|
|
5182
|
+
var renderMarkdown = (content) => {
|
|
5183
|
+
let html = escapeHtml(content);
|
|
5184
|
+
html = html.replace(
|
|
5185
|
+
/```(\w+)?\n([\s\S]*?)```/g,
|
|
5186
|
+
(_match, lang, code) => `
|
|
5187
|
+
<div class="code-block">
|
|
5188
|
+
${lang ? `<div class="code-header"><span class="code-lang">${escapeHtml(lang.toUpperCase())}</span></div>` : ""}
|
|
5189
|
+
<pre><code class="language-${escapeHtml(lang || "text")}">${code.trim()}</code></pre>
|
|
5190
|
+
</div>
|
|
5191
|
+
`
|
|
5192
|
+
);
|
|
5193
|
+
html = html.replace(/`([^`]+)`/g, '<code class="inline-code">$1</code>');
|
|
5194
|
+
html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
|
|
5195
|
+
html = html.replace(/\*(.+?)\*/g, "<em>$1</em>");
|
|
5196
|
+
html = html.replace(/^### (.+)$/gm, '<h3 class="markdown-h3">$1</h3>');
|
|
5197
|
+
html = html.replace(/^## (.+)$/gm, '<h2 class="markdown-h2">$1</h2>');
|
|
5198
|
+
html = html.replace(/^# (.+)$/gm, '<h1 class="markdown-h1">$1</h1>');
|
|
5199
|
+
html = html.replace(
|
|
5200
|
+
/\[([^\]]+)\]\(([^)]+)\)/g,
|
|
5201
|
+
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
|
|
5202
|
+
);
|
|
5203
|
+
html = html.split("\n\n").map((para) => {
|
|
5204
|
+
if (para.startsWith("<h") || para.startsWith("<div") || para.startsWith("<pre") || para.trim() === "") {
|
|
5205
|
+
return para;
|
|
5206
|
+
}
|
|
5207
|
+
return `<p class="markdown-p">${para.replace(/\n/g, "<br>")}</p>`;
|
|
5208
|
+
}).join("\n");
|
|
5209
|
+
return html;
|
|
5210
|
+
};
|
|
5211
|
+
var renderUserEntry = (entry) => {
|
|
5212
|
+
const contentArray = Array.isArray(entry.message.content) ? entry.message.content : [entry.message.content];
|
|
5213
|
+
const contentHtml = contentArray.map((msg) => {
|
|
5214
|
+
if (typeof msg === "string") {
|
|
5215
|
+
return `<div class="markdown-content">${renderMarkdown(msg)}</div>`;
|
|
5216
|
+
}
|
|
5217
|
+
if (msg.type === "text") {
|
|
5218
|
+
return `<div class="markdown-content">${renderMarkdown(msg.text)}</div>`;
|
|
5219
|
+
}
|
|
5220
|
+
if (msg.type === "image") {
|
|
5221
|
+
return `<img src="data:${msg.source.media_type};base64,${msg.source.data}" alt="User uploaded image" class="message-image" />`;
|
|
5222
|
+
}
|
|
5223
|
+
if (msg.type === "document") {
|
|
5224
|
+
return `<div class="document-content"><strong>Document:</strong> ${escapeHtml(msg.source.media_type)}</div>`;
|
|
5225
|
+
}
|
|
5226
|
+
if (msg.type === "tool_result") {
|
|
5227
|
+
return "";
|
|
5228
|
+
}
|
|
5229
|
+
return "";
|
|
5230
|
+
}).join("");
|
|
5231
|
+
if (!contentHtml.trim()) {
|
|
5232
|
+
return "";
|
|
5233
|
+
}
|
|
5234
|
+
return `
|
|
5235
|
+
<div class="conversation-entry user-entry">
|
|
5236
|
+
<div class="entry-header">
|
|
5237
|
+
<span class="entry-role">User</span>
|
|
5238
|
+
<span class="entry-timestamp">${formatTimestamp(entry.timestamp)}</span>
|
|
5239
|
+
</div>
|
|
5240
|
+
<div class="entry-content">
|
|
5241
|
+
${contentHtml}
|
|
5242
|
+
</div>
|
|
5243
|
+
</div>
|
|
5244
|
+
`;
|
|
5245
|
+
};
|
|
5246
|
+
var renderAssistantEntry = (entry) => {
|
|
5247
|
+
const contentHtml = entry.message.content.map((msg) => {
|
|
5248
|
+
if (msg.type === "text") {
|
|
5249
|
+
return `<div class="markdown-content">${renderMarkdown(msg.text)}</div>`;
|
|
5250
|
+
}
|
|
5251
|
+
if (msg.type === "thinking") {
|
|
5252
|
+
const charCount = msg.thinking.length;
|
|
5253
|
+
return `
|
|
5254
|
+
<div class="thinking-block collapsible">
|
|
5255
|
+
<div class="thinking-header collapsible-trigger">
|
|
5256
|
+
<svg class="icon-lightbulb" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
5257
|
+
<path d="M12 2v1m0 18v1m9-10h1M2 12H1m17.66-7.66l.71.71M3.63 20.37l.71.71m0-14.14l-.71.71m17.02 12.73l-.71.71M12 7a5 5 0 0 1 5 5 5 5 0 0 1-1.47 3.53c-.6.6-.94 1.42-.94 2.27V18a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1v-.2c0-.85-.34-1.67-.94-2.27A5 5 0 0 1 7 12a5 5 0 0 1 5-5Z"/>
|
|
5258
|
+
</svg>
|
|
5259
|
+
<span class="thinking-title">Thinking</span>
|
|
5260
|
+
<span class="expand-hint">(${charCount} characters \xB7 click to collapse)</span>
|
|
5261
|
+
<svg class="icon-chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
5262
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
5263
|
+
</svg>
|
|
5264
|
+
</div>
|
|
5265
|
+
<div class="thinking-content collapsible-content">
|
|
5266
|
+
<pre class="thinking-text">${escapeHtml(msg.thinking)}</pre>
|
|
5267
|
+
</div>
|
|
5268
|
+
</div>
|
|
5269
|
+
`;
|
|
5270
|
+
}
|
|
5271
|
+
if (msg.type === "tool_use") {
|
|
5272
|
+
const inputKeys = Object.keys(msg.input).length;
|
|
5273
|
+
return `
|
|
5274
|
+
<div class="tool-use-block collapsible">
|
|
5275
|
+
<div class="tool-use-header collapsible-trigger">
|
|
5276
|
+
<svg class="icon-wrench" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
5277
|
+
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
|
|
5278
|
+
</svg>
|
|
5279
|
+
<span class="tool-name">${escapeHtml(msg.name)}</span>
|
|
5280
|
+
<span class="expand-hint">(${inputKeys} parameter${inputKeys !== 1 ? "s" : ""} \xB7 click to collapse)</span>
|
|
5281
|
+
<svg class="icon-chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
5282
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
5283
|
+
</svg>
|
|
5284
|
+
</div>
|
|
5285
|
+
<div class="tool-use-content collapsible-content">
|
|
5286
|
+
<div class="tool-id"><strong>Tool ID:</strong> <code>${escapeHtml(msg.id)}</code></div>
|
|
5287
|
+
<div class="tool-input">
|
|
5288
|
+
<strong>Input Parameters:</strong>
|
|
5289
|
+
<pre class="json-input">${escapeHtml(formatJsonWithNewlines(msg.input))}</pre>
|
|
5290
|
+
</div>
|
|
5291
|
+
</div>
|
|
5292
|
+
</div>
|
|
5293
|
+
`;
|
|
5294
|
+
}
|
|
5295
|
+
return "";
|
|
5296
|
+
}).join("");
|
|
5297
|
+
return `
|
|
5298
|
+
<div class="conversation-entry assistant-entry">
|
|
5299
|
+
<div class="entry-header">
|
|
5300
|
+
<span class="entry-role">Assistant</span>
|
|
5301
|
+
<span class="entry-timestamp">${formatTimestamp(entry.timestamp)}</span>
|
|
5302
|
+
</div>
|
|
5303
|
+
<div class="entry-content">
|
|
5304
|
+
${contentHtml}
|
|
5305
|
+
</div>
|
|
5306
|
+
</div>
|
|
5307
|
+
`;
|
|
5308
|
+
};
|
|
5309
|
+
var renderSystemEntry = (entry) => {
|
|
5310
|
+
return `
|
|
5311
|
+
<div class="conversation-entry system-entry">
|
|
5312
|
+
<div class="entry-header">
|
|
5313
|
+
<span class="entry-role">System</span>
|
|
5314
|
+
<span class="entry-timestamp">${formatTimestamp(entry.timestamp)}</span>
|
|
5315
|
+
</div>
|
|
5316
|
+
<div class="entry-content">
|
|
5317
|
+
<div class="system-message">${escapeHtml(entry.content)}</div>
|
|
5318
|
+
</div>
|
|
5319
|
+
</div>
|
|
5320
|
+
`;
|
|
5321
|
+
};
|
|
5322
|
+
var groupConsecutiveAssistantMessages = (conversations) => {
|
|
5323
|
+
const grouped = [];
|
|
5324
|
+
let currentGroup = [];
|
|
5325
|
+
for (const conv of conversations) {
|
|
5326
|
+
if (conv.type === "assistant") {
|
|
5327
|
+
currentGroup.push(conv);
|
|
5328
|
+
} else if (conv.type === "user" || conv.type === "system") {
|
|
5329
|
+
if (currentGroup.length > 0) {
|
|
5330
|
+
grouped.push({
|
|
5331
|
+
type: currentGroup.length > 1 ? "grouped" : "single",
|
|
5332
|
+
entries: currentGroup
|
|
5333
|
+
});
|
|
5334
|
+
currentGroup = [];
|
|
5335
|
+
}
|
|
5336
|
+
grouped.push({ type: "single", entries: [conv] });
|
|
5337
|
+
}
|
|
5338
|
+
}
|
|
5339
|
+
if (currentGroup.length > 0) {
|
|
5340
|
+
grouped.push({
|
|
5341
|
+
type: currentGroup.length > 1 ? "grouped" : "single",
|
|
5342
|
+
entries: currentGroup
|
|
5343
|
+
});
|
|
5344
|
+
}
|
|
5345
|
+
return grouped;
|
|
5346
|
+
};
|
|
5347
|
+
var renderGroupedAssistantEntries = (entries) => {
|
|
5348
|
+
const allContent = entries.flatMap((entry) => entry.message.content);
|
|
5349
|
+
const firstEntry = entries[0];
|
|
5350
|
+
if (!firstEntry) {
|
|
5351
|
+
return "";
|
|
4979
5352
|
}
|
|
5353
|
+
const contentHtml = allContent.map((msg) => {
|
|
5354
|
+
if (msg.type === "text") {
|
|
5355
|
+
return `<div class="markdown-content">${renderMarkdown(msg.text)}</div>`;
|
|
5356
|
+
}
|
|
5357
|
+
if (msg.type === "thinking") {
|
|
5358
|
+
const charCount = msg.thinking.length;
|
|
5359
|
+
return `
|
|
5360
|
+
<div class="thinking-block collapsible">
|
|
5361
|
+
<div class="thinking-header collapsible-trigger">
|
|
5362
|
+
<svg class="icon-lightbulb" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
5363
|
+
<path d="M12 2v1m0 18v1m9-10h1M2 12H1m17.66-7.66l.71.71M3.63 20.37l.71.71m0-14.14l-.71.71m17.02 12.73l-.71.71M12 7a5 5 0 0 1 5 5 5 5 0 0 1-1.47 3.53c-.6.6-.94 1.42-.94 2.27V18a1 1 0 0 1-1 1h-3a1 1 0 0 1-1-1v-.2c0-.85-.34-1.67-.94-2.27A5 5 0 0 1 7 12a5 5 0 0 1 5-5Z"/>
|
|
5364
|
+
</svg>
|
|
5365
|
+
<span class="thinking-title">Thinking</span>
|
|
5366
|
+
<span class="expand-hint">(${charCount} characters \xB7 click to collapse)</span>
|
|
5367
|
+
<svg class="icon-chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
5368
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
5369
|
+
</svg>
|
|
5370
|
+
</div>
|
|
5371
|
+
<div class="thinking-content collapsible-content">
|
|
5372
|
+
<pre class="thinking-text">${escapeHtml(msg.thinking)}</pre>
|
|
5373
|
+
</div>
|
|
5374
|
+
</div>
|
|
5375
|
+
`;
|
|
5376
|
+
}
|
|
5377
|
+
if (msg.type === "tool_use") {
|
|
5378
|
+
const inputKeys = Object.keys(msg.input).length;
|
|
5379
|
+
return `
|
|
5380
|
+
<div class="tool-use-block collapsible">
|
|
5381
|
+
<div class="tool-use-header collapsible-trigger">
|
|
5382
|
+
<svg class="icon-wrench" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
5383
|
+
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
|
|
5384
|
+
</svg>
|
|
5385
|
+
<span class="tool-name">${escapeHtml(msg.name)}</span>
|
|
5386
|
+
<span class="expand-hint">(${inputKeys} parameter${inputKeys !== 1 ? "s" : ""} \xB7 click to collapse)</span>
|
|
5387
|
+
<svg class="icon-chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
5388
|
+
<polyline points="6 9 12 15 18 9"></polyline>
|
|
5389
|
+
</svg>
|
|
5390
|
+
</div>
|
|
5391
|
+
<div class="tool-use-content collapsible-content">
|
|
5392
|
+
<div class="tool-id"><strong>Tool ID:</strong> <code>${escapeHtml(msg.id)}</code></div>
|
|
5393
|
+
<div class="tool-input">
|
|
5394
|
+
<strong>Input Parameters:</strong>
|
|
5395
|
+
<pre class="json-input">${escapeHtml(formatJsonWithNewlines(msg.input))}</pre>
|
|
5396
|
+
</div>
|
|
5397
|
+
</div>
|
|
5398
|
+
</div>
|
|
5399
|
+
`;
|
|
5400
|
+
}
|
|
5401
|
+
return "";
|
|
5402
|
+
}).join("");
|
|
5403
|
+
return `
|
|
5404
|
+
<div class="conversation-entry assistant-entry">
|
|
5405
|
+
<div class="entry-header">
|
|
5406
|
+
<span class="entry-role">Assistant</span>
|
|
5407
|
+
<span class="entry-timestamp">${formatTimestamp(firstEntry.timestamp)}</span>
|
|
5408
|
+
</div>
|
|
5409
|
+
<div class="entry-content">
|
|
5410
|
+
${contentHtml}
|
|
5411
|
+
</div>
|
|
5412
|
+
</div>
|
|
5413
|
+
`;
|
|
4980
5414
|
};
|
|
5415
|
+
var generateSessionHtml = (session, projectId) => Effect37.gen(function* () {
|
|
5416
|
+
const grouped = groupConsecutiveAssistantMessages(session.conversations);
|
|
5417
|
+
const conversationsHtml = grouped.map((group) => {
|
|
5418
|
+
if (group.type === "grouped") {
|
|
5419
|
+
return renderGroupedAssistantEntries(
|
|
5420
|
+
group.entries
|
|
5421
|
+
);
|
|
5422
|
+
}
|
|
5423
|
+
const conv = group.entries[0];
|
|
5424
|
+
if (!conv) {
|
|
5425
|
+
return "";
|
|
5426
|
+
}
|
|
5427
|
+
if (conv.type === "user") {
|
|
5428
|
+
return renderUserEntry(conv);
|
|
5429
|
+
}
|
|
5430
|
+
if (conv.type === "assistant") {
|
|
5431
|
+
return renderAssistantEntry(conv);
|
|
5432
|
+
}
|
|
5433
|
+
if (conv.type === "system") {
|
|
5434
|
+
return renderSystemEntry(conv);
|
|
5435
|
+
}
|
|
5436
|
+
return "";
|
|
5437
|
+
}).filter((html2) => html2 !== "").join("\n");
|
|
5438
|
+
const html = `<!DOCTYPE html>
|
|
5439
|
+
<html lang="en">
|
|
5440
|
+
<head>
|
|
5441
|
+
<meta charset="UTF-8">
|
|
5442
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
5443
|
+
<title>Claude Code Session - ${escapeHtml(session.id)}</title>
|
|
5444
|
+
<style>
|
|
5445
|
+
* {
|
|
5446
|
+
margin: 0;
|
|
5447
|
+
padding: 0;
|
|
5448
|
+
box-sizing: border-box;
|
|
5449
|
+
}
|
|
5450
|
+
|
|
5451
|
+
:root {
|
|
5452
|
+
--background: 0 0% 100%;
|
|
5453
|
+
--foreground: 0 0% 3.9%;
|
|
5454
|
+
--muted: 0 0% 96.1%;
|
|
5455
|
+
--muted-foreground: 0 0% 45.1%;
|
|
5456
|
+
--border: 0 0% 89.8%;
|
|
5457
|
+
--primary: 0 0% 9%;
|
|
5458
|
+
--blue-50: 214 100% 97%;
|
|
5459
|
+
--blue-200: 213 97% 87%;
|
|
5460
|
+
--blue-600: 217 91% 60%;
|
|
5461
|
+
--blue-800: 217 91% 35%;
|
|
5462
|
+
}
|
|
5463
|
+
|
|
5464
|
+
body {
|
|
5465
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
5466
|
+
line-height: 1.6;
|
|
5467
|
+
color: hsl(var(--foreground));
|
|
5468
|
+
background: hsl(var(--background));
|
|
5469
|
+
padding: 2rem;
|
|
5470
|
+
max-width: 1200px;
|
|
5471
|
+
margin: 0 auto;
|
|
5472
|
+
}
|
|
5473
|
+
|
|
5474
|
+
.header {
|
|
5475
|
+
border-bottom: 1px solid hsl(var(--border));
|
|
5476
|
+
padding-bottom: 2rem;
|
|
5477
|
+
margin-bottom: 2rem;
|
|
5478
|
+
}
|
|
5479
|
+
|
|
5480
|
+
.header h1 {
|
|
5481
|
+
font-size: 2rem;
|
|
5482
|
+
font-weight: 700;
|
|
5483
|
+
margin-bottom: 0.5rem;
|
|
5484
|
+
}
|
|
5485
|
+
|
|
5486
|
+
.header .metadata {
|
|
5487
|
+
color: hsl(var(--muted-foreground));
|
|
5488
|
+
font-size: 0.875rem;
|
|
5489
|
+
}
|
|
5490
|
+
|
|
5491
|
+
.conversation-list {
|
|
5492
|
+
display: flex;
|
|
5493
|
+
flex-direction: column;
|
|
5494
|
+
gap: 1.5rem;
|
|
5495
|
+
}
|
|
5496
|
+
|
|
5497
|
+
.conversation-entry {
|
|
5498
|
+
border-radius: 0.5rem;
|
|
5499
|
+
overflow: hidden;
|
|
5500
|
+
}
|
|
5501
|
+
|
|
5502
|
+
.entry-header {
|
|
5503
|
+
display: flex;
|
|
5504
|
+
justify-content: space-between;
|
|
5505
|
+
align-items: center;
|
|
5506
|
+
padding: 0.75rem 1rem;
|
|
5507
|
+
font-size: 0.875rem;
|
|
5508
|
+
font-weight: 500;
|
|
5509
|
+
border-bottom: 1px solid;
|
|
5510
|
+
}
|
|
5511
|
+
|
|
5512
|
+
.entry-timestamp {
|
|
5513
|
+
color: hsl(var(--muted-foreground));
|
|
5514
|
+
font-size: 0.75rem;
|
|
5515
|
+
}
|
|
5516
|
+
|
|
5517
|
+
.entry-content {
|
|
5518
|
+
padding: 1.5rem;
|
|
5519
|
+
}
|
|
5520
|
+
|
|
5521
|
+
/* User entry styles */
|
|
5522
|
+
.user-entry {
|
|
5523
|
+
background: hsl(var(--muted) / 0.3);
|
|
5524
|
+
border: 1px solid hsl(var(--border));
|
|
5525
|
+
}
|
|
5526
|
+
|
|
5527
|
+
.user-entry .entry-header {
|
|
5528
|
+
background: hsl(var(--muted) / 0.5);
|
|
5529
|
+
border-bottom-color: hsl(var(--border));
|
|
5530
|
+
}
|
|
5531
|
+
|
|
5532
|
+
/* Assistant entry styles */
|
|
5533
|
+
.assistant-entry {
|
|
5534
|
+
background: hsl(var(--background));
|
|
5535
|
+
border: 1px solid hsl(var(--border));
|
|
5536
|
+
}
|
|
5537
|
+
|
|
5538
|
+
.assistant-entry .entry-header {
|
|
5539
|
+
background: hsl(var(--muted) / 0.3);
|
|
5540
|
+
border-bottom-color: hsl(var(--border));
|
|
5541
|
+
}
|
|
5542
|
+
|
|
5543
|
+
/* System entry styles */
|
|
5544
|
+
.system-entry {
|
|
5545
|
+
background: hsl(var(--muted) / 0.2);
|
|
5546
|
+
border: 1px dashed hsl(var(--border));
|
|
5547
|
+
}
|
|
5548
|
+
|
|
5549
|
+
.system-entry .entry-header {
|
|
5550
|
+
background: hsl(var(--muted) / 0.4);
|
|
5551
|
+
border-bottom-color: hsl(var(--border));
|
|
5552
|
+
}
|
|
5553
|
+
|
|
5554
|
+
.system-message {
|
|
5555
|
+
font-family: monospace;
|
|
5556
|
+
font-size: 0.875rem;
|
|
5557
|
+
color: hsl(var(--muted-foreground));
|
|
5558
|
+
}
|
|
5559
|
+
|
|
5560
|
+
/* Markdown styles */
|
|
5561
|
+
.markdown-content {
|
|
5562
|
+
width: 100%;
|
|
5563
|
+
margin: 1rem 0.25rem;
|
|
5564
|
+
}
|
|
5565
|
+
|
|
5566
|
+
.markdown-h1 {
|
|
5567
|
+
font-size: 1.875rem;
|
|
5568
|
+
font-weight: 700;
|
|
5569
|
+
margin-bottom: 1.5rem;
|
|
5570
|
+
margin-top: 2rem;
|
|
5571
|
+
padding-bottom: 0.75rem;
|
|
5572
|
+
border-bottom: 1px solid hsl(var(--border));
|
|
5573
|
+
}
|
|
5574
|
+
|
|
5575
|
+
.markdown-h2 {
|
|
5576
|
+
font-size: 1.5rem;
|
|
5577
|
+
font-weight: 600;
|
|
5578
|
+
margin-bottom: 1rem;
|
|
5579
|
+
margin-top: 2rem;
|
|
5580
|
+
padding-bottom: 0.5rem;
|
|
5581
|
+
border-bottom: 1px solid hsl(var(--border) / 0.5);
|
|
5582
|
+
}
|
|
5583
|
+
|
|
5584
|
+
.markdown-h3 {
|
|
5585
|
+
font-size: 1.25rem;
|
|
5586
|
+
font-weight: 600;
|
|
5587
|
+
margin-bottom: 0.75rem;
|
|
5588
|
+
margin-top: 1.5rem;
|
|
5589
|
+
}
|
|
5590
|
+
|
|
5591
|
+
.markdown-p {
|
|
5592
|
+
margin-bottom: 1rem;
|
|
5593
|
+
line-height: 1.75;
|
|
5594
|
+
word-break: break-all;
|
|
5595
|
+
}
|
|
5596
|
+
|
|
5597
|
+
.inline-code {
|
|
5598
|
+
background: hsl(var(--muted) / 0.7);
|
|
5599
|
+
padding: 0.25rem 0.5rem;
|
|
5600
|
+
border-radius: 0.375rem;
|
|
5601
|
+
font-size: 0.875rem;
|
|
5602
|
+
font-family: monospace;
|
|
5603
|
+
border: 1px solid hsl(var(--border));
|
|
5604
|
+
}
|
|
5605
|
+
|
|
5606
|
+
.code-block {
|
|
5607
|
+
position: relative;
|
|
5608
|
+
margin: 1.5rem 0;
|
|
5609
|
+
}
|
|
5610
|
+
|
|
5611
|
+
.code-header {
|
|
5612
|
+
display: flex;
|
|
5613
|
+
align-items: center;
|
|
5614
|
+
justify-content: space-between;
|
|
5615
|
+
background: hsl(var(--muted) / 0.3);
|
|
5616
|
+
padding: 0.5rem 1rem;
|
|
5617
|
+
border-bottom: 1px solid hsl(var(--border));
|
|
5618
|
+
border-top-left-radius: 0.5rem;
|
|
5619
|
+
border-top-right-radius: 0.5rem;
|
|
5620
|
+
border: 1px solid hsl(var(--border));
|
|
5621
|
+
border-bottom: none;
|
|
5622
|
+
}
|
|
5623
|
+
|
|
5624
|
+
.code-lang {
|
|
5625
|
+
font-size: 0.75rem;
|
|
5626
|
+
font-weight: 500;
|
|
5627
|
+
color: hsl(var(--muted-foreground));
|
|
5628
|
+
text-transform: uppercase;
|
|
5629
|
+
letter-spacing: 0.05em;
|
|
5630
|
+
}
|
|
5631
|
+
|
|
5632
|
+
.code-block pre {
|
|
5633
|
+
margin: 0;
|
|
5634
|
+
padding: 1rem;
|
|
5635
|
+
background: hsl(var(--muted) / 0.2);
|
|
5636
|
+
border: 1px solid hsl(var(--border));
|
|
5637
|
+
border-top: none;
|
|
5638
|
+
border-bottom-left-radius: 0.5rem;
|
|
5639
|
+
border-bottom-right-radius: 0.5rem;
|
|
5640
|
+
overflow-x: auto;
|
|
5641
|
+
}
|
|
5642
|
+
|
|
5643
|
+
.code-block code {
|
|
5644
|
+
font-family: 'Monaco', 'Courier New', monospace;
|
|
5645
|
+
font-size: 0.875rem;
|
|
5646
|
+
line-height: 1.5;
|
|
5647
|
+
}
|
|
5648
|
+
|
|
5649
|
+
/* Thinking block styles */
|
|
5650
|
+
.thinking-block {
|
|
5651
|
+
background: hsl(var(--muted) / 0.5);
|
|
5652
|
+
border: 2px dashed hsl(var(--border));
|
|
5653
|
+
border-radius: 0.5rem;
|
|
5654
|
+
margin-bottom: 0.5rem;
|
|
5655
|
+
overflow: hidden;
|
|
5656
|
+
}
|
|
5657
|
+
|
|
5658
|
+
.thinking-header {
|
|
5659
|
+
display: flex;
|
|
5660
|
+
align-items: center;
|
|
5661
|
+
gap: 0.5rem;
|
|
5662
|
+
padding: 0.75rem 1rem;
|
|
5663
|
+
cursor: pointer;
|
|
5664
|
+
background: hsl(var(--muted) / 0.3);
|
|
5665
|
+
transition: background 0.2s;
|
|
5666
|
+
}
|
|
5667
|
+
|
|
5668
|
+
.thinking-header:hover {
|
|
5669
|
+
background: hsl(var(--muted) / 0.5);
|
|
5670
|
+
}
|
|
5671
|
+
|
|
5672
|
+
.icon-lightbulb {
|
|
5673
|
+
color: hsl(var(--muted-foreground));
|
|
5674
|
+
flex-shrink: 0;
|
|
5675
|
+
}
|
|
5676
|
+
|
|
5677
|
+
.thinking-title {
|
|
5678
|
+
font-size: 0.875rem;
|
|
5679
|
+
font-weight: 500;
|
|
5680
|
+
}
|
|
5681
|
+
|
|
5682
|
+
.expand-hint {
|
|
5683
|
+
font-size: 0.75rem;
|
|
5684
|
+
color: hsl(var(--muted-foreground));
|
|
5685
|
+
font-weight: normal;
|
|
5686
|
+
margin-left: 0.5rem;
|
|
5687
|
+
}
|
|
5688
|
+
|
|
5689
|
+
.collapsible:not(.collapsed) .expand-hint {
|
|
5690
|
+
display: none;
|
|
5691
|
+
}
|
|
5692
|
+
|
|
5693
|
+
.icon-chevron {
|
|
5694
|
+
margin-left: auto;
|
|
5695
|
+
color: hsl(var(--muted-foreground));
|
|
5696
|
+
transition: transform 0.2s;
|
|
5697
|
+
}
|
|
5698
|
+
|
|
5699
|
+
.collapsible.collapsed .icon-chevron {
|
|
5700
|
+
transform: rotate(-90deg);
|
|
5701
|
+
}
|
|
5702
|
+
|
|
5703
|
+
.thinking-content {
|
|
5704
|
+
padding: 0.5rem 1rem;
|
|
5705
|
+
}
|
|
5706
|
+
|
|
5707
|
+
.collapsible-content {
|
|
5708
|
+
max-height: 1000px;
|
|
5709
|
+
overflow: hidden;
|
|
5710
|
+
transition: max-height 0.3s ease-out, opacity 0.2s ease-out;
|
|
5711
|
+
}
|
|
5712
|
+
|
|
5713
|
+
.collapsible.collapsed .collapsible-content {
|
|
5714
|
+
max-height: 0;
|
|
5715
|
+
opacity: 0;
|
|
5716
|
+
}
|
|
5717
|
+
|
|
5718
|
+
.thinking-text {
|
|
5719
|
+
font-size: 0.875rem;
|
|
5720
|
+
color: hsl(var(--muted-foreground));
|
|
5721
|
+
font-family: monospace;
|
|
5722
|
+
white-space: pre-wrap;
|
|
5723
|
+
word-break: break-word;
|
|
5724
|
+
}
|
|
5725
|
+
|
|
5726
|
+
/* Tool use block styles */
|
|
5727
|
+
.tool-use-block {
|
|
5728
|
+
border: 1px solid hsl(var(--blue-200));
|
|
5729
|
+
background: hsl(var(--blue-50) / 0.5);
|
|
5730
|
+
border-radius: 0.5rem;
|
|
5731
|
+
margin-bottom: 0.5rem;
|
|
5732
|
+
overflow: hidden;
|
|
5733
|
+
}
|
|
5734
|
+
|
|
5735
|
+
.tool-use-header {
|
|
5736
|
+
display: flex;
|
|
5737
|
+
align-items: center;
|
|
5738
|
+
gap: 0.5rem;
|
|
5739
|
+
padding: 0.375rem 0.75rem;
|
|
5740
|
+
cursor: pointer;
|
|
5741
|
+
background: hsl(var(--blue-50) / 0.3);
|
|
5742
|
+
transition: background 0.2s;
|
|
5743
|
+
}
|
|
5744
|
+
|
|
5745
|
+
.tool-use-header:hover {
|
|
5746
|
+
background: hsl(var(--blue-50) / 0.6);
|
|
5747
|
+
}
|
|
5748
|
+
|
|
5749
|
+
.icon-wrench {
|
|
5750
|
+
color: hsl(var(--blue-600));
|
|
5751
|
+
flex-shrink: 0;
|
|
5752
|
+
}
|
|
5753
|
+
|
|
5754
|
+
.tool-name {
|
|
5755
|
+
font-size: 0.875rem;
|
|
5756
|
+
font-weight: 500;
|
|
5757
|
+
flex: 1;
|
|
5758
|
+
overflow: hidden;
|
|
5759
|
+
text-overflow: ellipsis;
|
|
5760
|
+
white-space: nowrap;
|
|
5761
|
+
}
|
|
5762
|
+
|
|
5763
|
+
.tool-use-content {
|
|
5764
|
+
padding: 0.75rem 1rem;
|
|
5765
|
+
border-top: 1px solid hsl(var(--blue-200));
|
|
5766
|
+
display: flex;
|
|
5767
|
+
flex-direction: column;
|
|
5768
|
+
gap: 0.75rem;
|
|
5769
|
+
}
|
|
5770
|
+
|
|
5771
|
+
.tool-id {
|
|
5772
|
+
font-size: 0.75rem;
|
|
5773
|
+
}
|
|
5774
|
+
|
|
5775
|
+
.tool-id code {
|
|
5776
|
+
background: hsl(var(--background) / 0.5);
|
|
5777
|
+
padding: 0.25rem 0.5rem;
|
|
5778
|
+
border-radius: 0.25rem;
|
|
5779
|
+
border: 1px solid hsl(var(--blue-200));
|
|
5780
|
+
font-family: monospace;
|
|
5781
|
+
font-size: 0.75rem;
|
|
5782
|
+
}
|
|
5783
|
+
|
|
5784
|
+
.tool-input {
|
|
5785
|
+
font-size: 0.75rem;
|
|
5786
|
+
}
|
|
5787
|
+
|
|
5788
|
+
.json-input {
|
|
5789
|
+
background: hsl(var(--background));
|
|
5790
|
+
border: 1px solid hsl(var(--border));
|
|
5791
|
+
border-radius: 0.375rem;
|
|
5792
|
+
padding: 0.75rem;
|
|
5793
|
+
margin-top: 0.5rem;
|
|
5794
|
+
overflow-x: auto;
|
|
5795
|
+
font-family: monospace;
|
|
5796
|
+
font-size: 0.75rem;
|
|
5797
|
+
white-space: pre-wrap;
|
|
5798
|
+
word-break: break-all;
|
|
5799
|
+
overflow-wrap: break-word;
|
|
5800
|
+
}
|
|
5801
|
+
|
|
5802
|
+
.message-image {
|
|
5803
|
+
max-width: 100%;
|
|
5804
|
+
height: auto;
|
|
5805
|
+
border-radius: 0.5rem;
|
|
5806
|
+
margin: 1rem 0;
|
|
5807
|
+
}
|
|
5808
|
+
|
|
5809
|
+
strong {
|
|
5810
|
+
font-weight: 600;
|
|
5811
|
+
}
|
|
5812
|
+
|
|
5813
|
+
em {
|
|
5814
|
+
font-style: italic;
|
|
5815
|
+
}
|
|
5816
|
+
|
|
5817
|
+
a {
|
|
5818
|
+
color: hsl(var(--primary));
|
|
5819
|
+
text-decoration: underline;
|
|
5820
|
+
text-decoration-color: hsl(var(--primary) / 0.3);
|
|
5821
|
+
text-underline-offset: 4px;
|
|
5822
|
+
transition: text-decoration-color 0.2s;
|
|
5823
|
+
}
|
|
5824
|
+
|
|
5825
|
+
a:hover {
|
|
5826
|
+
text-decoration-color: hsl(var(--primary) / 0.6);
|
|
5827
|
+
}
|
|
5828
|
+
|
|
5829
|
+
.header-top {
|
|
5830
|
+
display: flex;
|
|
5831
|
+
justify-content: space-between;
|
|
5832
|
+
align-items: center;
|
|
5833
|
+
margin-bottom: 1rem;
|
|
5834
|
+
}
|
|
5835
|
+
|
|
5836
|
+
.toggle-all-button {
|
|
5837
|
+
padding: 0.5rem 1rem;
|
|
5838
|
+
background: hsl(var(--primary));
|
|
5839
|
+
color: white;
|
|
5840
|
+
border: none;
|
|
5841
|
+
border-radius: 0.375rem;
|
|
5842
|
+
font-size: 0.875rem;
|
|
5843
|
+
font-weight: 500;
|
|
5844
|
+
cursor: pointer;
|
|
5845
|
+
transition: opacity 0.2s;
|
|
5846
|
+
}
|
|
5847
|
+
|
|
5848
|
+
.toggle-all-button:hover {
|
|
5849
|
+
opacity: 0.9;
|
|
5850
|
+
}
|
|
5851
|
+
|
|
5852
|
+
.toggle-all-button:active {
|
|
5853
|
+
opacity: 0.8;
|
|
5854
|
+
}
|
|
5855
|
+
|
|
5856
|
+
.footer {
|
|
5857
|
+
margin-top: 4rem;
|
|
5858
|
+
padding-top: 2rem;
|
|
5859
|
+
border-top: 1px solid hsl(var(--border));
|
|
5860
|
+
text-align: center;
|
|
5861
|
+
color: hsl(var(--muted-foreground));
|
|
5862
|
+
font-size: 0.875rem;
|
|
5863
|
+
}
|
|
5864
|
+
</style>
|
|
5865
|
+
</head>
|
|
5866
|
+
<body>
|
|
5867
|
+
<div class="header">
|
|
5868
|
+
<div class="header-top">
|
|
5869
|
+
<h1>Claude Code Session Export</h1>
|
|
5870
|
+
<button id="toggle-all-btn" class="toggle-all-button">Collapse All</button>
|
|
5871
|
+
</div>
|
|
5872
|
+
<div class="metadata">
|
|
5873
|
+
<div><strong>Session ID:</strong> ${escapeHtml(session.id)}</div>
|
|
5874
|
+
<div><strong>Project ID:</strong> ${escapeHtml(projectId)}</div>
|
|
5875
|
+
<div><strong>Exported:</strong> ${formatTimestamp(Date.now())}</div>
|
|
5876
|
+
<div><strong>Total Conversations:</strong> ${session.conversations.length}</div>
|
|
5877
|
+
</div>
|
|
5878
|
+
</div>
|
|
5879
|
+
|
|
5880
|
+
<div class="conversation-list">
|
|
5881
|
+
${conversationsHtml}
|
|
5882
|
+
</div>
|
|
5883
|
+
|
|
5884
|
+
<div class="footer">
|
|
5885
|
+
<p>Exported from Claude Code Viewer</p>
|
|
5886
|
+
</div>
|
|
5887
|
+
|
|
5888
|
+
<script>
|
|
5889
|
+
// Add click handlers for collapsible blocks
|
|
5890
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
5891
|
+
const triggers = document.querySelectorAll('.collapsible-trigger');
|
|
5892
|
+
const toggleAllBtn = document.getElementById('toggle-all-btn');
|
|
5893
|
+
let allExpanded = true; // Start as expanded since blocks are expanded by default
|
|
5894
|
+
|
|
5895
|
+
// Individual collapsible click handlers
|
|
5896
|
+
triggers.forEach(function(trigger) {
|
|
5897
|
+
trigger.addEventListener('click', function() {
|
|
5898
|
+
const collapsible = this.closest('.collapsible');
|
|
5899
|
+
if (collapsible) {
|
|
5900
|
+
collapsible.classList.toggle('collapsed');
|
|
5901
|
+
}
|
|
5902
|
+
});
|
|
5903
|
+
});
|
|
5904
|
+
|
|
5905
|
+
// Toggle all button
|
|
5906
|
+
if (toggleAllBtn) {
|
|
5907
|
+
toggleAllBtn.addEventListener('click', function() {
|
|
5908
|
+
const collapsibles = document.querySelectorAll('.collapsible');
|
|
5909
|
+
|
|
5910
|
+
if (allExpanded) {
|
|
5911
|
+
// Collapse all
|
|
5912
|
+
collapsibles.forEach(function(collapsible) {
|
|
5913
|
+
collapsible.classList.add('collapsed');
|
|
5914
|
+
});
|
|
5915
|
+
toggleAllBtn.textContent = 'Expand All';
|
|
5916
|
+
allExpanded = false;
|
|
5917
|
+
} else {
|
|
5918
|
+
// Expand all
|
|
5919
|
+
collapsibles.forEach(function(collapsible) {
|
|
5920
|
+
collapsible.classList.remove('collapsed');
|
|
5921
|
+
});
|
|
5922
|
+
toggleAllBtn.textContent = 'Collapse All';
|
|
5923
|
+
allExpanded = true;
|
|
5924
|
+
}
|
|
5925
|
+
});
|
|
5926
|
+
}
|
|
5927
|
+
});
|
|
5928
|
+
</script>
|
|
5929
|
+
</body>
|
|
5930
|
+
</html>`;
|
|
5931
|
+
return html;
|
|
5932
|
+
});
|
|
4981
5933
|
|
|
4982
5934
|
// src/server/core/session/presentation/SessionController.ts
|
|
4983
|
-
|
|
4984
|
-
var LayerImpl23 = Effect34.gen(function* () {
|
|
5935
|
+
var LayerImpl25 = Effect38.gen(function* () {
|
|
4985
5936
|
const sessionRepository = yield* SessionRepository;
|
|
4986
|
-
const getSession = (options) =>
|
|
5937
|
+
const getSession = (options) => Effect38.gen(function* () {
|
|
4987
5938
|
const { projectId, sessionId } = options;
|
|
4988
5939
|
const { session } = yield* sessionRepository.getSession(
|
|
4989
5940
|
projectId,
|
|
@@ -4994,13 +5945,32 @@ var LayerImpl23 = Effect34.gen(function* () {
|
|
|
4994
5945
|
response: { session }
|
|
4995
5946
|
};
|
|
4996
5947
|
});
|
|
5948
|
+
const exportSessionHtml = (options) => Effect38.gen(function* () {
|
|
5949
|
+
const { projectId, sessionId } = options;
|
|
5950
|
+
const { session } = yield* sessionRepository.getSession(
|
|
5951
|
+
projectId,
|
|
5952
|
+
sessionId
|
|
5953
|
+
);
|
|
5954
|
+
if (session === null) {
|
|
5955
|
+
return {
|
|
5956
|
+
status: 404,
|
|
5957
|
+
response: { error: "Session not found" }
|
|
5958
|
+
};
|
|
5959
|
+
}
|
|
5960
|
+
const html = yield* generateSessionHtml(session, projectId);
|
|
5961
|
+
return {
|
|
5962
|
+
status: 200,
|
|
5963
|
+
response: { html }
|
|
5964
|
+
};
|
|
5965
|
+
});
|
|
4997
5966
|
return {
|
|
4998
|
-
getSession
|
|
5967
|
+
getSession,
|
|
5968
|
+
exportSessionHtml
|
|
4999
5969
|
};
|
|
5000
5970
|
});
|
|
5001
|
-
var SessionController = class extends
|
|
5971
|
+
var SessionController = class extends Context31.Tag("SessionController")() {
|
|
5002
5972
|
static {
|
|
5003
|
-
this.Live =
|
|
5973
|
+
this.Live = Layer33.effect(this, LayerImpl25);
|
|
5004
5974
|
}
|
|
5005
5975
|
};
|
|
5006
5976
|
|
|
@@ -5009,12 +5979,12 @@ import { Hono } from "hono";
|
|
|
5009
5979
|
var honoApp = new Hono();
|
|
5010
5980
|
|
|
5011
5981
|
// src/server/hono/initialize.ts
|
|
5012
|
-
import { Context as
|
|
5013
|
-
var InitializeService = class extends
|
|
5982
|
+
import { Context as Context32, Effect as Effect39, Layer as Layer34, Ref as Ref11, Schedule as Schedule2 } from "effect";
|
|
5983
|
+
var InitializeService = class extends Context32.Tag("InitializeService")() {
|
|
5014
5984
|
static {
|
|
5015
|
-
this.Live =
|
|
5985
|
+
this.Live = Layer34.effect(
|
|
5016
5986
|
this,
|
|
5017
|
-
|
|
5987
|
+
Effect39.gen(function* () {
|
|
5018
5988
|
const eventBus = yield* EventBus;
|
|
5019
5989
|
const fileWatcher = yield* FileWatcherService;
|
|
5020
5990
|
const projectRepository = yield* ProjectRepository;
|
|
@@ -5024,20 +5994,20 @@ var InitializeService = class extends Context30.Tag("InitializeService")() {
|
|
|
5024
5994
|
const virtualConversationDatabase = yield* VirtualConversationDatabase;
|
|
5025
5995
|
const listenersRef = yield* Ref11.make({});
|
|
5026
5996
|
const startInitialization = () => {
|
|
5027
|
-
return
|
|
5997
|
+
return Effect39.gen(function* () {
|
|
5028
5998
|
yield* fileWatcher.startWatching();
|
|
5029
|
-
const daemon =
|
|
5999
|
+
const daemon = Effect39.repeat(
|
|
5030
6000
|
eventBus.emit("heartbeat", {}),
|
|
5031
6001
|
Schedule2.fixed("10 seconds")
|
|
5032
6002
|
);
|
|
5033
6003
|
console.log("start heartbeat");
|
|
5034
|
-
yield*
|
|
6004
|
+
yield* Effect39.forkDaemon(daemon);
|
|
5035
6005
|
console.log("after starting heartbeat fork");
|
|
5036
6006
|
const onSessionChanged = (event) => {
|
|
5037
|
-
|
|
6007
|
+
Effect39.runFork(
|
|
5038
6008
|
projectMetaService.invalidateProject(event.projectId)
|
|
5039
6009
|
);
|
|
5040
|
-
|
|
6010
|
+
Effect39.runFork(
|
|
5041
6011
|
sessionMetaService.invalidateSession(
|
|
5042
6012
|
event.projectId,
|
|
5043
6013
|
event.sessionId
|
|
@@ -5046,7 +6016,7 @@ var InitializeService = class extends Context30.Tag("InitializeService")() {
|
|
|
5046
6016
|
};
|
|
5047
6017
|
const onSessionProcessChanged = (event) => {
|
|
5048
6018
|
if ((event.changed.type === "completed" || event.changed.type === "paused") && event.changed.sessionId !== void 0) {
|
|
5049
|
-
|
|
6019
|
+
Effect39.runFork(
|
|
5050
6020
|
virtualConversationDatabase.deleteVirtualConversations(
|
|
5051
6021
|
event.changed.sessionId
|
|
5052
6022
|
)
|
|
@@ -5060,12 +6030,12 @@ var InitializeService = class extends Context30.Tag("InitializeService")() {
|
|
|
5060
6030
|
});
|
|
5061
6031
|
yield* eventBus.on("sessionChanged", onSessionChanged);
|
|
5062
6032
|
yield* eventBus.on("sessionProcessChanged", onSessionProcessChanged);
|
|
5063
|
-
yield*
|
|
6033
|
+
yield* Effect39.gen(function* () {
|
|
5064
6034
|
console.log("Initializing projects cache");
|
|
5065
6035
|
const { projects } = yield* projectRepository.getProjects();
|
|
5066
6036
|
console.log(`${projects.length} projects cache initialized`);
|
|
5067
6037
|
console.log("Initializing sessions cache");
|
|
5068
|
-
const results = yield*
|
|
6038
|
+
const results = yield* Effect39.all(
|
|
5069
6039
|
projects.map(
|
|
5070
6040
|
(project) => sessionRepository.getSessions(project.id)
|
|
5071
6041
|
),
|
|
@@ -5077,12 +6047,12 @@ var InitializeService = class extends Context30.Tag("InitializeService")() {
|
|
|
5077
6047
|
);
|
|
5078
6048
|
console.log(`${totalSessions} sessions cache initialized`);
|
|
5079
6049
|
}).pipe(
|
|
5080
|
-
|
|
5081
|
-
|
|
6050
|
+
Effect39.catchAll(() => Effect39.void),
|
|
6051
|
+
Effect39.withSpan("initialize-cache")
|
|
5082
6052
|
);
|
|
5083
|
-
}).pipe(
|
|
6053
|
+
}).pipe(Effect39.withSpan("start-initialization"));
|
|
5084
6054
|
};
|
|
5085
|
-
const stopCleanup = () =>
|
|
6055
|
+
const stopCleanup = () => Effect39.gen(function* () {
|
|
5086
6056
|
const listeners = yield* Ref11.get(listenersRef);
|
|
5087
6057
|
if (listeners.sessionChanged) {
|
|
5088
6058
|
yield* eventBus.off("sessionChanged", listeners.sessionChanged);
|
|
@@ -5107,7 +6077,7 @@ var InitializeService = class extends Context30.Tag("InitializeService")() {
|
|
|
5107
6077
|
|
|
5108
6078
|
// src/server/hono/route.ts
|
|
5109
6079
|
import { zValidator } from "@hono/zod-validator";
|
|
5110
|
-
import { Effect as
|
|
6080
|
+
import { Effect as Effect41, Runtime as Runtime3 } from "effect";
|
|
5111
6081
|
import { setCookie as setCookie2 } from "hono/cookie";
|
|
5112
6082
|
import { streamSSE } from "hono/streaming";
|
|
5113
6083
|
import prexit from "prexit";
|
|
@@ -5116,7 +6086,7 @@ import { z as z28 } from "zod";
|
|
|
5116
6086
|
// package.json
|
|
5117
6087
|
var package_default = {
|
|
5118
6088
|
name: "@kimuson/claude-code-viewer",
|
|
5119
|
-
version: "0.4.
|
|
6089
|
+
version: "0.4.7",
|
|
5120
6090
|
type: "module",
|
|
5121
6091
|
license: "MIT",
|
|
5122
6092
|
repository: {
|
|
@@ -5160,8 +6130,8 @@ var package_default = {
|
|
|
5160
6130
|
"@anthropic-ai/claude-agent-sdk": "0.1.30",
|
|
5161
6131
|
"@anthropic-ai/claude-code": "2.0.24",
|
|
5162
6132
|
"@anthropic-ai/sdk": "0.67.0",
|
|
5163
|
-
"@effect/platform": "0.
|
|
5164
|
-
"@effect/platform-node": "0.
|
|
6133
|
+
"@effect/platform": "0.93.2",
|
|
6134
|
+
"@effect/platform-node": "0.100.0",
|
|
5165
6135
|
"@hono/node-server": "1.19.5",
|
|
5166
6136
|
"@hono/zod-validator": "0.7.4",
|
|
5167
6137
|
"@lingui/core": "5.5.1",
|
|
@@ -5184,7 +6154,7 @@ var package_default = {
|
|
|
5184
6154
|
"class-variance-authority": "0.7.1",
|
|
5185
6155
|
clsx: "2.1.1",
|
|
5186
6156
|
"date-fns": "4.1.0",
|
|
5187
|
-
effect: "3.
|
|
6157
|
+
effect: "3.19.3",
|
|
5188
6158
|
"es-toolkit": "1.41.0",
|
|
5189
6159
|
hono: "4.10.3",
|
|
5190
6160
|
jotai: "2.15.0",
|
|
@@ -5378,11 +6348,12 @@ var userConfigSchema = z27.object({
|
|
|
5378
6348
|
locale: localeSchema.optional().default("en"),
|
|
5379
6349
|
theme: z27.enum(["light", "dark", "system"]).optional().default("system")
|
|
5380
6350
|
});
|
|
6351
|
+
var defaultUserConfig = userConfigSchema.parse({});
|
|
5381
6352
|
|
|
5382
6353
|
// src/server/lib/effect/toEffectResponse.ts
|
|
5383
|
-
import { Effect as
|
|
6354
|
+
import { Effect as Effect40 } from "effect";
|
|
5384
6355
|
var effectToResponse = async (ctx, effect) => {
|
|
5385
|
-
const result = await
|
|
6356
|
+
const result = await Effect40.runPromise(effect);
|
|
5386
6357
|
const result2 = ctx.json(result.response, result.status);
|
|
5387
6358
|
return result2;
|
|
5388
6359
|
};
|
|
@@ -5414,12 +6385,8 @@ var configMiddleware = createMiddleware(
|
|
|
5414
6385
|
c,
|
|
5415
6386
|
"ccv-config",
|
|
5416
6387
|
JSON.stringify({
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
enterKeyBehavior: "shift-enter-send",
|
|
5420
|
-
permissionMode: "default",
|
|
5421
|
-
locale: preferredLocale,
|
|
5422
|
-
theme: "system"
|
|
6388
|
+
...defaultUserConfig,
|
|
6389
|
+
locale: preferredLocale
|
|
5423
6390
|
})
|
|
5424
6391
|
);
|
|
5425
6392
|
}
|
|
@@ -5429,9 +6396,10 @@ var configMiddleware = createMiddleware(
|
|
|
5429
6396
|
);
|
|
5430
6397
|
|
|
5431
6398
|
// src/server/hono/route.ts
|
|
5432
|
-
var routes = (app) =>
|
|
6399
|
+
var routes = (app) => Effect41.gen(function* () {
|
|
5433
6400
|
const projectController = yield* ProjectController;
|
|
5434
6401
|
const sessionController = yield* SessionController;
|
|
6402
|
+
const agentSessionController = yield* AgentSessionController;
|
|
5435
6403
|
const gitController = yield* GitController;
|
|
5436
6404
|
const claudeCodeSessionProcessController = yield* ClaudeCodeSessionProcessController;
|
|
5437
6405
|
const claudeCodePermissionController = yield* ClaudeCodePermissionController;
|
|
@@ -5444,7 +6412,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5444
6412
|
const userConfigService = yield* UserConfigService;
|
|
5445
6413
|
const claudeCodeLifeCycleService = yield* ClaudeCodeLifeCycleService;
|
|
5446
6414
|
const initializeService = yield* InitializeService;
|
|
5447
|
-
const runtime = yield*
|
|
6415
|
+
const runtime = yield* Effect41.runtime();
|
|
5448
6416
|
if ((yield* envService.getEnv("NEXT_PHASE")) !== "phase-production-build") {
|
|
5449
6417
|
yield* initializeService.startInitialization();
|
|
5450
6418
|
prexit(async () => {
|
|
@@ -5452,7 +6420,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5452
6420
|
});
|
|
5453
6421
|
}
|
|
5454
6422
|
return app.use(configMiddleware).use(async (c, next) => {
|
|
5455
|
-
await
|
|
6423
|
+
await Effect41.runPromise(
|
|
5456
6424
|
userConfigService.setUserConfig({
|
|
5457
6425
|
...c.get("userConfig")
|
|
5458
6426
|
})
|
|
@@ -5487,7 +6455,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5487
6455
|
projectController.getProject({
|
|
5488
6456
|
...c.req.param(),
|
|
5489
6457
|
...c.req.valid("query")
|
|
5490
|
-
}).pipe(
|
|
6458
|
+
}).pipe(Effect41.provide(runtime))
|
|
5491
6459
|
);
|
|
5492
6460
|
return response;
|
|
5493
6461
|
}
|
|
@@ -5504,7 +6472,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5504
6472
|
c,
|
|
5505
6473
|
projectController.createProject({
|
|
5506
6474
|
...c.req.valid("json")
|
|
5507
|
-
}).pipe(
|
|
6475
|
+
}).pipe(Effect41.provide(runtime))
|
|
5508
6476
|
);
|
|
5509
6477
|
return response;
|
|
5510
6478
|
}
|
|
@@ -5513,13 +6481,32 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5513
6481
|
c,
|
|
5514
6482
|
projectController.getProjectLatestSession({
|
|
5515
6483
|
...c.req.param()
|
|
5516
|
-
}).pipe(
|
|
6484
|
+
}).pipe(Effect41.provide(runtime))
|
|
5517
6485
|
);
|
|
5518
6486
|
return response;
|
|
5519
6487
|
}).get("/api/projects/:projectId/sessions/:sessionId", async (c) => {
|
|
5520
6488
|
const response = await effectToResponse(
|
|
5521
6489
|
c,
|
|
5522
|
-
sessionController.getSession({ ...c.req.param() }).pipe(
|
|
6490
|
+
sessionController.getSession({ ...c.req.param() }).pipe(Effect41.provide(runtime))
|
|
6491
|
+
);
|
|
6492
|
+
return response;
|
|
6493
|
+
}).get(
|
|
6494
|
+
"/api/projects/:projectId/sessions/:sessionId/export",
|
|
6495
|
+
async (c) => {
|
|
6496
|
+
const response = await effectToResponse(
|
|
6497
|
+
c,
|
|
6498
|
+
sessionController.exportSessionHtml({ ...c.req.param() }).pipe(Effect41.provide(runtime))
|
|
6499
|
+
);
|
|
6500
|
+
return response;
|
|
6501
|
+
}
|
|
6502
|
+
).get("/api/projects/:projectId/agent-sessions/:agentId", async (c) => {
|
|
6503
|
+
const { projectId, agentId } = c.req.param();
|
|
6504
|
+
const response = await effectToResponse(
|
|
6505
|
+
c,
|
|
6506
|
+
agentSessionController.getAgentSession({
|
|
6507
|
+
projectId,
|
|
6508
|
+
agentId
|
|
6509
|
+
}).pipe(Effect41.provide(runtime))
|
|
5523
6510
|
);
|
|
5524
6511
|
return response;
|
|
5525
6512
|
}).get("/api/projects/:projectId/git/current-revisions", async (c) => {
|
|
@@ -5527,7 +6514,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5527
6514
|
c,
|
|
5528
6515
|
gitController.getCurrentRevisions({
|
|
5529
6516
|
...c.req.param()
|
|
5530
|
-
}).pipe(
|
|
6517
|
+
}).pipe(Effect41.provide(runtime))
|
|
5531
6518
|
);
|
|
5532
6519
|
return response;
|
|
5533
6520
|
}).post(
|
|
@@ -5545,7 +6532,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5545
6532
|
gitController.getGitDiff({
|
|
5546
6533
|
...c.req.param(),
|
|
5547
6534
|
...c.req.valid("json")
|
|
5548
|
-
}).pipe(
|
|
6535
|
+
}).pipe(Effect41.provide(runtime))
|
|
5549
6536
|
);
|
|
5550
6537
|
return response;
|
|
5551
6538
|
}
|
|
@@ -5558,7 +6545,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5558
6545
|
gitController.commitFiles({
|
|
5559
6546
|
...c.req.param(),
|
|
5560
6547
|
...c.req.valid("json")
|
|
5561
|
-
}).pipe(
|
|
6548
|
+
}).pipe(Effect41.provide(runtime))
|
|
5562
6549
|
);
|
|
5563
6550
|
return response;
|
|
5564
6551
|
}
|
|
@@ -5571,7 +6558,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5571
6558
|
gitController.pushCommits({
|
|
5572
6559
|
...c.req.param(),
|
|
5573
6560
|
...c.req.valid("json")
|
|
5574
|
-
}).pipe(
|
|
6561
|
+
}).pipe(Effect41.provide(runtime))
|
|
5575
6562
|
);
|
|
5576
6563
|
return response;
|
|
5577
6564
|
}
|
|
@@ -5584,7 +6571,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5584
6571
|
gitController.commitAndPush({
|
|
5585
6572
|
...c.req.param(),
|
|
5586
6573
|
...c.req.valid("json")
|
|
5587
|
-
}).pipe(
|
|
6574
|
+
}).pipe(Effect41.provide(runtime))
|
|
5588
6575
|
);
|
|
5589
6576
|
return response;
|
|
5590
6577
|
}
|
|
@@ -5593,7 +6580,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5593
6580
|
c,
|
|
5594
6581
|
claudeCodeController.getClaudeCommands({
|
|
5595
6582
|
...c.req.param()
|
|
5596
|
-
})
|
|
6583
|
+
}).pipe(Effect41.provide(runtime))
|
|
5597
6584
|
);
|
|
5598
6585
|
return response;
|
|
5599
6586
|
}).get("/api/projects/:projectId/mcp/list", async (c) => {
|
|
@@ -5601,19 +6588,19 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5601
6588
|
c,
|
|
5602
6589
|
claudeCodeController.getMcpListRoute({
|
|
5603
6590
|
...c.req.param()
|
|
5604
|
-
}).pipe(
|
|
6591
|
+
}).pipe(Effect41.provide(runtime))
|
|
5605
6592
|
);
|
|
5606
6593
|
return response;
|
|
5607
6594
|
}).get("/api/cc/meta", async (c) => {
|
|
5608
6595
|
const response = await effectToResponse(
|
|
5609
6596
|
c,
|
|
5610
|
-
claudeCodeController.getClaudeCodeMeta().pipe(
|
|
6597
|
+
claudeCodeController.getClaudeCodeMeta().pipe(Effect41.provide(runtime))
|
|
5611
6598
|
);
|
|
5612
6599
|
return response;
|
|
5613
6600
|
}).get("/api/cc/features", async (c) => {
|
|
5614
6601
|
const response = await effectToResponse(
|
|
5615
6602
|
c,
|
|
5616
|
-
claudeCodeController.getAvailableFeatures().pipe(
|
|
6603
|
+
claudeCodeController.getAvailableFeatures().pipe(Effect41.provide(runtime))
|
|
5617
6604
|
);
|
|
5618
6605
|
return response;
|
|
5619
6606
|
}).get("/api/cc/session-processes", async (c) => {
|
|
@@ -5657,7 +6644,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5657
6644
|
claudeCodeSessionProcessController.continueSessionProcess({
|
|
5658
6645
|
...c.req.param(),
|
|
5659
6646
|
...c.req.valid("json")
|
|
5660
|
-
}).pipe(
|
|
6647
|
+
}).pipe(Effect41.provide(runtime))
|
|
5661
6648
|
);
|
|
5662
6649
|
return response;
|
|
5663
6650
|
}
|
|
@@ -5666,7 +6653,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5666
6653
|
zValidator("json", z28.object({ projectId: z28.string() })),
|
|
5667
6654
|
async (c) => {
|
|
5668
6655
|
const { sessionProcessId } = c.req.param();
|
|
5669
|
-
void
|
|
6656
|
+
void Effect41.runFork(
|
|
5670
6657
|
claudeCodeLifeCycleService.abortTask(sessionProcessId)
|
|
5671
6658
|
);
|
|
5672
6659
|
return c.json({ message: "Task aborted" });
|
|
@@ -5694,7 +6681,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5694
6681
|
c,
|
|
5695
6682
|
async (rawStream) => {
|
|
5696
6683
|
await Runtime3.runPromise(runtime)(
|
|
5697
|
-
sseController.handleSSE(rawStream).pipe(
|
|
6684
|
+
sseController.handleSSE(rawStream).pipe(Effect41.provide(TypeSafeSSE.make(rawStream)))
|
|
5698
6685
|
);
|
|
5699
6686
|
},
|
|
5700
6687
|
async (err) => {
|
|
@@ -5704,7 +6691,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5704
6691
|
}).get("/api/scheduler/jobs", async (c) => {
|
|
5705
6692
|
const response = await effectToResponse(
|
|
5706
6693
|
c,
|
|
5707
|
-
schedulerController.getJobs().pipe(
|
|
6694
|
+
schedulerController.getJobs().pipe(Effect41.provide(runtime))
|
|
5708
6695
|
);
|
|
5709
6696
|
return response;
|
|
5710
6697
|
}).post(
|
|
@@ -5715,7 +6702,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5715
6702
|
c,
|
|
5716
6703
|
schedulerController.addJob({
|
|
5717
6704
|
job: c.req.valid("json")
|
|
5718
|
-
}).pipe(
|
|
6705
|
+
}).pipe(Effect41.provide(runtime))
|
|
5719
6706
|
);
|
|
5720
6707
|
return response;
|
|
5721
6708
|
}
|
|
@@ -5728,7 +6715,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5728
6715
|
schedulerController.updateJob({
|
|
5729
6716
|
id: c.req.param("id"),
|
|
5730
6717
|
job: c.req.valid("json")
|
|
5731
|
-
}).pipe(
|
|
6718
|
+
}).pipe(Effect41.provide(runtime))
|
|
5732
6719
|
);
|
|
5733
6720
|
return response;
|
|
5734
6721
|
}
|
|
@@ -5737,7 +6724,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5737
6724
|
c,
|
|
5738
6725
|
schedulerController.deleteJob({
|
|
5739
6726
|
id: c.req.param("id")
|
|
5740
|
-
}).pipe(
|
|
6727
|
+
}).pipe(Effect41.provide(runtime))
|
|
5741
6728
|
);
|
|
5742
6729
|
return response;
|
|
5743
6730
|
}).get(
|
|
@@ -5779,7 +6766,7 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5779
6766
|
).get("/api/flags", async (c) => {
|
|
5780
6767
|
const response = await effectToResponse(
|
|
5781
6768
|
c,
|
|
5782
|
-
featureFlagController.getFlags().pipe(
|
|
6769
|
+
featureFlagController.getFlags().pipe(Effect41.provide(runtime))
|
|
5783
6770
|
);
|
|
5784
6771
|
return response;
|
|
5785
6772
|
});
|
|
@@ -5787,13 +6774,13 @@ var routes = (app) => Effect37.gen(function* () {
|
|
|
5787
6774
|
|
|
5788
6775
|
// src/server/lib/effect/layers.ts
|
|
5789
6776
|
import { NodeContext } from "@effect/platform-node";
|
|
5790
|
-
import { Layer as
|
|
5791
|
-
var platformLayer =
|
|
6777
|
+
import { Layer as Layer35 } from "effect";
|
|
6778
|
+
var platformLayer = Layer35.mergeAll(
|
|
5792
6779
|
ApplicationContext.Live,
|
|
5793
6780
|
UserConfigService.Live,
|
|
5794
6781
|
EventBus.Live,
|
|
5795
6782
|
EnvService.Live
|
|
5796
|
-
).pipe(
|
|
6783
|
+
).pipe(Layer35.provide(EnvService.Live), Layer35.provide(NodeContext.layer));
|
|
5797
6784
|
|
|
5798
6785
|
// src/server/main.ts
|
|
5799
6786
|
var isDevelopment = process.env.NODE_ENV === "development";
|
|
@@ -5816,42 +6803,44 @@ if (!isDevelopment) {
|
|
|
5816
6803
|
}
|
|
5817
6804
|
var program = routes(honoApp).pipe(
|
|
5818
6805
|
/** Presentation */
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
6806
|
+
Effect42.provide(ProjectController.Live),
|
|
6807
|
+
Effect42.provide(SessionController.Live),
|
|
6808
|
+
Effect42.provide(AgentSessionController.Live),
|
|
6809
|
+
Effect42.provide(GitController.Live),
|
|
6810
|
+
Effect42.provide(ClaudeCodeController.Live),
|
|
6811
|
+
Effect42.provide(ClaudeCodeSessionProcessController.Live),
|
|
6812
|
+
Effect42.provide(ClaudeCodePermissionController.Live),
|
|
6813
|
+
Effect42.provide(FileSystemController.Live),
|
|
6814
|
+
Effect42.provide(SSEController.Live),
|
|
6815
|
+
Effect42.provide(SchedulerController.Live),
|
|
6816
|
+
Effect42.provide(FeatureFlagController.Live)
|
|
5829
6817
|
).pipe(
|
|
5830
6818
|
/** Application */
|
|
5831
|
-
|
|
5832
|
-
|
|
6819
|
+
Effect42.provide(InitializeService.Live),
|
|
6820
|
+
Effect42.provide(FileWatcherService.Live)
|
|
5833
6821
|
).pipe(
|
|
5834
6822
|
/** Domain */
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
6823
|
+
Effect42.provide(ClaudeCodeLifeCycleService.Live),
|
|
6824
|
+
Effect42.provide(ClaudeCodePermissionService.Live),
|
|
6825
|
+
Effect42.provide(ClaudeCodeSessionProcessService.Live),
|
|
6826
|
+
Effect42.provide(ClaudeCodeService.Live),
|
|
6827
|
+
Effect42.provide(GitService.Live),
|
|
6828
|
+
Effect42.provide(SchedulerService.Live),
|
|
6829
|
+
Effect42.provide(SchedulerConfigBaseDir.Live)
|
|
5842
6830
|
).pipe(
|
|
5843
6831
|
/** Infrastructure */
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
6832
|
+
Effect42.provide(ProjectRepository.Live),
|
|
6833
|
+
Effect42.provide(SessionRepository.Live),
|
|
6834
|
+
Effect42.provide(ProjectMetaService.Live),
|
|
6835
|
+
Effect42.provide(SessionMetaService.Live),
|
|
6836
|
+
Effect42.provide(VirtualConversationDatabase.Live),
|
|
6837
|
+
Effect42.provide(AgentSessionLayer)
|
|
5849
6838
|
).pipe(
|
|
5850
6839
|
/** Platform */
|
|
5851
|
-
|
|
5852
|
-
|
|
6840
|
+
Effect42.provide(platformLayer),
|
|
6841
|
+
Effect42.provide(NodeContext2.layer)
|
|
5853
6842
|
);
|
|
5854
|
-
await
|
|
6843
|
+
await Effect42.runPromise(program);
|
|
5855
6844
|
var port = isDevelopment ? (
|
|
5856
6845
|
// biome-ignore lint/style/noProcessEnv: allow only here
|
|
5857
6846
|
process.env.DEV_BE_PORT ?? "3401"
|