@liendev/lien 0.37.0 → 0.38.0

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/index.js CHANGED
@@ -4022,7 +4022,7 @@ async function indexCommand(options) {
4022
4022
  // src/cli/serve.ts
4023
4023
  import chalk6 from "chalk";
4024
4024
  import fs5 from "fs/promises";
4025
- import path4 from "path";
4025
+ import path7 from "path";
4026
4026
 
4027
4027
  // src/mcp/server.ts
4028
4028
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -4930,8 +4930,8 @@ function getErrorMap() {
4930
4930
 
4931
4931
  // ../../node_modules/zod/v3/helpers/parseUtil.js
4932
4932
  var makeIssue = (params) => {
4933
- const { data, path: path7, errorMaps, issueData } = params;
4934
- const fullPath = [...path7, ...issueData.path || []];
4933
+ const { data, path: path10, errorMaps, issueData } = params;
4934
+ const fullPath = [...path10, ...issueData.path || []];
4935
4935
  const fullIssue = {
4936
4936
  ...issueData,
4937
4937
  path: fullPath
@@ -5047,11 +5047,11 @@ var errorUtil;
5047
5047
 
5048
5048
  // ../../node_modules/zod/v3/types.js
5049
5049
  var ParseInputLazyPath = class {
5050
- constructor(parent, value, path7, key) {
5050
+ constructor(parent, value, path10, key) {
5051
5051
  this._cachedPath = [];
5052
5052
  this.parent = parent;
5053
5053
  this.data = value;
5054
- this._path = path7;
5054
+ this._path = path10;
5055
5055
  this._key = key;
5056
5056
  }
5057
5057
  get path() {
@@ -8524,10 +8524,15 @@ var FindSimilarSchema = external_exports.object({
8524
8524
  });
8525
8525
 
8526
8526
  // src/mcp/schemas/file.schema.ts
8527
+ import path4 from "path";
8528
+ var safeFilepath = external_exports.string().min(1, "Filepath cannot be empty").max(1e3).refine((p) => {
8529
+ const normalized = p.replace(/\\/g, "/");
8530
+ return !path4.isAbsolute(normalized) && !normalized.split("/").includes("..");
8531
+ }, 'Path must be relative and cannot contain ".." traversal');
8527
8532
  var GetFilesContextSchema = external_exports.object({
8528
8533
  filepaths: external_exports.union([
8529
- external_exports.string().min(1, "Filepath cannot be empty").max(1e3),
8530
- external_exports.array(external_exports.string().min(1, "Filepath cannot be empty").max(1e3)).min(1, "Array must contain at least one filepath").max(50, "Maximum 50 files per request")
8534
+ safeFilepath,
8535
+ external_exports.array(safeFilepath).min(1, "Array must contain at least one filepath").max(50, "Maximum 50 files per request")
8531
8536
  ]).describe(
8532
8537
  "Single filepath or array of filepaths (relative to workspace root).\n\nSingle file: 'src/components/Button.tsx'\nMultiple files: ['src/auth.ts', 'src/user.ts']\n\nMaximum 50 files per request for batch operations."
8533
8538
  ),
@@ -8554,8 +8559,12 @@ var ListFunctionsSchema = external_exports.object({
8554
8559
  });
8555
8560
 
8556
8561
  // src/mcp/schemas/dependents.schema.ts
8562
+ import path5 from "path";
8557
8563
  var GetDependentsSchema = external_exports.object({
8558
- filepath: external_exports.string().min(1, "Filepath cannot be empty").max(1e3).describe(
8564
+ filepath: external_exports.string().min(1, "Filepath cannot be empty").max(1e3).refine((p) => {
8565
+ const normalized = p.replace(/\\/g, "/");
8566
+ return !path5.isAbsolute(normalized) && !normalized.split("/").includes("..");
8567
+ }, 'Path must be relative and cannot contain ".." traversal').describe(
8559
8568
  "Path to file to find dependents for (relative to workspace root).\n\nExample: 'src/utils/validate.ts'\n\nReturns all files that import or depend on this file.\n\nNote: Scans up to 10,000 code chunks. For very large codebases,\nresults may be incomplete (a warning will be included if truncated)."
8560
8569
  ),
8561
8570
  symbol: external_exports.string().min(1, "Symbol cannot be an empty string").max(500).optional().describe(
@@ -8570,8 +8579,14 @@ var GetDependentsSchema = external_exports.object({
8570
8579
  });
8571
8580
 
8572
8581
  // src/mcp/schemas/complexity.schema.ts
8582
+ import path6 from "path";
8573
8583
  var GetComplexitySchema = external_exports.object({
8574
- files: external_exports.array(external_exports.string().min(1, "Filepath cannot be empty").max(1e3)).optional().describe(
8584
+ files: external_exports.array(
8585
+ external_exports.string().min(1, "Filepath cannot be empty").max(1e3).refine((p) => {
8586
+ const normalized = p.replace(/\\/g, "/");
8587
+ return !path6.isAbsolute(normalized) && !normalized.split("/").includes("..");
8588
+ }, 'Path must be relative and cannot contain ".." traversal')
8589
+ ).optional().describe(
8575
8590
  "Specific files to analyze. If omitted, analyzes entire codebase.\n\nExample: ['src/auth.ts', 'src/api/user.ts']"
8576
8591
  ),
8577
8592
  top: external_exports.number().int().min(1, "Top must be at least 1").max(50, "Top cannot exceed 50").default(10).describe(
@@ -9091,7 +9106,7 @@ async function handleSemanticSearch(args, ctx) {
9091
9106
  const shaped = shapeResults(results, "semantic_search");
9092
9107
  if (shaped.length === 0) {
9093
9108
  notes.push(
9094
- '0 results. Try rephrasing as a full question (e.g. "How does X work?"), or use grep for exact string matches. If the codebase was recently updated, run "lien reindex".'
9109
+ '0 results. Try rephrasing as a full question (e.g. "How does X work?"), or use grep for exact string matches. If the codebase was recently updated, run "lien index".'
9095
9110
  );
9096
9111
  }
9097
9112
  return {
@@ -9209,10 +9224,10 @@ async function findRelatedChunks(filepaths, fileChunksMap, ctx) {
9209
9224
  }
9210
9225
  function createPathCache(workspaceRoot) {
9211
9226
  const cache = /* @__PURE__ */ new Map();
9212
- const normalize = (path7) => {
9213
- if (cache.has(path7)) return cache.get(path7);
9214
- const normalized = normalizePath(path7, workspaceRoot);
9215
- cache.set(path7, normalized);
9227
+ const normalize = (path10) => {
9228
+ if (cache.has(path10)) return cache.get(path10);
9229
+ const normalized = normalizePath(path10, workspaceRoot);
9230
+ cache.set(path10, normalized);
9216
9231
  return normalized;
9217
9232
  };
9218
9233
  return { normalize, cache };
@@ -9400,7 +9415,7 @@ async function handleListFunctions(args, ctx) {
9400
9415
  );
9401
9416
  }
9402
9417
  if (queryResult.method === "content") {
9403
- notes.push('Using content search. Run "lien reindex" to enable faster symbol-based queries.');
9418
+ notes.push('Using content search. Run "lien index" to enable faster symbol-based queries.');
9404
9419
  }
9405
9420
  return {
9406
9421
  indexInfo: getIndexMetadata(),
@@ -9587,11 +9602,11 @@ async function scanChunksPaginated(vectorDB, crossRepo, log, normalizePathCached
9587
9602
  function createPathNormalizer() {
9588
9603
  const workspaceRoot = process.cwd().replace(/\\/g, "/");
9589
9604
  const cache = /* @__PURE__ */ new Map();
9590
- return (path7) => {
9591
- if (!cache.has(path7)) {
9592
- cache.set(path7, normalizePath2(path7, workspaceRoot));
9605
+ return (path10) => {
9606
+ if (!cache.has(path10)) {
9607
+ cache.set(path10, normalizePath2(path10, workspaceRoot));
9593
9608
  }
9594
- return cache.get(path7);
9609
+ return cache.get(path10);
9595
9610
  };
9596
9611
  }
9597
9612
  function groupChunksByFile(chunks) {
@@ -11067,7 +11082,7 @@ async function startMCPServer(options) {
11067
11082
  // src/cli/serve.ts
11068
11083
  init_banner();
11069
11084
  async function serveCommand(options) {
11070
- const rootDir = options.root ? path4.resolve(options.root) : process.cwd();
11085
+ const rootDir = options.root ? path7.resolve(options.root) : process.cwd();
11071
11086
  try {
11072
11087
  if (options.root) {
11073
11088
  try {
@@ -11113,7 +11128,7 @@ async function serveCommand(options) {
11113
11128
  // src/cli/complexity.ts
11114
11129
  import chalk7 from "chalk";
11115
11130
  import fs6 from "fs";
11116
- import path5 from "path";
11131
+ import path8 from "path";
11117
11132
  import { VectorDB } from "@liendev/core";
11118
11133
  import { ComplexityAnalyzer as ComplexityAnalyzer2 } from "@liendev/core";
11119
11134
  import { formatReport } from "@liendev/core";
@@ -11138,7 +11153,7 @@ function validateFormat(format) {
11138
11153
  function validateFilesExist(files, rootDir) {
11139
11154
  if (!files || files.length === 0) return;
11140
11155
  const missingFiles = files.filter((file) => {
11141
- const fullPath = path5.isAbsolute(file) ? file : path5.join(rootDir, file);
11156
+ const fullPath = path8.isAbsolute(file) ? file : path8.join(rootDir, file);
11142
11157
  return !fs6.existsSync(fullPath);
11143
11158
  });
11144
11159
  if (missingFiles.length > 0) {
@@ -11184,10 +11199,10 @@ async function complexityCommand(options) {
11184
11199
 
11185
11200
  // src/cli/config.ts
11186
11201
  import chalk8 from "chalk";
11187
- import path6 from "path";
11202
+ import path9 from "path";
11188
11203
  import os2 from "os";
11189
11204
  import { loadGlobalConfig, mergeGlobalConfig } from "@liendev/core";
11190
- var CONFIG_PATH = path6.join(os2.homedir(), ".lien", "config.json");
11205
+ var CONFIG_PATH = path9.join(os2.homedir(), ".lien", "config.json");
11191
11206
  var ALLOWED_KEYS = {
11192
11207
  backend: {
11193
11208
  values: ["lancedb", "qdrant"],