@zhigang1992/happy-cli 0.13.6 → 0.13.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.
@@ -1,7 +1,7 @@
1
1
  import chalk from 'chalk';
2
2
  import os$1, { homedir } from 'node:os';
3
3
  import { randomUUID, randomBytes, createHmac } from 'node:crypto';
4
- import { l as logger, p as projectPath, j as backoff, k as delay, R as RawJSONLinesSchema, m as AsyncLock, c as configuration, n as readDaemonState, o as clearDaemonState, i as packageJson, r as readSettings, q as readCredentials, g as encodeBase64, u as updateSettings, s as encodeBase64Url, d as decodeBase64, w as writeCredentialsLegacy, t as writeCredentialsDataKey, v as acquireDaemonLock, x as writeDaemonState, A as ApiClient, y as releaseDaemonLock, z as authChallenge, B as clearCredentials, C as clearMachineId, D as getLatestDaemonLog } from './types-DiRuiHcP.mjs';
4
+ import { l as logger, p as projectPath, j as backoff, k as delay, R as RawJSONLinesSchema, m as AsyncLock, c as configuration, n as readDaemonState, o as clearDaemonState, i as packageJson, r as readSettings, q as readCredentials, g as encodeBase64, u as updateSettings, s as encodeBase64Url, d as decodeBase64, w as writeCredentialsLegacy, t as writeCredentialsDataKey, v as acquireDaemonLock, x as writeDaemonState, A as ApiClient, y as releaseDaemonLock, z as authChallenge, B as clearCredentials, C as clearMachineId, D as getLatestDaemonLog } from './types-D5Yw1ZVE.mjs';
5
5
  import { spawn, execSync, exec as exec$1, execFileSync } from 'node:child_process';
6
6
  import { resolve, join, extname, basename as basename$1 } from 'node:path';
7
7
  import { createInterface } from 'node:readline';
@@ -3113,38 +3113,6 @@ async function claudeRemoteLauncher(session) {
3113
3113
  cwd: session.path,
3114
3114
  version: process.env.npm_package_version
3115
3115
  }, permissionHandler.getResponses());
3116
- const sentMessageUuids = /* @__PURE__ */ new Set();
3117
- function getMessageDedupeKey(msg) {
3118
- if (msg.type === "summary") {
3119
- return `summary:${msg.leafUuid}:${msg.summary}`;
3120
- }
3121
- if (msg.type === "system") {
3122
- return `system:${msg.uuid}`;
3123
- }
3124
- try {
3125
- const content = JSON.stringify(msg.message?.content ?? "");
3126
- const contentKey = content.slice(0, 100) + ":" + content.length;
3127
- return `${msg.type}:${contentKey}`;
3128
- } catch {
3129
- return msg.uuid ?? null;
3130
- }
3131
- }
3132
- const sessionScanner = await createSessionScanner({
3133
- sessionId: session.sessionId,
3134
- workingDirectory: session.path,
3135
- onMessage: (logMessage) => {
3136
- const dedupeKey = getMessageDedupeKey(logMessage);
3137
- if (dedupeKey && sentMessageUuids.has(dedupeKey)) {
3138
- logger.debug(`[remote]: Scanner skipping (already sent): ${logMessage.type}`);
3139
- return;
3140
- }
3141
- if (dedupeKey) {
3142
- sentMessageUuids.add(dedupeKey);
3143
- }
3144
- logger.debug(`[remote]: Scanner forwarding message: ${logMessage.type}`);
3145
- messageQueue.enqueue(logMessage);
3146
- }
3147
- });
3148
3116
  let ongoingToolCalls = /* @__PURE__ */ new Map();
