@kimuson/claude-code-viewer 0.5.2 → 0.5.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/README.md +16 -0
- package/dist/main.js +136 -44
- package/dist/main.js.map +3 -3
- package/dist/static/assets/ProtectedRoute-BKa2KNL5.js +56 -0
- package/dist/static/assets/{eye-CVAoW3ii.js → eye-BuuMK_10.js} +1 -1
- package/dist/static/assets/index-B5f8xC3F.js +199 -0
- package/dist/static/assets/{index-DTWGKLpI.js → index-CPXteyzl.js} +1 -1
- package/dist/static/assets/index-U9oGzuMt.css +1 -0
- package/dist/static/assets/{index-BHEtzNnp.js → index-if6WtkX7.js} +2 -2
- package/dist/static/assets/{label-CMDlxfdk.js → label-CBuy4auH.js} +1 -1
- package/dist/static/assets/{login-B68oY8aW.js → login-Umq8wXxy.js} +1 -1
- package/dist/static/assets/messages-BJ1VgsgX.js +1 -0
- package/dist/static/assets/messages-IXcunSHt.js +1 -0
- package/dist/static/assets/messages-oFJMtVzX.js +1 -0
- package/dist/static/assets/{session-BTtdE4b-.js → session-DTsxKUn0.js} +1 -1
- package/dist/static/assets/{session-B6zUBwuL.js → session-k-eoDLbo.js} +57 -57
- package/dist/static/index.html +2 -2
- package/package.json +4 -4
- package/dist/static/assets/ProtectedRoute-CchCkvZ3.js +0 -56
- package/dist/static/assets/index-BdX76yyf.js +0 -199
- package/dist/static/assets/index-XlCGs7Gh.css +0 -1
- package/dist/static/assets/messages-BG-jsA6S.js +0 -1
- package/dist/static/assets/messages-B_apS9Hh.js +0 -1
- package/dist/static/assets/messages-D_XaPnhD.js +0 -1
package/README.md
CHANGED
|
@@ -138,6 +138,10 @@ The application reads Claude Code conversation logs from:
|
|
|
138
138
|
|
|
139
139
|
**Note on Version Support**: Recent versions of Claude Code have adopted more aggressive summarization behavior. To accommodate users who prefer to pin to specific versions, Claude Code Viewer maintains compatibility with Claude Code v1.0.50 and later for the foreseeable future.
|
|
140
140
|
|
|
141
|
+
### Environment Variables
|
|
142
|
+
|
|
143
|
+
**NODE_ENV Consideration**: If you have `NODE_ENV=development` set in your environment (from other projects or system configuration), the application may not work correctly. Either set `NODE_ENV=production` or leave it unset when running Claude Code Viewer.
|
|
144
|
+
|
|
141
145
|
## Configuration
|
|
142
146
|
|
|
143
147
|
### Command-Line Options and Environment Variables
|
|
@@ -166,6 +170,7 @@ Settings can be configured from the sidebar in Claude Code Viewer.
|
|
|
166
170
|
| Hide sessions without user messages | true | Claude Code creates logs for operations like `/compact` that aren't tied to actual tasks, which can create noise. When enabled, sessions without user messages are hidden. |
|
|
167
171
|
| Unify sessions with same title | false | When resuming, Claude Code creates a new session with regenerated conversation logs. When enabled, only the latest session with the same title is displayed. |
|
|
168
172
|
| Enter Key Behavior | Shift+Enter | Specifies which key combination sends messages. Options include Enter, Shift+Enter, and Command+Enter. |
|
|
173
|
+
| Search Hotkey | Command+K | Select the hotkey to open search dialog. Options include Ctrl+K and Command+K. |
|
|
169
174
|
| Permission Mode | Ask permission | Controls the approval logic when Claude Code requests tool invocations. By default, users approve requests through the UI. This feature requires Claude Code v1.0.82 or later; earlier versions automatically approve regardless of this setting. |
|
|
170
175
|
| Theme | System | Toggles between Dark Mode and Light Mode. Default follows system settings. |
|
|
171
176
|
| Notifications | None | Enables sound notifications when running session processes complete. Choose from multiple notification sounds with test playback functionality. |
|
|
@@ -224,6 +229,17 @@ Claude Code Viewer is designed with remote hosting in mind. To support remote de
|
|
|
224
229
|
|
|
225
230
|
The application features a separated client-server architecture that enables remote hosting. **Basic password authentication is available** via the `--password` command-line option or `CCV_PASSWORD` environment variable. When set, users must authenticate with the configured password before accessing the application. However, this is a simple single-password authentication mechanism without advanced features like multi-user support, role-based access control, or OAuth integration. If you require more sophisticated authentication, carefully evaluate your security requirements and implement appropriate access controls at the infrastructure level (e.g., reverse proxy with OAuth, VPN, IP whitelisting).
|
|
226
231
|
|
|
232
|
+
## Privacy and Network Communication
|
|
233
|
+
|
|
234
|
+
Claude Code Viewer is designed with privacy in mind:
|
|
235
|
+
|
|
236
|
+
- **Localhost-Only Communication**: The application runs a web client and API server on localhost, communicating exclusively between your browser and the local server
|
|
237
|
+
- **Anthropic API Access**: Claude Code is invoked via the Claude Agent SDK, which handles communication to the Anthropic API. No other external services are contacted
|
|
238
|
+
- **No Tracking or Telemetry**: The application does not collect crash reports, usage statistics, or any other telemetry. Tracking for Claude Code itself follows the settings configured in Claude Code's own configuration
|
|
239
|
+
- **Network Isolation**: The application functions correctly even if network access is restricted to only the Anthropic API and the localhost port. There are no plans to add external network dependencies in the future
|
|
240
|
+
|
|
241
|
+
If you have concerns about network access, you can verify that the application only communicates with the Anthropic API and localhost by monitoring network traffic.
|
|
242
|
+
|
|
227
243
|
## License
|
|
228
244
|
|
|
229
245
|
This project is available under the MIT License.
|
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.
|
|
10
|
+
version: "0.5.4",
|
|
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.
|
|
54
|
+
"@anthropic-ai/claude-agent-sdk": "0.2.2",
|
|
55
55
|
"@anthropic-ai/claude-code": "2.0.24",
|
|
56
|
-
"@anthropic-ai/sdk": "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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1294
|
+
return claudeCodeSdk.query({
|
|
1244
1295
|
prompt,
|
|
1245
1296
|
options: {
|
|
1246
|
-
...
|
|
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
|
|
@@ -1605,7 +1670,8 @@ var LayerImpl12 = Effect17.gen(function* () {
|
|
|
1605
1670
|
enterKeyBehavior: "shift-enter-send",
|
|
1606
1671
|
permissionMode: "default",
|
|
1607
1672
|
locale: DEFAULT_LOCALE,
|
|
1608
|
-
theme: "system"
|
|
1673
|
+
theme: "system",
|
|
1674
|
+
searchHotkey: "command-k"
|
|
1609
1675
|
});
|
|
1610
1676
|
const setUserConfig = (newConfig) => Effect17.gen(function* () {
|
|
1611
1677
|
yield* Ref5.update(configRef, () => newConfig);
|
|
@@ -1799,12 +1865,36 @@ import { Context as Context15, Effect as Effect20, Layer as Layer17, Ref as Ref7
|
|
|
1799
1865
|
|
|
1800
1866
|
// src/server/core/session/constants/pricing.ts
|
|
1801
1867
|
var MODEL_PRICING = {
|
|
1868
|
+
"claude-opus-4.5": {
|
|
1869
|
+
input: 5,
|
|
1870
|
+
output: 25,
|
|
1871
|
+
cache_creation: 6.25,
|
|
1872
|
+
cache_read: 0.5
|
|
1873
|
+
},
|
|
1874
|
+
"claude-opus-4.1": {
|
|
1875
|
+
input: 15,
|
|
1876
|
+
output: 75,
|
|
1877
|
+
cache_creation: 18.75,
|
|
1878
|
+
cache_read: 1.5
|
|
1879
|
+
},
|
|
1880
|
+
"claude-sonnet-4.5": {
|
|
1881
|
+
input: 3,
|
|
1882
|
+
output: 15,
|
|
1883
|
+
cache_creation: 3.75,
|
|
1884
|
+
cache_read: 0.3
|
|
1885
|
+
},
|
|
1802
1886
|
"claude-3.5-sonnet": {
|
|
1803
1887
|
input: 3,
|
|
1804
1888
|
output: 15,
|
|
1805
1889
|
cache_creation: 3.75,
|
|
1806
1890
|
cache_read: 0.3
|
|
1807
1891
|
},
|
|
1892
|
+
"claude-haiku-4.5": {
|
|
1893
|
+
input: 1,
|
|
1894
|
+
output: 5,
|
|
1895
|
+
cache_creation: 1.25,
|
|
1896
|
+
cache_read: 0.1
|
|
1897
|
+
},
|
|
1808
1898
|
"claude-3-opus": {
|
|
1809
1899
|
input: 15,
|
|
1810
1900
|
output: 75,
|
|
@@ -1816,22 +1906,6 @@ var MODEL_PRICING = {
|
|
|
1816
1906
|
output: 1.25,
|
|
1817
1907
|
cache_creation: 0.3,
|
|
1818
1908
|
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
1909
|
}
|
|
1836
1910
|
};
|
|
1837
1911
|
var DEFAULT_MODEL_PRICING = MODEL_PRICING["claude-3.5-sonnet"];
|
|
@@ -1839,6 +1913,18 @@ var DEFAULT_MODEL_PRICING = MODEL_PRICING["claude-3.5-sonnet"];
|
|
|
1839
1913
|
// src/server/core/session/functions/calculateSessionCost.ts
|
|
1840
1914
|
function normalizeModelName(modelName) {
|
|
1841
1915
|
const normalized = modelName.toLowerCase();
|
|
1916
|
+
if (normalized.includes("opus-4-5") || normalized.includes("opus-4.5")) {
|
|
1917
|
+
return "claude-opus-4.5";
|
|
1918
|
+
}
|
|
1919
|
+
if (normalized.includes("opus-4-1") || normalized.includes("opus-4.1")) {
|
|
1920
|
+
return "claude-opus-4.1";
|
|
1921
|
+
}
|
|
1922
|
+
if (normalized.includes("sonnet-4-5") || normalized.includes("sonnet-4.5")) {
|
|
1923
|
+
return "claude-sonnet-4.5";
|
|
1924
|
+
}
|
|
1925
|
+
if (normalized.includes("haiku-4-5") || normalized.includes("haiku-4.5")) {
|
|
1926
|
+
return "claude-haiku-4.5";
|
|
1927
|
+
}
|
|
1842
1928
|
if (normalized.includes("sonnet-4") || normalized.includes("3-5-sonnet") || normalized.includes("3.5-sonnet")) {
|
|
1843
1929
|
return "claude-3.5-sonnet";
|
|
1844
1930
|
}
|
|
@@ -1848,12 +1934,6 @@ function normalizeModelName(modelName) {
|
|
|
1848
1934
|
if (normalized.includes("3-haiku") || normalized.includes("haiku-20")) {
|
|
1849
1935
|
return "claude-3-haiku";
|
|
1850
1936
|
}
|
|
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
1937
|
return "claude-3.5-sonnet";
|
|
1858
1938
|
}
|
|
1859
1939
|
function getModelPricing(modelName) {
|
|
@@ -3051,7 +3131,7 @@ var LayerImpl15 = Effect24.gen(function* () {
|
|
|
3051
3131
|
userConfig,
|
|
3052
3132
|
sessionId: task.def.baseSessionId
|
|
3053
3133
|
});
|
|
3054
|
-
return yield*
|
|
3134
|
+
return yield* query3(generateMessages(), {
|
|
3055
3135
|
resume: task.def.baseSessionId,
|
|
3056
3136
|
cwd: sessionProcess.def.cwd,
|
|
3057
3137
|
abortController: sessionProcess.def.abortController,
|
|
@@ -3062,6 +3142,9 @@ var LayerImpl15 = Effect24.gen(function* () {
|
|
|
3062
3142
|
setNextMessage(input);
|
|
3063
3143
|
try {
|
|
3064
3144
|
for await (const message of messageIter) {
|
|
3145
|
+
if (sessionProcess.def.abortController.signal.aborted) {
|
|
3146
|
+
break;
|
|
3147
|
+
}
|
|
3065
3148
|
const fallbackMessage = fallbackSdkMessage(message);
|
|
3066
3149
|
const result = await Runtime2.runPromise(runtime)(
|
|
3067
3150
|
handleMessage(fallbackMessage)
|
|
@@ -3596,6 +3679,14 @@ var LayerImpl18 = Effect29.gen(function* () {
|
|
|
3596
3679
|
{
|
|
3597
3680
|
name: "sidechain-separation",
|
|
3598
3681
|
enabled: claudeCodeFeatures.sidechainSeparation
|
|
3682
|
+
},
|
|
3683
|
+
{
|
|
3684
|
+
name: "uuid-on-sdk-message",
|
|
3685
|
+
enabled: claudeCodeFeatures.uuidOnSDKMessage
|
|
3686
|
+
},
|
|
3687
|
+
{
|
|
3688
|
+
name: "run-skills-directly",
|
|
3689
|
+
enabled: claudeCodeFeatures.runSkillsDirectly
|
|
3599
3690
|
}
|
|
3600
3691
|
]
|
|
3601
3692
|
},
|
|
@@ -5656,14 +5747,14 @@ var LayerImpl26 = Effect40.gen(function* () {
|
|
|
5656
5747
|
yield* Ref12.set(indexCacheRef, { index, documents, builtAt: now });
|
|
5657
5748
|
return { index, documents };
|
|
5658
5749
|
});
|
|
5659
|
-
const search = (
|
|
5750
|
+
const search = (query4, limit = 20, projectId) => Effect40.gen(function* () {
|
|
5660
5751
|
const { claudeProjectsDirPath } = yield* context.claudeCodePaths;
|
|
5661
5752
|
const dirExists = yield* fs.exists(claudeProjectsDirPath);
|
|
5662
5753
|
if (!dirExists) {
|
|
5663
5754
|
return { results: [] };
|
|
5664
5755
|
}
|
|
5665
5756
|
const { index: miniSearch, documents } = yield* getIndex();
|
|
5666
|
-
const searchResults = miniSearch.search(
|
|
5757
|
+
const searchResults = miniSearch.search(query4).slice(0, limit * 2);
|
|
5667
5758
|
const results = [];
|
|
5668
5759
|
for (const result of searchResults) {
|
|
5669
5760
|
if (results.length >= limit) break;
|
|
@@ -5673,7 +5764,7 @@ var LayerImpl26 = Effect40.gen(function* () {
|
|
|
5673
5764
|
const score = doc.type === "user" ? result.score * 1.2 : result.score;
|
|
5674
5765
|
const snippetLength = 150;
|
|
5675
5766
|
const text = doc.text;
|
|
5676
|
-
const queryLower =
|
|
5767
|
+
const queryLower = query4.toLowerCase();
|
|
5677
5768
|
const textLower = text.toLowerCase();
|
|
5678
5769
|
const matchIndex = textLower.indexOf(queryLower);
|
|
5679
5770
|
let snippet;
|
|
@@ -5713,8 +5804,8 @@ var SearchService = class extends Context32.Tag("SearchService")() {
|
|
|
5713
5804
|
var LayerImpl27 = Effect41.gen(function* () {
|
|
5714
5805
|
const searchService = yield* SearchService;
|
|
5715
5806
|
const search = (options) => Effect41.gen(function* () {
|
|
5716
|
-
const { query:
|
|
5717
|
-
if (
|
|
5807
|
+
const { query: query4, limit, projectId } = options;
|
|
5808
|
+
if (query4.trim().length < 2) {
|
|
5718
5809
|
return {
|
|
5719
5810
|
status: 400,
|
|
5720
5811
|
response: {
|
|
@@ -5723,7 +5814,7 @@ var LayerImpl27 = Effect41.gen(function* () {
|
|
|
5723
5814
|
};
|
|
5724
5815
|
}
|
|
5725
5816
|
const { results } = yield* searchService.search(
|
|
5726
|
-
|
|
5817
|
+
query4.trim(),
|
|
5727
5818
|
limit,
|
|
5728
5819
|
projectId
|
|
5729
5820
|
);
|
|
@@ -6881,7 +6972,8 @@ var userConfigSchema = z27.object({
|
|
|
6881
6972
|
enterKeyBehavior: z27.enum(["shift-enter-send", "enter-send", "command-enter-send"]).optional().default("shift-enter-send"),
|
|
6882
6973
|
permissionMode: z27.enum(["acceptEdits", "bypassPermissions", "default", "plan"]).optional().default("default"),
|
|
6883
6974
|
locale: localeSchema.optional().default("en"),
|
|
6884
|
-
theme: z27.enum(["light", "dark", "system"]).optional().default("system")
|
|
6975
|
+
theme: z27.enum(["light", "dark", "system"]).optional().default("system"),
|
|
6976
|
+
searchHotkey: z27.enum(["ctrl-k", "command-k"]).optional().default("command-k")
|
|
6885
6977
|
});
|
|
6886
6978
|
var defaultUserConfig = userConfigSchema.parse({});
|
|
6887
6979
|
|