@kimuson/claude-code-viewer 0.5.8 → 0.5.9

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 CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  // src/server/main.ts
4
4
  import { Command as Command3 } from "commander";
5
- import { Effect as Effect51 } from "effect";
5
+ import { Effect as Effect53 } from "effect";
6
6
 
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@kimuson/claude-code-viewer",
10
- version: "0.5.8",
10
+ version: "0.5.9",
11
11
  description: "A full-featured web-based Claude Code client that provides complete interactive functionality for managing Claude Code projects.",
12
12
  type: "module",
13
13
  license: "MIT",
@@ -51,7 +51,7 @@ var package_default = {
51
51
  prepare: "lefthook install"
52
52
  },
53
53
  dependencies: {
54
- "@anthropic-ai/claude-agent-sdk": "0.2.19",
54
+ "@anthropic-ai/claude-agent-sdk": "0.2.20",
55
55
  "@anthropic-ai/claude-code": "2.0.24",
56
56
  "@anthropic-ai/sdk": "0.71.2",
57
57
  "@effect/cluster": "0.56.1",
@@ -219,7 +219,7 @@ import { resolve as resolve6 } from "node:path";
219
219
  import { NodeContext as NodeContext2 } from "@effect/platform-node";
220
220
  import { serve } from "@hono/node-server";
221
221
  import { serveStatic } from "@hono/node-server/serve-static";
222
- import { Effect as Effect50 } from "effect";
222
+ import { Effect as Effect52, Layer as Layer43 } from "effect";
223
223
 
224
224
  // src/server/core/agent-session/index.ts
225
225
  import { Layer as Layer3 } from "effect";
@@ -8042,17 +8042,355 @@ var SessionController = class extends Context35.Tag("SessionController")() {
8042
8042
  }
8043
8043
  };
8044
8044
 
