@bike4mind/cli 0.2.31-b4m-cli-undo-command.19534 → 0.2.31-b4m-cli-undo-command.19535

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.
@@ -3,7 +3,7 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@bike4mind/cli",
6
- version: "0.2.31-b4m-cli-undo-command.19534+db45140bb",
6
+ version: "0.2.31-b4m-cli-undo-command.19535+040263f1d",
7
7
  type: "module",
8
8
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
9
9
  license: "UNLICENSED",
@@ -114,10 +114,10 @@ var package_default = {
114
114
  },
115
115
  devDependencies: {
116
116
  "@bike4mind/agents": "0.1.0",
117
- "@bike4mind/common": "2.52.1-b4m-cli-undo-command.19534+db45140bb",
118
- "@bike4mind/mcp": "1.31.1-b4m-cli-undo-command.19534+db45140bb",
119
- "@bike4mind/services": "2.50.1-b4m-cli-undo-command.19534+db45140bb",
120
- "@bike4mind/utils": "2.7.1-b4m-cli-undo-command.19534+db45140bb",
117
+ "@bike4mind/common": "2.52.1-b4m-cli-undo-command.19535+040263f1d",
118
+ "@bike4mind/mcp": "1.31.1-b4m-cli-undo-command.19535+040263f1d",
119
+ "@bike4mind/services": "2.50.1-b4m-cli-undo-command.19535+040263f1d",
120
+ "@bike4mind/utils": "2.7.1-b4m-cli-undo-command.19535+040263f1d",
121
121
  "@types/better-sqlite3": "^7.6.13",
122
122
  "@types/diff": "^5.0.9",
123
123
  "@types/jsonwebtoken": "^9.0.4",
@@ -138,7 +138,7 @@ var package_default = {
138
138
  optionalDependencies: {
139
139
  "@vscode/ripgrep": "^1.17.0"
140
140
  },
141
- gitHead: "db45140bb943bbc4dbccd53c99a8e305cb792d88"
141
+ gitHead: "040263f1d1bb68be464392da9dc0129ea349940d"
142
142
  };
143
143
 
144
144
  // src/utils/updateChecker.ts
@@ -3,7 +3,7 @@ import {
3
3
  fetchLatestVersion,
4
4
  forceCheckForUpdate,
5
5
  package_default
6
- } from "../chunk-WVFOWKNW.js";
6
+ } from "../chunk-M2QCFHVX.js";
7
7
 
8
8
  // src/commands/doctorCommand.ts
9
9
  import { execSync } from "child_process";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  forceCheckForUpdate,
4
4
  package_default
5
- } from "../chunk-WVFOWKNW.js";
5
+ } from "../chunk-M2QCFHVX.js";
6
6
 
7
7
  // src/commands/updateCommand.ts
