@ksm0709/context 0.0.33 → 0.0.35

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 CHANGED
@@ -10,7 +10,20 @@ Context plugin for Bun
10
10
 
11
11
  ## MCP Server
12
12
 
13
- This plugin automatically registers an MCP (Model Context Protocol) server named `context-mcp` with OpenCode. The server provides tools for searching knowledge base files (`.md` files in `docs/` and `.context/` directories).
13
+ This plugin automatically registers an MCP (Model Context Protocol) server named `context-mcp` with OpenCode. The server provides metadata-first knowledge discovery for `.md` files in `docs/` and `.context/`.
14
+
15
+ Recommended workflow:
16
+
17
+ 1. Run `search_knowledge` to get ranked candidate notes.
18
+ 2. Compare each result's path, title, description, tags, score, and snippet.
19
+ 3. Open the best match with `read_knowledge`.
20
+ 4. Use the related-note metadata appended to `read_knowledge` output to continue exploring linked notes.
21
+
22
+ Core knowledge tools:
23
+
24
+ - `search_knowledge` — returns ranked note summaries so agents can choose what to open next without relying on exact full-text matches.
25
+ - `read_knowledge` — opens a selected note and appends linked-note metadata for relevant `[[wikilink]]` references.
26
+ - `create_knowledge_note` / `update_knowledge_note` — create and maintain knowledge notes once the relevant context is understood.
14
27
 
15
28
  ## OMX Support
16
29
 
package/dist/cli/index.js CHANGED
@@ -2,9 +2,9 @@
2
2
  // @bun
3
3
 
4
4
  // src/cli/commands/update.ts
5
- import { resolve as resolve3, join as join7 } from "path";
6
- import { existsSync as existsSync8 } from "fs";
7
- import { homedir as homedir3 } from "os";
5
+ import { resolve as resolve3, join as join8 } from "path";
6
+ import { existsSync as existsSync9 } from "fs";
7
+ import { homedir as homedir4 } from "os";
8
8
 
9
9
  // src/lib/scaffold.ts