3149
3117
  function onMessage(message) {
3150
3118
  formatClaudeMessageForInk(message, messageBuffer);
@@ -3173,10 +3141,6 @@ async function claudeRemoteLauncher(session) {
3173
3141
  }
3174
3142
  const logMessage = sdkToLogConverter.convert(message);
3175
3143
  if (logMessage) {
3176
- const dedupeKey = getMessageDedupeKey(logMessage);
3177
- if (dedupeKey) {
3178
- sentMessageUuids.add(dedupeKey);
3179
- }
3180
3144
  if (logMessage.type === "user" && logMessage.message?.content) {
3181
3145
  const content = Array.isArray(logMessage.message.content) ? logMessage.message.content : [];
3182
3146
  for (let i = 0; i < content.length; i++) {
@@ -3224,14 +3188,6 @@ async function claudeRemoteLauncher(session) {
3224
3188
  }
3225
3189
  }
3226
3190
  }
3227
- if (logMessage.type === "user") {
3228
- const content = logMessage.message?.content;
3229
- const hasToolResult = Array.isArray(content) && content.some((c) => c.type === "tool_result");
3230
- if (!hasToolResult) {
3231
- logger.debug("[remote]: Skipping user text message (scanner will handle)");
3232
- return;
3233
- }
3234
- }
3235
3191
  messageQueue.enqueue(logMessage);
3236
3192
  }
3237
3193
  if (message.type === "assistant") {
@@ -3241,10 +3197,6 @@ async function claudeRemoteLauncher(session) {
3241
3197
  if (c.type === "tool_use" && c.name === "Task" && c.input && typeof c.input.prompt === "string") {
3242
3198
  const logMessage2 = sdkToLogConverter.convertSidechainUserMessage(c.id, c.input.prompt);
3243
3199
  if (logMessage2) {
3244
- const dedupeKey2 = getMessageDedupeKey(logMessage2);
3245
- if (dedupeKey2) {
3246
- sentMessageUuids.add(dedupeKey2);
3247
- }
3248
3200
  messageQueue.enqueue(logMessage2);
3249
3201
  }
3250
3202
  }
@@ -3324,7 +3276,6 @@ async function claudeRemoteLauncher(session) {
3324
3276
  onSessionFound: (sessionId) => {
3325
3277
  sdkToLogConverter.updateSessionId(sessionId);
3326
3278
  session.onSessionFound(sessionId);
3327
- sessionScanner.onNewSession(sessionId);
3328
3279
  },
3329
3280
  onThinkingChange: session.onThinkingChange,
3330
3281
  claudeEnvVars: session.claudeEnvVars,
@@ -3420,7 +3371,6 @@ async function claudeRemoteLauncher(session) {
3420
3371
  }
3421
3372
  }
3422
3373
  } finally {
3423
- await sessionScanner.cleanup();
3424
3374
  permissionHandler.reset();
3425
3375
  process.stdin.off("data", abort);
3426
3376
  if (process.stdin.isTTY) {
@@ -7075,7 +7025,7 @@ async function handleConnectVendor(vendor, displayName) {
7075
7025
  return;
7076
7026
  } else if (subcommand === "codex") {
7077
7027
  try {
7078
- const { runCodex } = await import('./runCodex-D0U-q5eD.mjs');
7028
+ const { runCodex } = await import('./runCodex-CAH8Q5j0.mjs');
7079
7029
  let startedBy = void 0;
7080
7030
  for (let i = 1; i < args.length; i++) {
7081
7031
  if (args[i] === "--started-by") {
@@ -7120,7 +7070,7 @@ async function handleConnectVendor(vendor, displayName) {
7120
7070
  } else if (subcommand === "list") {
7121
7071
  try {
7122
7072
  const { credentials } = await authAndSetupMachineIfNeeded();
7123
- const { listSessions } = await import('./list-CJIFYb6N.mjs');
7073
+ const { listSessions } = await import('./list-MUmi4ZF2.mjs');
7124
7074
  let sessionId;
7125
7075
  let titleFilter;
7126
7076
  let recentMsgs;
@@ -7222,7 +7172,7 @@ Examples:
7222
7172
  process.exit(1);
7223
7173
  }
7224
7174
  const { credentials } = await authAndSetupMachineIfNeeded();
7225
- const { promptSession } = await import('./prompt-CsSxmvT_.mjs');
7175
+ const { promptSession } = await import('./prompt-C8uOM9BM.mjs');
7226
7176
  await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
7227
7177
  } catch (error) {
7228
7178
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -3,7 +3,7 @@
3
3
  var chalk = require('chalk');
4
4
  var os = require('node:os');
5
5
  var node_crypto = require('node:crypto');
6
- var types = require('./types-PYoidcSb.cjs');
6
+ var types = require('./types-rIsjYnBh.cjs');
7
7
  var node_child_process = require('node:child_process');
8
8
  var node_path = require('node:path');
9
9
  var node_readline = require('node:readline');
@@ -1184,7 +1184,7 @@ class AbortError extends Error {
1184
1184
  }
1185
1185
  }
1186
1186
 
1187
- const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-g2JPIqmn.cjs', document.baseURI).href)));
1187
+ const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-pL_ungbb.cjs', document.baseURI).href)));
1188
1188
  const __dirname$1 = node_path.join(__filename$1, "..");
1189
1189
  function getGlobalClaudeVersion() {
1190
1190
  try {
@@ -3136,38 +3136,6 @@ async function claudeRemoteLauncher(session) {
3136
3136
  cwd: session.path,
3137
3137
  version: process.env.npm_package_version
3138
3138
  }, permissionHandler.getResponses());
3139
- const sentMessageUuids = /* @__PURE__ */ new Set();
3140
- function getMessageDedupeKey(msg) {
3141
- if (msg.type === "summary") {
3142
- return `summary:${msg.leafUuid}:${msg.summary}`;
3143
- }
3144
- if (msg.type === "system") {
3145
- return `system:${msg.uuid}`;
3146
- }
3147
- try {
3148
- const content = JSON.stringify(msg.message?.content ?? "");
3149
- const contentKey = content.slice(0, 100) + ":" + content.length;
3150
- return `${msg.type}:${contentKey}`;
3151
- } catch {
3152
- return msg.uuid ?? null;
3153
- }
3154
- }
3155
- const sessionScanner = await createSessionScanner({
3156
- sessionId: session.sessionId,
3157
- workingDirectory: session.path,
3158
- onMessage: (logMessage) => {
3159
- const dedupeKey = getMessageDedupeKey(logMessage);
3160
- if (dedupeKey && sentMessageUuids.has(dedupeKey)) {
3161
- types.logger.debug(`[remote]: Scanner skipping (already sent): ${logMessage.type}`);
3162
- return;
3163
- }
3164
- if (dedupeKey) {
3165
- sentMessageUuids.add(dedupeKey);
3166
- }
3167
- types.logger.debug(`[remote]: Scanner forwarding message: ${logMessage.type}`);
3168
- messageQueue.enqueue(logMessage);
3169
- }
3170
- });
3171
3139
  let ongoingToolCalls = /* @__PURE__ */ new Map();
3172
3140
  function onMessage(message) {
3173
3141
  formatClaudeMessageForInk(message, messageBuffer);
@@ -3196,10 +3164,6 @@ async function claudeRemoteLauncher(session) {
3196
3164
  }
3197
3165
  const logMessage = sdkToLogConverter.convert(message);
3198
3166
  if (logMessage) {
3199
- const dedupeKey = getMessageDedupeKey(logMessage);
3200
- if (dedupeKey) {
3201
- sentMessageUuids.add(dedupeKey);
3202
- }
3203
3167
  if (logMessage.type === "user" && logMessage.message?.content) {
3204
3168
  const content = Array.isArray(logMessage.message.content) ? logMessage.message.content : [];
3205
3169
  for (let i = 0; i < content.length; i++) {
@@ -3247,14 +3211,6 @@ async function claudeRemoteLauncher(session) {
3247
3211
  }
3248
3212
  }
3249
3213
  }
3250
- if (logMessage.type === "user") {
3251
- const content = logMessage.message?.content;
3252
- const hasToolResult = Array.isArray(content) && content.some((c) => c.type === "tool_result");
3253
- if (!hasToolResult) {
3254
- types.logger.debug("[remote]: Skipping user text message (scanner will handle)");
3255
- return;
3256
- }
3257
- }
3258
3214
  messageQueue.enqueue(logMessage);
3259
3215
  }
3260
3216
  if (message.type === "assistant") {
@@ -3264,10 +3220,6 @@ async function claudeRemoteLauncher(session) {
3264
3220
  if (c.type === "tool_use" && c.name === "Task" && c.input && typeof c.input.prompt === "string") {
3265
3221
  const logMessage2 = sdkToLogConverter.convertSidechainUserMessage(c.id, c.input.prompt);
3266
3222
  if (logMessage2) {
3267
- const dedupeKey2 = getMessageDedupeKey(logMessage2);
3268
- if (dedupeKey2) {
3269
- sentMessageUuids.add(dedupeKey2);
3270
- }
3271
3223
  messageQueue.enqueue(logMessage2);
3272
3224
  }
3273
3225
  }
@@ -3347,7 +3299,6 @@ async function claudeRemoteLauncher(session) {
3347
3299
  onSessionFound: (sessionId) => {
3348
3300
  sdkToLogConverter.updateSessionId(sessionId);
3349
3301
  session.onSessionFound(sessionId);
3350
- sessionScanner.onNewSession(sessionId);
3351
3302
  },
3352
3303
  onThinkingChange: session.onThinkingChange,
3353
3304
  claudeEnvVars: session.claudeEnvVars,
@@ -3443,7 +3394,6 @@ async function claudeRemoteLauncher(session) {
3443
3394
  }
3444
3395
  }
3445
3396
  } finally {
3446
- await sessionScanner.cleanup();
3447
3397
  permissionHandler.reset();
3448
3398
  process.stdin.off("data", abort);
3449
3399
  if (process.stdin.isTTY) {
@@ -7098,7 +7048,7 @@ async function handleConnectVendor(vendor, displayName) {
7098
7048
  return;
7099
7049
  } else if (subcommand === "codex") {
7100
7050
  try {
7101
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-Cci-tAjU.cjs'); });
7051
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-DWxgaq32.cjs'); });
7102
7052
  let startedBy = void 0;
7103
7053
  for (let i = 1; i < args.length; i++) {
7104
7054
  if (args[i] === "--started-by") {
@@ -7143,7 +7093,7 @@ async function handleConnectVendor(vendor, displayName) {
7143
7093
  } else if (subcommand === "list") {
7144
7094
  try {
7145
7095
  const { credentials } = await authAndSetupMachineIfNeeded();
7146
- const { listSessions } = await Promise.resolve().then(function () { return require('./list-oXfJPJTM.cjs'); });
7096
+ const { listSessions } = await Promise.resolve().then(function () { return require('./list-BFBIw5l1.cjs'); });
7147
7097
  let sessionId;
7148
7098
  let titleFilter;
7149
7099
  let recentMsgs;
@@ -7245,7 +7195,7 @@ Examples:
7245
7195
  process.exit(1);
7246
7196
  }
7247
7197
  const { credentials } = await authAndSetupMachineIfNeeded();
7248
- const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-la2aaOYY.cjs'); });
7198
+ const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-TC7YWFCb.cjs'); });
7249
7199
  await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
7250
7200
  } catch (error) {
7251
7201
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  require('chalk');
4
- require('./index-g2JPIqmn.cjs');
5
- require('./types-PYoidcSb.cjs');
4
+ require('./index-pL_ungbb.cjs');
5
+ require('./types-rIsjYnBh.cjs');
6
6
  require('zod');
7
7
  require('node:child_process');
8
8
  require('node:os');
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import 'chalk';
2
- import './index-CygCJIPr.mjs';
3
- import './types-DiRuiHcP.mjs';
2
+ import './index-BfZGZNIf.mjs';
3
+ import './types-D5Yw1ZVE.mjs';
4
4
  import 'zod';
5
5
  import 'node:child_process';
6
6
  import 'node:os';
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types-PYoidcSb.cjs');
3
+ var types = require('./types-rIsjYnBh.cjs');
4
4
  require('axios');
5
5
  require('chalk');
6
6
  require('fs');
package/dist/lib.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-DiRuiHcP.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-D5Yw1ZVE.mjs';
2
2
  import 'axios';
3
3
  import 'chalk';
4
4
  import 'fs';
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types-PYoidcSb.cjs');
3
+ var types = require('./types-rIsjYnBh.cjs');
4
4
  var axios = require('axios');
5
5
  var fs = require('fs');
6
6
  var path = require('path');
@@ -1,4 +1,4 @@
1
- import { c as configuration, l as logger, d as decodeBase64, b as decrypt, f as formatTimeAgo, e as libsodiumDecryptFromPublicKey } from './types-DiRuiHcP.mjs';
1
+ import { c as configuration, l as logger, d as decodeBase64, b as decrypt, f as formatTimeAgo, e as libsodiumDecryptFromPublicKey } from './types-D5Yw1ZVE.mjs';
2
2
  import axios from 'axios';
3
3
  import { existsSync, readdirSync, statSync, readFileSync } from 'fs';
4
4
  import { join } from 'path';
@@ -1,4 +1,4 @@
1
- import { c as configuration, b as decrypt, d as decodeBase64, l as logger, g as encodeBase64, h as encrypt } from './types-DiRuiHcP.mjs';
1
+ import { c as configuration, b as decrypt, d as decodeBase64, l as logger, g as encodeBase64, h as encrypt } from './types-D5Yw1ZVE.mjs';
2
2
  import axios from 'axios';
3
3
  import { io } from 'socket.io-client';
4
4
  import 'chalk';
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types-PYoidcSb.cjs');
3
+ var types = require('./types-rIsjYnBh.cjs');
4
4
  var axios = require('axios');
5
5
  var socket_ioClient = require('socket.io-client');
6
6
  require('chalk');
@@ -1,13 +1,13 @@
1
1
  import { useStdout, useInput, Box, Text, render } from 'ink';
2
2
  import React, { useState, useRef, useEffect, useCallback } from 'react';
3
- import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, i as packageJson } from './types-DiRuiHcP.mjs';
3
+ import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, i as packageJson } from './types-D5Yw1ZVE.mjs';
4
4
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
5
5
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
6
6
  import { z } from 'zod';
7
7
  import { ElicitRequestSchema } from '@modelcontextprotocol/sdk/types.js';
8
8
  import { execSync } from 'child_process';
9
9
  import { randomUUID } from 'node:crypto';
10
- import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, r as registerKillSessionHandler, a as MessageBuffer, s as startHappyServer, t as trimIdent, b as stopCaffeinate } from './index-CygCJIPr.mjs';
10
+ import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, r as registerKillSessionHandler, a as MessageBuffer, s as startHappyServer, t as trimIdent, b as stopCaffeinate } from './index-BfZGZNIf.mjs';
11
11
  import os from 'node:os';
12
12
  import { resolve, join } from 'node:path';
13
13
  import fs from 'node:fs';
@@ -2,14 +2,14 @@
2
2
 
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
- var types = require('./types-PYoidcSb.cjs');
5
+ var types = require('./types-rIsjYnBh.cjs');
6
6
  var index_js = require('@modelcontextprotocol/sdk/client/index.js');
7
7
  var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
8
8
  var z = require('zod');
9
9
  var types_js = require('@modelcontextprotocol/sdk/types.js');
10
10
  var child_process = require('child_process');
11
11
  var node_crypto = require('node:crypto');
12
- var index = require('./index-g2JPIqmn.cjs');
12
+ var index = require('./index-pL_ungbb.cjs');
13
13
  var os = require('node:os');
14
14
  var node_path = require('node:path');
15
15
  var fs = require('node:fs');
@@ -20,7 +20,7 @@ import { fileURLToPath } from 'url';
20
20
  import { Expo } from 'expo-server-sdk';
21
21
 
22
22
  var name = "@zhigang1992/happy-cli";
23
- var version = "0.13.6";
23
+ var version = "0.13.7";
24
24
  var description = "Mobile and Web client for Claude Code and Codex";
25
25
  var author = "Kirill Dubovitskiy";
26
26
  var license = "MIT";
@@ -41,7 +41,7 @@ function _interopNamespaceDefault(e) {
41
41
  var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
42
42
 
43
43
  var name = "@zhigang1992/happy-cli";
44
- var version = "0.13.6";
44
+ var version = "0.13.7";
45
45
  var description = "Mobile and Web client for Claude Code and Codex";
46
46
  var author = "Kirill Dubovitskiy";
47
47
  var license = "MIT";
@@ -1150,7 +1150,7 @@ class RpcHandlerManager {
1150
1150
  }
1151
1151
  }
1152
1152
 
1153
- const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-PYoidcSb.cjs', document.baseURI).href))));
1153
+ const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-rIsjYnBh.cjs', document.baseURI).href))));
1154
1154
  function projectPath() {
1155
1155
  const path$1 = path.resolve(__dirname$1, "..");
1156
1156
  return path$1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhigang1992/happy-cli",
3
- "version": "0.13.6",
3
+ "version": "0.13.7",
4
4
  "description": "Mobile and Web client for Claude Code and Codex",
5
5
  "author": "Kirill Dubovitskiy",
6
6
  "license": "MIT",
@@ -252,20 +252,13 @@ function findLatestVersionBinary(versionsDir, binaryName = null) {
252
252
  /**
253
253
  * Find path to globally installed Claude Code CLI
254
254
  * Checks multiple installation methods in order of preference:
255
- * 0. HAPPY_CLAUDE_PATH env var (highest priority)
256
- * 1. npm global
255
+ * 1. npm global (highest priority)
257
256
  * 2. Homebrew
258
257
  * 3. Native installer
259
258
  * @returns {{path: string, source: string}|null} Path and source, or null if not found
260
259
  */
261
260
  function findGlobalClaudeCliPath() {
262
- // Environment variable takes highest priority
263
- const envPath = process.env.HAPPY_CLAUDE_PATH;
264
- if (envPath && fs.existsSync(envPath)) {
265
- return { path: envPath, source: 'HAPPY_CLAUDE_PATH env' };
266
- }
267
-
268
- // Check npm global
261
+ // Check npm global first (highest priority)
269
262
  const npmPath = findNpmGlobalCliPath();
270
263
  if (npmPath) return { path: npmPath, source: 'npm' };
271
264