happy-coder 0.11.2 → 0.12.0
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/dist/codex/happyMcpStdioBridge.cjs +2 -3
- package/dist/codex/happyMcpStdioBridge.mjs +2 -3
- package/dist/{index-sSOy3f2x.mjs → index-DMBGazgc.mjs} +144 -48
- package/dist/{index-DmJ8WyYo.cjs → index-IPZkNBoV.cjs} +142 -46
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +6 -15
- package/dist/lib.d.mts +6 -15
- package/dist/lib.mjs +1 -1
- package/dist/{runCodex-BnjA1TX6.mjs → runCodex-BgCwl6pc.mjs} +3 -3
- package/dist/{runCodex-DQPZNHzH.cjs → runCodex-DuUtfZ9i.cjs} +3 -3
- package/dist/{types-CjceR-4_.mjs → types-7HcYY6Ao.mjs} +73 -28
- package/dist/{types-Bg43e3vc.cjs → types-CO3A_kFm.cjs} +74 -29
- package/package.json +15 -15
- package/scripts/claude_local_launcher.cjs +5 -30
- package/scripts/claude_remote_launcher.cjs +4 -1
- package/scripts/claude_version_utils.cjs +378 -0
|
@@ -31,7 +31,7 @@ async function main() {
|
|
|
31
31
|
if (httpClient) return httpClient;
|
|
32
32
|
const client = new index_js.Client(
|
|
33
33
|
{ name: "happy-stdio-bridge", version: "1.0.0" },
|
|
34
|
-
{ capabilities: {
|
|
34
|
+
{ capabilities: {} }
|
|
35
35
|
);
|
|
36
36
|
const transport = new streamableHttp_js.StreamableHTTPClientTransport(new URL(baseUrl));
|
|
37
37
|
await client.connect(transport);
|
|
@@ -40,8 +40,7 @@ async function main() {
|
|
|
40
40
|
}
|
|
41
41
|
const server = new mcp_js.McpServer({
|
|
42
42
|
name: "Happy MCP Bridge",
|
|
43
|
-
version: "1.0.0"
|
|
44
|
-
description: "STDIO bridge forwarding to Happy HTTP MCP"
|
|
43
|
+
version: "1.0.0"
|
|
45
44
|
});
|
|
46
45
|
server.registerTool(
|
|
47
46
|
"change_title",
|
|
@@ -29,7 +29,7 @@ async function main() {
|
|
|
29
29
|
if (httpClient) return httpClient;
|
|
30
30
|
const client = new Client(
|
|
31
31
|
{ name: "happy-stdio-bridge", version: "1.0.0" },
|
|
32
|
-
{ capabilities: {
|
|
32
|
+
{ capabilities: {} }
|
|
33
33
|
);
|
|
34
34
|
const transport = new StreamableHTTPClientTransport(new URL(baseUrl));
|
|
35
35
|
await client.connect(transport);
|
|
@@ -38,8 +38,7 @@ async function main() {
|
|
|
38
38
|
}
|
|
39
39
|
const server = new McpServer({
|
|
40
40
|
name: "Happy MCP Bridge",
|
|
41
|
-
version: "1.0.0"
|
|
42
|
-
description: "STDIO bridge forwarding to Happy HTTP MCP"
|
|
41
|
+
version: "1.0.0"
|
|
43
42
|
});
|
|
44
43
|
server.registerTool(
|
|
45
44
|
"change_title",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import os$1, { homedir } from 'node:os';
|
|
3
3
|
import { randomUUID, randomBytes } from 'node:crypto';
|
|
4
|
-
import { l as logger, p as projectPath, d as backoff, e as delay, R as RawJSONLinesSchema, f as AsyncLock, c as configuration, g as readDaemonState, h as clearDaemonState, b as packageJson, r as readSettings, i as readCredentials, j as encodeBase64, u as updateSettings, k as encodeBase64Url, m as decodeBase64, w as writeCredentialsLegacy, n as writeCredentialsDataKey, o as acquireDaemonLock, q as writeDaemonState, A as ApiClient, s as releaseDaemonLock, t as clearCredentials, v as clearMachineId, x as getLatestDaemonLog } from './types-
|
|
4
|
+
import { l as logger, p as projectPath, d as backoff, e as delay, R as RawJSONLinesSchema, f as AsyncLock, c as configuration, g as readDaemonState, h as clearDaemonState, b as packageJson, r as readSettings, i as readCredentials, j as encodeBase64, u as updateSettings, k as encodeBase64Url, m as decodeBase64, w as writeCredentialsLegacy, n as writeCredentialsDataKey, o as acquireDaemonLock, q as writeDaemonState, A as ApiClient, s as releaseDaemonLock, t as clearCredentials, v as clearMachineId, x as getLatestDaemonLog } from './types-7HcYY6Ao.mjs';
|
|
5
5
|
import { spawn, execSync, execFileSync } from 'node:child_process';
|
|
6
6
|
import { resolve, join } from 'node:path';
|
|
7
7
|
import { createInterface } from 'node:readline';
|
|
8
|
-
import { existsSync, readFileSync, mkdirSync,
|
|
8
|
+
import { existsSync, readFileSync, mkdirSync, readdirSync, statSync, rmSync } from 'node:fs';
|
|
9
9
|
import { readFile } from 'node:fs/promises';
|
|
10
|
-
import fs, { watch
|
|
10
|
+
import fs, { watch, access } from 'fs/promises';
|
|
11
11
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
12
12
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
13
13
|
import { fileURLToPath } from 'node:url';
|
|
@@ -220,31 +220,19 @@ const claudeCliPath = resolve(join(projectPath(), "scripts", "claude_local_launc
|
|
|
220
220
|
async function claudeLocal(opts) {
|
|
221
221
|
const projectDir = getProjectPath(opts.path);
|
|
222
222
|
mkdirSync(projectDir, { recursive: true });
|
|
223
|
-
const watcher = watch(projectDir);
|
|
224
|
-
let resolvedSessionId = null;
|
|
225
|
-
const detectedIdsRandomUUID = /* @__PURE__ */ new Set();
|
|
226
|
-
const detectedIdsFileSystem = /* @__PURE__ */ new Set();
|
|
227
|
-
watcher.on("change", (event, filename) => {
|
|
228
|
-
if (typeof filename === "string" && filename.toLowerCase().endsWith(".jsonl")) {
|
|
229
|
-
logger.debug("change", event, filename);
|
|
230
|
-
const sessionId = filename.replace(".jsonl", "");
|
|
231
|
-
if (detectedIdsFileSystem.has(sessionId)) {
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
detectedIdsFileSystem.add(sessionId);
|
|
235
|
-
if (resolvedSessionId) {
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
if (detectedIdsRandomUUID.has(sessionId)) {
|
|
239
|
-
resolvedSessionId = sessionId;
|
|
240
|
-
opts.onSessionFound(sessionId);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
223
|
let startFrom = opts.sessionId;
|
|
245
224
|
if (opts.sessionId && !claudeCheckSession(opts.sessionId, opts.path)) {
|
|
246
225
|
startFrom = null;
|
|
247
226
|
}
|
|
227
|
+
const newSessionId = startFrom ? null : randomUUID();
|
|
228
|
+
const effectiveSessionId = startFrom || newSessionId;
|
|
229
|
+
if (newSessionId) {
|
|
230
|
+
logger.debug(`[ClaudeLocal] Generated new session ID: ${newSessionId}`);
|
|
231
|
+
opts.onSessionFound(newSessionId);
|
|
232
|
+
} else {
|
|
233
|
+
logger.debug(`[ClaudeLocal] Resuming session: ${startFrom}`);
|
|
234
|
+
opts.onSessionFound(startFrom);
|
|
235
|
+
}
|
|
248
236
|
let thinking = false;
|
|
249
237
|
let stopThinkingTimeout = null;
|
|
250
238
|
const updateThinking = (newThinking) => {
|
|
@@ -262,6 +250,8 @@ async function claudeLocal(opts) {
|
|
|
262
250
|
const args = [];
|
|
263
251
|
if (startFrom) {
|
|
264
252
|
args.push("--resume", startFrom);
|
|
253
|
+
} else {
|
|
254
|
+
args.push("--session-id", newSessionId);
|
|
265
255
|
}
|
|
266
256
|
args.push("--append-system-prompt", systemPrompt);
|
|
267
257
|
if (opts.mcpServers && Object.keys(opts.mcpServers).length > 0) {
|
|
@@ -280,6 +270,8 @@ async function claudeLocal(opts) {
|
|
|
280
270
|
...process.env,
|
|
281
271
|
...opts.claudeEnvVars
|
|
282
272
|
};
|
|
273
|
+
logger.debug(`[ClaudeLocal] Spawning launcher: ${claudeCliPath}`);
|
|
274
|
+
logger.debug(`[ClaudeLocal] Args: ${JSON.stringify(args)}`);
|
|
283
275
|
const child = spawn("node", [claudeCliPath, ...args], {
|
|
284
276
|
stdio: ["inherit", "inherit", "inherit", "pipe"],
|
|
285
277
|
signal: opts.abort,
|
|
@@ -296,13 +288,6 @@ async function claudeLocal(opts) {
|
|
|
296
288
|
try {
|
|
297
289
|
const message = JSON.parse(line);
|
|
298
290
|
switch (message.type) {
|
|
299
|
-
case "uuid":
|
|
300
|
-
detectedIdsRandomUUID.add(message.value);
|
|
301
|
-
if (!resolvedSessionId && detectedIdsFileSystem.has(message.value)) {
|
|
302
|
-
resolvedSessionId = message.value;
|
|
303
|
-
opts.onSessionFound(message.value);
|
|
304
|
-
}
|
|
305
|
-
break;
|
|
306
291
|
case "fetch-start":
|
|
307
292
|
activeFetches.set(message.id, {
|
|
308
293
|
hostname: message.hostname,
|
|
@@ -356,7 +341,6 @@ async function claudeLocal(opts) {
|
|
|
356
341
|
});
|
|
357
342
|
});
|
|
358
343
|
} finally {
|
|
359
|
-
watcher.close();
|
|
360
344
|
process.stdin.resume();
|
|
361
345
|
if (stopThinkingTimeout) {
|
|
362
346
|
clearTimeout(stopThinkingTimeout);
|
|
@@ -364,7 +348,7 @@ async function claudeLocal(opts) {
|
|
|
364
348
|
}
|
|
365
349
|
updateThinking(false);
|
|
366
350
|
}
|
|
367
|
-
return
|
|
351
|
+
return effectiveSessionId;
|
|
368
352
|
}
|
|
369
353
|
|
|
370
354
|
class Future {
|
|
@@ -460,7 +444,7 @@ function startFileWatcher(file, onFileChange) {
|
|
|
460
444
|
while (true) {
|
|
461
445
|
try {
|
|
462
446
|
logger.debug(`[FILE_WATCHER] Starting watcher for ${file}`);
|
|
463
|
-
const watcher = watch
|
|
447
|
+
const watcher = watch(file, { persistent: true, signal: abortController.signal });
|
|
464
448
|
for await (const event of watcher) {
|
|
465
449
|
if (abortController.signal.aborted) {
|
|
466
450
|
return;
|
|
@@ -482,6 +466,11 @@ function startFileWatcher(file, onFileChange) {
|
|
|
482
466
|
};
|
|
483
467
|
}
|
|
484
468
|
|
|
469
|
+
const INTERNAL_CLAUDE_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
470
|
+
"file-history-snapshot",
|
|
471
|
+
"change",
|
|
472
|
+
"queue-operation"
|
|
473
|
+
]);
|
|
485
474
|
async function createSessionScanner(opts) {
|
|
486
475
|
const projectDir = getProjectPath(opts.workingDirectory);
|
|
487
476
|
let finishedSessions = /* @__PURE__ */ new Set();
|
|
@@ -491,26 +480,42 @@ async function createSessionScanner(opts) {
|
|
|
491
480
|
let processedMessageKeys = /* @__PURE__ */ new Set();
|
|
492
481
|
if (opts.sessionId) {
|
|
493
482
|
let messages = await readSessionLog(projectDir, opts.sessionId);
|
|
483
|
+
logger.debug(`[SESSION_SCANNER] Marking ${messages.length} existing messages as processed from session ${opts.sessionId}`);
|
|
494
484
|
for (let m of messages) {
|
|
495
485
|
processedMessageKeys.add(messageKey(m));
|
|
496
486
|
}
|
|
487
|
+
currentSessionId = opts.sessionId;
|
|
497
488
|
}
|
|
498
489
|
const sync = new InvalidateSync(async () => {
|
|
499
490
|
let sessions = [];
|
|
500
491
|
for (let p of pendingSessions) {
|
|
501
492
|
sessions.push(p);
|
|
502
493
|
}
|
|
503
|
-
if (currentSessionId) {
|
|
494
|
+
if (currentSessionId && !pendingSessions.has(currentSessionId)) {
|
|
504
495
|
sessions.push(currentSessionId);
|
|
505
496
|
}
|
|
497
|
+
for (let [sessionId] of watchers) {
|
|
498
|
+
if (!sessions.includes(sessionId)) {
|
|
499
|
+
sessions.push(sessionId);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
506
502
|
for (let session of sessions) {
|
|
507
|
-
|
|
503
|
+
const sessionMessages = await readSessionLog(projectDir, session);
|
|
504
|
+
let skipped = 0;
|
|
505
|
+
let sent = 0;
|
|
506
|
+
for (let file of sessionMessages) {
|
|
508
507
|
let key = messageKey(file);
|
|
509
508
|
if (processedMessageKeys.has(key)) {
|
|
509
|
+
skipped++;
|
|
510
510
|
continue;
|
|
511
511
|
}
|
|
512
512
|
processedMessageKeys.add(key);
|
|
513
|
+
logger.debug(`[SESSION_SCANNER] Sending new message: type=${file.type}, uuid=${file.type === "summary" ? file.leafUuid : file.uuid}`);
|
|
513
514
|
opts.onMessage(file);
|
|
515
|
+
sent++;
|
|
516
|
+
}
|
|
517
|
+
if (sessionMessages.length > 0) {
|
|
518
|
+
logger.debug(`[SESSION_SCANNER] Session ${session}: found=${sessionMessages.length}, skipped=${skipped}, sent=${sent}`);
|
|
514
519
|
}
|
|
515
520
|
}
|
|
516
521
|
for (let p of sessions) {
|
|
@@ -521,6 +526,7 @@ async function createSessionScanner(opts) {
|
|
|
521
526
|
}
|
|
522
527
|
for (let p of sessions) {
|
|
523
528
|
if (!watchers.has(p)) {
|
|
529
|
+
logger.debug(`[SESSION_SCANNER] Starting watcher for session: ${p}`);
|
|
524
530
|
watchers.set(p, startFileWatcher(join(projectDir, `${p}.jsonl`), () => {
|
|
525
531
|
sync.invalidate();
|
|
526
532
|
}));
|
|
@@ -594,9 +600,11 @@ async function readSessionLog(projectDir, sessionId) {
|
|
|
594
600
|
continue;
|
|
595
601
|
}
|
|
596
602
|
let message = JSON.parse(l);
|
|
603
|
+
if (message.type && INTERNAL_CLAUDE_EVENT_TYPES.has(message.type)) {
|
|
604
|
+
continue;
|
|
605
|
+
}
|
|
597
606
|
let parsed = RawJSONLinesSchema.safeParse(message);
|
|
598
607
|
if (!parsed.success) {
|
|
599
|
-
logger.debugLargeJson(`[SESSION_SCANNER] Failed to parse message`, message);
|
|
600
608
|
continue;
|
|
601
609
|
}
|
|
602
610
|
messages.push(parsed.data);
|
|
@@ -961,8 +969,92 @@ class AbortError extends Error {
|
|
|
961
969
|
|
|
962
970
|
const __filename = fileURLToPath(import.meta.url);
|
|
963
971
|
const __dirname = join(__filename, "..");
|
|
972
|
+
function getGlobalClaudeVersion() {
|
|
973
|
+
try {
|
|
974
|
+
const cleanEnv = getCleanEnv();
|
|
975
|
+
const output = execSync("claude --version", {
|
|
976
|
+
encoding: "utf8",
|
|
977
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
978
|
+
cwd: homedir(),
|
|
979
|
+
env: cleanEnv
|
|
980
|
+
}).trim();
|
|
981
|
+
const match = output.match(/(\d+\.\d+\.\d+)/);
|
|
982
|
+
logger.debug(`[Claude SDK] Global claude --version output: ${output}`);
|
|
983
|
+
return match ? match[1] : null;
|
|
984
|
+
} catch {
|
|
985
|
+
return null;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
function getCleanEnv() {
|
|
989
|
+
const env = { ...process.env };
|
|
990
|
+
const cwd = process.cwd();
|
|
991
|
+
const pathSep = process.platform === "win32" ? ";" : ":";
|
|
992
|
+
const pathKey = process.platform === "win32" ? "Path" : "PATH";
|
|
993
|
+
const actualPathKey = Object.keys(env).find((k) => k.toLowerCase() === "path") || pathKey;
|
|
994
|
+
if (env[actualPathKey]) {
|
|
995
|
+
const cleanPath = env[actualPathKey].split(pathSep).filter((p) => {
|
|
996
|
+
const normalizedP = p.replace(/\\/g, "/").toLowerCase();
|
|
997
|
+
const normalizedCwd = cwd.replace(/\\/g, "/").toLowerCase();
|
|
998
|
+
return !normalizedP.startsWith(normalizedCwd);
|
|
999
|
+
}).join(pathSep);
|
|
1000
|
+
env[actualPathKey] = cleanPath;
|
|
1001
|
+
logger.debug(`[Claude SDK] Cleaned PATH, removed local paths from: ${cwd}`);
|
|
1002
|
+
}
|
|
1003
|
+
return env;
|
|
1004
|
+
}
|
|
1005
|
+
function findGlobalClaudePath() {
|
|
1006
|
+
const homeDir = homedir();
|
|
1007
|
+
const cleanEnv = getCleanEnv();
|
|
1008
|
+
try {
|
|
1009
|
+
execSync("claude --version", {
|
|
1010
|
+
encoding: "utf8",
|
|
1011
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1012
|
+
cwd: homeDir,
|
|
1013
|
+
env: cleanEnv
|
|
1014
|
+
});
|
|
1015
|
+
logger.debug("[Claude SDK] Global claude command available (checked with clean PATH)");
|
|
1016
|
+
return "claude";
|
|
1017
|
+
} catch {
|
|
1018
|
+
}
|
|
1019
|
+
if (process.platform !== "win32") {
|
|
1020
|
+
try {
|
|
1021
|
+
const result = execSync("which claude", {
|
|
1022
|
+
encoding: "utf8",
|
|
1023
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1024
|
+
cwd: homeDir,
|
|
1025
|
+
env: cleanEnv
|
|
1026
|
+
}).trim();
|
|
1027
|
+
if (result && existsSync(result)) {
|
|
1028
|
+
logger.debug(`[Claude SDK] Found global claude path via which: ${result}`);
|
|
1029
|
+
return result;
|
|
1030
|
+
}
|
|
1031
|
+
} catch {
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
return null;
|
|
1035
|
+
}
|
|
964
1036
|
function getDefaultClaudeCodePath() {
|
|
965
|
-
|
|
1037
|
+
const nodeModulesPath = join(__dirname, "..", "..", "..", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
1038
|
+
if (process.env.HAPPY_CLAUDE_PATH) {
|
|
1039
|
+
logger.debug(`[Claude SDK] Using HAPPY_CLAUDE_PATH: ${process.env.HAPPY_CLAUDE_PATH}`);
|
|
1040
|
+
return process.env.HAPPY_CLAUDE_PATH;
|
|
1041
|
+
}
|
|
1042
|
+
if (process.env.HAPPY_USE_BUNDLED_CLAUDE === "1") {
|
|
1043
|
+
logger.debug(`[Claude SDK] Forced bundled version: ${nodeModulesPath}`);
|
|
1044
|
+
return nodeModulesPath;
|
|
1045
|
+
}
|
|
1046
|
+
const globalPath = findGlobalClaudePath();
|
|
1047
|
+
if (!globalPath) {
|
|
1048
|
+
logger.debug(`[Claude SDK] No global claude found, using bundled: ${nodeModulesPath}`);
|
|
1049
|
+
return nodeModulesPath;
|
|
1050
|
+
}
|
|
1051
|
+
const globalVersion = getGlobalClaudeVersion();
|
|
1052
|
+
logger.debug(`[Claude SDK] Global version: ${globalVersion || "unknown"}`);
|
|
1053
|
+
if (!globalVersion) {
|
|
1054
|
+
logger.debug(`[Claude SDK] Cannot compare versions, using global: ${globalPath}`);
|
|
1055
|
+
return globalPath;
|
|
1056
|
+
}
|
|
1057
|
+
return globalPath;
|
|
966
1058
|
}
|
|
967
1059
|
function logDebug(message) {
|
|
968
1060
|
if (process.env.DEBUG) {
|
|
@@ -1227,17 +1319,22 @@ function query(config) {
|
|
|
1227
1319
|
} else {
|
|
1228
1320
|
args.push("--input-format", "stream-json");
|
|
1229
1321
|
}
|
|
1230
|
-
|
|
1322
|
+
const isJsFile = pathToClaudeCodeExecutable.endsWith(".js") || pathToClaudeCodeExecutable.endsWith(".cjs");
|
|
1323
|
+
const isCommandOnly = pathToClaudeCodeExecutable === "claude";
|
|
1324
|
+
if (!isCommandOnly && !existsSync(pathToClaudeCodeExecutable)) {
|
|
1231
1325
|
throw new ReferenceError(`Claude Code executable not found at ${pathToClaudeCodeExecutable}. Is options.pathToClaudeCodeExecutable set?`);
|
|
1232
1326
|
}
|
|
1233
|
-
|
|
1234
|
-
const
|
|
1327
|
+
const spawnCommand = isJsFile ? executable : pathToClaudeCodeExecutable;
|
|
1328
|
+
const spawnArgs = isJsFile ? [...executableArgs, pathToClaudeCodeExecutable, ...args] : args;
|
|
1329
|
+
const spawnEnv = isCommandOnly ? getCleanEnv() : process.env;
|
|
1330
|
+
logDebug(`Spawning Claude Code process: ${spawnCommand} ${spawnArgs.join(" ")} (using ${isCommandOnly ? "clean" : "normal"} env)`);
|
|
1331
|
+
const child = spawn(spawnCommand, spawnArgs, {
|
|
1235
1332
|
cwd,
|
|
1236
1333
|
stdio: ["pipe", "pipe", "pipe"],
|
|
1237
1334
|
signal: config.options?.abort,
|
|
1238
|
-
env:
|
|
1239
|
-
|
|
1240
|
-
|
|
1335
|
+
env: spawnEnv,
|
|
1336
|
+
// Use shell on Windows for global binaries and command-only mode
|
|
1337
|
+
shell: !isJsFile && process.platform === "win32"
|
|
1241
1338
|
});
|
|
1242
1339
|
let childStdin = null;
|
|
1243
1340
|
if (typeof prompt === "string") {
|
|
@@ -4583,8 +4680,7 @@ async function startHappyServer(client) {
|
|
|
4583
4680
|
};
|
|
4584
4681
|
const mcp = new McpServer({
|
|
4585
4682
|
name: "Happy MCP",
|
|
4586
|
-
version: "1.0.0"
|
|
4587
|
-
description: "Happy CLI MCP server with chat session management tools"
|
|
4683
|
+
version: "1.0.0"
|
|
4588
4684
|
});
|
|
4589
4685
|
mcp.registerTool("change_title", {
|
|
4590
4686
|
description: "Change the title of the current chat session",
|
|
@@ -4675,7 +4771,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
4675
4771
|
const settings = await readSettings();
|
|
4676
4772
|
let machineId = settings?.machineId;
|
|
4677
4773
|
if (!machineId) {
|
|
4678
|
-
console.error(`[START] No machine ID found in settings, which is
|
|
4774
|
+
console.error(`[START] No machine ID found in settings, which is unexpected since authAndSetupMachineIfNeeded should have created it. Please report this issue on https://github.com/slopus/happy-cli/issues`);
|
|
4679
4775
|
process.exit(1);
|
|
4680
4776
|
}
|
|
4681
4777
|
logger.debug(`Using machineId: ${machineId}`);
|
|
@@ -5794,7 +5890,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
5794
5890
|
return;
|
|
5795
5891
|
} else if (subcommand === "codex") {
|
|
5796
5892
|
try {
|
|
5797
|
-
const { runCodex } = await import('./runCodex-
|
|
5893
|
+
const { runCodex } = await import('./runCodex-BgCwl6pc.mjs');
|
|
5798
5894
|
let startedBy = void 0;
|
|
5799
5895
|
for (let i = 1; i < args.length; i++) {
|
|
5800
5896
|
if (args[i] === "--started-by") {
|