8045
+ // src/server/core/tasks/presentation/TasksController.ts
8046
+ import { Context as Context37, Effect as Effect47, Layer as Layer39 } from "effect";
8047
+
8048
+ // src/server/core/tasks/services/TasksService.ts
8049
+ import { homedir as homedir5 } from "node:os";
8050
+ import { join as join3 } from "node:path";
8051
+ import { FileSystem as FileSystem17, Path as Path19 } from "@effect/platform";
8052
+ import { Context as Context36, Effect as Effect46, Layer as Layer38, Option as Option4 } from "effect";
8053
+
8054
+ // src/server/core/tasks/schema.ts
8055
+ import { z as z26 } from "zod";
8056
+ var TaskStatusSchema = z26.enum([
8057
+ "pending",
8058
+ "in_progress",
8059
+ "completed",
8060
+ "failed"
8061
+ ]);
8062
+ var TaskSchema = z26.object({
8063
+ id: z26.string(),
8064
+ subject: z26.string(),
8065
+ description: z26.string().optional(),
8066
+ status: TaskStatusSchema,
8067
+ owner: z26.string().optional(),
8068
+ blocks: z26.array(z26.string()).optional(),
8069
+ blockedBy: z26.array(z26.string()).optional(),
8070
+ metadata: z26.record(z26.string(), z26.any()).optional(),
8071
+ activeForm: z26.string().optional()
8072
+ });
8073
+ var TaskCreateSchema = z26.object({
8074
+ subject: z26.string(),
8075
+ description: z26.string().optional(),
8076
+ activeForm: z26.string().optional(),
8077
+ metadata: z26.record(z26.string(), z26.any()).optional()
8078
+ });
8079
+ var TaskUpdateSchema = z26.object({
8080
+ taskId: z26.string(),
8081
+ status: TaskStatusSchema.optional(),
8082
+ subject: z26.string().optional(),
8083
+ description: z26.string().optional(),
8084
+ activeForm: z26.string().optional(),
8085
+ owner: z26.string().optional(),
8086
+ addBlockedBy: z26.array(z26.string()).optional(),
8087
+ addBlocks: z26.array(z26.string()).optional(),
8088
+ metadata: z26.record(z26.string(), z26.any()).optional()
8089
+ });
8090
+
8091
+ // src/server/core/tasks/services/TasksService.ts
8092
+ var TASKS_DIR_NAME = "tasks";
8093
+ var PROJECTS_DIR_NAME = "projects";
8094
+ var CLAUDE_DIR_NAME = ".claude";
8095
+ var TasksService = class extends Context36.Tag("TasksService")() {
8096
+ static {
8097
+ this.Live = Layer38.effect(
8098
+ this,
8099
+ Effect46.gen(function* () {
8100
+ const fs = yield* FileSystem17.FileSystem;
8101
+ const path = yield* Path19.Path;
8102
+ const getClaudeDir = () => Effect46.succeed(join3(homedir5(), CLAUDE_DIR_NAME));
8103
+ const normalizeProjectPath = (projectPath) => {
8104
+ const normalized = projectPath.replaceAll(path.sep, "-");
8105
+ return normalized.startsWith("-") ? normalized : `-${normalized}`;
8106
+ };
8107
+ const resolveProjectUuid = (projectPath, specificSessionId) => Effect46.gen(function* () {
8108
+ const claudeDir = yield* getClaudeDir();
8109
+ if (specificSessionId) {
8110
+ const sessionTasksDir = path.join(
8111
+ claudeDir,
8112
+ TASKS_DIR_NAME,
8113
+ specificSessionId
8114
+ );
8115
+ if (yield* fs.exists(sessionTasksDir)) {
8116
+ return Option4.some(specificSessionId);
8117
+ }
8118
+ return Option4.none();
8119
+ }
8120
+ const isMetadataPath = projectPath.includes(join3(CLAUDE_DIR_NAME, PROJECTS_DIR_NAME)) && projectPath.split(path.sep).pop()?.startsWith("-");
8121
+ let projectMetaDir;
8122
+ if (isMetadataPath && (yield* fs.exists(projectPath))) {
8123
+ projectMetaDir = projectPath;
8124
+ } else {
8125
+ const identifier = normalizeProjectPath(projectPath);
8126
+ projectMetaDir = path.join(
8127
+ claudeDir,
8128
+ PROJECTS_DIR_NAME,
8129
+ identifier
8130
+ );
8131
+ }
8132
+ const exists = yield* fs.exists(projectMetaDir);
8133
+ if (!exists) {
8134
+ return Option4.none();
8135
+ }
8136
+ const files = yield* fs.readDirectory(projectMetaDir);
8137
+ const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
8138
+ const candidates = files.filter((f) => uuidPattern.test(f));
8139
+ if (candidates.length === 0) {
8140
+ return Option4.none();
8141
+ }
8142
+ const candidateInfo = yield* Effect46.all(
8143
+ candidates.map(
8144
+ (file) => Effect46.gen(function* () {
8145
+ const fullPath = path.join(projectMetaDir, file);
8146
+ const stat = yield* fs.stat(fullPath);
8147
+ const match = file.match(uuidPattern);
8148
+ const uuid = match ? match[0] : file;
8149
+ const tasksPath = path.join(claudeDir, TASKS_DIR_NAME, uuid);
8150
+ const hasTasks = yield* fs.exists(tasksPath);
8151
+ return {
8152
+ file,
8153
+ uuid,
8154
+ mtime: Option4.getOrElse(stat.mtime, () => /* @__PURE__ */ new Date(0)),
8155
+ hasTasks
8156
+ };
8157
+ })
8158
+ ),
8159
+ { concurrency: "unbounded" }
8160
+ );
8161
+ const sorted = candidateInfo.sort((a, b) => {
8162
+ if (a.hasTasks && !b.hasTasks) return -1;
8163
+ if (!a.hasTasks && b.hasTasks) return 1;
8164
+ return b.mtime.getTime() - a.mtime.getTime();
8165
+ });
8166
+ const best = sorted[0];
8167
+ if (!best) {
8168
+ return Option4.none();
8169
+ }
8170
+ return Option4.some(best.uuid);
8171
+ });
8172
+ const resolveProjectUuidOrFail = (projectPath, specificSessionId) => Effect46.gen(function* () {
8173
+ const uuidOption = yield* resolveProjectUuid(
8174
+ projectPath,
8175
+ specificSessionId
8176
+ );
8177
+ if (Option4.isNone(uuidOption)) {
8178
+ if (specificSessionId) {
8179
+ return yield* Effect46.fail(
8180
+ new Error(
8181
+ `Requested session ${specificSessionId} has no tasks directory`
8182
+ )
8183
+ );
8184
+ }
8185
+ const claudeDir = yield* getClaudeDir();
8186
+ const identifier = normalizeProjectPath(projectPath);
8187
+ const projectMetaDir = path.join(
8188
+ claudeDir,
8189
+ PROJECTS_DIR_NAME,
8190
+ identifier
8191
+ );
8192
+ return yield* Effect46.fail(
8193
+ new Error(
8194
+ `Project metadata directory not found or no UUID: ${projectMetaDir}`
8195
+ )
8196
+ );
8197
+ }
8198
+ return uuidOption.value;
8199
+ });
8200
+ const getTasksDir = (projectPath, specificSessionId) => Effect46.gen(function* () {
8201
+ const claudeDir = yield* getClaudeDir();
8202
+ const uuidOption = yield* resolveProjectUuid(
8203
+ projectPath,
8204
+ specificSessionId
8205
+ );
8206
+ return Option4.map(
8207
+ uuidOption,
8208
+ (uuid) => path.join(claudeDir, TASKS_DIR_NAME, uuid)
8209
+ );
8210
+ });
8211
+ const getTasksDirOrFail = (projectPath, specificSessionId) => Effect46.gen(function* () {
8212
+ const claudeDir = yield* getClaudeDir();
8213
+ const uuid = yield* resolveProjectUuidOrFail(
8214
+ projectPath,
8215
+ specificSessionId
8216
+ );
8217
+ return path.join(claudeDir, TASKS_DIR_NAME, uuid);
8218
+ });
8219
+ const listTasks = (projectPath, specificSessionId) => Effect46.gen(function* () {
8220
+ const tasksDirOption = yield* getTasksDir(
8221
+ projectPath,
8222
+ specificSessionId
8223
+ );
8224
+ if (Option4.isNone(tasksDirOption)) {
8225
+ return [];
8226
+ }
8227
+ const tasksDir = tasksDirOption.value;
8228
+ const exists = yield* fs.exists(tasksDir);
8229
+ if (!exists) {
8230
+ return [];
8231
+ }
8232
+ const files = yield* fs.readDirectory(tasksDir);
8233
+ const tasks = [];
8234
+ for (const file of files) {
8235
+ if (!file.endsWith(".json")) continue;
8236
+ const content = yield* fs.readFileString(path.join(tasksDir, file));
8237
+ try {
8238
+ const task = JSON.parse(content);
8239
+ const parsed = TaskSchema.safeParse(task);
8240
+ if (parsed.success) {
8241
+ tasks.push(parsed.data);
8242
+ } else {
8243
+ console.warn(`Invalid task file ${file}:`, parsed.error);
8244
+ const fallbackTask = {
8245
+ id: typeof task === "object" && task !== null && "id" in task && typeof task.id === "string" ? task.id : file.replace(".json", ""),
8246
+ subject: typeof task === "object" && task !== null && "subject" in task && typeof task.subject === "string" ? task.subject : typeof task === "object" && task !== null && "title" in task && typeof task.title === "string" ? task.title : "Invalid Task Schema",
8247
+ description: `Validation Error: ${JSON.stringify(parsed.error.format())}. Raw: ${JSON.stringify(task)}`,
8248
+ status: typeof task === "object" && task !== null && "status" in task && typeof task.status === "string" && (task.status === "pending" || task.status === "in_progress" || task.status === "completed" || task.status === "failed") ? task.status : "failed",
8249
+ blocks: [],
8250
+ blockedBy: []
8251
+ };
8252
+ tasks.push(fallbackTask);
8253
+ }
8254
+ } catch (e) {
8255
+ console.error(`Failed to parse task file ${file}`, e);
8256
+ const fallbackTask = {
8257
+ id: file.replace(".json", ""),
8258
+ subject: "Corrupted Task File",
8259
+ description: String(e),
8260
+ status: "failed",
8261
+ blocks: [],
8262
+ blockedBy: []
8263
+ };
8264
+ tasks.push(fallbackTask);
8265
+ }
8266
+ }
8267
+ return tasks.sort((a, b) => parseInt(a.id, 10) - parseInt(b.id, 10));
8268
+ });
8269
+ const getTask = (projectPath, taskId, specificSessionId) => Effect46.gen(function* () {
8270
+ const tasksDir = yield* getTasksDirOrFail(
8271
+ projectPath,
8272
+ specificSessionId
8273
+ );
8274
+ const taskFile = path.join(tasksDir, `${taskId}.json`);
8275
+ const exists = yield* fs.exists(taskFile);
8276
+ if (!exists) {
8277
+ return yield* Effect46.fail(new Error(`Task ${taskId} not found`));
8278
+ }
8279
+ const content = yield* fs.readFileString(taskFile);
8280
+ const task = JSON.parse(content);
8281
+ return yield* Effect46.try(() => TaskSchema.parse(task));
8282
+ });
8283
+ const createTask = (projectPath, taskDef, specificSessionId) => Effect46.gen(function* () {
8284
+ const tasksDir = yield* getTasksDirOrFail(
8285
+ projectPath,
8286
+ specificSessionId
8287
+ );
8288
+ const dirExists = yield* fs.exists(tasksDir);
8289
+ if (!dirExists) {
8290
+ yield* fs.makeDirectory(tasksDir, { recursive: true });
8291
+ }
8292
+ const files = yield* fs.readDirectory(tasksDir);
8293
+ let maxId = 0;
8294
+ for (const file of files) {
8295
+ if (file.endsWith(".json")) {
8296
+ const idPart = file.replace(".json", "");
8297
+ const idNum = parseInt(idPart, 10);
8298
+ if (!Number.isNaN(idNum) && idNum > maxId) {
8299
+ maxId = idNum;
8300
+ }
8301
+ }
8302
+ }
8303
+ const newId = (maxId + 1).toString();
8304
+ const newTask = {
8305
+ id: newId,
8306
+ status: "pending",
8307
+ blocks: [],
8308
+ blockedBy: [],
8309
+ ...taskDef
8310
+ };
8311
+ const filePath = path.join(tasksDir, `${newId}.json`);
8312
+ yield* fs.writeFileString(filePath, JSON.stringify(newTask, null, 2));
8313
+ return newTask;
8314
+ });
8315
+ const updateTask = (projectPath, update, specificSessionId) => Effect46.gen(function* () {
8316
+ const tasksDir = yield* getTasksDirOrFail(
8317
+ projectPath,
8318
+ specificSessionId
8319
+ );
8320
+ const filePath = path.join(tasksDir, `${update.taskId}.json`);
8321
+ const exists = yield* fs.exists(filePath);
8322
+ if (!exists) {
8323
+ return yield* Effect46.fail(
8324
+ new Error(`Task ${update.taskId} not found`)
8325
+ );
8326
+ }
8327
+ const content = yield* fs.readFileString(filePath);
8328
+ const currentTask = TaskSchema.parse(JSON.parse(content));
8329
+ const updatedTask = {
8330
+ ...currentTask,
8331
+ // User cannot update status via Viewer, it is managed by Claude Agent
8332
+ status: currentTask.status,
8333
+ subject: update.subject ?? currentTask.subject,
8334
+ description: update.description ?? currentTask.description,
8335
+ activeForm: update.activeForm ?? currentTask.activeForm,
8336
+ owner: update.owner ?? currentTask.owner,
8337
+ blockedBy: update.addBlockedBy ? [...currentTask.blockedBy || [], ...update.addBlockedBy] : currentTask.blockedBy,
8338
+ blocks: update.addBlocks ? [...currentTask.blocks || [], ...update.addBlocks] : currentTask.blocks,
8339
+ metadata: update.metadata ? { ...currentTask.metadata, ...update.metadata } : currentTask.metadata
8340
+ };
8341
+ if (updatedTask.metadata) {
8342
+ for (const key in updatedTask.metadata) {
8343
+ if (updatedTask.metadata[key] === null) {
8344
+ delete updatedTask.metadata[key];
8345
+ }
8346
+ }
8347
+ }
8348
+ yield* fs.writeFileString(
8349
+ filePath,
8350
+ JSON.stringify(updatedTask, null, 2)
8351
+ );
8352
+ return updatedTask;
8353
+ });
8354
+ return {
8355
+ listTasks,
8356
+ getTask,
8357
+ createTask,
8358
+ updateTask
8359
+ };
8360
+ })
8361
+ );
8362
+ }
8363
+ };
8364
+
8365
+ // src/server/core/tasks/presentation/TasksController.ts
8366
+ var make = Effect47.gen(function* () {
8367
+ const service = yield* TasksService;
8368
+ const listTasks = (projectPath, specificSessionId) => service.listTasks(projectPath, specificSessionId);
8369
+ const createTask = (projectPath, task, specificSessionId) => service.createTask(projectPath, task, specificSessionId);
8370
+ const updateTask = (projectPath, task, specificSessionId) => service.updateTask(projectPath, task, specificSessionId);
8371
+ return {
8372
+ listTasks,
8373
+ createTask,
8374
+ updateTask
8375
+ };
8376
+ });
8377
+ var TasksController = class extends Context37.Tag("TasksController")() {
8378
+ static {
8379
+ this.Live = Layer39.effect(this, make);
8380
+ }
8381
+ };
8382
+
8045
8383
  // src/server/hono/app.ts
