@kimuson/claude-code-viewer 0.5.1 → 0.5.3

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
@@ -7,7 +7,7 @@ import { Effect as Effect49 } from "effect";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@kimuson/claude-code-viewer",
10
- version: "0.5.1",
10
+ version: "0.5.3",
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,9 +51,9 @@ var package_default = {
51
51
  prepare: "lefthook install"
52
52
  },
53
53
  dependencies: {
54
- "@anthropic-ai/claude-agent-sdk": "0.1.30",
54
+ "@anthropic-ai/claude-agent-sdk": "0.2.2",
55
55
  "@anthropic-ai/claude-code": "2.0.24",
56
- "@anthropic-ai/sdk": "0.67.0",
56
+ "@anthropic-ai/sdk": "0.71.2",
57
57
  "@effect/cluster": "0.55.0",
58
58
  "@effect/experimental": "0.57.11",
59
59
  "@effect/platform": "0.93.6",
@@ -62,7 +62,7 @@ var package_default = {
62
62
  "@effect/sql": "0.48.6",
63
63
  "@effect/workflow": "0.15.1",
64
64
  "@hono/node-server": "1.19.5",
65
- "@hono/zod-validator": "0.7.4",
65
+ "@hono/zod-validator": "0.7.6",
66
66
  "@lingui/core": "5.5.1",
67
67
  "@lingui/react": "5.5.1",
68
68
  "@radix-ui/react-avatar": "1.1.10",
@@ -95,7 +95,6 @@ var package_default = {
95
95
  react: "19.2.0",
96
96
  "react-dom": "19.2.0",
97
97
  "react-error-boundary": "6.0.0",
98
- "react-helmet-async": "2.0.5",
99
98
  "react-markdown": "10.1.0",
100
99
  "react-syntax-highlighter": "15.6.6",
101
100
  "remark-gfm": "4.0.1",
@@ -669,6 +668,7 @@ var LayerImpl4 = Effect5.gen(function* () {
669
668
  globalClaudeDirectoryPath,
670
669
  "commands"
671
670
  ),
671
+ claudeSkillsDirPath: path.resolve(globalClaudeDirectoryPath, "skills"),
672
672
  claudeProjectsDirPath: path.resolve(
673
673
  globalClaudeDirectoryPath,
674
674
  "projects"
@@ -1042,6 +1042,49 @@ var scanCommandFilesRecursively = (dirPath) => Effect10.gen(function* () {
1042
1042
  })
1043
1043
  );
1044
1044
  });
1045
+ var scanSkillFilesRecursively = (dirPath) => Effect10.gen(function* () {
1046
+ const fs = yield* FileSystem5.FileSystem;
1047
+ const path = yield* Path6.Path;
1048
+ const scanDirectory = (currentPath, relativePath) => Effect10.gen(function* () {
1049
+ const exists = yield* fs.exists(currentPath);
1050
+ if (!exists) {
1051
+ return [];
1052
+ }
1053
+ const skillFilePath = path.join(currentPath, "SKILL.md");
1054
+ const skillFileExists = yield* fs.exists(skillFilePath);
1055
+ const skillNames = [];
1056
+ if (skillFileExists) {
1057
+ const skillName = relativePath.replace(/\//g, ":");
1058
+ if (skillName) {
1059
+ skillNames.push(skillName);
1060
+ }
1061
+ }
1062
+ const items = yield* fs.readDirectory(currentPath);
1063
+ const results = yield* Effect10.forEach(
1064
+ items,
1065
+ (item) => Effect10.gen(function* () {
1066
+ if (item.startsWith(".")) {
1067
+ return [];
1068
+ }
1069
+ const itemPath = path.join(currentPath, item);
1070
+ const info = yield* fs.stat(itemPath);
1071
+ if (info.type === "Directory") {
1072
+ const newRelativePath = relativePath ? `${relativePath}/${item}` : item;
1073
+ return yield* scanDirectory(itemPath, newRelativePath);
1074
+ }
1075
+ return [];
1076
+ }),
1077
+ { concurrency: "unbounded" }
1078
+ );
1079
+ return [...skillNames, ...results.flat()];
1080
+ });
1081
+ return yield* scanDirectory(dirPath, "").pipe(
1082
+ Effect10.match({
1083
+ onSuccess: (items) => items,
1084
+ onFailure: () => []
1085
+ })
1086
+ );
1087
+ });
1045
1088
 
1046
1089
  // src/server/core/claude-code/models/ClaudeCodeVersion.ts
1047
1090
  import { z as z19 } from "zod";
@@ -1094,10 +1137,8 @@ var parseMcpListOutput = (output) => {
1094
1137
  };
1095
1138
 
1096
1139
  // src/server/core/claude-code/models/ClaudeCode.ts
1097
- import { query as agentSdkQuery } from "@anthropic-ai/claude-agent-sdk";
1098
- import {
1099
- query as claudeCodeQuery
1100
- } from "@anthropic-ai/claude-code";
1140
+ import * as agentSdk from "@anthropic-ai/claude-agent-sdk";
1141
+ import * as claudeCodeSdk from "@anthropic-ai/claude-code";
1101
1142
  import { Command, Path as Path7 } from "@effect/platform";
1102
1143
  import { Data, Effect as Effect11 } from "effect";
1103
1144
  import { uniq } from "es-toolkit";
@@ -1202,10 +1243,19 @@ var getAvailableFeatures = (claudeCodeVersion) => ({
1202
1243
  minor: 0,
1203
1244
  patch: 28
1204
1245
  // Sidechain conversations stored in agent-*.jsonl since v2.0.28
1246
+ }) : false,
1247
+ runSkillsDirectly: claudeCodeVersion !== null ? greaterThanOrEqual(claudeCodeVersion, {
1248
+ major: 2,
1249
+ minor: 1,
1250
+ patch: 0
1251
+ }) || greaterThanOrEqual(claudeCodeVersion, {
1252
+ major: 2,
1253
+ minor: 0,
1254
+ patch: 77
1205
1255
  }) : false
1206
1256
  });
1207
- var query = (prompt, options) => {
1208
- const { canUseTool, permissionMode, ...baseOptions } = options;
1257
+ var query3 = (prompt, options) => {
1258
+ const { canUseTool, permissionMode, hooks, ...baseOptions } = options;
1209
1259
  return Effect11.gen(function* () {
1210
1260
  const { claudeCodeExecutablePath, claudeCodeVersion } = yield* Config;
1211
1261
  const availableFeatures = getAvailableFeatures(claudeCodeVersion);
@@ -1217,7 +1267,7 @@ var query = (prompt, options) => {
1217
1267
  }
1218
1268
  };
1219
1269
  if (availableFeatures.agentSdk) {
1220
- return agentSdkQuery({
1270
+ return agentSdk.query({
1221
1271
  prompt,
1222
1272
  options: {
1223
1273
  systemPrompt: { type: "preset", preset: "claude_code" },
@@ -1241,10 +1291,15 @@ var query = (prompt, options) => {
1241
1291
  };
1242
1292
  return fn;
1243
1293
  })();
1244
- return claudeCodeQuery({
1294
+ return claudeCodeSdk.query({
1245
1295
  prompt,
1246
1296
  options: {
1247
- ...options2,
1297
+ ...baseOptions,
1298
+ permissionMode: (
1299
+ // fallback unsupported permission modes
1300
+ permissionMode === "delegate" || permissionMode === "dontAsk" ? "bypassPermissions" : permissionMode
1301
+ ),
1302
+ hooks,
1248
1303
  canUseTool: fallbackCanUseTool
1249
1304
  }
1250
1305
  });
@@ -1301,16 +1356,25 @@ var LayerImpl9 = Effect13.gen(function* () {
1301
1356
  const getClaudeCommands = (options) => Effect13.gen(function* () {
1302
1357
  const { projectId } = options;
1303
1358
  const { project } = yield* projectRepository.getProject(projectId);
1359
+ const features = yield* claudeCodeService.getAvailableFeatures();
1304
1360
  const globalCommands = yield* scanCommandFilesRecursively(
1305
1361
  (yield* context.claudeCodePaths).claudeCommandsDirPath
1306
1362
  );
1307
1363
  const projectCommands = project.meta.projectPath === null ? [] : yield* scanCommandFilesRecursively(
1308
1364
  path.resolve(project.meta.projectPath, ".claude", "commands")
1309
1365
  );
1366
+ const globalSkills = features.runSkillsDirectly ? yield* scanSkillFilesRecursively(
1367
+ (yield* context.claudeCodePaths).claudeSkillsDirPath
1368
+ ) : [];
1369
+ const projectSkills = features.runSkillsDirectly && project.meta.projectPath !== null ? yield* scanSkillFilesRecursively(
1370
+ path.resolve(project.meta.projectPath, ".claude", "skills")
1371
+ ) : [];
1310
1372
  return {
1311
1373
  response: {
1312
1374
  globalCommands,
1313
1375
  projectCommands,
1376
+ globalSkills,
1377
+ projectSkills,
1314
1378
  defaultCommands: ["init", "compact", "security-review", "review"]
1315
1379
  },
1316
1380
  status: 200
@@ -1800,12 +1864,36 @@ import { Context as Context15, Effect as Effect20, Layer as Layer17, Ref as Ref7
1800
1864
 
1801
1865
  // src/server/core/session/constants/pricing.ts
1802
1866
  var MODEL_PRICING = {
1867
+ "claude-opus-4.5": {
1868
+ input: 5,
1869
+ output: 25,
1870
+ cache_creation: 6.25,
1871
+ cache_read: 0.5
1872
+ },
1873
+ "claude-opus-4.1": {
1874
+ input: 15,
1875
+ output: 75,
1876
+ cache_creation: 18.75,
1877
+ cache_read: 1.5
1878
+ },
1879
+ "claude-sonnet-4.5": {
1880
+ input: 3,
1881
+ output: 15,
1882
+ cache_creation: 3.75,
1883
+ cache_read: 0.3
1884
+ },
1803
1885
  "claude-3.5-sonnet": {
1804
1886
  input: 3,
1805
1887
  output: 15,
1806
1888
  cache_creation: 3.75,
1807
1889
  cache_read: 0.3
1808
1890
  },
1891
+ "claude-haiku-4.5": {
1892
+ input: 1,
1893
+ output: 5,
1894
+ cache_creation: 1.25,
1895
+ cache_read: 0.1
1896
+ },
1809
1897
  "claude-3-opus": {
1810
1898
  input: 15,
1811
1899
  output: 75,
@@ -1817,22 +1905,6 @@ var MODEL_PRICING = {
1817
1905
  output: 1.25,
1818
1906
  cache_creation: 0.3,
1819
1907
  cache_read: 0.03
1820
- },
1821
- "claude-instant-1.2": {
1822
- input: 1.63,
1823
- output: 5.51,
1824
- cache_creation: 2.0375,
1825
- // 1.63 * 1.25
1826
- cache_read: 0.163
1827
- // 1.63 * 0.1
1828
- },
1829
- "claude-2": {
1830
- input: 8,
1831
- output: 24,
1832
- cache_creation: 10,
1833
- // 8.0 * 1.25
1834
- cache_read: 0.8
1835
- // 8.0 * 0.1
1836
1908
  }
1837
1909
  };
1838
1910
  var DEFAULT_MODEL_PRICING = MODEL_PRICING["claude-3.5-sonnet"];
@@ -1840,6 +1912,18 @@ var DEFAULT_MODEL_PRICING = MODEL_PRICING["claude-3.5-sonnet"];
1840
1912
  // src/server/core/session/functions/calculateSessionCost.ts
1841
1913
  function normalizeModelName(modelName) {
1842
1914
  const normalized = modelName.toLowerCase();
1915
+ if (normalized.includes("opus-4-5") || normalized.includes("opus-4.5")) {
1916
+ return "claude-opus-4.5";
1917
+ }
1918
+ if (normalized.includes("opus-4-1") || normalized.includes("opus-4.1")) {
1919
+ return "claude-opus-4.1";
1920
+ }
1921
+ if (normalized.includes("sonnet-4-5") || normalized.includes("sonnet-4.5")) {
1922
+ return "claude-sonnet-4.5";
1923
+ }
1924
+ if (normalized.includes("haiku-4-5") || normalized.includes("haiku-4.5")) {
1925
+ return "claude-haiku-4.5";
1926
+ }
1843
1927
  if (normalized.includes("sonnet-4") || normalized.includes("3-5-sonnet") || normalized.includes("3.5-sonnet")) {
1844
1928
  return "claude-3.5-sonnet";
1845
1929
  }
@@ -1849,12 +1933,6 @@ function normalizeModelName(modelName) {
1849
1933
  if (normalized.includes("3-haiku") || normalized.includes("haiku-20")) {
1850
1934
  return "claude-3-haiku";
1851
1935
  }
1852
- if (normalized.includes("instant-1.2") || normalized.includes("instant-1")) {
1853
- return "claude-instant-1.2";
1854
- }
1855
- if (normalized.startsWith("claude-2")) {
1856
- return "claude-2";
1857
- }
1858
1936
  return "claude-3.5-sonnet";
1859
1937
  }
1860
1938
  function getModelPricing(modelName) {
@@ -3052,7 +3130,7 @@ var LayerImpl15 = Effect24.gen(function* () {
3052
3130
  userConfig,
3053
3131
  sessionId: task.def.baseSessionId
3054
3132
  });
3055
- return yield* query(generateMessages(), {
3133
+ return yield* query3(generateMessages(), {
3056
3134
  resume: task.def.baseSessionId,
3057
3135
  cwd: sessionProcess.def.cwd,
3058
3136
  abortController: sessionProcess.def.abortController,
@@ -3063,6 +3141,9 @@ var LayerImpl15 = Effect24.gen(function* () {
3063
3141
  setNextMessage(input);
3064
3142
  try {
3065
3143
  for await (const message of messageIter) {
3144
+ if (sessionProcess.def.abortController.signal.aborted) {
3145
+ break;
3146
+ }
3066
3147
  const fallbackMessage = fallbackSdkMessage(message);
3067
3148
  const result = await Runtime2.runPromise(runtime)(
3068
3149
  handleMessage(fallbackMessage)
@@ -3597,6 +3678,14 @@ var LayerImpl18 = Effect29.gen(function* () {
3597
3678
  {
3598
3679
  name: "sidechain-separation",
3599
3680
  enabled: claudeCodeFeatures.sidechainSeparation
3681
+ },
3682
+ {
3683
+ name: "uuid-on-sdk-message",
3684
+ enabled: claudeCodeFeatures.uuidOnSDKMessage
3685
+ },
3686
+ {
3687
+ name: "run-skills-directly",
3688
+ enabled: claudeCodeFeatures.runSkillsDirectly
3600
3689
  }
3601
3690
  ]
3602
3691
  },
@@ -5657,14 +5746,14 @@ var LayerImpl26 = Effect40.gen(function* () {
5657
5746
  yield* Ref12.set(indexCacheRef, { index, documents, builtAt: now });
5658
5747
  return { index, documents };
5659
5748
  });
5660
- const search = (query2, limit = 20, projectId) => Effect40.gen(function* () {
5749
+ const search = (query4, limit = 20, projectId) => Effect40.gen(function* () {
5661
5750
  const { claudeProjectsDirPath } = yield* context.claudeCodePaths;
5662
5751
  const dirExists = yield* fs.exists(claudeProjectsDirPath);
5663
5752
  if (!dirExists) {
5664
5753
  return { results: [] };
5665
5754
  }
5666
5755
  const { index: miniSearch, documents } = yield* getIndex();
5667
- const searchResults = miniSearch.search(query2).slice(0, limit * 2);
5756
+ const searchResults = miniSearch.search(query4).slice(0, limit * 2);
5668
5757
  const results = [];
5669
5758
  for (const result of searchResults) {
5670
5759
  if (results.length >= limit) break;
@@ -5674,7 +5763,7 @@ var LayerImpl26 = Effect40.gen(function* () {
5674
5763
  const score = doc.type === "user" ? result.score * 1.2 : result.score;
5675
5764
  const snippetLength = 150;
5676
5765
  const text = doc.text;
5677
- const queryLower = query2.toLowerCase();
5766
+ const queryLower = query4.toLowerCase();
5678
5767
  const textLower = text.toLowerCase();
5679
5768
  const matchIndex = textLower.indexOf(queryLower);
5680
5769
  let snippet;
@@ -5714,8 +5803,8 @@ var SearchService = class extends Context32.Tag("SearchService")() {
5714
5803
  var LayerImpl27 = Effect41.gen(function* () {
5715
5804
  const searchService = yield* SearchService;
5716
5805
  const search = (options) => Effect41.gen(function* () {
5717
- const { query: query2, limit, projectId } = options;
5718
- if (query2.trim().length < 2) {
5806
+ const { query: query4, limit, projectId } = options;
5807
+ if (query4.trim().length < 2) {
5719
5808
  return {
5720
5809
  status: 400,
5721
5810
  response: {
@@ -5724,7 +5813,7 @@ var LayerImpl27 = Effect41.gen(function* () {
5724
5813
  };
5725
5814
  }
5726
5815
  const { results } = yield* searchService.search(
5727
- query2.trim(),
5816
+ query4.trim(),
5728
5817
  limit,
5729
5818
  projectId
5730
5819
  );