@hienlh/ppm 0.7.12 → 0.7.14

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.14] - 2026-03-21
4
+
5
+ ### Fixed
6
+ - **Explorer .env access**: removed hardcoded `.env` block from file tree, directory browser, and file read/write — `.env` files are now visible and editable like any other file
7
+
8
+ ## [0.7.13] - 2026-03-20
9
+
10
+ ### Fixed
11
+ - **Account decrypt crash on different machine**: `getWithTokens` now catches decrypt errors (mismatched `account.key`) and returns `null` instead of crashing the API
12
+
3
13
  ## [0.7.12] - 2026-03-20
4
14
 
5
15
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.7.12",
3
+ "version": "0.7.14",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "author": "hienlh",
6
6
  "license": "MIT",
@@ -66,7 +66,13 @@ class AccountService {
66
66
 
67
67
  getWithTokens(id: string): AccountWithTokens | null {
68
68
  const row = getAccountById(id);
69
- return row ? this.toAccountWithTokens(row) : null;
69
+ if (!row) return null;
70
+ try {
71
+ return this.toAccountWithTokens(row);
72
+ } catch (e) {
73
+ console.error(`[accounts] Failed to decrypt tokens for ${row.label ?? id}:`, (e as Error).message);
74
+ return null;
75
+ }
70
76
  }
71
77
 
72
78
  add(params: {
@@ -13,7 +13,7 @@ import { resolve, relative, basename, dirname, join, normalize } from "node:path
13
13
  import type { FileNode } from "../types/project.ts";
14
14
 
15
15
  /** Directories/files excluded from tree listing */
16
- const EXCLUDED_NAMES = new Set([".git", "node_modules", ".env"]);
16
+ const EXCLUDED_NAMES = new Set([".git", "node_modules"]);
17
17
 
18
18
  /** Max buffer size for binary detection (first 8KB) */
19
19
  const BINARY_CHECK_BYTES = 8192;
@@ -64,8 +64,6 @@ class FileService {
64
64
 
65
65
  for (const entry of entries) {
66
66
  if (this.isExcluded(entry.name)) continue;
67
- // Skip hidden files at root level (like .env.local etc.)
68
- if (entry.name.startsWith(".env")) continue;
69
67
 
70
68
  const fullPath = join(dirPath, entry.name);
71
69
  const relPath = relative(rootPath, fullPath);
@@ -219,7 +217,7 @@ class FileService {
219
217
  this.renameFile(projectPath, source, destination);
220
218
  }
221
219
 
222
- /** Block access to sensitive paths (.git/, .env*) */
220
+ /** Block access to sensitive paths (.git/) */
223
221
  private blockSensitive(filePath: string): void {
224
222
  const normalized = normalize(filePath);
225
223
  const parts = normalized.split("/");
@@ -228,11 +226,6 @@ class FileService {
228
226
  throw new SecurityError(`Access denied: ${filePath}`);
229
227
  }
230
228
  }
231
- // Block .env files
232
- const file = basename(normalized);
233
- if (file.startsWith(".env")) {
234
- throw new SecurityError(`Access denied: ${filePath}`);
235
- }
236
229
  }
237
230
  }
238
231
 
@@ -88,7 +88,6 @@ export function browse(
88
88
 
89
89
  for (const entry of raw) {
90
90
  if (!options?.showHidden && entry.name.startsWith(".")) continue;
91
- if (entry.name.startsWith(".env")) continue; // always hide .env*
92
91
 
93
92
  const fullPath = resolve(resolved, entry.name);
94
93
  try {