depwire-cli 0.9.22 → 0.9.24

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.
@@ -445,6 +445,16 @@ async function connectToRepo(source, subdirectory, state) {
445
445
  }
446
446
  }
447
447
  projectRoot = subdirectory ? join3(cloneDir, subdirectory) : cloneDir;
448
+ if (subdirectory) {
449
+ const resolvedRoot = resolve(cloneDir);
450
+ const resolvedProject = resolve(projectRoot);
451
+ if (!resolvedProject.startsWith(resolvedRoot + "/") && resolvedProject !== resolvedRoot) {
452
+ return {
453
+ error: "Access denied",
454
+ message: "Subdirectory must be within the project root"
455
+ };
456
+ }
457
+ }
448
458
  } else {
449
459
  const validation2 = validateProjectPath(source);
450
460
  if (!validation2.valid) {
@@ -460,6 +470,16 @@ async function connectToRepo(source, subdirectory, state) {
460
470
  };
461
471
  }
462
472
  projectRoot = subdirectory ? join3(source, subdirectory) : source;
473
+ if (subdirectory) {
474
+ const resolvedRoot = resolve(source);
475
+ const resolvedProject = resolve(projectRoot);
476
+ if (!resolvedProject.startsWith(resolvedRoot + "/") && resolvedProject !== resolvedRoot) {
477
+ return {
478
+ error: "Access denied",
479
+ message: "Subdirectory must be within the project root"
480
+ };
481
+ }
482
+ }
463
483
  projectName = basename2(projectRoot);
464
484
  }
465
485
  const validation = validateProjectPath(projectRoot);
@@ -575,6 +595,9 @@ async function connectToRepo(source, subdirectory, state) {
575
595
  import { execSync } from "child_process";
576
596
  async function getCommitLog(dir, limit) {
577
597
  try {
598
+ if (limit !== void 0 && (!Number.isInteger(limit) || limit < 1)) {
599
+ throw new Error(`Invalid git log limit: ${limit}`);
600
+ }
578
601
  const limitArg = limit ? `-n ${limit}` : "";
579
602
  const output = execSync(
580
603
  `git log ${limitArg} --pretty=format:"%H|%aI|%s|%an"`,
@@ -602,6 +625,9 @@ async function getCurrentBranch(dir) {
602
625
  }
603
626
  }
604
627
  async function checkoutCommit(dir, hash) {
628
+ if (!/^[a-zA-Z0-9_.\-\/]+$/.test(hash)) {
629
+ throw new Error(`Invalid git ref: ${hash}`);
630
+ }
605
631
  try {
606
632
  execSync(`git checkout -q ${hash}`, { cwd: dir, stdio: "ignore" });
607
633
  } catch (error) {
@@ -609,6 +635,9 @@ async function checkoutCommit(dir, hash) {
609
635
  }
610
636
  }
611
637
  async function restoreOriginal(dir, originalBranch) {
638
+ if (!/^[a-zA-Z0-9_.\-\/]+$/.test(originalBranch)) {
639
+ throw new Error(`Invalid git ref: ${originalBranch}`);
640
+ }
612
641
  try {
613
642
  execSync(`git checkout -q ${originalBranch}`, {
614
643
  cwd: dir,
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  stashChanges,
18
18
  updateFileInGraph,
19
19
  watchProject
20
- } from "./chunk-XBCQPU63.js";
20
+ } from "./chunk-ORGAO3HT.js";
21
21
  import {
22
22
  SimulationEngine,
23
23
  analyzeDeadCode,
@@ -4,7 +4,7 @@ import {
4
4
  startMcpServer,
5
5
  updateFileInGraph,
6
6
  watchProject
7
- } from "./chunk-XBCQPU63.js";
7
+ } from "./chunk-ORGAO3HT.js";
8
8
  import {
9
9
  buildGraph,
10
10
  parseProject
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "depwire-cli",
3
- "version": "0.9.22",
4
- "description": "The missing context layer for AI coding assistants. Dependency graph, MCP server, architecture health, dead code detection.",
3
+ "version": "0.9.24",
4
+ "description": "Dependency graph + 16 MCP tools for AI coding assistants. Impact analysis, health scoring, visualization.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "depwire": "dist/index.js"