8
8
  import { execSync } from "child_process";
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  import {
17
17
  checkForUpdate,
18
18
  package_default
19
- } from "./chunk-WVFOWKNW.js";
19
+ } from "./chunk-M2QCFHVX.js";
20
20
  import {
21
21
  selectActiveBackgroundAgents,
22
22
  useCliStore
@@ -2912,13 +2912,16 @@ var CheckpointStore = class {
2912
2912
  try {
2913
2913
  let hasChanges = false;
2914
2914
  for (const filePath of filePaths) {
2915
- const absolutePath = path6.resolve(this.projectDir, filePath);
2915
+ const absolutePath = this.validatePathWithinProject(filePath);
2916
2916
  const shadowPath = path6.join(this.shadowRepoDir, filePath);
2917
2917
  const shadowDir = path6.dirname(shadowPath);
2918
2918
  const absentMarkerPath = path6.join(shadowDir, `${path6.basename(filePath)}${ABSENT_MARKER}`);
2919
2919
  await fs5.mkdir(shadowDir, { recursive: true });
2920
2920
  if (existsSync4(absolutePath)) {
2921
- const stats = await fs5.stat(absolutePath);
2921
+ const stats = await fs5.lstat(absolutePath);
2922
+ if (stats.isSymbolicLink()) {
2923
+ continue;
2924
+ }
2922
2925
  if (stats.size > MAX_FILE_SIZE2) {
2923
2926
  continue;
2924
2927
  }
@@ -2995,7 +2998,7 @@ var CheckpointStore = class {
2995
2998
  throw new Error(`Checkpoint #${index} not found. Use /checkpoints to see available restore points.`);
2996
2999
  }
2997
3000
  for (const filePath of checkpoint.filePaths) {
2998
- const absolutePath = path6.resolve(this.projectDir, filePath);
3001
+ const absolutePath = this.validatePathWithinProject(filePath);
2999
3002
  try {
3000
3003
  const content = this.git("show", `${checkpoint.id}:${filePath}`);
3001
3004
  await fs5.mkdir(path6.dirname(absolutePath), { recursive: true });
@@ -3031,7 +3034,9 @@ var CheckpointStore = class {
3031
3034
  }
3032
3035
  const diffParts = [];
3033
3036
  for (const filePath of checkpoint.filePaths) {
3034
- const absolutePath = path6.resolve(this.projectDir, filePath);
3037
+ const absolutePath = this.validatePathWithinProject(filePath);
3038
+ const tmpCheckpoint = path6.join(this.shadowRepoDir, ".diff-a");
3039
+ const tmpCurrent = path6.join(this.shadowRepoDir, ".diff-b");
3035
3040
  try {
3036
3041
  let checkpointContent;
3037
3042
  try {
@@ -3046,8 +3051,6 @@ var CheckpointStore = class {
3046
3051
  if (checkpointContent === currentContent) {
3047
3052
  continue;
3048
3053
  }
3049
- const tmpCheckpoint = path6.join(this.shadowRepoDir, ".diff-a");
3050
- const tmpCurrent = path6.join(this.shadowRepoDir, ".diff-b");
3051
3054
  writeFileSync(tmpCheckpoint, checkpointContent, "utf-8");
3052
3055
  writeFileSync(tmpCurrent, currentContent, "utf-8");
3053
3056
  try {
@@ -3070,12 +3073,16 @@ ${output}`);
3070
3073
  }
3071
3074
  }
3072
3075
  }
3076
+ } catch {
3077
+ } finally {
3073
3078
  try {
3074
3079
  unlinkSync(tmpCheckpoint);
3080
+ } catch {
3081
+ }
3082
+ try {
3075
3083
  unlinkSync(tmpCurrent);
3076
3084
  } catch {
3077
3085
  }
3078
- } catch {
3079
3086
  }
3080
3087
  }
3081
3088
  return diffParts.join("\n");
@@ -3109,6 +3116,18 @@ ${output}`);
3109
3116
  }
3110
3117
  }
3111
3118
  // --- Private helpers ---
3119
+ /**
3120
+ * Validate that a file path resolves within the project directory.
3121
+ * Prevents path traversal attacks (e.g., ../../etc/passwd).
3122
+ */
3123
+ validatePathWithinProject(filePath) {
3124
+ const absolutePath = path6.resolve(this.projectDir, filePath);
3125
+ const normalizedProject = path6.resolve(this.projectDir) + path6.sep;
3126
+ if (!absolutePath.startsWith(normalizedProject) && absolutePath !== path6.resolve(this.projectDir)) {
3127
+ throw new Error(`Path traversal detected: ${filePath}`);
3128
+ }
3129
+ return absolutePath;
3130
+ }
3112
3131
  /**
3113
3132
  * Execute a git command in the shadow repo
3114
3133
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.2.31-b4m-cli-undo-command.19534+db45140bb",
3
+ "version": "0.2.31-b4m-cli-undo-command.19535+040263f1d",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -111,10 +111,10 @@
111
111
  },
112
112
  "devDependencies": {
113
113
  "@bike4mind/agents": "0.1.0",
114
- "@bike4mind/common": "2.52.1-b4m-cli-undo-command.19534+db45140bb",
115
- "@bike4mind/mcp": "1.31.1-b4m-cli-undo-command.19534+db45140bb",
116
- "@bike4mind/services": "2.50.1-b4m-cli-undo-command.19534+db45140bb",
117
- "@bike4mind/utils": "2.7.1-b4m-cli-undo-command.19534+db45140bb",
114
+ "@bike4mind/common": "2.52.1-b4m-cli-undo-command.19535+040263f1d",
115
+ "@bike4mind/mcp": "1.31.1-b4m-cli-undo-command.19535+040263f1d",
116
+ "@bike4mind/services": "2.50.1-b4m-cli-undo-command.19535+040263f1d",
117
+ "@bike4mind/utils": "2.7.1-b4m-cli-undo-command.19535+040263f1d",
118
118
  "@types/better-sqlite3": "^7.6.13",
119
119
  "@types/diff": "^5.0.9",
120
120
  "@types/jsonwebtoken": "^9.0.4",
@@ -135,5 +135,5 @@
135
135
  "optionalDependencies": {
136
136
  "@vscode/ripgrep": "^1.17.0"
137
137
  },
138
- "gitHead": "db45140bb943bbc4dbccd53c99a8e305cb792d88"
138
+ "gitHead": "040263f1d1bb68be464392da9dc0129ea349940d"
139
139
  }