10
10
  import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -27,7 +27,7 @@ function resolveContextDir(projectDir) {
27
27
  // package.json
28
28
  var package_default = {
29
29
  name: "@ksm0709/context",
30
- version: "0.0.33",
30
+ version: "0.0.35",
31
31
  author: {
32
32
  name: "TaehoKang",
33
33
  email: "ksm07091@gmail.com"
@@ -69,24 +69,23 @@ var package_default = {
69
69
  "@opencode-ai/plugin": ">=1.0.0"
70
70
  },
71
71
  dependencies: {
72
- "@ksm0709/context": "^0.0.33",
73
72
  "@modelcontextprotocol/sdk": "^1.27.1",
74
73
  "jsonc-parser": "^3.0.0"
75
74
  },
76
75
  devDependencies: {
77
- "@opencode-ai/plugin": "^1.2.10",
78
76
  "@eslint/js": "^9.39.1",
77
+ "@opencode-ai/plugin": "^1.2.10",
79
78
  "@types/node": "^20.11.5",
80
79
  "@typescript-eslint/eslint-plugin": "8.47.0",
81
80
  "@typescript-eslint/parser": "8.47.0",
81
+ "@vitest/coverage-v8": "^3.2.4",
82
82
  "bun-types": "latest",
83
83
  eslint: "^9.39.1",
84
84
  "eslint-config-prettier": "10.1.8",
85
85
  "eslint-plugin-prettier": "^5.1.3",
86
86
  prettier: "^3.2.4",
87
87
  "typescript-eslint": "^8.47.0",
88
- vitest: "^3.2.4",
89
- "@vitest/coverage-v8": "^3.2.4"
88
+ vitest: "^3.2.4"
90
89
  }
91
90
  };
92
91
 
@@ -450,8 +449,8 @@ function writeVersion(contextDir, version) {
450
449
  }
451
450
 
452
451
  // src/cli/commands/install.ts
453
- import { join as join6, resolve as resolve2, dirname as dirname5 } from "path";
454
- import { existsSync as existsSync7, mkdirSync as mkdirSync5, copyFileSync } from "fs";
452
+ import { join as join7, resolve as resolve2, dirname as dirname5 } from "path";
453
+ import { existsSync as existsSync8, mkdirSync as mkdirSync5, copyFileSync } from "fs";
455
454
  import { fileURLToPath as fileURLToPath2 } from "url";
456
455
  import { createRequire as createRequire2 } from "module";
457
456
  import { execSync as execSync2 } from "child_process";
@@ -622,14 +621,17 @@ var STATIC_KNOWLEDGE_CONTEXT = `## Knowledge Context
622
621
  3. **\uC790\uAE30 \uC5B8\uC5B4** -- \uBCF5\uC0AC-\uBD99\uC5EC\uB123\uAE30\uAC00 \uC544\uB2CC, \uD575\uC2EC\uC744 \uC774\uD574\uD558\uACE0 \uAC04\uACB0\uD558\uAC8C \uC11C\uC220\uD558\uC138\uC694.
623
622
 
624
623
  ### MCP Tools
625
- - **\uC9C0\uC2DD \uAD00\uB9AC**: \`context_mcp_search_knowledge\`, \`context_mcp_read_knowledge\`, \`context_mcp_create_knowledge_note\`, \`context_mcp_update_knowledge_note\`
624
+ - **\uC9C0\uC2DD \uD0D0\uC0C9**: \`context_mcp_search_knowledge\`\uB85C \uD6C4\uBCF4 \uB178\uD2B8\uB97C \uCC3E\uACE0, \uACB0\uACFC\uC758 title / description / tags / path / score\uB97C \uBA3C\uC800 \uBE44\uAD50\uD558\uC138\uC694.
625
+ - **\uB178\uD2B8 \uC5F4\uAE30**: \`context_mcp_read_knowledge\`\uB85C \uC120\uD0DD\uD55C \uB178\uD2B8\uB97C \uC5F4\uACE0, \uB05D\uC5D0 \uBD99\uB294 related notes \uBA54\uD0C0\uB370\uC774\uD130\uB85C \uB2E4\uC74C \uD0D0\uC0C9 \uACBD\uB85C\uB97C \uC815\uD558\uC138\uC694.
626
+ - **\uB178\uD2B8 \uC791\uC131/\uC218\uC815**: \`context_mcp_create_knowledge_note\`, \`context_mcp_update_knowledge_note\`
626
627
  - **\uB370\uC77C\uB9AC \uB178\uD2B8**: \`context_mcp_read_daily_note\`, \`context_mcp_append_daily_note\`
627
628
  - **\uC791\uC5C5 \uC644\uB8CC**: \`context_mcp_submit_turn_complete\` (\uC791\uC5C5 \uC885\uB8CC \uC2DC \uD544\uC218 \uD638\uCD9C)
628
629
 
629
630
  ### \uC791\uC5C5 \uC804 \uD544\uC218
630
631
  - **\uB370\uC77C\uB9AC \uB178\uD2B8 \uD655\uC778**: \uAC00\uC7A5 \uCD5C\uADFC\uC758 \uB370\uC77C\uB9AC \uB178\uD2B8\uB97C \uC77D\uACE0 \uC774\uC804 \uC138\uC158\uC758 \uCEE8\uD14D\uC2A4\uD2B8\uC640 \uBBF8\uD574\uACB0 \uC774\uC288\uB97C \uD30C\uC545\uD558\uC138\uC694.
631
632
  - **\uC791\uC5C5 \uC758\uB3C4 \uC120\uC5B8**: \uC791\uC5C5 \uC2DC\uC791 \uC804, \uD604\uC7AC \uC138\uC158\uC758 \uBAA9\uD45C\uC640 \uC791\uC5C5 \uC758\uB3C4\uB97C \uBA85\uD655\uD788 \uD30C\uC545\uD558\uACE0 \uC120\uC5B8\uD558\uC138\uC694.
632
- - **\uC9C0\uC2DD \uAC80\uC0C9**: \uC791\uC5C5\uACFC \uAD00\uB828\uB41C \uBB38\uC11C\uB97C **\uC9C1\uC811 \uBA3C\uC800** \uAC80\uC0C9\uD558\uACE0 \uC77D\uC73C\uC138\uC694.
633
+ - **\uBA54\uD0C0\uB370\uC774\uD130 \uC6B0\uC120 \uAC80\uC0C9**: \uBA3C\uC800 \`search_knowledge\`\uB85C \uAD00\uB828 \uD6C4\uBCF4\uB97C \uCC3E\uACE0, \uBA54\uD0C0\uB370\uC774\uD130\uB97C \uBE44\uAD50\uD55C \uB4A4 \uAC00\uC7A5 \uC720\uB825\uD55C \uB178\uD2B8\uB97C \`read_knowledge\`\uB85C \uC5EC\uC138\uC694.
634
+ - **\uAD00\uB828 \uB178\uD2B8 \uCD94\uC801**: \`read_knowledge\` \uB05D\uC758 related notes \uC139\uC158\uC5D0\uC11C \uC5F0\uACB0\uB41C \uB178\uD2B8\uC758 title / description / tags / path\uB97C \uD655\uC778\uD558\uACE0 \uD544\uC694\uC2DC \uC5F0\uC1C4 \uD0D0\uC0C9\uD558\uC138\uC694.
633
635
  - \uC9C0\uC2DD \uD30C\uC77C\uC5D0 \uAE30\uB85D\uB41C \uC544\uD0A4\uD14D\uCC98 \uACB0\uC815, \uD328\uD134, \uC81C\uC57D\uC0AC\uD56D\uC744 \uBC18\uB4DC\uC2DC \uB530\uB974\uC138\uC694.
634
636
 
635
637
  ### \uAC1C\uBC1C \uC6D0\uCE59
@@ -647,10 +649,63 @@ var STATIC_KNOWLEDGE_CONTEXT = `## Knowledge Context
647
649
  - \uC774 \uD638\uCD9C \uC5C6\uC774 \uC138\uC158\uC744 \uC885\uB8CC\uD558\uBA74 \uC791\uC5C5 \uAE30\uB85D\uC774 \uBCF4\uC874\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
648
650
  - \uD544\uC694\uD55C \uC778\uC790: daily_note_update_proof, knowledge_note_proof, quality_check_output, checkpoint_commit_hashes, scope_review_notes`;
649
651
 
650
- // src/shared/claude-settings.ts
651
- import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync4, renameSync as renameSync2, mkdirSync as mkdirSync4 } from "fs";
652
- import { dirname as dirname4, join as join5 } from "path";
652
+ // src/shared/codex-settings.ts
653
+ import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
653
654
  import { homedir as homedir2 } from "os";
655
+ import { isAbsolute, join as join5 } from "path";
656
+ var STALE_MOCK_MCP_SERVER_NAME = "mock-mcp";
657
+ var codexConfigPath = join5(homedir2(), ".codex", "config.toml");
658
+ function findMcpServerBlockRange(lines, serverName) {
659
+ const header = `[mcp_servers.${serverName}]`;
660
+ const start = lines.findIndex((line) => line.trim() === header);
661
+ if (start === -1) {
662
+ return null;
663
+ }
664
+ let end = lines.length;
665
+ for (let index = start + 1;index < lines.length; index += 1) {
666
+ if (lines[index].startsWith("[")) {
667
+ end = index;
668
+ break;
669
+ }
670
+ }
671
+ return { start, end };
672
+ }
673
+ function resolveFirstArgPath(blockLines) {
674
+ for (const line of blockLines) {
675
+ const match = line.match(/^\s*args\s*=\s*\[\s*["']([^"']+)["']/);
676
+ if (!match) {
677
+ continue;
678
+ }
679
+ return match[1];
680
+ }
681
+ return null;
682
+ }
683
+ function pruneStaleMockMcpServer() {
684
+ if (!existsSync6(codexConfigPath)) {
685
+ return false;
686
+ }
687
+ const content = readFileSync4(codexConfigPath, "utf8");
688
+ const lines = content.split(`
689
+ `);
690
+ const blockRange = findMcpServerBlockRange(lines, STALE_MOCK_MCP_SERVER_NAME);
691
+ if (!blockRange) {
692
+ return false;
693
+ }
694
+ const blockLines = lines.slice(blockRange.start, blockRange.end);
695
+ const firstArgPath = resolveFirstArgPath(blockLines);
696
+ if (!firstArgPath || !isAbsolute(firstArgPath) || existsSync6(firstArgPath)) {
697
+ return false;
698
+ }
699
+ const nextLines = [...lines.slice(0, blockRange.start), ...lines.slice(blockRange.end)];
700
+ writeFileSync4(codexConfigPath, nextLines.join(`
701
+ `), "utf8");
702
+ return true;
703
+ }
704
+
705
+ // src/shared/claude-settings.ts
706
+ import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync5, renameSync as renameSync2, mkdirSync as mkdirSync4 } from "fs";
707
+ import { dirname as dirname4, join as join6 } from "path";
708
+ import { homedir as homedir3 } from "os";
654
709
 
655
710
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
656
711
  function createScanner(text, ignoreTrivia = false) {
@@ -1978,12 +2033,12 @@ function applyEdits(text, edits) {
1978
2033
  // src/shared/claude-settings.ts
1979
2034
  var CONTEXT_MCP_SERVER_NAME = "context-mcp";
1980
2035
  var LEGACY_CONTEXT_MCP_SERVER_NAME = "context_mcp";
1981
- var settingsPath = join5(homedir2(), ".claude", "settings.json");
2036
+ var settingsPath = join6(homedir3(), ".claude", "settings.json");
1982
2037
  function readClaudeSettings() {
1983
- if (!existsSync6(settingsPath)) {
2038
+ if (!existsSync7(settingsPath)) {
1984
2039
  return {};
1985
2040
  }
1986
- const content = readFileSync4(settingsPath, "utf8");
2041
+ const content = readFileSync5(settingsPath, "utf8");
1987
2042
  return parse2(content) ?? {};
1988
2043
  }
1989
2044
  function hasContextMcpServer(settings) {
@@ -1994,12 +2049,12 @@ function hasContextMcpServer(settings) {
1994
2049
  }
1995
2050
  function writeClaudeSettings(settings) {
1996
2051
  const dir = dirname4(settingsPath);
1997
- if (!existsSync6(dir)) {
2052
+ if (!existsSync7(dir)) {
1998
2053
  mkdirSync4(dir, { recursive: true });
1999
2054
  }
2000
2055
  let content;
2001
- if (existsSync6(settingsPath)) {
2002
- content = readFileSync4(settingsPath, "utf8");
2056
+ if (existsSync7(settingsPath)) {
2057
+ content = readFileSync5(settingsPath, "utf8");
2003
2058
  for (const [key, value] of Object.entries(settings)) {
2004
2059
  const edits = modify(content, [key], value, {});
2005
2060
  content = applyEdits(content, edits);
@@ -2015,7 +2070,7 @@ function writeClaudeSettings(settings) {
2015
2070
  content = JSON.stringify(settings, null, 2);
2016
2071
  }
2017
2072
  const tmp = settingsPath + ".tmp";
2018
- writeFileSync4(tmp, content, "utf8");
2073
+ writeFileSync5(tmp, content, "utf8");
2019
2074
  renameSync2(tmp, settingsPath);
2020
2075
  }
2021
2076
  function removeMcpServer(name) {
@@ -2082,8 +2137,8 @@ function resolveOmxSource() {
2082
2137
  try {
2083
2138
  const cliDir = dirname5(fileURLToPath2(import.meta.url));
2084
2139
  const pkgRoot = resolve2(cliDir, "..", "..");
2085
- const source = join6(pkgRoot, "dist", "omx", "index.mjs");
2086
- if (existsSync7(source))
2140
+ const source = join7(pkgRoot, "dist", "omx", "index.mjs");
2141
+ if (existsSync8(source))
2087
2142
  return source;
2088
2143
  } catch {}
2089
2144
  try {
@@ -2094,31 +2149,35 @@ function resolveOmxSource() {
2094
2149
  }
2095
2150
  }
2096
2151
  function installOmx(projectDir, sourcePath) {
2097
- if (!existsSync7(sourcePath)) {
2152
+ if (!existsSync8(sourcePath)) {
2098
2153
  process.stderr.write(`Could not find OMX plugin source file: ${sourcePath}
2099
2154
  `);
2100
2155
  process.exit(1);
2101
2156
  return;
2102
2157
  }
2103
- const targetDir = join6(projectDir, ".omx", "hooks");
2158
+ const targetDir = join7(projectDir, ".omx", "hooks");
2104
2159
  mkdirSync5(targetDir, { recursive: true });
2105
- copyFileSync(sourcePath, join6(targetDir, "context.mjs"));
2160
+ copyFileSync(sourcePath, join7(targetDir, "context.mjs"));
2106
2161
  process.stdout.write(`Installed context plugin to .omx/hooks/context.mjs
2107
2162
  `);
2108
2163
  if (ensureMcpRegistered()) {
2109
2164
  process.stdout.write(`Successfully registered context-mcp in ~/.omx/mcp-registry.json
2165
+ `);
2166
+ }
2167
+ if (pruneStaleMockMcpServer()) {
2168
+ process.stdout.write(`Removed stale mock-mcp from ~/.codex/config.toml because its target file is missing
2110
2169
  `);
2111
2170
  }
2112
2171
  }
2113
2172
  function installOmc(projectDir) {
2114
2173
  scaffoldIfNeeded(projectDir);
2115
- injectIntoAgentsMd(join6(projectDir, "AGENTS.md"), STATIC_KNOWLEDGE_CONTEXT);
2174
+ injectIntoAgentsMd(join7(projectDir, "AGENTS.md"), STATIC_KNOWLEDGE_CONTEXT);
2116
2175
  let bunPath = "bun";
2117
2176
  try {
2118
2177
  bunPath = execSync2("which bun", { encoding: "utf-8" }).trim();
2119
2178
  } catch {}
2120
2179
  const mcpPath = resolveMcpPath();
2121
- const hookBasePath = join6(dirname5(mcpPath), "omc") + "/";
2180
+ const hookBasePath = join7(dirname5(mcpPath), "omc") + "/";
2122
2181
  removeMcpServer("context_mcp");
2123
2182
  removeMcpServer("context-mcp");
2124
2183
  try {
@@ -2220,7 +2279,7 @@ function runUpdate(args) {
2220
2279
  }
2221
2280
  }
2222
2281
  function isOmxInstalled(projectDir) {
2223
- return existsSync8(join7(projectDir, ".omx", "hooks", "context.mjs"));
2282
+ return existsSync9(join8(projectDir, ".omx", "hooks", "context.mjs"));
2224
2283
  }
2225
2284
  function isOmcInstalled() {
2226
2285
  try {
@@ -2281,20 +2340,20 @@ OMX plugin is not installed for this project; skipping omx reinstall.
2281
2340
  `);
2282
2341
  }
