coder-config 0.43.19 → 0.43.21

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/lib/constants.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Constants and tool path configurations
3
3
  */
4
4
 
5
- const VERSION = '0.43.19';
5
+ const VERSION = '0.43.21';
6
6
 
7
7
  // Tool-specific path configurations
8
8
  const TOOL_PATHS = {
@@ -1176,7 +1176,8 @@ _coder_workstream_cd() {
1176
1176
  fi
1177
1177
  fi
1178
1178
  }
1179
- alias cd='_coder_workstream_cd'
1179
+ # Only alias cd in interactive shells (avoid breaking scripts/Claude Code)
1180
+ [[ $- == *i* ]] && alias cd='_coder_workstream_cd'
1180
1181
  ${endMarker}
1181
1182
  `;
1182
1183
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coder-config",
3
- "version": "0.43.19",
3
+ "version": "0.43.21",
4
4
  "description": "Configuration manager for AI coding tools - Claude Code, Gemini CLI, Codex CLI, Antigravity. Manage MCPs, rules, permissions, memory, and workstreams.",
5
5
  "author": "regression.io",
6
6
  "main": "config-loader.js",
@@ -5,7 +5,34 @@
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
7
  const os = require('os');
8
- const { spawn } = require('child_process');
8
+ const { spawn, execFileSync } = require('child_process');
9
+
10
+ /**
11
+ * Get the full path to the claude binary
12
+ * Needed because daemon processes may not have full PATH
13
+ */
14
+ function getClaudePath() {
15
+ // Common locations
16
+ const candidates = [
17
+ path.join(os.homedir(), '.local', 'bin', 'claude'),
18
+ '/usr/local/bin/claude',
19
+ '/opt/homebrew/bin/claude',
20
+ path.join(os.homedir(), '.npm-global', 'bin', 'claude'),
21
+ ];
22
+
23
+ for (const p of candidates) {
24
+ if (fs.existsSync(p)) return p;
25
+ }
26
+
27
+ // Try to resolve via which command
28
+ try {
29
+ const resolved = execFileSync('which', ['claude'], { encoding: 'utf8' }).trim();
30
+ if (resolved && fs.existsSync(resolved)) return resolved;
31
+ } catch (e) {}
32
+
33
+ // Fallback to hoping it's in PATH
34
+ return 'claude';
35
+ }
9
36
 
10
37
  /**
11
38
  * Default marketplace to auto-install
@@ -59,7 +86,7 @@ async function ensureDefaultMarketplace() {
59
86
  */
60
87
  function addMarketplaceInternal(repo) {
61
88
  return new Promise((resolve, reject) => {
62
- const proc = spawn('claude', ['plugin', 'marketplace', 'add', repo], {
89
+ const proc = spawn(getClaudePath(), ['plugin', 'marketplace', 'add', repo], {
63
90
  cwd: os.homedir(),
64
91
  env: process.env,
65
92
  stdio: ['ignore', 'pipe', 'pipe']
@@ -221,7 +248,7 @@ async function installPlugin(pluginId, marketplace, scope = 'user', projectDir =
221
248
  args.push('--scope', scope);
222
249
  }
223
250
  return new Promise((resolve) => {
224
- const proc = spawn('claude', args, {
251
+ const proc = spawn(getClaudePath(), args, {
225
252
  cwd: projectDir || os.homedir(),
226
253
  env: process.env,
227
254
  stdio: ['ignore', 'pipe', 'pipe']
@@ -252,7 +279,7 @@ async function installPlugin(pluginId, marketplace, scope = 'user', projectDir =
252
279
  */
253
280
  async function uninstallPlugin(pluginId) {
254
281
  return new Promise((resolve) => {
255
- const proc = spawn('claude', ['plugin', 'uninstall', pluginId], {
282
+ const proc = spawn(getClaudePath(), ['plugin', 'uninstall', pluginId], {
256
283
  cwd: os.homedir(),
257
284
  env: process.env,
258
285
  stdio: ['ignore', 'pipe', 'pipe']
@@ -283,7 +310,7 @@ async function uninstallPlugin(pluginId) {
283
310
  */
284
311
  async function addMarketplace(name, repo) {
285
312
  return new Promise((resolve) => {
286
- const proc = spawn('claude', ['plugin', 'marketplace', 'add', repo], {
313
+ const proc = spawn(getClaudePath(), ['plugin', 'marketplace', 'add', repo], {
287
314
  cwd: os.homedir(),
288
315
  env: process.env,
289
316
  stdio: ['ignore', 'pipe', 'pipe']
@@ -314,7 +341,7 @@ async function addMarketplace(name, repo) {
314
341
  */
315
342
  async function refreshMarketplace(name) {
316
343
  return new Promise((resolve) => {
317
- const proc = spawn('claude', ['plugin', 'marketplace', 'update', name], {
344
+ const proc = spawn(getClaudePath(), ['plugin', 'marketplace', 'update', name], {
318
345
  cwd: os.homedir(),
319
346
  env: process.env,
320
347
  stdio: ['ignore', 'pipe', 'pipe']
@@ -7,6 +7,30 @@ const path = require('path');
7
7
  const os = require('os');
8
8
  const { execFileSync, spawn } = require('child_process');
9
9
 
10
+ /**
11
+ * Get the full path to the claude binary
12
+ * Needed because daemon processes may not have full PATH
13
+ */
14
+ function getClaudePath() {
15
+ const candidates = [
16
+ path.join(os.homedir(), '.local', 'bin', 'claude'),
17
+ '/usr/local/bin/claude',
18
+ '/opt/homebrew/bin/claude',
19
+ path.join(os.homedir(), '.npm-global', 'bin', 'claude'),
20
+ ];
21
+
22
+ for (const p of candidates) {
23
+ if (fs.existsSync(p)) return p;
24
+ }
25
+
26
+ try {
27
+ const resolved = execFileSync('which', ['claude'], { encoding: 'utf8' }).trim();
28
+ if (resolved && fs.existsSync(resolved)) return resolved;
29
+ } catch (e) {}
30
+
31
+ return 'claude';
32
+ }
33
+
10
34
  /**
11
35
  * Get all registered projects with status info
12
36
  */
@@ -239,7 +263,7 @@ function streamClaudeInit(res, projectPath) {
239
263
 
240
264
  res.write(`data: ${JSON.stringify({ type: 'status', message: 'Starting claude -p /init...' })}\n\n`);
241
265
 
242
- const child = spawn('claude', ['-p', '/init'], {
266
+ const child = spawn(getClaudePath(), ['-p', '/init'], {
243
267
  cwd: absPath,
244
268
  env: { ...process.env, TERM: 'dumb' },
245
269
  stdio: ['ignore', 'pipe', 'pipe']