@kimuson/claude-code-viewer 0.5.2 → 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.2",
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",
@@ -668,6 +668,7 @@ var LayerImpl4 = Effect5.gen(function* () {
668
668
  globalClaudeDirectoryPath,
669
669
  "commands"
670
670
  ),
671
+ claudeSkillsDirPath: path.resolve(globalClaudeDirectoryPath, "skills"),
671
672
  claudeProjectsDirPath: path.resolve(
672
673
  globalClaudeDirectoryPath,
673
674
  "projects"
@@ -1041,6 +1042,49 @@ var scanCommandFilesRecursively = (dirPath) => Effect10.gen(function* () {
1041
1042
  })
1042
1043
  );
1043
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
+ });
1044
1088
 
1045
1089
  // src/server/core/claude-code/models/ClaudeCodeVersion.ts
1046
1090
  import { z as z19 } from "zod";
@@ -1093,10 +1137,8 @@ var parseMcpListOutput = (output) => {
1093
1137
  };
1094
1138
 
1095
1139
  // src/server/core/claude-code/models/ClaudeCode.ts
1096
- import { query as agentSdkQuery } from "@anthropic-ai/claude-agent-sdk";
1097
- import {
1098
- query as claudeCodeQuery
1099
- } from "@anthropic-ai/claude-code";
1140
+ import * as agentSdk from "@anthropic-ai/claude-agent-sdk";
1141
+ import * as claudeCodeSdk from "@anthropic-ai/claude-code";
1100
1142
  import { Command, Path as Path7 } from "@effect/platform";
1101
1143
  import { Data, Effect as Effect11 } from "effect";
1102
1144
  import { uniq } from "es-toolkit";
@@ -1201,10 +1243,19 @@ var getAvailableFeatures = (claudeCodeVersion) => ({
1201
1243
  minor: 0,
1202
1244
  patch: 28
1203
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
1204
1255
  }) : false
1205
1256
  });