2283
2342
  function detectPackageManager() {
2284
- if (existsSync8("bun.lock") || existsSync8("bun.lockb"))
2343
+ if (existsSync9("bun.lock") || existsSync9("bun.lockb"))
2285
2344
  return "bun";
2286
- if (existsSync8("pnpm-lock.yaml"))
2345
+ if (existsSync9("pnpm-lock.yaml"))
2287
2346
  return "pnpm";
2288
- if (existsSync8("yarn.lock"))
2347
+ if (existsSync9("yarn.lock"))
2289
2348
  return "yarn";
2290
- if (existsSync8("package-lock.json"))
2349
+ if (existsSync9("package-lock.json"))
2291
2350
  return "npm";
2292
2351
  return "bun";
2293
2352
  }
2294
2353
  function detectGlobalInstalls() {
2295
2354
  const installs = [];
2296
- const bunGlobalBin = join7(homedir3(), ".bun", "bin", "context");
2297
- if (existsSync8(bunGlobalBin)) {
2355
+ const bunGlobalBin = join8(homedir4(), ".bun", "bin", "context");
2356
+ if (existsSync9(bunGlobalBin)) {
2298
2357
  installs.push({ pm: "bun", label: "bun global", installCmd: ["bun", "install", "-g"] });
2299
2358
  }
2300
2359
  const spawnSync = globalThis.Bun?.spawnSync;
@@ -2347,22 +2406,22 @@ function runUpdatePlugin(version) {
2347
2406
  }
2348
2407
 
2349
2408
  // src/cli/commands/migrate.ts
2350
- import { resolve as resolve4, join as join8 } from "path";
2351
- import { existsSync as existsSync9, cpSync, rmSync, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
2409
+ import { resolve as resolve4, join as join9 } from "path";
2410
+ import { existsSync as existsSync10, cpSync, rmSync, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
2352
2411
  var LEGACY_CONTEXT_DIR = ".opencode/context";
2353
2412
  var NEW_CONTEXT_DIR = ".context";
2354
2413
  function runMigrate(args) {
2355
2414
  const keepFlag = args.includes("--keep");
2356
2415
  const pathArg = args.find((a) => !a.startsWith("--"));
2357
2416
  const projectDir = resolve4(pathArg ?? process.cwd());
2358
- const legacyDir = join8(projectDir, LEGACY_CONTEXT_DIR);
2359
- const newDir = join8(projectDir, NEW_CONTEXT_DIR);
2360
- if (!existsSync9(legacyDir)) {
2417
+ const legacyDir = join9(projectDir, LEGACY_CONTEXT_DIR);
2418
+ const newDir = join9(projectDir, NEW_CONTEXT_DIR);
2419
+ if (!existsSync10(legacyDir)) {
2361
2420
  process.stdout.write(`Nothing to migrate.
2362
2421
  `);
2363
2422
  return;
2364
2423
  }
2365
- if (existsSync9(newDir)) {
2424
+ if (existsSync10(newDir)) {
2366
2425
  process.stderr.write(`Target .context/ already exists. Aborting.
2367
2426
  `);
2368
2427
  process.exit(1);
@@ -2377,14 +2436,14 @@ function runMigrate(args) {
2377
2436
  `);
2378
2437
  }
2379
2438
  function updateConfigPaths(contextDir) {
2380
- const configPath = join8(contextDir, "config.jsonc");
2381
- if (!existsSync9(configPath))
2439
+ const configPath = join9(contextDir, "config.jsonc");
2440
+ if (!existsSync10(configPath))
2382
2441
  return;
2383
2442
  try {
2384
- const content = readFileSync5(configPath, "utf-8");
2443
+ const content = readFileSync6(configPath, "utf-8");
2385
2444
  const updated = content.replaceAll(".opencode/context/", "");
2386
2445
  if (updated !== content) {
2387
- writeFileSync5(configPath, updated, "utf-8");
2446
+ writeFileSync6(configPath, updated, "utf-8");
2388
2447
  }
2389
2448
  } catch {}
2390
2449
  }
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ import { join as join2 } from "path";
25
25
  // package.json
26
26
  var package_default = {
27
27
  name: "@ksm0709/context",
28
- version: "0.0.33",
28
+ version: "0.0.35",
29
29
  author: {
30
30
  name: "TaehoKang",
31
31
  email: "ksm07091@gmail.com"
@@ -67,24 +67,23 @@ var package_default = {
67
67
  "@opencode-ai/plugin": ">=1.0.0"
68
68
  },
69
69
  dependencies: {
70
- "@ksm0709/context": "^0.0.33",
71
70
  "@modelcontextprotocol/sdk": "^1.27.1",
72
71
  "jsonc-parser": "^3.0.0"
73
72
  },
74
73
  devDependencies: {
75
- "@opencode-ai/plugin": "^1.2.10",
76
74
  "@eslint/js": "^9.39.1",
75
+ "@opencode-ai/plugin": "^1.2.10",
77
76
  "@types/node": "^20.11.5",
78
77
  "@typescript-eslint/eslint-plugin": "8.47.0",
79
78
  "@typescript-eslint/parser": "8.47.0",
79
+ "@vitest/coverage-v8": "^3.2.4",
80
80
  "bun-types": "latest",
81
81
  eslint: "^9.39.1",
82
82
  "eslint-config-prettier": "10.1.8",
83
83
  "eslint-plugin-prettier": "^5.1.3",
84
84
  prettier: "^3.2.4",
85
85
  "typescript-eslint": "^8.47.0",
86
- vitest: "^3.2.4",
87
- "@vitest/coverage-v8": "^3.2.4"
86
+ vitest: "^3.2.4"
88
87
  }
89
88
  };
90
89