obsidian-plugin-config 1.6.5 โ†’ 1.6.7

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.
@@ -41,6 +41,14 @@
41
41
  "presentation": { "reveal": "always", "panel": "shared" },
42
42
  "problemMatcher": []
43
43
  },
44
+ {
45
+ "label": "Check Global CLI Version",
46
+ "type": "shell",
47
+ "command": "npm list -g obsidian-plugin-config --depth=0",
48
+ "group": "build",
49
+ "presentation": { "reveal": "always", "panel": "shared" },
50
+ "problemMatcher": []
51
+ },
44
52
  {
45
53
  "label": "NPM Publish",
46
54
  "type": "shell",
@@ -0,0 +1,82 @@
1
+ # Windows node_modules Cleanup Problem
2
+
3
+ ## Issue
4
+ Injection fails on Windows with EPERM error when Yarn tries to install dependencies:
5
+ ```
6
+ error Error: EPERM: operation not permitted, unlink 'C:\...\node_modules\@esbuild\win32-x64\esbuild.exe'
7
+ ```
8
+
9
+ ## Root Cause
10
+ 1. Script reports "๐Ÿ—‘๏ธ Removed node_modules" but `rmdir /s /q` fails silently on locked .exe files
11
+ 2. node_modules remains partially present with corrupted/locked files
12
+ 3. Yarn tries to reuse this corrupted node_modules and fails
13
+
14
+ ## Current Code (inject-core.ts, ~line 680)
15
+ ```typescript
16
+ if (fs.existsSync(nodeModulesPath)) {
17
+ console.log(` โณ Removing node_modules (this may take a moment)...`);
18
+ try {
19
+ execSync(`rmdir /s /q "${nodeModulesPath}"`, {
20
+ stdio: 'pipe',
21
+ windowsHide: true
22
+ });
23
+ console.log(` ๐Ÿ—‘๏ธ Removed node_modules (will be reinstalled with Yarn)`);
24
+ } catch {
25
+ // Rename fallback - BUT THIS NEVER EXECUTES because rmdir doesn't throw!
26
+ try {
27
+ const timestamp = Date.now();
28
+ const oldPath = `${nodeModulesPath}.old.${timestamp}`;
29
+ fs.renameSync(nodeModulesPath, oldPath);
30
+ console.log(` ๐Ÿ”„ Renamed locked node_modules to ${path.basename(oldPath)}`);
31
+ } catch {
32
+ console.log(` โš ๏ธ Could not remove/rename node_modules`);
33
+ throw new Error('node_modules locked - close processes and retry');
34
+ }
35
+ }
36
+ }
37
+ ```
38
+
39
+ ## Problem
40
+ `execSync('rmdir /s /q ...')` with `stdio: 'pipe'` does NOT throw an exception when it fails to delete locked files. It exits with code 0 even though files remain.
41
+
42
+ ## Required Fix
43
+ After `rmdir` command, CHECK if node_modules still exists. If yes, execute the rename fallback:
44
+
45
+ ```typescript
46
+ if (fs.existsSync(nodeModulesPath)) {
47
+ console.log(` โณ Removing node_modules (this may take a moment)...`);
48
+
49
+ // Try to remove
50
+ execSync(`rmdir /s /q "${nodeModulesPath}"`, {
51
+ stdio: 'pipe',
52
+ windowsHide: true
53
+ });
54
+
55
+ // CHECK if it actually worked
56
+ if (fs.existsSync(nodeModulesPath)) {
57
+ // rmdir failed silently - rename instead
58
+ const timestamp = Date.now();
59
+ const oldPath = `${nodeModulesPath}.old.${timestamp}`;
60
+ try {
61
+ fs.renameSync(nodeModulesPath, oldPath);
62
+ console.log(` ๐Ÿ”„ Renamed locked node_modules to ${path.basename(oldPath)}`);
63
+ console.log(` ๐Ÿ’ก Delete it manually later: ${oldPath}`);
64
+ } catch {
65
+ console.log(` โš ๏ธ Could not remove/rename node_modules (locked by processes)`);
66
+ console.log(` ๐Ÿ’ก Close Obsidian/VSCode and run: obsidian-inject again`);
67
+ throw new Error('node_modules locked - close processes and retry');
68
+ }
69
+ } else {
70
+ console.log(` ๐Ÿ—‘๏ธ Removed node_modules (will be reinstalled with Yarn)`);
71
+ }
72
+ }
73
+ ```
74
+
75
+ ## File to Fix
76
+ `scripts/inject-core.ts` - function `cleanNpmArtifactsIfNeeded` (around line 680-730)
77
+
78
+ ## Test Case
79
+ User runs `obsidian-inject` while VSCode is open on the plugin directory. The esbuild.exe file is locked by VSCode's TypeScript server.
80
+
81
+ Expected: node_modules gets renamed to node_modules.old.{timestamp}, Yarn creates fresh node_modules
82
+ Actual: rmdir fails silently, Yarn tries to use corrupted node_modules, EPERM error
package/README.md CHANGED
@@ -20,15 +20,24 @@ npm install -g obsidian-plugin-config@latest --force
20
20
  ## Usage (global CLI)
21
21
 
22
22
  ```bash
23
- # Inject in current plugin directory
23
+ # Inject in current plugin directory (with confirmation)
24
24
  obsidian-inject
25
25
 
26
- # Inject by path
26
+ # Inject by path (with confirmation)
27
27
  obsidian-inject ../my-plugin
28
28
 
29
+ # Inject without confirmation
30
+ obsidian-inject ../my-plugin --no
31
+
29
32
  # Inject with SASS support (adds esbuild-sass-plugin)
30
33
  obsidian-inject ../my-plugin --sass
31
34
 
35
+ # Interactive mode (choose what to inject)
36
+ obsidian-inject ../my-plugin --interactive
37
+
38
+ # Use preset
39
+ obsidian-inject ../my-plugin --preset=minimal
40
+
32
41
  # Verification only (no changes)
33
42
  obsidian-inject ../my-plugin --dry-run
34
43
 
@@ -36,6 +45,14 @@ obsidian-inject ../my-plugin --dry-run
36
45
  obsidian-inject --help
37
46
  ```
38
47
 
48
+ ## CLI Options
49
+
50
+ - `--no`, `-n` - Skip confirmation prompts (auto-confirm)
51
+ - `--sass` - Add SASS support (esbuild-sass-plugin)
52
+ - `--interactive`, `-i` - Choose what to inject interactively
53
+ - `--preset=<name>` - Use preset (minimal, scripts-only, config-only)
54
+ - `--dry-run` - Verification only (no changes)
55
+
39
56
  ## What is injected
40
57
 
41
58
  - โœ… **Standalone local scripts**: `esbuild.config.ts`, `acp.ts`,
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * Obsidian Plugin Config - CLI Entry Point
5
5
  * Global command: obsidian-inject
6
- * Version: 1.6.5
6
+ * Version: 1.6.7
7
7
  */
8
8
 
9
9
  import { execSync } from 'child_process';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "obsidian-plugin-config",
3
- "version": "1.6.5",
3
+ "version": "1.6.7",
4
4
  "description": "Global CLI injection tool for Obsidian plugins",
5
5
  "type": "module",
6
6
  "bin": {
@@ -662,35 +662,27 @@ export async function cleanNpmArtifactsIfNeeded(targetPath: string): Promise<voi
662
662
  // Remove node_modules FIRST (before lock files)
663
663
  if (fs.existsSync(nodeModulesPath)) {
664
664
  console.log(` โณ Removing node_modules (this may take a moment)...`);
665
- try {
666
- execSync(`rmdir /s /q "${nodeModulesPath}"`, {
667
- stdio: 'pipe',
668
- windowsHide: true
669
- });
670
- console.log(
671
- ` ๐Ÿ—‘๏ธ Removed node_modules (will be reinstalled with Yarn)`
672
- );
673
- } catch {
674
- // If locked, rename it
665
+
666
+ execSync(`rmdir /s /q "${nodeModulesPath}"`, {
667
+ stdio: 'pipe',
668
+ windowsHide: true
669
+ });
670
+
671
+ if (fs.existsSync(nodeModulesPath)) {
672
+ // rmdir failed silently (locked .exe files) - rename instead
673
+ const timestamp = Date.now();
674
+ const oldPath = `${nodeModulesPath}.old.${timestamp}`;
675
675
  try {
676
- const timestamp = Date.now();
677
- const oldPath = `${nodeModulesPath}.old.${timestamp}`;
678
676
  fs.renameSync(nodeModulesPath, oldPath);
679
- console.log(
680
- ` ๐Ÿ”„ Renamed locked node_modules to ${path.basename(oldPath)}`
681
- );
682
- console.log(
683
- ` ๐Ÿ’ก Delete it manually later: ${oldPath}`
684
- );
677
+ console.log(` ๐Ÿ”„ Renamed locked node_modules to ${path.basename(oldPath)}`);
678
+ console.log(` ๐Ÿ’ก Delete it manually later: ${oldPath}`);
685
679
  } catch {
686
- console.log(
687
- ` โš ๏ธ Could not remove/rename node_modules (locked by processes)`
688
- );
689
- console.log(
690
- ` ๐Ÿ’ก Close Obsidian/VSCode and run: obsidian-inject again`
691
- );
680
+ console.log(` โš ๏ธ Could not remove/rename node_modules (locked by processes)`);
681
+ console.log(` ๐Ÿ’ก Close Obsidian/VSCode and run: obsidian-inject again`);
692
682
  throw new Error('node_modules locked - close processes and retry');
693
683
  }
684
+ } else {
685
+ console.log(` ๐Ÿ—‘๏ธ Removed node_modules (will be reinstalled with Yarn)`);
694
686
  }
695
687
  }
696
688
 
@@ -788,6 +780,26 @@ export async function performInjection(
788
780
 
789
781
  await runYarnInstall(targetPath);
790
782
 
783
+ // Clean up old node_modules if yarn install succeeded
784
+ const oldDirs = fs.readdirSync(targetPath)
785
+ .filter(name => name.startsWith('node_modules.old.'))
786
+ .map(name => path.join(targetPath, name));
787
+
788
+ if (oldDirs.length > 0) {
789
+ console.log(`\n๐Ÿงน Cleaning up old node_modules...`);
790
+ for (const oldDir of oldDirs) {
791
+ try {
792
+ execSync(`rmdir /s /q "${oldDir}"`, {
793
+ stdio: 'pipe',
794
+ windowsHide: true
795
+ });
796
+ console.log(` ๐Ÿ—‘๏ธ Removed ${path.basename(oldDir)}`);
797
+ } catch {
798
+ console.log(` โš ๏ธ Could not remove ${path.basename(oldDir)} (delete manually)`);
799
+ }
800
+ }
801
+ }
802
+
791
803
  console.log(`\n๐Ÿ“ Creating injection info...`);
792
804
  await createInjectionInfo(targetPath);
793
805
 
@@ -49,6 +49,14 @@
49
49
  "presentation": { "reveal": "always", "panel": "shared" },
50
50
  "problemMatcher": []
51
51
  },
52
+ {
53
+ "label": "Obsidian Inject (no confirm)",
54
+ "type": "shell",
55
+ "command": "obsidian-inject --no",
56
+ "group": "build",
57
+ "presentation": { "reveal": "always", "panel": "shared" },
58
+ "problemMatcher": []
59
+ },
52
60
  {
53
61
  "label": "Cleanup: Lint + Prettier + Build",
54
62
  "dependsOrder": "sequence",