@kimuson/claude-code-viewer 0.4.2 → 0.4.4

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
@@ -112,7 +112,7 @@ var encodeProjectIdFromSessionFilePath = (sessionFilePath) => {
112
112
  // src/server/core/project/services/ProjectMetaService.ts
113
113
  import { FileSystem as FileSystem2, Path as Path3 } from "@effect/platform";
114
114
  import { Context as Context4, Effect as Effect5, Layer as Layer5, Option, Ref as Ref3 } from "effect";
115
- import { z as z18 } from "zod";
115
+ import { z as z19 } from "zod";
116
116
 
117
117
  // src/server/lib/storage/FileCacheStorage/index.ts
118
118
  import { Context as Context3, Effect as Effect4, Layer as Layer4, Ref as Ref2, Runtime } from "effect";
@@ -245,7 +245,7 @@ var makeFileCacheStorageLayer = (storageKey, schema) => Layer4.effect(
245
245
  );
246
246
 
247
247
  // src/lib/conversation-schema/index.ts
248
- import { z as z17 } from "zod";
248
+ import { z as z18 } from "zod";
249
249
 
250
250
  // src/lib/conversation-schema/entry/AssistantEntrySchema.ts
251
251
  import { z as z10 } from "zod";
@@ -381,80 +381,99 @@ var FileHistorySnapshotEntrySchema = z11.object({
381
381
  isSnapshotUpdate: z11.boolean()
382
382
  });
383
383
 
384
- // src/lib/conversation-schema/entry/SummaryEntrySchema.ts
384
+ // src/lib/conversation-schema/entry/QueueOperationEntrySchema.ts
385
385
  import { z as z12 } from "zod";
386
- var SummaryEntrySchema = z12.object({
387
- type: z12.literal("summary"),
388
- summary: z12.string(),
389
- leafUuid: z12.string().uuid()
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()
390
408
  });
391
409
 
392
410
  // src/lib/conversation-schema/entry/SystemEntrySchema.ts
393
- import { z as z13 } from "zod";
411
+ import { z as z14 } from "zod";
394
412
  var SystemEntrySchema = BaseEntrySchema.extend({
395
413
  // discriminator
396
- type: z13.literal("system"),
414
+ type: z14.literal("system"),
397
415
  // required
398
- content: z13.string(),
399
- toolUseID: z13.string(),
400
- level: z13.enum(["info"])
416
+ content: z14.string(),
417
+ toolUseID: z14.string(),
418
+ level: z14.enum(["info"])
401
419
  });
402
420
 
403
421
  // src/lib/conversation-schema/entry/UserEntrySchema.ts
404
- import { z as z16 } from "zod";
422
+ import { z as z17 } from "zod";
405
423
 
406
424
  // src/lib/conversation-schema/message/UserMessageSchema.ts
407
- import { z as z15 } from "zod";
425
+ import { z as z16 } from "zod";
408
426
 
409
427
  // src/lib/conversation-schema/content/DocumentContentSchema.ts
410
- import { z as z14 } from "zod";
411
- var DocumentContentSchema = z14.object({
412
- type: z14.literal("document"),
413
- source: z14.union([
414
- z14.object({
415
- media_type: z14.literal("text/plain"),
416
- type: z14.literal("text"),
417
- data: z14.string()
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()
418
436
  }),
419
- z14.object({
420
- media_type: z14.enum(["application/pdf"]),
421
- type: z14.literal("base64"),
422
- data: z14.string()
437
+ z15.object({
438
+ media_type: z15.enum(["application/pdf"]),
439
+ type: z15.literal("base64"),
440
+ data: z15.string()
423
441
  })
424
442
  ])
425
443
  });
426
444
 
427
445
  // src/lib/conversation-schema/message/UserMessageSchema.ts
428
- var UserMessageContentSchema = z15.union([
429
- z15.string(),
446
+ var UserMessageContentSchema = z16.union([
447
+ z16.string(),
430
448
  TextContentSchema,
431
449
  ToolResultContentSchema,
432
450
  ImageContentSchema,
433
451
  DocumentContentSchema
434
452
  ]);
435
- var UserMessageSchema = z15.object({
436
- role: z15.literal("user"),
437
- content: z15.union([
438
- z15.string(),
439
- z15.array(z15.union([z15.string(), UserMessageContentSchema]))
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]))
440
458
  ])
441
459
  });
442
460
 
443
461
  // src/lib/conversation-schema/entry/UserEntrySchema.ts
444
462
  var UserEntrySchema = BaseEntrySchema.extend({
445
463
  // discriminator
446
- type: z16.literal("user"),
464
+ type: z17.literal("user"),
447
465
  // required
448
466
  message: UserMessageSchema
449
467
  });
450
468
 
451
469
  // src/lib/conversation-schema/index.ts
452
- var ConversationSchema = z17.union([
470
+ var ConversationSchema = z18.union([
453
471
  UserEntrySchema,
454
472
  AssistantEntrySchema,
455
473
  SummaryEntrySchema,
456
474
  SystemEntrySchema,
457
- FileHistorySnapshotEntrySchema
475
+ FileHistorySnapshotEntrySchema,
476
+ QueueOperationEntrySchema
458
477
  ]);
459
478
 
460
479
  // src/server/core/claude-code/functions/parseJsonl.ts
@@ -475,7 +494,7 @@ var parseJsonl = (content) => {
475
494
  };
476
495
 
477
496
  // src/server/core/project/services/ProjectMetaService.ts
478
- var ProjectPathSchema = z18.string().nullable();
497
+ var ProjectPathSchema = z19.string().nullable();
479
498
  var LayerImpl4 = Effect5.gen(function* () {
480
499
  const fs = yield* FileSystem2.FileSystem;
481
500
  const path = yield* Path3.Path;
@@ -491,7 +510,7 @@ var LayerImpl4 = Effect5.gen(function* () {
491
510
  let cwd = null;
492
511
  for (const line of lines) {
493
512
  const conversation = parseJsonl(line).at(0);
494
- if (conversation === void 0 || conversation.type === "summary" || conversation.type === "x-error" || conversation.type === "file-history-snapshot") {
513
+ if (conversation === void 0 || conversation.type === "summary" || conversation.type === "x-error" || conversation.type === "file-history-snapshot" || conversation.type === "queue-operation") {
495
514
  continue;
496
515
  }
497
516
  cwd = conversation.cwd;
@@ -649,12 +668,12 @@ var ProjectRepository = class extends Context5.Tag("ProjectRepository")() {
649
668
  };
650
669
 
651
670
  // src/server/core/claude-code/models/ClaudeCodeVersion.ts
652
- import { z as z19 } from "zod";
671
+ import { z as z20 } from "zod";
653
672
  var versionRegex = /^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/;
654
- var versionSchema = z19.object({
655
- major: z19.string().transform((value) => Number.parseInt(value, 10)),
656
- minor: z19.string().transform((value) => Number.parseInt(value, 10)),
657
- patch: z19.string().transform((value) => Number.parseInt(value, 10))
673
+ var versionSchema = z20.object({
674
+ major: z20.string().transform((value) => Number.parseInt(value, 10)),
675
+ minor: z20.string().transform((value) => Number.parseInt(value, 10)),
676
+ patch: z20.string().transform((value) => Number.parseInt(value, 10))
658
677
  }).refine(
659
678
  (data) => [data.major, data.minor, data.patch].every((value) => !Number.isNaN(value))
660
679
  );
@@ -700,7 +719,9 @@ var parseMcpListOutput = (output) => {
700
719
 
701
720
  // src/server/core/claude-code/models/ClaudeCode.ts
702
721
  import { query as agentSdkQuery } from "@anthropic-ai/claude-agent-sdk";
703
- import { query as claudeCodeQuery } from "@anthropic-ai/claude-code";
722
+ import {
723
+ query as claudeCodeQuery
724
+ } from "@anthropic-ai/claude-code";
704
725
  import { Command, Path as Path5 } from "@effect/platform";
705
726
  import { Data, Effect as Effect7 } from "effect";
706
727
  var ClaudeCodePathNotFoundError = class extends Data.TaggedError(
@@ -818,9 +839,27 @@ var query = (prompt, options) => {
818
839
  }
819
840
  });
820
841
  }
842
+ const fallbackCanUseTool = (() => {
843
+ const canUseTool2 = options2.canUseTool;
844
+ if (canUseTool2 === void 0) {
845
+ return void 0;
846
+ }
847
+ const fn = async (toolName, input, canUseToolOptions) => {
848
+ const response = await canUseTool2(toolName, input, {
849
+ signal: canUseToolOptions.signal,
850
+ suggestions: canUseToolOptions.suggestions,
851
+ toolUseID: void 0
852
+ });
853
+ return response;
854
+ };
855
+ return fn;
856
+ })();
821
857
  return claudeCodeQuery({
822
858
  prompt,
823
- options: options2
859
+ options: {
860
+ ...options2,
861
+ canUseTool: fallbackCanUseTool
862
+ }
824
863
  });
825
864
  });
826
865
  };
@@ -1145,7 +1184,7 @@ import { Context as Context11, Effect as Effect13, Layer as Layer12, Ref as Ref5
1145
1184
  var LayerImpl10 = Effect13.gen(function* () {
1146
1185
  const configRef = yield* Ref5.make({
1147
1186
  hideNoUserMessageSession: true,
1148
- unifySameTitleSession: true,
1187
+ unifySameTitleSession: false,
1149
1188
  enterKeyBehavior: "shift-enter-send",
1150
1189
  permissionMode: "default",
1151
1190
  locale: "ja",
@@ -1204,26 +1243,26 @@ import { FileSystem as FileSystem6, Path as Path7 } from "@effect/platform";
1204
1243
  import { Context as Context14, Effect as Effect16, Layer as Layer15, Option as Option3 } from "effect";
1205
1244
 
1206
1245
  // src/server/core/claude-code/functions/parseUserMessage.ts
1207
- import { z as z20 } from "zod";
1246
+ import { z as z21 } from "zod";
1208
1247
  var regExp = /<(?<tag>[^>]+)>(?<content>\s*[^<]*?\s*)<\/\k<tag>>/g;
1209
- var matchSchema = z20.object({
1210
- tag: z20.string(),
1211
- content: z20.string()
1248
+ var matchSchema = z21.object({
1249
+ tag: z21.string(),
1250
+ content: z21.string()
1212
1251
  });
1213
- var parsedUserMessageSchema = z20.union([
1214
- z20.object({
1215
- kind: z20.literal("command"),
1216
- commandName: z20.string(),
1217
- commandArgs: z20.string().optional(),
1218
- commandMessage: z20.string().optional()
1252
+ var parsedUserMessageSchema = z21.union([
1253
+ z21.object({
1254
+ kind: z21.literal("command"),
1255
+ commandName: z21.string(),
1256
+ commandArgs: z21.string().optional(),
1257
+ commandMessage: z21.string().optional()
1219
1258
  }),
1220
- z20.object({
1221
- kind: z20.literal("local-command"),
1222
- stdout: z20.string()
1259
+ z21.object({
1260
+ kind: z21.literal("local-command"),
1261
+ stdout: z21.string()
1223
1262
  }),
1224
- z20.object({
1225
- kind: z20.literal("text"),
1226
- content: z20.string()
1263
+ z21.object({
1264
+ kind: z21.literal("text"),
1265
+ content: z21.string()
1227
1266
  })
1228
1267
  ]);
1229
1268
  var parseUserMessage = (content) => {
@@ -1741,6 +1780,31 @@ var createMessageGenerator = () => {
1741
1780
  };
1742
1781
  };
1743
1782
 
1783
+ // src/server/core/claude-code/functions/fallbackSdkMessage.ts
1784
+ var fallbackSdkMessage = (message) => {
1785
+ if (message.type === "system") {
1786
+ if (message.subtype === "init") {
1787
+ return {
1788
+ ...message,
1789
+ plugins: []
1790
+ };
1791
+ }
1792
+ return message;
1793
+ }
1794
+ if (message.type === "result") {
1795
+ if (message.subtype === "success") {
1796
+ return {
1797
+ ...message
1798
+ };
1799
+ }
1800
+ return {
1801
+ ...message,
1802
+ errors: []
1803
+ };
1804
+ }
1805
+ return message;
1806
+ };
1807
+
1744
1808
  // src/server/core/claude-code/models/CCSessionProcess.ts
1745
1809
  import { Effect as Effect17 } from "effect";
1746
1810
  var isPublic = (process2) => {
@@ -2318,19 +2382,9 @@ var LayerImpl13 = Effect19.gen(function* () {
2318
2382
  setNextMessage(input);
2319
2383
  try {
2320
2384
  for await (const message of messageIter) {
2321
- if (message.type === "system" && message.subtype === "hook_response") {
2322
- continue;
2323
- }
2324
- if (message.type === "system" && message.subtype === "compact_boundary") {
2325
- continue;
2326
- }
2385
+ const fallbackMessage = fallbackSdkMessage(message);
2327
2386
  const result = await Runtime2.runPromise(runtime)(
2328
- handleMessage(
2329
- message.type === "system" ? {
2330
- ...message,
2331
- plugins: []
2332
- } : message
2333
- )
2387
+ handleMessage(fallbackMessage)
2334
2388
  ).catch((error) => {
2335
2389
  Effect19.runFork(
2336
2390
  sessionProcessService.changeTaskState({
@@ -2675,11 +2729,11 @@ var SSEController = class extends Context19.Tag("SSEController")() {
2675
2729
  import { watch } from "node:fs";
2676
2730
  import { Path as Path8 } from "@effect/platform";
2677
2731
  import { Context as Context20, Effect as Effect23, Layer as Layer21, Ref as Ref9 } from "effect";
2678
- import z21 from "zod";
2732
+ import z22 from "zod";
2679
2733
  var fileRegExp = /(?<projectId>.*?)\/(?<sessionId>.*?)\.jsonl/;
2680
- var fileRegExpGroupSchema = z21.object({
2681
- projectId: z21.string(),
2682
- sessionId: z21.string()
2734
+ var fileRegExpGroupSchema = z22.object({
2735
+ projectId: z22.string(),
2736
+ sessionId: z22.string()
2683
2737
  });
2684
2738
  var FileWatcherService = class extends Context20.Tag("FileWatcherService")() {
2685
2739
  static {
@@ -3605,6 +3659,114 @@ var LayerImpl18 = Effect26.gen(function* () {
3605
3659
  console.log("[GitService.push] Push succeeded");
3606
3660
  return { branch, output: "success" };
3607
3661
  });
3662
+ const getBranchHash = (cwd, branchName) => Effect26.gen(function* () {
3663
+ const result = yield* execGitCommand(["rev-parse", branchName], cwd).pipe(
3664
+ Effect26.map((output) => output.trim().split("\n")[0] ?? null)
3665
+ );
3666
+ return result;
3667
+ });
3668
+ const getBranchNamesByCommitHash = (cwd, hash) => Effect26.gen(function* () {
3669
+ const result = yield* execGitCommand(
3670
+ ["branch", "--contains", hash, "--format=%(refname:short)"],
3671
+ cwd
3672
+ );
3673
+ return result.split("\n").map((line) => line.trim()).filter((line) => line !== "");
3674
+ });
3675
+ const compareCommitHash = (cwd, targetHash, compareHash) => Effect26.gen(function* () {
3676
+ const aheadResult = yield* execGitCommand(
3677
+ ["rev-list", `${targetHash}..${compareHash}`],
3678
+ cwd
3679
+ );
3680
+ const aheadCounts = aheadResult.split("\n").map((line) => line.trim()).filter((line) => line !== "").length;
3681
+ const behindResult = yield* execGitCommand(
3682
+ ["rev-list", `${compareHash}..${targetHash}`],
3683
+ cwd
3684
+ );
3685
+ const behindCounts = behindResult.split("\n").map((line) => line.trim()).filter((line) => line !== "").length;
3686
+ if (aheadCounts === 0 && behindCounts === 0) {
3687
+ return "un-related";
3688
+ }
3689
+ if (aheadCounts > 0) {
3690
+ return "ahead";
3691
+ }
3692
+ if (behindCounts > 0) {
3693
+ return "behind";
3694
+ }
3695
+ return "un-related";
3696
+ });
3697
+ const getCommitsWithParent = (cwd, options) => Effect26.gen(function* () {
3698
+ const { offset, limit } = options;
3699
+ const result = yield* execGitCommand(
3700
+ [
3701
+ "log",
3702
+ "-n",
3703
+ String(limit),
3704
+ "--skip",
3705
+ String(offset),
3706
+ "--graph",
3707
+ "--pretty=format:%h %p"
3708
+ ],
3709
+ cwd
3710
+ );
3711
+ const lines = result.split("\n").map((line) => line.trim()).filter((line) => line !== "");
3712
+ const commits = [];
3713
+ for (const line of lines) {
3714
+ const match = /^\* (?<current>.+) (?<parent>.+)$/.exec(line);
3715
+ if (match?.groups?.current && match.groups.parent) {
3716
+ commits.push({
3717
+ current: match.groups.current,
3718
+ parent: match.groups.parent
3719
+ });
3720
+ }
3721
+ }
3722
+ return commits;
3723
+ });
3724
+ const findBaseBranch = (cwd, targetBranch) => Effect26.gen(function* () {
3725
+ let offset = 0;
3726
+ const limit = 20;
3727
+ while (offset < 100) {
3728
+ const commits = yield* getCommitsWithParent(cwd, { offset, limit });
3729
+ for (const commit2 of commits) {
3730
+ const branchNames = yield* getBranchNamesByCommitHash(
3731
+ cwd,
3732
+ commit2.current
3733
+ );
3734
+ if (!branchNames.includes(targetBranch)) {
3735
+ continue;
3736
+ }
3737
+ const otherBranchNames = branchNames.filter(
3738
+ (branchName) => branchName !== targetBranch
3739
+ );
3740
+ if (otherBranchNames.length === 0) {
3741
+ continue;
3742
+ }
3743
+ for (const branchName of otherBranchNames) {
3744
+ const comparison = yield* compareCommitHash(
3745
+ cwd,
3746
+ targetBranch,
3747
+ branchName
3748
+ );
3749
+ if (comparison === "behind") {
3750
+ return { branch: branchName, hash: commit2.current };
3751
+ }
3752
+ }
3753
+ }
3754
+ offset += limit;
3755
+ }
3756
+ return null;
3757
+ });
3758
+ const getCommitsBetweenBranches = (cwd, baseBranch, targetBranch) => Effect26.gen(function* () {
3759
+ const result = yield* execGitCommand(
3760
+ [
3761
+ "log",
3762
+ `${baseBranch}..${targetBranch}`,
3763
+ "--format=%H|%s|%an|%ad",
3764
+ "--date=iso"
3765
+ ],
3766
+ cwd
3767
+ );
3768
+ return parseGitCommitsOutput(result);
3769
+ });
3608
3770
  return {
3609
3771
  getBranches,
3610
3772
  getCurrentBranch,
@@ -3612,7 +3774,13 @@ var LayerImpl18 = Effect26.gen(function* () {
3612
3774
  getCommits,
3613
3775
  stageFiles,
3614
3776
  commit,
3615
- push
3777
+ push,
3778
+ getBranchHash,
3779
+ getBranchNamesByCommitHash,
3780
+ compareCommitHash,
3781
+ getCommitsWithParent,
3782
+ findBaseBranch,
3783
+ getCommitsBetweenBranches
3616
3784
  };
3617
3785
  });
3618
3786
  var GitService = class extends Context23.Tag("GitService")() {
@@ -3625,56 +3793,6 @@ var GitService = class extends Context23.Tag("GitService")() {
3625
3793
  var LayerImpl19 = Effect27.gen(function* () {
3626
3794
  const gitService = yield* GitService;
3627
3795
  const projectRepository = yield* ProjectRepository;
3628
- const getGitBranches = (options) => Effect27.gen(function* () {
3629
- const { projectId } = options;
3630
- const { project } = yield* projectRepository.getProject(projectId);
3631
- if (project.meta.projectPath === null) {
3632
- return {
3633
- response: { error: "Project path not found" },
3634
- status: 400
3635
- };
3636
- }
3637
- const projectPath = project.meta.projectPath;
3638
- const branches = yield* Effect27.either(
3639
- gitService.getBranches(projectPath)
3640
- );
3641
- if (Either2.isLeft(branches)) {
3642
- return {
3643
- response: {
3644
- success: false
3645
- },
3646
- status: 200
3647
- };
3648
- }
3649
- return {
3650
- response: branches.right,
3651
- status: 200
3652
- };
3653
- });
3654
- const getGitCommits = (options) => Effect27.gen(function* () {
3655
- const { projectId } = options;
3656
- const { project } = yield* projectRepository.getProject(projectId);
3657
- if (project.meta.projectPath === null) {
3658
- return {
3659
- response: { error: "Project path not found" },
3660
- status: 400
3661
- };
3662
- }
3663
- const projectPath = project.meta.projectPath;
3664
- const commits = yield* Effect27.either(gitService.getCommits(projectPath));
3665
- if (Either2.isLeft(commits)) {
3666
- return {
3667
- response: {
3668
- success: false
3669
- },
3670
- status: 200
3671
- };
3672
- }
3673
- return {
3674
- response: commits.right,
3675
- status: 200
3676
- };
3677
- });
3678
3796
  const getGitDiff = (options) => Effect27.gen(function* () {
3679
3797
  const { projectId, fromRef, toRef } = options;
3680
3798
  const { project } = yield* projectRepository.getProject(projectId);
@@ -3869,13 +3987,86 @@ var LayerImpl19 = Effect27.gen(function* () {
3869
3987
  status: 200
3870
3988
  };
3871
3989
  });
3990
+ const getCurrentRevisions = (options) => Effect27.gen(function* () {
3991
+ const { projectId } = options;
3992
+ const { project } = yield* projectRepository.getProject(projectId);
3993
+ if (project.meta.projectPath === null) {
3994
+ return {
3995
+ response: { error: "Project path not found" },
3996
+ status: 400
3997
+ };
3998
+ }
3999
+ const projectPath = project.meta.projectPath;
4000
+ const currentBranchResult = yield* Effect27.either(
4001
+ gitService.getCurrentBranch(projectPath)
4002
+ );
4003
+ if (Either2.isLeft(currentBranchResult)) {
4004
+ return {
4005
+ response: {
4006
+ success: false
4007
+ },
4008
+ status: 200
4009
+ };
4010
+ }
4011
+ const currentBranch = currentBranchResult.right;
4012
+ const baseBranchResult = yield* Effect27.either(
4013
+ gitService.findBaseBranch(projectPath, currentBranch)
4014
+ );
4015
+ const allBranchesResult = yield* Effect27.either(
4016
+ gitService.getBranches(projectPath)
4017
+ );
4018
+ if (Either2.isLeft(allBranchesResult)) {
4019
+ return {
4020
+ response: {
4021
+ success: false
4022
+ },
4023
+ status: 200
4024
+ };
4025
+ }
4026
+ const allBranches = allBranchesResult.right.data;
4027
+ const currentBranchDetails = allBranches.find(
4028
+ (branch) => branch.name === currentBranch
4029
+ );
4030
+ let baseBranchDetails;
4031
+ if (Either2.isRight(baseBranchResult) && baseBranchResult.right !== null) {
4032
+ const baseBranchName = baseBranchResult.right.branch;
4033
+ baseBranchDetails = allBranches.find(
4034
+ (branch) => branch.name === baseBranchName
4035
+ );
4036
+ }
4037
+ let commits = [];
4038
+ if (Either2.isRight(baseBranchResult) && baseBranchResult.right !== null) {
4039
+ const baseBranchHash = baseBranchResult.right.hash;
4040
+ const commitsResult = yield* Effect27.either(
4041
+ gitService.getCommitsBetweenBranches(
4042
+ projectPath,
4043
+ baseBranchHash,
4044
+ "HEAD"
4045
+ )
4046
+ );
4047
+ if (Either2.isRight(commitsResult)) {
4048
+ commits = commitsResult.right.data;
4049
+ }
4050
+ }
4051
+ return {
4052
+ response: {
4053
+ success: true,
4054
+ data: {
4055
+ baseBranch: baseBranchDetails ?? null,
4056
+ currentBranch: currentBranchDetails ?? null,
4057
+ head: currentBranchDetails?.commit ?? null,
4058
+ commits
4059
+ }
4060
+ },
4061
+ status: 200
4062
+ };
4063
+ });
3872
4064
  return {
3873
- getGitBranches,
3874
- getGitCommits,
3875
4065
  getGitDiff,
3876
4066
  commitFiles,
3877
4067
  pushCommits,
3878
- commitAndPush
4068
+ commitAndPush,
4069
+ getCurrentRevisions
3879
4070
  };
3880
4071
  });
3881
4072
  function parsePushError(stderr) {
@@ -4062,39 +4253,39 @@ import { FileSystem as FileSystem9, Path as Path12 } from "@effect/platform";
4062
4253
  import { Context as Context26, Data as Data5, Effect as Effect30, Layer as Layer27 } from "effect";
4063
4254
 
4064
4255
  // src/server/core/scheduler/schema.ts
4065
- import { z as z22 } from "zod";
4066
- var concurrencyPolicySchema = z22.enum(["skip", "run"]);
4067
- var cronScheduleSchema = z22.object({
4068
- type: z22.literal("cron"),
4069
- expression: z22.string(),
4256
+ import { z as z23 } from "zod";
4257
+ var concurrencyPolicySchema = z23.enum(["skip", "run"]);
4258
+ var cronScheduleSchema = z23.object({
4259
+ type: z23.literal("cron"),
4260
+ expression: z23.string(),
4070
4261
  concurrencyPolicy: concurrencyPolicySchema
4071
4262
  });
4072
- var reservedScheduleSchema = z22.object({
4073
- type: z22.literal("reserved"),
4074
- reservedExecutionTime: z22.iso.datetime()
4263
+ var reservedScheduleSchema = z23.object({
4264
+ type: z23.literal("reserved"),
4265
+ reservedExecutionTime: z23.iso.datetime()
4075
4266
  });
4076
- var scheduleSchema = z22.discriminatedUnion("type", [
4267
+ var scheduleSchema = z23.discriminatedUnion("type", [
4077
4268
  cronScheduleSchema,
4078
4269
  reservedScheduleSchema
4079
4270
  ]);
4080
- var messageConfigSchema = z22.object({
4081
- content: z22.string(),
4082
- projectId: z22.string(),
4083
- baseSessionId: z22.string().nullable()
4271
+ var messageConfigSchema = z23.object({
4272
+ content: z23.string(),
4273
+ projectId: z23.string(),
4274
+ baseSessionId: z23.string().nullable()
4084
4275
  });
4085
- var jobStatusSchema = z22.enum(["success", "failed"]);
4086
- var schedulerJobSchema = z22.object({
4087
- id: z22.string(),
4088
- name: z22.string(),
4276
+ var jobStatusSchema = z23.enum(["success", "failed"]);
4277
+ var schedulerJobSchema = z23.object({
4278
+ id: z23.string(),
4279
+ name: z23.string(),
4089
4280
  schedule: scheduleSchema,
4090
4281
  message: messageConfigSchema,
4091
- enabled: z22.boolean(),
4092
- createdAt: z22.string().datetime(),
4093
- lastRunAt: z22.string().datetime().nullable(),
4282
+ enabled: z23.boolean(),
4283
+ createdAt: z23.string().datetime(),
4284
+ lastRunAt: z23.string().datetime().nullable(),
4094
4285
  lastRunStatus: jobStatusSchema.nullable()
4095
4286
  });
4096
- var schedulerConfigSchema = z22.object({
4097
- jobs: z22.array(schedulerJobSchema)
4287
+ var schedulerConfigSchema = z23.object({
4288
+ jobs: z23.array(schedulerJobSchema)
4098
4289
  });
4099
4290
  var newSchedulerJobSchema = schedulerJobSchema.omit({
4100
4291
  id: true,
@@ -4102,7 +4293,7 @@ var newSchedulerJobSchema = schedulerJobSchema.omit({
4102
4293
  lastRunAt: true,
4103
4294
  lastRunStatus: true
4104
4295
  }).extend({
4105
- enabled: z22.boolean().default(true)
4296
+ enabled: z23.boolean().default(true)
4106
4297
  });
4107
4298
  var updateSchedulerJobSchema = schedulerJobSchema.partial().pick({
4108
4299
  name: true,
@@ -4680,12 +4871,12 @@ import { Effect as Effect37, Runtime as Runtime3 } from "effect";
4680
4871
  import { setCookie as setCookie2 } from "hono/cookie";
4681
4872
  import { streamSSE } from "hono/streaming";
4682
4873
  import prexit from "prexit";
4683
- import { z as z27 } from "zod";
4874
+ import { z as z28 } from "zod";
4684
4875
 
4685
4876
  // package.json
4686
4877
  var package_default = {
4687
4878
  name: "@kimuson/claude-code-viewer",
4688
- version: "0.4.2-beta.2",
4879
+ version: "0.4.3",
4689
4880
  type: "module",
4690
4881
  license: "MIT",
4691
4882
  repository: {
@@ -4722,10 +4913,11 @@ var package_default = {
4722
4913
  e2e: "./scripts/e2e/exec_e2e.sh",
4723
4914
  "e2e:start-server": "./scripts/e2e/start_server.sh",
4724
4915
  "e2e:capture-snapshots": "./scripts/e2e/capture_snapshots.sh",
4916
+ "lingui:extract": "lingui extract --clean",
4725
4917
  "lingui:compile": "lingui compile --typescript"
4726
4918
  },
4727
4919
  dependencies: {
4728
- "@anthropic-ai/claude-agent-sdk": "0.1.27",
4920
+ "@anthropic-ai/claude-agent-sdk": "0.1.30",
4729
4921
  "@anthropic-ai/claude-code": "2.0.24",
4730
4922
  "@anthropic-ai/sdk": "0.67.0",
4731
4923
  "@effect/platform": "0.92.1",
@@ -4739,6 +4931,7 @@ var package_default = {
4739
4931
  "@radix-ui/react-collapsible": "1.1.12",
4740
4932
  "@radix-ui/react-dialog": "1.1.15",
4741
4933
  "@radix-ui/react-hover-card": "1.1.15",
4934
+ "@radix-ui/react-popover": "^1.1.15",
4742
4935
  "@radix-ui/react-select": "2.2.6",
4743
4936
  "@radix-ui/react-slot": "1.2.3",
4744
4937
  "@radix-ui/react-tabs": "1.1.13",
@@ -4802,49 +4995,62 @@ var package_default = {
4802
4995
  };
4803
4996
 
4804
4997
  // src/server/core/claude-code/schema.ts
4805
- import { z as z23 } from "zod";
4806
- var imageBlockSchema = z23.object({
4807
- type: z23.literal("image"),
4808
- source: z23.object({
4809
- type: z23.literal("base64"),
4810
- media_type: z23.enum(["image/png", "image/jpeg", "image/gif", "image/webp"]),
4811
- data: z23.string()
4998
+ import { z as z24 } from "zod";
4999
+ var mediaTypeSchema = z24.enum([
5000
+ "image/png",
5001
+ "image/jpeg",
5002
+ "image/gif",
5003
+ "image/webp"
5004
+ ]);
5005
+ var imageBlockSchema = z24.object({
5006
+ type: z24.literal("image"),
5007
+ source: z24.object({
5008
+ type: z24.literal("base64"),
5009
+ media_type: mediaTypeSchema,
5010
+ data: z24.string()
4812
5011
  })
4813
5012
  });
4814
- var documentBlockSchema = z23.object({
4815
- type: z23.literal("document"),
4816
- source: z23.object({
4817
- type: z23.literal("base64"),
4818
- media_type: z23.enum(["application/pdf"]),
4819
- data: z23.string()
4820
- })
5013
+ var documentBlockSchema = z24.object({
5014
+ type: z24.literal("document"),
5015
+ source: z24.union([
5016
+ z24.object({
5017
+ type: z24.literal("text"),
5018
+ media_type: z24.enum(["text/plain"]),
5019
+ data: z24.string()
5020
+ }),
5021
+ z24.object({
5022
+ type: z24.literal("base64"),
5023
+ media_type: z24.enum(["application/pdf"]),
5024
+ data: z24.string()
5025
+ })
5026
+ ])
4821
5027
  });
4822
- var userMessageInputSchema = z23.object({
4823
- text: z23.string().min(1),
4824
- images: z23.array(imageBlockSchema).optional(),
4825
- documents: z23.array(documentBlockSchema).optional()
5028
+ var userMessageInputSchema = z24.object({
5029
+ text: z24.string().min(1),
5030
+ images: z24.array(imageBlockSchema).optional(),
5031
+ documents: z24.array(documentBlockSchema).optional()
4826
5032
  });
4827
5033
 
4828
5034
  // src/server/core/git/schema.ts
4829
- import { z as z24 } from "zod";
4830
- var CommitRequestSchema = z24.object({
4831
- projectId: z24.string().min(1),
4832
- files: z24.array(z24.string().min(1)).min(1),
4833
- message: z24.string().trim().min(1)
5035
+ import { z as z25 } from "zod";
5036
+ var CommitRequestSchema = z25.object({
5037
+ projectId: z25.string().min(1),
5038
+ files: z25.array(z25.string().min(1)).min(1),
5039
+ message: z25.string().trim().min(1)
4834
5040
  });
4835
- var PushRequestSchema = z24.object({
4836
- projectId: z24.string().min(1)
5041
+ var PushRequestSchema = z25.object({
5042
+ projectId: z25.string().min(1)
4837
5043
  });
4838
- var CommitResultSuccessSchema = z24.object({
4839
- success: z24.literal(true),
4840
- commitSha: z24.string().length(40),
4841
- filesCommitted: z24.number().int().positive(),
4842
- message: z24.string()
5044
+ var CommitResultSuccessSchema = z25.object({
5045
+ success: z25.literal(true),
5046
+ commitSha: z25.string().length(40),
5047
+ filesCommitted: z25.number().int().positive(),
5048
+ message: z25.string()
4843
5049
  });
4844
- var CommitResultErrorSchema = z24.object({
4845
- success: z24.literal(false),
4846
- error: z24.string(),
4847
- errorCode: z24.enum([
5050
+ var CommitResultErrorSchema = z25.object({
5051
+ success: z25.literal(false),
5052
+ error: z25.string(),
5053
+ errorCode: z25.enum([
4848
5054
  "EMPTY_MESSAGE",
4849
5055
  "NO_FILES",
4850
5056
  "PROJECT_NOT_FOUND",
@@ -4852,22 +5058,22 @@ var CommitResultErrorSchema = z24.object({
4852
5058
  "HOOK_FAILED",
4853
5059
  "GIT_COMMAND_ERROR"
4854
5060
  ]),
4855
- details: z24.string().optional()
5061
+ details: z25.string().optional()
4856
5062
  });
4857
- var CommitResultSchema = z24.discriminatedUnion("success", [
5063
+ var CommitResultSchema = z25.discriminatedUnion("success", [
4858
5064
  CommitResultSuccessSchema,
4859
5065
  CommitResultErrorSchema
4860
5066
  ]);
4861
- var PushResultSuccessSchema = z24.object({
4862
- success: z24.literal(true),
4863
- remote: z24.string(),
4864
- branch: z24.string(),
4865
- objectsPushed: z24.number().int().optional()
5067
+ var PushResultSuccessSchema = z25.object({
5068
+ success: z25.literal(true),
5069
+ remote: z25.string(),
5070
+ branch: z25.string(),
5071
+ objectsPushed: z25.number().int().optional()
4866
5072
  });
4867
- var PushResultErrorSchema = z24.object({
4868
- success: z24.literal(false),
4869
- error: z24.string(),
4870
- errorCode: z24.enum([
5073
+ var PushResultErrorSchema = z25.object({
5074
+ success: z25.literal(false),
5075
+ error: z25.string(),
5076
+ errorCode: z25.enum([
4871
5077
  "PROJECT_NOT_FOUND",
4872
5078
  "NOT_A_REPOSITORY",
4873
5079
  "NO_UPSTREAM",
@@ -4877,26 +5083,26 @@ var PushResultErrorSchema = z24.object({
4877
5083
  "TIMEOUT",
4878
5084
  "GIT_COMMAND_ERROR"
4879
5085
  ]),
4880
- details: z24.string().optional()
5086
+ details: z25.string().optional()
4881
5087
  });
4882
- var PushResultSchema = z24.discriminatedUnion("success", [
5088
+ var PushResultSchema = z25.discriminatedUnion("success", [
4883
5089
  PushResultSuccessSchema,
4884
5090
  PushResultErrorSchema
4885
5091
  ]);
4886
- var CommitAndPushResultSuccessSchema = z24.object({
4887
- success: z24.literal(true),
4888
- commitSha: z24.string().length(40),
4889
- filesCommitted: z24.number().int().positive(),
4890
- message: z24.string(),
4891
- remote: z24.string(),
4892
- branch: z24.string()
5092
+ var CommitAndPushResultSuccessSchema = z25.object({
5093
+ success: z25.literal(true),
5094
+ commitSha: z25.string().length(40),
5095
+ filesCommitted: z25.number().int().positive(),
5096
+ message: z25.string(),
5097
+ remote: z25.string(),
5098
+ branch: z25.string()
4893
5099
  });
4894
- var CommitAndPushResultErrorSchema = z24.object({
4895
- success: z24.literal(false),
4896
- commitSucceeded: z24.boolean(),
4897
- commitSha: z24.string().length(40).optional(),
4898
- error: z24.string(),
4899
- errorCode: z24.enum([
5100
+ var CommitAndPushResultErrorSchema = z25.object({
5101
+ success: z25.literal(false),
5102
+ commitSucceeded: z25.boolean(),
5103
+ commitSha: z25.string().length(40).optional(),
5104
+ error: z25.string(),
5105
+ errorCode: z25.enum([
4900
5106
  "EMPTY_MESSAGE",
4901
5107
  "NO_FILES",
4902
5108
  "PROJECT_NOT_FOUND",
@@ -4909,28 +5115,28 @@ var CommitAndPushResultErrorSchema = z24.object({
4909
5115
  "NETWORK_ERROR",
4910
5116
  "TIMEOUT"
4911
5117
  ]),
4912
- details: z24.string().optional()
5118
+ details: z25.string().optional()
4913
5119
  });
4914
- var CommitAndPushResultSchema = z24.discriminatedUnion("success", [
5120
+ var CommitAndPushResultSchema = z25.discriminatedUnion("success", [
4915
5121
  CommitAndPushResultSuccessSchema,
4916
5122
  CommitAndPushResultErrorSchema
4917
5123
  ]);
4918
5124
 
4919
5125
  // src/server/lib/config/config.ts
4920
- import z26 from "zod";
5126
+ import z27 from "zod";
4921
5127
 
4922
5128
  // src/lib/i18n/schema.ts
4923
- import z25 from "zod";
4924
- var localeSchema = z25.enum(["ja", "en"]);
5129
+ import z26 from "zod";
5130
+ var localeSchema = z26.enum(["ja", "en", "zh_CN"]);
4925
5131
 
4926
5132
  // src/server/lib/config/config.ts
4927
- var userConfigSchema = z26.object({
4928
- hideNoUserMessageSession: z26.boolean().optional().default(true),
4929
- unifySameTitleSession: z26.boolean().optional().default(true),
4930
- enterKeyBehavior: z26.enum(["shift-enter-send", "enter-send", "command-enter-send"]).optional().default("shift-enter-send"),
4931
- permissionMode: z26.enum(["acceptEdits", "bypassPermissions", "default", "plan"]).optional().default("default"),
5133
+ var userConfigSchema = z27.object({
5134
+ hideNoUserMessageSession: z27.boolean().optional().default(true),
5135
+ unifySameTitleSession: z27.boolean().optional().default(false),
5136
+ enterKeyBehavior: z27.enum(["shift-enter-send", "enter-send", "command-enter-send"]).optional().default("shift-enter-send"),
5137
+ permissionMode: z27.enum(["acceptEdits", "bypassPermissions", "default", "plan"]).optional().default("default"),
4932
5138
  locale: localeSchema.optional().default("en"),
4933
- theme: z26.enum(["light", "dark", "system"]).optional().default("system")
5139
+ theme: z27.enum(["light", "dark", "system"]).optional().default("system")
4934
5140
  });
4935
5141
 
4936
5142
  // src/server/lib/effect/toEffectResponse.ts
@@ -5033,7 +5239,7 @@ var routes = (app) => Effect37.gen(function* () {
5033
5239
  return response;
5034
5240
  }).get(
5035
5241
  "/api/projects/:projectId",
5036
- zValidator("query", z27.object({ cursor: z27.string().optional() })),
5242
+ zValidator("query", z28.object({ cursor: z28.string().optional() })),
5037
5243
  async (c) => {
5038
5244
  const response = await effectToResponse(
5039
5245
  c,
@@ -5048,8 +5254,8 @@ var routes = (app) => Effect37.gen(function* () {
5048
5254
  "/api/projects",
5049
5255
  zValidator(
5050
5256
  "json",
5051
- z27.object({
5052
- projectPath: z27.string().min(1, "Project path is required")
5257
+ z28.object({
5258
+ projectPath: z28.string().min(1, "Project path is required")
5053
5259
  })
5054
5260
  ),
5055
5261
  async (c) => {
@@ -5075,18 +5281,10 @@ var routes = (app) => Effect37.gen(function* () {
5075
5281
  sessionController.getSession({ ...c.req.param() }).pipe(Effect37.provide(runtime))
5076
5282
  );
5077
5283
  return response;
5078
- }).get("/api/projects/:projectId/git/branches", async (c) => {
5079
- const response = await effectToResponse(
5080
- c,
5081
- gitController.getGitBranches({
5082
- ...c.req.param()
5083
- }).pipe(Effect37.provide(runtime))
5084
- );
5085
- return response;
5086
- }).get("/api/projects/:projectId/git/commits", async (c) => {
5284
+ }).get("/api/projects/:projectId/git/current-revisions", async (c) => {
5087
5285
  const response = await effectToResponse(
5088
5286
  c,
5089
- gitController.getGitCommits({
5287
+ gitController.getCurrentRevisions({
5090
5288
  ...c.req.param()
5091
5289
  }).pipe(Effect37.provide(runtime))
5092
5290
  );
@@ -5095,9 +5293,9 @@ var routes = (app) => Effect37.gen(function* () {
5095
5293
  "/api/projects/:projectId/git/diff",
5096
5294
  zValidator(
5097
5295
  "json",
5098
- z27.object({
5099
- fromRef: z27.string().min(1, "fromRef is required"),
5100
- toRef: z27.string().min(1, "toRef is required")
5296
+ z28.object({
5297
+ fromRef: z28.string().min(1, "fromRef is required"),
5298
+ toRef: z28.string().min(1, "toRef is required")
5101
5299
  })
5102
5300
  ),
5103
5301
  async (c) => {
@@ -5187,10 +5385,10 @@ var routes = (app) => Effect37.gen(function* () {
5187
5385
  "/api/cc/session-processes",
5188
5386
  zValidator(
5189
5387
  "json",
5190
- z27.object({
5191
- projectId: z27.string(),
5388
+ z28.object({
5389
+ projectId: z28.string(),
5192
5390
  input: userMessageInputSchema,
5193
- baseSessionId: z27.string().optional()
5391
+ baseSessionId: z28.string().optional()
5194
5392
  })
5195
5393
  ),
5196
5394
  async (c) => {
@@ -5206,10 +5404,10 @@ var routes = (app) => Effect37.gen(function* () {
5206
5404
  "/api/cc/session-processes/:sessionProcessId/continue",
5207
5405
  zValidator(
5208
5406
  "json",
5209
- z27.object({
5210
- projectId: z27.string(),
5407
+ z28.object({
5408
+ projectId: z28.string(),
5211
5409
  input: userMessageInputSchema,
5212
- baseSessionId: z27.string()
5410
+ baseSessionId: z28.string()
5213
5411
  })
5214
5412
  ),
5215
5413
  async (c) => {
@@ -5224,7 +5422,7 @@ var routes = (app) => Effect37.gen(function* () {
5224
5422
  }
5225
5423
  ).post(
5226
5424
  "/api/cc/session-processes/:sessionProcessId/abort",
5227
- zValidator("json", z27.object({ projectId: z27.string() })),
5425
+ zValidator("json", z28.object({ projectId: z28.string() })),
5228
5426
  async (c) => {
5229
5427
  const { sessionProcessId } = c.req.param();
5230
5428
  void Effect37.runFork(
@@ -5236,9 +5434,9 @@ var routes = (app) => Effect37.gen(function* () {
5236
5434
  "/api/cc/permission-response",
5237
5435
  zValidator(
5238
5436
  "json",
5239
- z27.object({
5240
- permissionRequestId: z27.string(),
5241
- decision: z27.enum(["allow", "deny"])
5437
+ z28.object({
5438
+ permissionRequestId: z28.string(),
5439
+ decision: z28.enum(["allow", "deny"])
5242
5440
  })
5243
5441
  ),
5244
5442
  async (c) => {
@@ -5305,9 +5503,9 @@ var routes = (app) => Effect37.gen(function* () {
5305
5503
  "/api/fs/file-completion",
5306
5504
  zValidator(
5307
5505
  "query",
5308
- z27.object({
5309
- projectId: z27.string(),
5310
- basePath: z27.string().optional().default("/api/")
5506
+ z28.object({
5507
+ projectId: z28.string(),
5508
+ basePath: z28.string().optional().default("/api/")
5311
5509
  })
5312
5510
  ),
5313
5511
  async (c) => {
@@ -5323,9 +5521,9 @@ var routes = (app) => Effect37.gen(function* () {
5323
5521
  "/api/fs/directory-browser",
5324
5522
  zValidator(
5325
5523
  "query",
5326
- z27.object({
5327
- currentPath: z27.string().optional(),
5328
- showHidden: z27.string().optional().transform((val) => val === "true")
5524
+ z28.object({
5525
+ currentPath: z28.string().optional(),
5526
+ showHidden: z28.string().optional().transform((val) => val === "true")
5329
5527
  })
5330
5528
  ),
5331
5529
  async (c) => {