8046
8384
  import { Hono } from "hono";
8047
8385
  var honoApp = new Hono();
8048
8386
 
8049
8387
  // src/server/hono/initialize.ts
8050
- import { Context as Context36, Effect as Effect46, Layer as Layer38, Ref as Ref14, Schedule as Schedule2 } from "effect";
8051
- var InitializeService = class extends Context36.Tag("InitializeService")() {
8388
+ import { Context as Context38, Effect as Effect48, Layer as Layer40, Ref as Ref14, Schedule as Schedule2 } from "effect";
8389
+ var InitializeService = class extends Context38.Tag("InitializeService")() {
8052
8390
  static {
8053
- this.Live = Layer38.effect(
8391
+ this.Live = Layer40.effect(
8054
8392
  this,
8055
- Effect46.gen(function* () {
8393
+ Effect48.gen(function* () {
8056
8394
  const eventBus = yield* EventBus;
8057
8395
  const fileWatcher = yield* FileWatcherService;
8058
8396
  const projectRepository = yield* ProjectRepository;
@@ -8063,21 +8401,21 @@ var InitializeService = class extends Context36.Tag("InitializeService")() {
8063
8401
  const rateLimitAutoScheduleService = yield* RateLimitAutoScheduleService;
8064
8402
  const listenersRef = yield* Ref14.make({});
8065
8403
  const startInitialization = () => {
8066
- return Effect46.gen(function* () {
8404
+ return Effect48.gen(function* () {
8067
8405
  yield* fileWatcher.startWatching();
8068
8406
  yield* rateLimitAutoScheduleService.start();
8069
- const daemon = Effect46.repeat(
8407
+ const daemon = Effect48.repeat(
8070
8408
  eventBus.emit("heartbeat", {}),
8071
8409
  Schedule2.fixed("10 seconds")
8072
8410
  );
8073
8411
  console.log("start heartbeat");
8074
- yield* Effect46.forkDaemon(daemon);
8412
+ yield* Effect48.forkDaemon(daemon);
8075
8413
  console.log("after starting heartbeat fork");
8076
8414
  const onSessionChanged = (event) => {
8077
- Effect46.runFork(
8415
+ Effect48.runFork(
8078
8416
  projectMetaService.invalidateProject(event.projectId)
8079
8417
  );
8080
- Effect46.runFork(
8418
+ Effect48.runFork(
8081
8419
  sessionMetaService.invalidateSession(
8082
8420
  event.projectId,
8083
8421
  event.sessionId
@@ -8086,7 +8424,7 @@ var InitializeService = class extends Context36.Tag("InitializeService")() {
8086
8424
  };
8087
8425
  const onSessionProcessChanged = (event) => {
8088
8426
  if ((event.changed.type === "completed" || event.changed.type === "paused") && event.changed.sessionId !== void 0) {
8089
- Effect46.runFork(
8427
+ Effect48.runFork(
8090
8428
  virtualConversationDatabase.deleteVirtualConversations(
8091
8429
  event.changed.sessionId
8092
8430
  )
@@ -8100,12 +8438,12 @@ var InitializeService = class extends Context36.Tag("InitializeService")() {
8100
8438
  });
8101
8439
  yield* eventBus.on("sessionChanged", onSessionChanged);
8102
8440
  yield* eventBus.on("sessionProcessChanged", onSessionProcessChanged);
8103
- yield* Effect46.gen(function* () {
8441
+ yield* Effect48.gen(function* () {
8104
8442
  console.log("Initializing projects cache");
8105
8443
  const { projects } = yield* projectRepository.getProjects();
8106
8444
  console.log(`${projects.length} projects cache initialized`);
8107
8445
  console.log("Initializing sessions cache");
8108
- const results = yield* Effect46.all(
8446
+ const results = yield* Effect48.all(
8109
8447
  projects.map(
8110
8448
  (project) => sessionRepository.getSessions(project.id)
8111
8449
  ),
@@ -8117,12 +8455,12 @@ var InitializeService = class extends Context36.Tag("InitializeService")() {
8117
8455
  );
8118
8456
  console.log(`${totalSessions} sessions cache initialized`);
8119
8457
  }).pipe(
8120
- Effect46.catchAll(() => Effect46.void),
8121
- Effect46.withSpan("initialize-cache")
8458
+ Effect48.catchAll(() => Effect48.void),
8459
+ Effect48.withSpan("initialize-cache")
8122
8460
  );
8123
- }).pipe(Effect46.withSpan("start-initialization"));
8461
+ }).pipe(Effect48.withSpan("start-initialization"));
8124
8462
  };
8125
- const stopCleanup = () => Effect46.gen(function* () {
8463
+ const stopCleanup = () => Effect48.gen(function* () {
8126
8464
  const listeners = yield* Ref14.get(listenersRef);
8127
8465
  if (listeners.sessionChanged) {
8128
8466
  yield* eventBus.off("sessionChanged", listeners.sessionChanged);
@@ -8147,7 +8485,7 @@ var InitializeService = class extends Context36.Tag("InitializeService")() {
8147
8485
  };
8148
8486
 
8149
8487
  // src/server/hono/middleware/auth.middleware.ts
8150
- import { Context as Context37, Effect as Effect47, Layer as Layer39 } from "effect";
8488
+ import { Context as Context39, Effect as Effect49, Layer as Layer41 } from "effect";
8151
8489
  import { getCookie } from "hono/cookie";
8152
8490
  import { createMiddleware } from "hono/factory";
8153
8491
  var generateSessionToken = (password) => {
@@ -8162,9 +8500,9 @@ var PUBLIC_API_ROUTES = [
8162
8500
  // Allow config access for theme/locale loading
8163
8501
  "/api/version"
8164
8502
  ];
8165
- var LayerImpl30 = Effect47.gen(function* () {
8503
+ var LayerImpl30 = Effect49.gen(function* () {
8166
8504
  const ccvOptionsService = yield* CcvOptionsService;
8167
- return Effect47.gen(function* () {
8505
+ return Effect49.gen(function* () {
8168
8506
  const anthPassword = yield* ccvOptionsService.getCcvOptions("password");
8169
8507
  const authEnabled = anthPassword !== void 0;
8170
8508
  const validSessionToken = generateSessionToken(anthPassword);
@@ -8192,77 +8530,77 @@ var LayerImpl30 = Effect47.gen(function* () {
8192
8530
  };
8193
8531
  });
8194
8532
  });
8195
- var AuthMiddleware = class extends Context37.Tag("AuthMiddleware")() {
8533
+ var AuthMiddleware = class extends Context39.Tag("AuthMiddleware")() {
8196
8534
  static {
8197
- this.Live = Layer39.effect(this, LayerImpl30);
8535
+ this.Live = Layer41.effect(this, LayerImpl30);
8198
8536
  }
8199
8537
  };
8200
8538
 
8201
8539
  // src/server/hono/route.ts
8202
8540
  import { zValidator } from "@hono/zod-validator";
8203
- import { Effect as Effect49, Runtime as Runtime3 } from "effect";
8541
+ import { Effect as Effect51, Runtime as Runtime3 } from "effect";
8204
8542
  import { deleteCookie, getCookie as getCookie3, setCookie as setCookie2 } from "hono/cookie";
8205
8543
  import { streamSSE } from "hono/streaming";
8206
8544
  import prexit from "prexit";
8207
- import { z as z30 } from "zod";
8545
+ import { z as z31 } from "zod";
8208
8546
 
8209
8547
  // src/server/core/claude-code/schema.ts
8210
- import { z as z26 } from "zod";
8211
- var mediaTypeSchema = z26.enum([
8548
+ import { z as z27 } from "zod";
8549
+ var mediaTypeSchema = z27.enum([
8212
8550
  "image/png",
8213
8551
  "image/jpeg",
8214
8552
  "image/gif",
8215
8553
  "image/webp"
8216
8554
  ]);
8217
- var imageBlockSchema = z26.object({
8218
- type: z26.literal("image"),
8219
- source: z26.object({
8220
- type: z26.literal("base64"),
8555
+ var imageBlockSchema = z27.object({
8556
+ type: z27.literal("image"),
8557
+ source: z27.object({
8558
+ type: z27.literal("base64"),
8221
8559
  media_type: mediaTypeSchema,
8222
- data: z26.string()
8560
+ data: z27.string()
8223
8561
  })
8224
8562
  });
8225
- var documentBlockSchema = z26.object({
8226
- type: z26.literal("document"),
8227
- source: z26.union([
8228
- z26.object({
8229
- type: z26.literal("text"),
8230
- media_type: z26.enum(["text/plain"]),
8231
- data: z26.string()
8563
+ var documentBlockSchema = z27.object({
8564
+ type: z27.literal("document"),
8565
+ source: z27.union([
8566
+ z27.object({
8567
+ type: z27.literal("text"),
8568
+ media_type: z27.enum(["text/plain"]),
8569
+ data: z27.string()
8232
8570
  }),
8233
- z26.object({
8234
- type: z26.literal("base64"),
8235
- media_type: z26.enum(["application/pdf"]),
8236
- data: z26.string()
8571
+ z27.object({
8572
+ type: z27.literal("base64"),
8573
+ media_type: z27.enum(["application/pdf"]),
8574
+ data: z27.string()
8237
8575
  })
8238
8576
  ])
8239
8577
  });
8240
- var userMessageInputSchema = z26.object({
8241
- text: z26.string().min(1),
8242
- images: z26.array(imageBlockSchema).optional(),
8243
- documents: z26.array(documentBlockSchema).optional()
8578
+ var userMessageInputSchema = z27.object({
8579
+ text: z27.string().min(1),
8580
+ images: z27.array(imageBlockSchema).optional(),
8581
+ documents: z27.array(documentBlockSchema).optional()
8244
8582
  });
8245
8583
 
8246
8584
  // src/server/core/git/schema.ts
8247
- import { z as z27 } from "zod";
8248
- var CommitRequestSchema = z27.object({
8249
- projectId: z27.string().min(1),
8250
- files: z27.array(z27.string().min(1)).min(1),
8251
- message: z27.string().trim().min(1)
8585
+ import { z as z28 } from "zod";
8586
+ var CommitRequestSchema = z28.object({
8587
+ projectId: z28.string().min(1),
8588
+ files: z28.array(z28.string().min(1)).min(1),
8589
+ message: z28.string().trim().min(1)
8252
8590
  });
8253
- var PushRequestSchema = z27.object({
8254
- projectId: z27.string().min(1)
8591
+ var PushRequestSchema = z28.object({
8592
+ projectId: z28.string().min(1)
8255
8593
  });
8256
- var CommitResultSuccessSchema = z27.object({
8257
- success: z27.literal(true),
8258
- commitSha: z27.string().length(40),
8259
- filesCommitted: z27.number().int().positive(),
8260
- message: z27.string()
8594
+ var CommitResultSuccessSchema = z28.object({
8595
+ success: z28.literal(true),
8596
+ commitSha: z28.string().length(40),
8597
+ filesCommitted: z28.number().int().positive(),
8598
+ message: z28.string()
8261
8599
  });
8262
- var CommitResultErrorSchema = z27.object({
8263
- success: z27.literal(false),
8264
- error: z27.string(),
8265
- errorCode: z27.enum([
8600
+ var CommitResultErrorSchema = z28.object({
8601
+ success: z28.literal(false),
8602
+ error: z28.string(),
8603
+ errorCode: z28.enum([
8266
8604
  "EMPTY_MESSAGE",
8267
8605
  "NO_FILES",
8268
8606
  "PROJECT_NOT_FOUND",
@@ -8270,22 +8608,22 @@ var CommitResultErrorSchema = z27.object({
8270
8608
  "HOOK_FAILED",
8271
8609
  "GIT_COMMAND_ERROR"
8272
8610
  ]),
8273
- details: z27.string().optional()
8611
+ details: z28.string().optional()
8274
8612
  });
8275
- var CommitResultSchema = z27.discriminatedUnion("success", [
8613
+ var CommitResultSchema = z28.discriminatedUnion("success", [
8276
8614
  CommitResultSuccessSchema,
8277
8615
  CommitResultErrorSchema
8278
8616
  ]);
8279
- var PushResultSuccessSchema = z27.object({
8280
- success: z27.literal(true),
8281
- remote: z27.string(),
8282
- branch: z27.string(),
8283
- objectsPushed: z27.number().int().optional()
8617
+ var PushResultSuccessSchema = z28.object({
8618
+ success: z28.literal(true),
8619
+ remote: z28.string(),
8620
+ branch: z28.string(),
8621
+ objectsPushed: z28.number().int().optional()
8284
8622
  });
8285
- var PushResultErrorSchema = z27.object({
8286
- success: z27.literal(false),
8287
- error: z27.string(),
8288
- errorCode: z27.enum([
8623
+ var PushResultErrorSchema = z28.object({
8624
+ success: z28.literal(false),
8625
+ error: z28.string(),
8626
+ errorCode: z28.enum([
8289
8627
  "PROJECT_NOT_FOUND",
8290
8628
  "NOT_A_REPOSITORY",
8291
8629
  "NO_UPSTREAM",
@@ -8295,26 +8633,26 @@ var PushResultErrorSchema = z27.object({
8295
8633
  "TIMEOUT",
8296
8634
  "GIT_COMMAND_ERROR"
8297
8635
  ]),
8298
- details: z27.string().optional()
8636
+ details: z28.string().optional()
8299
8637
  });
8300
- var PushResultSchema = z27.discriminatedUnion("success", [
8638
+ var PushResultSchema = z28.discriminatedUnion("success", [
8301
8639
  PushResultSuccessSchema,
8302
8640
  PushResultErrorSchema
8303
8641
  ]);
8304
- var CommitAndPushResultSuccessSchema = z27.object({
8305
- success: z27.literal(true),
8306
- commitSha: z27.string().length(40),
8307
- filesCommitted: z27.number().int().positive(),
8308
- message: z27.string(),
8309
- remote: z27.string(),
8310
- branch: z27.string()
8642
+ var CommitAndPushResultSuccessSchema = z28.object({
8643
+ success: z28.literal(true),
8644
+ commitSha: z28.string().length(40),
8645
+ filesCommitted: z28.number().int().positive(),
8646
+ message: z28.string(),
8647
+ remote: z28.string(),
8648
+ branch: z28.string()
8311
8649
  });
8312
- var CommitAndPushResultErrorSchema = z27.object({
8313
- success: z27.literal(false),
8314
- commitSucceeded: z27.boolean(),
8315
- commitSha: z27.string().length(40).optional(),
8316
- error: z27.string(),
8317
- errorCode: z27.enum([
8650
+ var CommitAndPushResultErrorSchema = z28.object({
8651
+ success: z28.literal(false),
8652
+ commitSucceeded: z28.boolean(),
8653
+ commitSha: z28.string().length(40).optional(),
8654
+ error: z28.string(),
8655
+ errorCode: z28.enum([
8318
8656
  "EMPTY_MESSAGE",
8319
8657
  "NO_FILES",
8320
8658
  "PROJECT_NOT_FOUND",
@@ -8327,37 +8665,37 @@ var CommitAndPushResultErrorSchema = z27.object({
8327
8665
  "NETWORK_ERROR",
8328
8666
  "TIMEOUT"
8329
8667
  ]),
8330
- details: z27.string().optional()
8668
+ details: z28.string().optional()
8331
8669
  });
8332
- var CommitAndPushResultSchema = z27.discriminatedUnion("success", [
8670
+ var CommitAndPushResultSchema = z28.discriminatedUnion("success", [
8333
8671
  CommitAndPushResultSuccessSchema,
8334
8672
  CommitAndPushResultErrorSchema
8335
8673
  ]);
8336
8674
 
8337
8675
  // src/server/lib/config/config.ts
8338
- import z29 from "zod";
8676
+ import z30 from "zod";
8339
8677
 
8340
8678
  // src/lib/i18n/schema.ts
8341
- import z28 from "zod";
8342
- var localeSchema = z28.enum(["ja", "en", "zh_CN"]);
8679
+ import z29 from "zod";
8680
+ var localeSchema = z29.enum(["ja", "en", "zh_CN"]);
8343
8681
 
8344
8682
  // src/server/lib/config/config.ts
8345
- var userConfigSchema = z29.object({
8346
- hideNoUserMessageSession: z29.boolean().optional().default(true),
8347
- unifySameTitleSession: z29.boolean().optional().default(false),
8348
- enterKeyBehavior: z29.enum(["shift-enter-send", "enter-send", "command-enter-send"]).optional().default("shift-enter-send"),
8349
- permissionMode: z29.enum(["acceptEdits", "bypassPermissions", "default", "plan"]).optional().default("default"),
8683
+ var userConfigSchema = z30.object({
8684
+ hideNoUserMessageSession: z30.boolean().optional().default(true),
8685
+ unifySameTitleSession: z30.boolean().optional().default(false),
8686
+ enterKeyBehavior: z30.enum(["shift-enter-send", "enter-send", "command-enter-send"]).optional().default("shift-enter-send"),
8687
+ permissionMode: z30.enum(["acceptEdits", "bypassPermissions", "default", "plan"]).optional().default("default"),
8350
8688
  locale: localeSchema.optional().default("en"),
8351
- theme: z29.enum(["light", "dark", "system"]).optional().default("system"),
8352
- searchHotkey: z29.enum(["ctrl-k", "command-k"]).optional().default("command-k"),
8353
- autoScheduleContinueOnRateLimit: z29.boolean().optional().default(false)
8689
+ theme: z30.enum(["light", "dark", "system"]).optional().default("system"),
8690
+ searchHotkey: z30.enum(["ctrl-k", "command-k"]).optional().default("command-k"),
8691
+ autoScheduleContinueOnRateLimit: z30.boolean().optional().default(false)
8354
8692
  });
8355
8693
  var defaultUserConfig = userConfigSchema.parse({});
8356
8694
 
8357
8695
  // src/server/lib/effect/toEffectResponse.ts
8358
- import { Effect as Effect48 } from "effect";
8696
+ import { Effect as Effect50 } from "effect";
8359
8697
  var effectToResponse = async (ctx, effect) => {
8360
- const result = await Effect48.runPromise(effect);
8698
+ const result = await Effect50.runPromise(effect);
8361
8699
  const result2 = ctx.json(result.response, result.status);
8362
8700
  return result2;
8363
8701
  };
@@ -8400,7 +8738,7 @@ var configMiddleware = createMiddleware2(
8400
8738
  );
8401
8739
 
8402
8740
  // src/server/hono/route.ts
8403
- var routes = (app, options) => Effect49.gen(function* () {
8741
+ var routes = (app, options) => Effect51.gen(function* () {
8404
8742
  const ccvOptionsService = yield* CcvOptionsService;
8405
8743
  yield* ccvOptionsService.loadCliOptions(options);
8406
8744
  const envService = yield* EnvService;
@@ -8419,9 +8757,10 @@ var routes = (app, options) => Effect49.gen(function* () {
8419
8757
  const schedulerController = yield* SchedulerController;
8420
8758
  const featureFlagController = yield* FeatureFlagController;
8421
8759
  const searchController = yield* SearchController;
8760
+ const tasksController = yield* TasksController;
8422
8761
  const authMiddlewareService = yield* AuthMiddleware;
8423
8762
  const { authMiddleware, validSessionToken, authEnabled, anthPassword } = yield* authMiddlewareService;
8424
- const runtime = yield* Effect49.runtime();
8763
+ const runtime = yield* Effect51.runtime();
8425
8764
  if ((yield* envService.getEnv("NEXT_PHASE")) !== "phase-production-build") {
8426
8765
  yield* initializeService.startInitialization();
8427
8766
  prexit(async () => {
@@ -8429,7 +8768,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8429
8768
  });
8430
8769
  }
8431
8770
  return app.use(configMiddleware).use(authMiddleware).use(async (c, next) => {
8432
- await Effect49.runPromise(
8771
+ await Effect51.runPromise(
8433
8772
  userConfigService.setUserConfig({
8434
8773
  ...c.get("userConfig")
8435
8774
  })
@@ -8437,7 +8776,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8437
8776
  await next();
8438
8777
  }).post(
8439
8778
  "/api/auth/login",
8440
- zValidator("json", z30.object({ password: z30.string() })),
8779
+ zValidator("json", z31.object({ password: z31.string() })),
8441
8780
  async (c) => {
8442
8781
  const { password } = c.req.valid("json");
8443
8782
  if (!authEnabled) {
@@ -8491,14 +8830,14 @@ var routes = (app, options) => Effect49.gen(function* () {
8491
8830
  return response;
8492
8831
  }).get(
8493
8832
  "/api/projects/:projectId",
8494
- zValidator("query", z30.object({ cursor: z30.string().optional() })),
8833
+ zValidator("query", z31.object({ cursor: z31.string().optional() })),
8495
8834
  async (c) => {
8496
8835
  const response = await effectToResponse(
8497
8836
  c,
8498
8837
  projectController.getProject({
8499
8838
  ...c.req.param(),
8500
8839
  ...c.req.valid("query")
8501
- }).pipe(Effect49.provide(runtime))
8840
+ }).pipe(Effect51.provide(runtime))
8502
8841
  );
8503
8842
  return response;
8504
8843
  }
@@ -8506,8 +8845,8 @@ var routes = (app, options) => Effect49.gen(function* () {
8506
8845
  "/api/projects",
8507
8846
  zValidator(
8508
8847
  "json",
8509
- z30.object({
8510
- projectPath: z30.string().min(1, "Project path is required")
8848
+ z31.object({
8849
+ projectPath: z31.string().min(1, "Project path is required")
8511
8850
  })
8512
8851
  ),
8513
8852
  async (c) => {
@@ -8515,7 +8854,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8515
8854
  c,
8516
8855
  projectController.createProject({
8517
8856
  ...c.req.valid("json")
8518
- }).pipe(Effect49.provide(runtime))
8857
+ }).pipe(Effect51.provide(runtime))
8519
8858
  );
8520
8859
  return response;
8521
8860
  }
@@ -8524,13 +8863,13 @@ var routes = (app, options) => Effect49.gen(function* () {
8524
8863
  c,
8525
8864
  projectController.getProjectLatestSession({
8526
8865
  ...c.req.param()
8527
- }).pipe(Effect49.provide(runtime))
8866
+ }).pipe(Effect51.provide(runtime))
8528
8867
  );
8529
8868
  return response;
8530
8869
  }).get("/api/projects/:projectId/sessions/:sessionId", async (c) => {
8531
8870
  const response = await effectToResponse(
8532
8871
  c,
8533
- sessionController.getSession({ ...c.req.param() }).pipe(Effect49.provide(runtime))
8872
+ sessionController.getSession({ ...c.req.param() }).pipe(Effect51.provide(runtime))
8534
8873
  );
8535
8874
  return response;
8536
8875
  }).get(
@@ -8538,19 +8877,19 @@ var routes = (app, options) => Effect49.gen(function* () {
8538
8877
  async (c) => {
8539
8878
  const response = await effectToResponse(
8540
8879
  c,
8541
- sessionController.exportSessionHtml({ ...c.req.param() }).pipe(Effect49.provide(runtime))
8880
+ sessionController.exportSessionHtml({ ...c.req.param() }).pipe(Effect51.provide(runtime))
8542
8881
  );
8543
8882
  return response;
8544
8883
  }
8545
8884
  ).delete("/api/projects/:projectId/sessions/:sessionId", async (c) => {
8546
8885
  const response = await effectToResponse(
8547
8886
  c,
8548
- sessionController.deleteSession({ ...c.req.param() }).pipe(Effect49.provide(runtime))
8887
+ sessionController.deleteSession({ ...c.req.param() }).pipe(Effect51.provide(runtime))
8549
8888
  );
8550
8889
  return response;
8551
8890
  }).get(
8552
8891
  "/api/projects/:projectId/agent-sessions/:agentId",
8553
- zValidator("query", z30.object({ sessionId: z30.string().optional() })),
8892
+ zValidator("query", z31.object({ sessionId: z31.string().optional() })),
8554
8893
  async (c) => {
8555
8894
  const { projectId, agentId } = c.req.param();
8556
8895
  const { sessionId } = c.req.valid("query");
@@ -8560,7 +8899,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8560
8899
  projectId,
8561
8900
  agentId,
8562
8901
  sessionId
8563
- }).pipe(Effect49.provide(runtime))
8902
+ }).pipe(Effect51.provide(runtime))
8564
8903
  );
8565
8904
  return response;
8566
8905
  }
@@ -8569,16 +8908,16 @@ var routes = (app, options) => Effect49.gen(function* () {
8569
8908
  c,
8570
8909
  gitController.getCurrentRevisions({
8571
8910
  ...c.req.param()
8572
- }).pipe(Effect49.provide(runtime))
8911
+ }).pipe(Effect51.provide(runtime))
8573
8912
  );
8574
8913
  return response;
8575
8914
  }).post(
8576
8915
  "/api/projects/:projectId/git/diff",
8577
8916
  zValidator(
8578
8917
  "json",
8579
- z30.object({
8580
- fromRef: z30.string().min(1, "fromRef is required"),
8581
- toRef: z30.string().min(1, "toRef is required")
8918
+ z31.object({
8919
+ fromRef: z31.string().min(1, "fromRef is required"),
8920
+ toRef: z31.string().min(1, "toRef is required")
8582
8921
  })
8583
8922
  ),
8584
8923
  async (c) => {
@@ -8587,7 +8926,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8587
8926
  gitController.getGitDiff({
8588
8927
  ...c.req.param(),
8589
8928
  ...c.req.valid("json")
8590
- }).pipe(Effect49.provide(runtime))
8929
+ }).pipe(Effect51.provide(runtime))
8591
8930
  );
8592
8931
  return response;
8593
8932
  }
@@ -8600,7 +8939,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8600
8939
  gitController.commitFiles({
8601
8940
  ...c.req.param(),
8602
8941
  ...c.req.valid("json")
8603
- }).pipe(Effect49.provide(runtime))
8942
+ }).pipe(Effect51.provide(runtime))
8604
8943
  );
8605
8944
  return response;
8606
8945
  }
@@ -8613,7 +8952,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8613
8952
  gitController.pushCommits({
8614
8953
  ...c.req.param(),
8615
8954
  ...c.req.valid("json")
8616
- }).pipe(Effect49.provide(runtime))
8955
+ }).pipe(Effect51.provide(runtime))
8617
8956
  );
8618
8957
  return response;
8619
8958
  }
@@ -8626,7 +8965,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8626
8965
  gitController.commitAndPush({
8627
8966
  ...c.req.param(),
8628
8967
  ...c.req.valid("json")
8629
- }).pipe(Effect49.provide(runtime))
8968
+ }).pipe(Effect51.provide(runtime))
8630
8969
  );
8631
8970
  return response;
8632
8971
  }
@@ -8635,7 +8974,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8635
8974
  c,
8636
8975
  claudeCodeController.getClaudeCommands({
8637
8976
  ...c.req.param()
8638
- }).pipe(Effect49.provide(runtime))
8977
+ }).pipe(Effect51.provide(runtime))
8639
8978
  );
8640
8979
  return response;
8641
8980
  }).get("/api/projects/:projectId/mcp/list", async (c) => {
@@ -8643,19 +8982,19 @@ var routes = (app, options) => Effect49.gen(function* () {
8643
8982
  c,
8644
8983
  claudeCodeController.getMcpListRoute({
8645
8984
  ...c.req.param()
8646
- }).pipe(Effect49.provide(runtime))
8985
+ }).pipe(Effect51.provide(runtime))
8647
8986
  );
8648
8987
  return response;
8649
8988
  }).get("/api/cc/meta", async (c) => {
8650
8989
  const response = await effectToResponse(
8651
8990
  c,
8652
- claudeCodeController.getClaudeCodeMeta().pipe(Effect49.provide(runtime))
8991
+ claudeCodeController.getClaudeCodeMeta().pipe(Effect51.provide(runtime))
8653
8992
  );
8654
8993
  return response;
8655
8994
  }).get("/api/cc/features", async (c) => {
8656
8995
  const response = await effectToResponse(
8657
8996
  c,
8658
- claudeCodeController.getAvailableFeatures().pipe(Effect49.provide(runtime))
8997
+ claudeCodeController.getAvailableFeatures().pipe(Effect51.provide(runtime))
8659
8998
  );
8660
8999
  return response;
8661
9000
  }).get("/api/cc/session-processes", async (c) => {
@@ -8668,10 +9007,10 @@ var routes = (app, options) => Effect49.gen(function* () {
8668
9007
  "/api/cc/session-processes",
8669
9008
  zValidator(
8670
9009
  "json",
8671
- z30.object({
8672
- projectId: z30.string(),
9010
+ z31.object({
9011
+ projectId: z31.string(),
8673
9012
  input: userMessageInputSchema,
8674
- baseSessionId: z30.string().optional()
9013
+ baseSessionId: z31.string().optional()
8675
9014
  })
8676
9015
  ),
8677
9016
  async (c) => {
@@ -8687,10 +9026,10 @@ var routes = (app, options) => Effect49.gen(function* () {
8687
9026
  "/api/cc/session-processes/:sessionProcessId/continue",
8688
9027
  zValidator(
8689
9028
  "json",
8690
- z30.object({
8691
- projectId: z30.string(),
9029
+ z31.object({
9030
+ projectId: z31.string(),
8692
9031
  input: userMessageInputSchema,
8693
- baseSessionId: z30.string()
9032
+ baseSessionId: z31.string()
8694
9033
  })
8695
9034
  ),
8696
9035
  async (c) => {
@@ -8699,16 +9038,16 @@ var routes = (app, options) => Effect49.gen(function* () {
8699
9038
  claudeCodeSessionProcessController.continueSessionProcess({
8700
9039
  ...c.req.param(),
8701
9040
  ...c.req.valid("json")
8702
- }).pipe(Effect49.provide(runtime))
9041
+ }).pipe(Effect51.provide(runtime))
8703
9042
  );
8704
9043
  return response;
8705
9044
  }
8706
9045
  ).post(
8707
9046
  "/api/cc/session-processes/:sessionProcessId/abort",
8708
- zValidator("json", z30.object({ projectId: z30.string() })),
9047
+ zValidator("json", z31.object({ projectId: z31.string() })),
8709
9048
  async (c) => {
8710
9049
  const { sessionProcessId } = c.req.param();
8711
- void Effect49.runFork(
9050
+ void Effect51.runFork(
8712
9051
  claudeCodeLifeCycleService.abortTask(sessionProcessId)
8713
9052
  );
8714
9053
  return c.json({ message: "Task aborted" });
@@ -8717,9 +9056,9 @@ var routes = (app, options) => Effect49.gen(function* () {
8717
9056
  "/api/cc/permission-response",
8718
9057
  zValidator(
8719
9058
  "json",
8720
- z30.object({
8721
- permissionRequestId: z30.string(),
8722
- decision: z30.enum(["allow", "deny"])
9059
+ z31.object({
9060
+ permissionRequestId: z31.string(),
9061
+ decision: z31.enum(["allow", "deny"])
8723
9062
  })
8724
9063
  ),
8725
9064
  async (c) => {
@@ -8736,7 +9075,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8736
9075
  c,
8737
9076
  async (rawStream) => {
8738
9077
  await Runtime3.runPromise(runtime)(
8739
- sseController.handleSSE(rawStream).pipe(Effect49.provide(TypeSafeSSE.make(rawStream)))
9078
+ sseController.handleSSE(rawStream).pipe(Effect51.provide(TypeSafeSSE.make(rawStream)))
8740
9079
  );
8741
9080
  },
8742
9081
  async (err) => {
@@ -8746,7 +9085,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8746
9085
  }).get("/api/scheduler/jobs", async (c) => {
8747
9086
  const response = await effectToResponse(
8748
9087
  c,
8749
- schedulerController.getJobs().pipe(Effect49.provide(runtime))
9088
+ schedulerController.getJobs().pipe(Effect51.provide(runtime))
8750
9089
  );
8751
9090
  return response;
8752
9091
  }).post(
@@ -8757,7 +9096,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8757
9096
  c,
8758
9097
  schedulerController.addJob({
8759
9098
  job: c.req.valid("json")
8760
- }).pipe(Effect49.provide(runtime))
9099
+ }).pipe(Effect51.provide(runtime))
8761
9100
  );
8762
9101
  return response;
8763
9102
  }
@@ -8770,7 +9109,7 @@ var routes = (app, options) => Effect49.gen(function* () {
8770
9109
  schedulerController.updateJob({
8771
9110
  id: c.req.param("id"),
8772
9111
  job: c.req.valid("json")
8773
- }).pipe(Effect49.provide(runtime))
9112
+ }).pipe(Effect51.provide(runtime))
8774
9113
  );
8775
9114
  return response;
8776
9115
  }
@@ -8779,16 +9118,16 @@ var routes = (app, options) => Effect49.gen(function* () {
8779
9118
  c,
8780
9119
  schedulerController.deleteJob({
8781
9120
  id: c.req.param("id")
8782
- }).pipe(Effect49.provide(runtime))
9121
+ }).pipe(Effect51.provide(runtime))
8783
9122
  );
8784
9123
  return response;
8785
9124
  }).get(
8786
9125
  "/api/fs/file-completion",
8787
9126
  zValidator(
8788
9127
  "query",
8789
- z30.object({
8790
- projectId: z30.string(),
8791
- basePath: z30.string().optional().default("/api/")
9128
+ z31.object({
9129
+ projectId: z31.string(),
9130
+ basePath: z31.string().optional().default("/api/")
8792
9131
  })
8793
9132
  ),
8794
9133
  async (c) => {
@@ -8804,9 +9143,9 @@ var routes = (app, options) => Effect49.gen(function* () {
8804
9143
  "/api/fs/directory-browser",
8805
9144
  zValidator(
8806
9145
  "query",
8807
- z30.object({
8808
- currentPath: z30.string().optional(),
8809
- showHidden: z30.string().optional().transform((val) => val === "true")
9146
+ z31.object({
9147
+ currentPath: z31.string().optional(),
9148
+ showHidden: z31.string().optional().transform((val) => val === "true")
8810
9149
  })
8811
9150
  ),
8812
9151
  async (c) => {
@@ -8822,42 +9161,119 @@ var routes = (app, options) => Effect49.gen(function* () {
8822
9161
  "/api/search",
8823
9162
  zValidator(
8824
9163
  "query",
8825
- z30.object({
8826
- q: z30.string().min(2),
8827
- limit: z30.string().optional().transform((val) => val ? parseInt(val, 10) : void 0),
8828
- projectId: z30.string().optional()
9164
+ z31.object({
9165
+ q: z31.string().min(2),
9166
+ limit: z31.string().optional().transform((val) => val ? parseInt(val, 10) : void 0),
9167
+ projectId: z31.string().optional()
8829
9168
  })
8830
9169
  ),
8831
9170
  async (c) => {
8832
9171
  const { q, limit, projectId } = c.req.valid("query");
8833
9172
  const response = await effectToResponse(
8834
9173
  c,
8835
- searchController.search({ query: q, limit, projectId }).pipe(Effect49.provide(runtime))
9174
+ searchController.search({ query: q, limit, projectId }).pipe(Effect51.provide(runtime))
8836
9175
  );
8837
9176
  return response;
8838
9177
  }
8839
9178
  ).get("/api/flags", async (c) => {
8840
9179
  const response = await effectToResponse(
8841
9180
  c,
8842
- featureFlagController.getFlags().pipe(Effect49.provide(runtime))
9181
+ featureFlagController.getFlags().pipe(Effect51.provide(runtime))
8843
9182
  );
8844
9183
  return response;
8845
- });
9184
+ }).get(
9185
+ "/api/tasks",
9186
+ zValidator(
9187
+ "query",
9188
+ z31.object({
9189
+ projectId: z31.string(),
9190
+ sessionId: z31.string().optional()
9191
+ })
9192
+ ),
9193
+ async (c) => {
9194
+ const { projectId, sessionId } = c.req.valid("query");
9195
+ const projectPath = decodeProjectId(projectId);
9196
+ const response = await effectToResponse(
9197
+ c,
9198
+ tasksController.listTasks(projectPath, sessionId).pipe(
9199
+ Effect51.map((tasks) => ({
9200
+ status: 200,
9201
+ response: tasks
9202
+ })),
9203
+ Effect51.provide(runtime)
9204
+ )
9205
+ );
9206
+ return response;
9207
+ }
9208
+ ).post(
9209
+ "/api/tasks",
9210
+ zValidator(
9211
+ "query",
9212
+ z31.object({
9213
+ projectId: z31.string(),
9214
+ sessionId: z31.string().optional()
9215
+ })
9216
+ ),
9217
+ zValidator("json", TaskCreateSchema),
9218
+ async (c) => {
9219
+ const { projectId, sessionId } = c.req.valid("query");
9220
+ const body = c.req.valid("json");
9221
+ const projectPath = decodeProjectId(projectId);
9222
+ const response = await effectToResponse(
9223
+ c,
9224
+ tasksController.createTask(projectPath, body, sessionId).pipe(
9225
+ Effect51.map((task) => ({
9226
+ status: 200,
9227
+ response: task
9228
+ })),
9229
+ Effect51.provide(runtime)
9230
+ )
9231
+ );
9232
+ return response;
9233
+ }
9234
+ ).patch(
9235
+ "/api/tasks/:id",
9236
+ zValidator(
9237
+ "query",
9238
+ z31.object({
9239
+ projectId: z31.string(),
9240
+ sessionId: z31.string().optional()
9241
+ })
9242
+ ),
9243
+ zValidator("json", TaskUpdateSchema.omit({ taskId: true })),
9244
+ async (c) => {
9245
+ const { id } = c.req.param();
9246
+ const { projectId, sessionId } = c.req.valid("query");
9247
+ const body = c.req.valid("json");
9248
+ const projectPath = decodeProjectId(projectId);
9249
+ const response = await effectToResponse(
9250
+ c,
9251
+ tasksController.updateTask(projectPath, { ...body, taskId: id }, sessionId).pipe(
9252
+ Effect51.map((task) => ({
9253
+ status: 200,
9254
+ response: task
9255
+ })),
9256
+ Effect51.provide(runtime)
9257
+ )
9258
+ );
9259
+ return response;
9260
+ }
9261
+ );
8846
9262
  });
8847
9263
 
8848
9264
  // src/server/lib/effect/layers.ts
8849
9265
  import { NodeContext } from "@effect/platform-node";
8850
- import { Layer as Layer40 } from "effect";
8851
- var platformLayer = Layer40.mergeAll(
9266
+ import { Layer as Layer42 } from "effect";
9267
+ var platformLayer = Layer42.mergeAll(
8852
9268
  ApplicationContext.Live,
8853
9269
  UserConfigService.Live,
8854
9270
  EventBus.Live,
8855
9271
  EnvService.Live,
8856
9272
  CcvOptionsService.Live
8857
9273
  ).pipe(
8858
- Layer40.provide(EnvService.Live),
8859
- Layer40.provide(CcvOptionsService.Live),
8860
- Layer40.provide(NodeContext.layer)
9274
+ Layer42.provide(EnvService.Live),
9275
+ Layer42.provide(CcvOptionsService.Live),
9276
+ Layer42.provide(NodeContext.layer)
8861
9277
  );
8862
9278
 
8863
9279
  // src/server/startServer.ts
@@ -8880,50 +9296,8 @@ var startServer = async (options) => {
8880
9296
  return c.html(html);
8881
9297
  });
8882
9298
  }
8883
- const program2 = routes(honoApp, options).pipe(
8884
- /** Presentation */
8885
- Effect50.provide(ProjectController.Live),
8886
- Effect50.provide(SessionController.Live),
8887
- Effect50.provide(AgentSessionController.Live),
8888
- Effect50.provide(GitController.Live),
8889
- Effect50.provide(ClaudeCodeController.Live),
8890
- Effect50.provide(ClaudeCodeSessionProcessController.Live),
8891
- Effect50.provide(ClaudeCodePermissionController.Live),
8892
- Effect50.provide(FileSystemController.Live),
8893
- Effect50.provide(SSEController.Live),
8894
- Effect50.provide(SchedulerController.Live),
8895
- Effect50.provide(FeatureFlagController.Live),
8896
- Effect50.provide(SearchController.Live)
8897
- ).pipe(
8898
- /** Application */
8899
- Effect50.provide(InitializeService.Live),
8900
- Effect50.provide(FileWatcherService.Live),
8901
- Effect50.provide(RateLimitAutoScheduleService.Live),
8902
- Effect50.provide(AuthMiddleware.Live)
8903
- ).pipe(
8904
- /** Domain */
8905
- Effect50.provide(ClaudeCodeLifeCycleService.Live),
8906
- Effect50.provide(ClaudeCodePermissionService.Live),
8907
- Effect50.provide(ClaudeCodeSessionProcessService.Live),
8908
- Effect50.provide(ClaudeCodeService.Live),
8909
- Effect50.provide(GitService.Live),
8910
- Effect50.provide(SchedulerService.Live),
8911
- Effect50.provide(SchedulerConfigBaseDir.Live),
8912
- Effect50.provide(SearchService.Live)
8913
- ).pipe(
8914
- /** Infrastructure */
8915
- Effect50.provide(ProjectRepository.Live),
8916
- Effect50.provide(SessionRepository.Live),
8917
- Effect50.provide(ProjectMetaService.Live),
8918
- Effect50.provide(SessionMetaService.Live),
8919
- Effect50.provide(VirtualConversationDatabase.Live),
8920
- Effect50.provide(AgentSessionLayer)
8921
- ).pipe(
8922
- /** Platform */
8923
- Effect50.provide(platformLayer),
8924
- Effect50.provide(NodeContext2.layer)
8925
- );
8926
- await Effect50.runPromise(program2);
9299
+ const program2 = routes(honoApp, options).pipe(Effect52.provide(MainLayer));
9300
+ await Effect52.runPromise(program2);
8927
9301
  const port = isDevelopment ? (
8928
9302
  // biome-ignore lint/style/noProcessEnv: allow only here
8929
9303
  process.env.DEV_BE_PORT ?? "3401"
@@ -8943,12 +9317,65 @@ var startServer = async (options) => {
8943
9317
  }
8944
9318
  );
8945
9319
  };
9320
+ var PlatformLayer = Layer43.mergeAll(platformLayer, NodeContext2.layer);
9321
+ var InfraBasics = Layer43.mergeAll(
9322
+ VirtualConversationDatabase.Live,
9323
+ ProjectMetaService.Live,
9324
+ SessionMetaService.Live
9325
+ );
9326
+ var InfraRepos = Layer43.mergeAll(
9327
+ ProjectRepository.Live,
9328
+ SessionRepository.Live
9329
+ ).pipe(Layer43.provideMerge(InfraBasics));
9330
+ var InfraLayer = AgentSessionLayer.pipe(Layer43.provideMerge(InfraRepos));
9331
+ var DomainBase = Layer43.mergeAll(
9332
+ ClaudeCodePermissionService.Live,
9333
+ ClaudeCodeSessionProcessService.Live,
9334
+ ClaudeCodeService.Live,
9335
+ GitService.Live,
9336
+ SchedulerService.Live,
9337
+ SchedulerConfigBaseDir.Live,
9338
+ SearchService.Live,
9339
+ TasksService.Live
9340
+ );
9341
+ var DomainLayer = ClaudeCodeLifeCycleService.Live.pipe(
9342
+ Layer43.provideMerge(DomainBase)
9343
+ );
9344
+ var AppServices = Layer43.mergeAll(
9345
+ FileWatcherService.Live,
9346
+ RateLimitAutoScheduleService.Live,
9347
+ AuthMiddleware.Live
9348
+ );
9349
+ var ApplicationLayer = InitializeService.Live.pipe(
9350
+ Layer43.provideMerge(AppServices)
9351
+ );
9352
+ var PresentationLayer = Layer43.mergeAll(
9353
+ ProjectController.Live,
9354
+ SessionController.Live,
9355
+ AgentSessionController.Live,
9356
+ GitController.Live,
9357
+ ClaudeCodeController.Live,
9358
+ ClaudeCodeSessionProcessController.Live,
9359
+ ClaudeCodePermissionController.Live,
9360
+ FileSystemController.Live,
9361
+ SSEController.Live,
9362
+ SchedulerController.Live,
9363
+ FeatureFlagController.Live,
9364
+ SearchController.Live,
9365
+ TasksController.Live
9366
+ );
9367
+ var MainLayer = PresentationLayer.pipe(
9368
+ Layer43.provideMerge(ApplicationLayer),
9369
+ Layer43.provideMerge(DomainLayer),
9370
+ Layer43.provideMerge(InfraLayer),
9371
+ Layer43.provideMerge(PlatformLayer)
9372
+ );
8946
9373
 
8947
9374
  // src/server/main.ts
8948
9375
  var program = new Command3();
8949
9376
  program.name(package_default.name).version(package_default.version).description(package_default.description);
8950
9377
  program.option("-p, --port <port>", "port to listen on").option("-h, --hostname <hostname>", "hostname to listen on").option("-P, --password <password>", "password to authenticate").option("-e, --executable <executable>", "path to claude code executable").option("--claude-dir <claude-dir>", "path to claude directory").action(async (options) => {
8951
- await Effect51.runPromise(checkDeprecatedEnvs);
9378
+ await Effect53.runPromise(checkDeprecatedEnvs);
8952
9379
  await startServer(options);
8953
9380
  });
8954
9381
  var main = async () => {