|
2 | 2 | * Plugin Discovery Module |
3 | 3 | * |
4 | 4 | * Discovers OpenCode plugins from two locations (priority: last wins): |
5 | | - * 1. Global: npm global prefix (npm install -g) |
| 5 | + * 1. User config: ~/.config/opencode/node_modules/ |
6 | 6 | * 2. Local: {targetDir}/node_modules/ |
7 | 7 | * |
8 | 8 | * Each location can contain two types of packages: |
|
13 | 13 | import fs from 'fs'; |
14 | 14 | import os from 'os'; |
15 | 15 | import path from 'path'; |
16 | | -import { execSync } from 'child_process'; |
17 | 16 |
|
18 | 17 | /** |
19 | | - * Gets the npm global prefix directory. |
20 | | - * This is where `npm install -g` installs packages. |
| 18 | + * Gets the user config directory for OpenCode plugins. |
| 19 | + * This is where user-level plugins are installed. |
21 | 20 | * |
22 | | - * @returns {string|null} Path to npm global prefix or null if not determinable |
| 21 | + * @returns {string} Path to ~/.config/opencode/node_modules |
23 | 22 | */ |
24 | | -function getGlobalDir() { |
25 | | - try { |
26 | | - const prefix = execSync('npm config get prefix', { encoding: 'utf-8' }).trim(); |
27 | | - return path.join(prefix, 'lib', 'node_modules'); |
28 | | - } catch { |
29 | | - return null; |
30 | | - } |
| 23 | +function getUserConfigDir() { |
| 24 | + return path.join(os.homedir(), '.config', 'opencode', 'node_modules'); |
31 | 25 | } |
32 | 26 |
|
33 | 27 | /** |
34 | 28 | * Discovers all available plugins from all locations. |
35 | 29 | * |
36 | 30 | * Priority (last wins): |
37 | | - * 1. Global: npm global prefix (npm install -g) |
| 31 | + * 1. User config: ~/.config/opencode/node_modules/ |
38 | 32 | * 2. Local: {targetDir}/node_modules/ |
39 | 33 | * |
40 | 34 | * @param {string} targetDir - The .opencode directory (e.g., /project/.opencode) |
41 | 35 | * @returns {Map<string, PluginDescriptor>} Map of plugin name to descriptor |
42 | 36 | */ |
43 | 37 | export function discoverPlugins(targetDir) { |
44 | | - const globalDir = getGlobalDir(); |
| 38 | + const userConfigDir = getUserConfigDir(); |
45 | 39 |
|
46 | 40 | // Scan all locations (order matters: last wins) |
47 | 41 | const allPlugins = new Map(); |
48 | 42 |
|
49 | | - // 1. Global (lowest priority) |
50 | | - if (globalDir) { |
51 | | - const globalPlugins = scanLocation(globalDir, 'global'); |
52 | | - for (const [name, descriptor] of globalPlugins.entries()) { |
53 | | - allPlugins.set(name, descriptor); |
54 | | - } |
| 43 | + // 1. User config (lower priority) |
| 44 | + const userPlugins = scanLocation(userConfigDir, 'user'); |
| 45 | + for (const [name, descriptor] of userPlugins.entries()) { |
| 46 | + allPlugins.set(name, descriptor); |
55 | 47 | } |
56 | 48 |
|
57 | 49 | // 2. Local (highest priority) |
58 | 50 | const localPlugins = scanLocation(path.join(targetDir, 'node_modules'), 'local'); |
59 | 51 | for (const [name, descriptor] of localPlugins.entries()) { |
60 | 52 | if (allPlugins.has(name)) { |
61 | | - console.log(` ⚠️ Plugin "${name}" found in local, overrides global`); |
| 53 | + console.log(` ⚠️ Plugin "${name}" found in local, overrides user`); |
62 | 54 | } |
63 | 55 | allPlugins.set(name, descriptor); |
64 | 56 | } |
|
0 commit comments