1206
- var query = (prompt, options) => {
1207
- const { canUseTool, permissionMode, ...baseOptions } = options;
1257
+ var query3 = (prompt, options) => {
1258
+ const { canUseTool, permissionMode, hooks, ...baseOptions } = options;
1208
1259
  return Effect11.gen(function* () {
1209
1260
  const { claudeCodeExecutablePath, claudeCodeVersion } = yield* Config;
1210
1261
  const availableFeatures = getAvailableFeatures(claudeCodeVersion);
@@ -1216,7 +1267,7 @@ var query = (prompt, options) => {
1216
1267
  }
1217
1268
  };
1218
1269
  if (availableFeatures.agentSdk) {
1219
- return agentSdkQuery({
1270
+ return agentSdk.query({
1220
1271
  prompt,
1221
1272
  options: {
1222
1273
  systemPrompt: { type: "preset", preset: "claude_code" },
@@ -1240,10 +1291,15 @@ var query = (prompt, options) => {
1240
1291
  };
1241
1292
  return fn;
1242
1293
  })();
1243
- return claudeCodeQuery({
1294
+ return claudeCodeSdk.query({
1244
1295
  prompt,
1245
1296
  options: {
1246
- ...options2,
1297
+ ...baseOptions,
1298
+ permissionMode: (
1299
+ // fallback unsupported permission modes
1300
+ permissionMode === "delegate" || permissionMode === "dontAsk" ? "bypassPermissions" : permissionMode
1301
+ ),
1302
+ hooks,
1247
1303
  canUseTool: fallbackCanUseTool
1248
1304
  }
1249
1305
  });
@@ -1300,16 +1356,25 @@ var LayerImpl9 = Effect13.gen(function* () {
1300
1356
  const getClaudeCommands = (options) => Effect13.gen(function* () {
1301
1357
  const { projectId } = options;
1302
1358
  const { project } = yield* projectRepository.getProject(projectId);
1359
+ const features = yield* claudeCodeService.getAvailableFeatures();
1303
1360
  const globalCommands = yield* scanCommandFilesRecursively(
1304
1361
  (yield* context.claudeCodePaths).claudeCommandsDirPath
1305
1362
  );
1306
1363
  const projectCommands = project.meta.projectPath === null ? [] : yield* scanCommandFilesRecursively(
1307
1364
  path.resolve(project.meta.projectPath, ".claude", "commands")
1308
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
+ ) : [];
1309
1372
  return {
1310
1373
  response: {
1311
1374
  globalCommands,
1312
1375
  projectCommands,
1376
+ globalSkills,
1377
+ projectSkills,
1313
1378
  defaultCommands: ["init", "compact", "security-review", "review"]
1314
1379
  },
1315
1380
  status: 200
@@ -1799,12 +1864,36 @@ import { Context as Context15, Effect as Effect20, Layer as Layer17, Ref as Ref7
1799
1864
 
1800
1865
  // src/server/core/session/constants/pricing.ts
1801
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
+ },
1802
1885
  "claude-3.5-sonnet": {
1803
1886
  input: 3,
1804
1887
  output: 15,
1805
1888
  cache_creation: 3.75,
1806
1889
  cache_read: 0.3
1807
1890
  },
1891
+ "claude-haiku-4.5": {
1892
+ input: 1,
1893
+ output: 5,
1894
+ cache_creation: 1.25,
1895
+ cache_read: 0.1
1896
+ },
1808
1897
  "claude-3-opus": {
1809
1898
  input: 15,
1810
1899
  output: 75,
@@ -1816,22 +1905,6 @@ var MODEL_PRICING = {
1816
1905
  output: 1.25,
1817
1906
  cache_creation: 0.3,
1818
1907
  cache_read: 0.03
1819
- },
1820
- "claude-instant-1.2": {
1821
- input: 1.63,
1822
- output: 5.51,
1823
- cache_creation: 2.0375,
1824
- // 1.63 * 1.25
1825
- cache_read: 0.163
1826
- // 1.63 * 0.1
1827
- },
1828
- "claude-2": {
1829
- input: 8,
1830
- output: 24,
1831
- cache_creation: 10,
1832
- // 8.0 * 1.25
1833
- cache_read: 0.8
1834
- // 8.0 * 0.1
1835
1908
  }
1836
1909
  };
1837
1910
  var DEFAULT_MODEL_PRICING = MODEL_PRICING["claude-3.5-sonnet"];
@@ -1839,6 +1912,18 @@ var DEFAULT_MODEL_PRICING = MODEL_PRICING["claude-3.5-sonnet"];
1839
1912
  // src/server/core/session/functions/calculateSessionCost.ts
1840
1913
  function normalizeModelName(modelName) {
1841
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
+ }
1842
1927
  if (normalized.includes("sonnet-4") || normalized.includes("3-5-sonnet") || normalized.includes("3.5-sonnet")) {
1843
1928
  return "claude-3.5-sonnet";
1844
1929
  }
@@ -1848,12 +1933,6 @@ function normalizeModelName(modelName) {
1848
1933
  if (normalized.includes("3-haiku") || normalized.includes("haiku-20")) {
1849
1934
  return "claude-3-haiku";
1850
1935
  }
1851
- if (normalized.includes("instant-1.2") || normalized.includes("instant-1")) {
1852
- return "claude-instant-1.2";
1853
- }
1854
- if (normalized.startsWith("claude-2")) {
1855
- return "claude-2";
1856
- }
1857
1936
  return "claude-3.5-sonnet";
1858
1937
  }
1859
1938
  function getModelPricing(modelName) {
@@ -3051,7 +3130,7 @@ var LayerImpl15 = Effect24.gen(function* () {
3051
3130
  userConfig,
3052
3131
  sessionId: task.def.baseSessionId
3053
3132
  });
3054
- return yield* query(generateMessages(), {
3133
+ return yield* query3(generateMessages(), {
3055
3134
  resume: task.def.baseSessionId,
3056
3135
  cwd: sessionProcess.def.cwd,
3057
3136
  abortController: sessionProcess.def.abortController,
@@ -3062,6 +3141,9 @@ var LayerImpl15 = Effect24.gen(function* () {
3062
3141
  setNextMessage(input);
3063
3142
  try {
3064
3143
  for await (const message of messageIter) {
3144
+ if (sessionProcess.def.abortController.signal.aborted) {
3145
+ break;
3146
+ }
3065
3147
  const fallbackMessage = fallbackSdkMessage(message);
3066
3148
  const result = await Runtime2.runPromise(runtime)(
3067
3149
  handleMessage(fallbackMessage)
@@ -3596,6 +3678,14 @@ var LayerImpl18 = Effect29.gen(function* () {
3596
3678
  {
3597
3679
  name: "sidechain-separation",
3598
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
3599
3689
  }
3600
3690
  ]
3601
3691
  },
@@ -5656,14 +5746,14 @@ var LayerImpl26 = Effect40.gen(function* () {
5656
5746
  yield* Ref12.set(indexCacheRef, { index, documents, builtAt: now });
5657
5747
  return { index, documents };
5658
5748
  });
5659
- const search = (query2, limit = 20, projectId) => Effect40.gen(function* () {
5749
+ const search = (query4, limit = 20, projectId) => Effect40.gen(function* () {
5660
5750
  const { claudeProjectsDirPath } = yield* context.claudeCodePaths;
5661
5751
  const dirExists = yield* fs.exists(claudeProjectsDirPath);
5662
5752
  if (!dirExists) {
5663
5753
  return { results: [] };
5664
5754
  }
5665
5755
  const { index: miniSearch, documents } = yield* getIndex();
5666
- const searchResults = miniSearch.search(query2).slice(0, limit * 2);
5756
+ const searchResults = miniSearch.search(query4).slice(0, limit * 2);
5667
5757
  const results = [];
5668
5758
  for (const result of searchResults) {
5669
5759
  if (results.length >= limit) break;
@@ -5673,7 +5763,7 @@ var LayerImpl26 = Effect40.gen(function* () {
5673
5763
  const score = doc.type === "user" ? result.score * 1.2 : result.score;
5674
5764
  const snippetLength = 150;
5675
5765
  const text = doc.text;
5676
- const queryLower = query2.toLowerCase();
5766
+ const queryLower = query4.toLowerCase();
5677
5767
  const textLower = text.toLowerCase();
5678
5768
  const matchIndex = textLower.indexOf(queryLower);
5679
5769
  let snippet;
@@ -5713,8 +5803,8 @@ var SearchService = class extends Context32.Tag("SearchService")() {
5713
5803
  var LayerImpl27 = Effect41.gen(function* () {
5714
5804
  const searchService = yield* SearchService;
5715
5805
  const search = (options) => Effect41.gen(function* () {
5716
- const { query: query2, limit, projectId } = options;
5717
- if (query2.trim().length < 2) {
5806
+ const { query: query4, limit, projectId } = options;
5807
+ if (query4.trim().length < 2) {
5718
5808
  return {
5719
5809
  status: 400,
5720
5810
  response: {
@@ -5723,7 +5813,7 @@ var LayerImpl27 = Effect41.gen(function* () {
5723
5813
  };
5724
5814
  }
5725
5815
  const { results } = yield* searchService.search(
5726
- query2.trim(),
5816
+ query4.trim(),
5727
5817
  limit,
5728
5818
  projectId
5729
5819
  );