@zhigang1992/happy-cli 0.12.16 → 0.13.2
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/README.md +3 -3
- package/dist/{index-QoInQfUK.cjs → index-DgAw_5N1.cjs} +58 -77
- package/dist/{index-CLXYGqXj.mjs → index-Uj38Af20.mjs} +57 -76
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{list-CDicC5yo.mjs → list-CrgHUL0f.mjs} +1 -1
- package/dist/{list-E9fTkqQp.cjs → list-DTZJgObu.cjs} +1 -1
- package/dist/{prompt-B3lEGFCq.cjs → prompt-DA5MCiiO.cjs} +1 -1
- package/dist/{prompt-BjBlo4Gl.mjs → prompt-DQg5bz0P.mjs} +1 -1
- package/dist/{runCodex-DjF_K8ec.mjs → runCodex-C6yOfirQ.mjs} +2 -2
- package/dist/{runCodex-C5yIxRCL.cjs → runCodex-wtcLFv8_.cjs} +2 -2
- package/dist/{types-BH9WdkTA.cjs → types-Cd6JAaoe.cjs} +4 -4
- package/dist/{types-B8kwdDOp.mjs → types-DTrmDfm5.mjs} +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
## Fork Changes
|
|
8
8
|
|
|
9
9
|
- Renamed package to `@zhigang1992/happy-cli` for personal npm publishing
|
|
10
|
-
- Changed default server URLs to `happy-server.
|
|
10
|
+
- Changed default server URLs to `happy-server.innopals.com` and `happy.innopals.com`
|
|
11
11
|
- Switched from yarn to bun
|
|
12
12
|
- Lazy download of tools to reduce package size (~110MB to ~186KB)
|
|
13
13
|
- Added image attachment support in messages
|
|
@@ -59,8 +59,8 @@ This will:
|
|
|
59
59
|
|
|
60
60
|
## Environment Variables
|
|
61
61
|
|
|
62
|
-
- `HAPPY_SERVER_URL` - Custom server URL (default: https://happy-server.
|
|
63
|
-
- `HAPPY_WEBAPP_URL` - Custom web app URL (default: https://happy.
|
|
62
|
+
- `HAPPY_SERVER_URL` - Custom server URL (default: https://happy-server.innopals.com)
|
|
63
|
+
- `HAPPY_WEBAPP_URL` - Custom web app URL (default: https://happy.innopals.com)
|
|
64
64
|
- `HAPPY_HOME_DIR` - Custom home directory for Happy data (default: ~/.happy)
|
|
65
65
|
- `HAPPY_DISABLE_CAFFEINATE` - Disable macOS sleep prevention (set to `true`, `1`, or `yes`)
|
|
66
66
|
- `HAPPY_EXPERIMENTAL` - Enable experimental features (set to `true`, `1`, or `yes`)
|
|
@@ -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-
|
|
6
|
+
var types = require('./types-Cd6JAaoe.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-
|
|
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-DgAw_5N1.cjs', document.baseURI).href)));
|
|
1188
1188
|
const __dirname$1 = node_path.join(__filename$1, "..");
|
|
1189
1189
|
function getGlobalClaudeVersion() {
|
|
1190
1190
|
try {
|
|
@@ -2097,6 +2097,45 @@ Echo message: ${echoMessage}` : "");
|
|
|
2097
2097
|
prompt: messages,
|
|
2098
2098
|
options: sdkOptions
|
|
2099
2099
|
});
|
|
2100
|
+
let waitingForNextMessage = false;
|
|
2101
|
+
let messagePusherStopped = false;
|
|
2102
|
+
const messagePusherTask = (async () => {
|
|
2103
|
+
try {
|
|
2104
|
+
while (!messagePusherStopped) {
|
|
2105
|
+
if (!waitingForNextMessage) {
|
|
2106
|
+
await new Promise((resolve2) => {
|
|
2107
|
+
const checkInterval = setInterval(() => {
|
|
2108
|
+
if (waitingForNextMessage || messagePusherStopped) {
|
|
2109
|
+
clearInterval(checkInterval);
|
|
2110
|
+
resolve2();
|
|
2111
|
+
}
|
|
2112
|
+
}, 10);
|
|
2113
|
+
});
|
|
2114
|
+
}
|
|
2115
|
+
if (messagePusherStopped) {
|
|
2116
|
+
break;
|
|
2117
|
+
}
|
|
2118
|
+
types.logger.debug("[claudeRemote] Message pusher waiting for next message");
|
|
2119
|
+
const next = await opts.nextMessage();
|
|
2120
|
+
if (!next) {
|
|
2121
|
+
types.logger.debug("[claudeRemote] No more messages, ending message stream");
|
|
2122
|
+
messages.end();
|
|
2123
|
+
break;
|
|
2124
|
+
}
|
|
2125
|
+
types.logger.debug("[claudeRemote] Message pusher received new message, pushing to SDK");
|
|
2126
|
+
mode = next.mode;
|
|
2127
|
+
const nextContent = await buildMessageContent(next.message, next.mode.imageRefs);
|
|
2128
|
+
messages.push({
|
|
2129
|
+
type: "user",
|
|
2130
|
+
uuid: node_crypto.randomUUID(),
|
|
2131
|
+
message: { role: "user", content: nextContent }
|
|
2132
|
+
});
|
|
2133
|
+
waitingForNextMessage = false;
|
|
2134
|
+
}
|
|
2135
|
+
} catch (e) {
|
|
2136
|
+
types.logger.debug("[claudeRemote] Message pusher error:", e);
|
|
2137
|
+
}
|
|
2138
|
+
})();
|
|
2100
2139
|
updateThinking(true);
|
|
2101
2140
|
try {
|
|
2102
2141
|
types.logger.debug(`[claudeRemote] Starting to iterate over response`);
|
|
@@ -2116,7 +2155,7 @@ Echo message: ${echoMessage}` : "");
|
|
|
2116
2155
|
}
|
|
2117
2156
|
if (message.type === "result") {
|
|
2118
2157
|
updateThinking(false);
|
|
2119
|
-
types.logger.debug("[claudeRemote] Result received
|
|
2158
|
+
types.logger.debug("[claudeRemote] Result received");
|
|
2120
2159
|
if (isCompactCommand) {
|
|
2121
2160
|
types.logger.debug("[claudeRemote] Compaction completed");
|
|
2122
2161
|
if (opts.onCompletionEvent) {
|
|
@@ -2125,19 +2164,7 @@ Echo message: ${echoMessage}` : "");
|
|
|
2125
2164
|
isCompactCommand = false;
|
|
2126
2165
|
}
|
|
2127
2166
|
opts.onReady();
|
|
2128
|
-
|
|
2129
|
-
if (!next) {
|
|
2130
|
-
messages.end();
|
|
2131
|
-
return;
|
|
2132
|
-
}
|
|
2133
|
-
mode = next.mode;
|
|
2134
|
-
const nextContent = await buildMessageContent(next.message, next.mode.imageRefs);
|
|
2135
|
-
messages.push({
|
|
2136
|
-
type: "user",
|
|
2137
|
-
uuid: node_crypto.randomUUID(),
|
|
2138
|
-
// UUID is required for Claude CLI streaming mode
|
|
2139
|
-
message: { role: "user", content: nextContent }
|
|
2140
|
-
});
|
|
2167
|
+
waitingForNextMessage = true;
|
|
2141
2168
|
}
|
|
2142
2169
|
if (message.type === "user") {
|
|
2143
2170
|
const msg = message;
|
|
@@ -2145,6 +2172,7 @@ Echo message: ${echoMessage}` : "");
|
|
|
2145
2172
|
for (let c of msg.message.content) {
|
|
2146
2173
|
if (c.type === "tool_result" && c.tool_use_id && opts.isAborted(c.tool_use_id)) {
|
|
2147
2174
|
types.logger.debug("[claudeRemote] Tool aborted, exiting claudeRemote");
|
|
2175
|
+
messagePusherStopped = true;
|
|
2148
2176
|
return;
|
|
2149
2177
|
}
|
|
2150
2178
|
}
|
|
@@ -2159,12 +2187,14 @@ Echo message: ${echoMessage}` : "");
|
|
|
2159
2187
|
}
|
|
2160
2188
|
} finally {
|
|
2161
2189
|
updateThinking(false);
|
|
2190
|
+
messagePusherStopped = true;
|
|
2191
|
+
await Promise.race([
|
|
2192
|
+
messagePusherTask,
|
|
2193
|
+
new Promise((resolve2) => setTimeout(resolve2, 100))
|
|
2194
|
+
]);
|
|
2162
2195
|
}
|
|
2163
2196
|
}
|
|
2164
2197
|
|
|
2165
|
-
const PLAN_FAKE_REJECT = `User approved plan, but you need to be restarted. STOP IMMEDIATELY TO SWITCH FROM PLAN MODE. DO NOT REPLY TO THIS MESSAGE.`;
|
|
2166
|
-
const PLAN_FAKE_RESTART = `PlEaZe Continue with plan.`;
|
|
2167
|
-
|
|
2168
2198
|
function deepEqual(a, b) {
|
|
2169
2199
|
if (a === b) return true;
|
|
2170
2200
|
if (a == null || b == null) return false;
|
|
@@ -2275,15 +2305,10 @@ class PermissionHandler {
|
|
|
2275
2305
|
if (pending.toolName === "exit_plan_mode" || pending.toolName === "ExitPlanMode") {
|
|
2276
2306
|
types.logger.debug("Plan mode result received", response);
|
|
2277
2307
|
if (response.approved) {
|
|
2278
|
-
types.logger.debug("Plan approved -
|
|
2279
|
-
|
|
2280
|
-
this.session.queue.unshift(PLAN_FAKE_RESTART, { permissionMode: response.mode });
|
|
2281
|
-
} else {
|
|
2282
|
-
this.session.queue.unshift(PLAN_FAKE_RESTART, { permissionMode: "default" });
|
|
2283
|
-
}
|
|
2284
|
-
pending.resolve({ behavior: "deny", message: PLAN_FAKE_REJECT });
|
|
2308
|
+
types.logger.debug("Plan approved - continuing normally");
|
|
2309
|
+
pending.resolve({ behavior: "allow", updatedInput: pending.input || {} });
|
|
2285
2310
|
} else {
|
|
2286
|
-
pending.resolve({ behavior: "deny", message: response.reason || "Plan rejected" });
|
|
2311
|
+
pending.resolve({ behavior: "deny", message: response.reason || "Plan rejected by user. Ask the user what changes they would like to make to the plan." });
|
|
2287
2312
|
}
|
|
2288
2313
|
} else if (pending.toolName === "AskUserQuestion") {
|
|
2289
2314
|
if (response.approved) {
|
|
@@ -2320,7 +2345,8 @@ class PermissionHandler {
|
|
|
2320
2345
|
return { behavior: "allow", updatedInput: input };
|
|
2321
2346
|
}
|
|
2322
2347
|
const descriptor = getToolDescriptor(toolName);
|
|
2323
|
-
|
|
2348
|
+
const requiresUserInteraction = toolName === "AskUserQuestion" || toolName === "ExitPlanMode" || toolName === "exit_plan_mode";
|
|
2349
|
+
if (!requiresUserInteraction) {
|
|
2324
2350
|
if (this.permissionMode === "bypassPermissions") {
|
|
2325
2351
|
return { behavior: "allow", updatedInput: input };
|
|
2326
2352
|
}
|
|
@@ -2463,10 +2489,6 @@ class PermissionHandler {
|
|
|
2463
2489
|
if (this.responses.get(toolCallId)?.approved === false) {
|
|
2464
2490
|
return true;
|
|
2465
2491
|
}
|
|
2466
|
-
const toolCall = this.toolCalls.find((tc) => tc.id === toolCallId);
|
|
2467
|
-
if (toolCall && (toolCall.name === "exit_plan_mode" || toolCall.name === "ExitPlanMode")) {
|
|
2468
|
-
return true;
|
|
2469
|
-
}
|
|
2470
2492
|
return false;
|
|
2471
2493
|
}
|
|
2472
2494
|
/**
|
|
@@ -3093,22 +3115,10 @@ async function claudeRemoteLauncher(session) {
|
|
|
3093
3115
|
cwd: session.path,
|
|
3094
3116
|
version: process.env.npm_package_version
|
|
3095
3117
|
}, permissionHandler.getResponses());
|
|
3096
|
-
let planModeToolCalls = /* @__PURE__ */ new Set();
|
|
3097
3118
|
let ongoingToolCalls = /* @__PURE__ */ new Map();
|
|
3098
3119
|
function onMessage(message) {
|
|
3099
3120
|
formatClaudeMessageForInk(message, messageBuffer);
|
|
3100
3121
|
permissionHandler.onMessage(message);
|
|
3101
|
-
if (message.type === "assistant") {
|
|
3102
|
-
let umessage = message;
|
|
3103
|
-
if (umessage.message.content && Array.isArray(umessage.message.content)) {
|
|
3104
|
-
for (let c of umessage.message.content) {
|
|
3105
|
-
if (c.type === "tool_use" && (c.name === "exit_plan_mode" || c.name === "ExitPlanMode")) {
|
|
3106
|
-
types.logger.debug("[remote]: detected plan mode tool call " + c.id);
|
|
3107
|
-
planModeToolCalls.add(c.id);
|
|
3108
|
-
}
|
|
3109
|
-
}
|
|
3110
|
-
}
|
|
3111
|
-
}
|
|
3112
3122
|
if (message.type === "assistant") {
|
|
3113
3123
|
let umessage = message;
|
|
3114
3124
|
if (umessage.message.content && Array.isArray(umessage.message.content)) {
|
|
@@ -3131,36 +3141,7 @@ async function claudeRemoteLauncher(session) {
|
|
|
3131
3141
|
}
|
|
3132
3142
|
}
|
|
3133
3143
|
}
|
|
3134
|
-
|
|
3135
|
-
if (message.type === "user") {
|
|
3136
|
-
let umessage = message;
|
|
3137
|
-
if (umessage.message.content && Array.isArray(umessage.message.content)) {
|
|
3138
|
-
msg = {
|
|
3139
|
-
...umessage,
|
|
3140
|
-
message: {
|
|
3141
|
-
...umessage.message,
|
|
3142
|
-
content: umessage.message.content.map((c) => {
|
|
3143
|
-
if (c.type === "tool_result" && c.tool_use_id && planModeToolCalls.has(c.tool_use_id)) {
|
|
3144
|
-
if (c.content === PLAN_FAKE_REJECT) {
|
|
3145
|
-
types.logger.debug("[remote]: hack plan mode exit");
|
|
3146
|
-
types.logger.debugLargeJson("[remote]: hack plan mode exit", c);
|
|
3147
|
-
return {
|
|
3148
|
-
...c,
|
|
3149
|
-
is_error: false,
|
|
3150
|
-
content: "Plan approved",
|
|
3151
|
-
mode: c.mode
|
|
3152
|
-
};
|
|
3153
|
-
} else {
|
|
3154
|
-
return c;
|
|
3155
|
-
}
|
|
3156
|
-
}
|
|
3157
|
-
return c;
|
|
3158
|
-
})
|
|
3159
|
-
}
|
|
3160
|
-
};
|
|
3161
|
-
}
|
|
3162
|
-
}
|
|
3163
|
-
const logMessage = sdkToLogConverter.convert(msg);
|
|
3144
|
+
const logMessage = sdkToLogConverter.convert(message);
|
|
3164
3145
|
if (logMessage) {
|
|
3165
3146
|
if (logMessage.type === "user" && logMessage.message?.content) {
|
|
3166
3147
|
const content = Array.isArray(logMessage.message.content) ? logMessage.message.content : [];
|
|
@@ -7037,7 +7018,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
7037
7018
|
return;
|
|
7038
7019
|
} else if (subcommand === "codex") {
|
|
7039
7020
|
try {
|
|
7040
|
-
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-
|
|
7021
|
+
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-wtcLFv8_.cjs'); });
|
|
7041
7022
|
let startedBy = void 0;
|
|
7042
7023
|
for (let i = 1; i < args.length; i++) {
|
|
7043
7024
|
if (args[i] === "--started-by") {
|
|
@@ -7082,7 +7063,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
7082
7063
|
} else if (subcommand === "list") {
|
|
7083
7064
|
try {
|
|
7084
7065
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
7085
|
-
const { listSessions } = await Promise.resolve().then(function () { return require('./list-
|
|
7066
|
+
const { listSessions } = await Promise.resolve().then(function () { return require('./list-DTZJgObu.cjs'); });
|
|
7086
7067
|
let sessionId;
|
|
7087
7068
|
let titleFilter;
|
|
7088
7069
|
let recentMsgs;
|
|
@@ -7184,7 +7165,7 @@ Examples:
|
|
|
7184
7165
|
process.exit(1);
|
|
7185
7166
|
}
|
|
7186
7167
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
7187
|
-
const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-
|
|
7168
|
+
const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-DA5MCiiO.cjs'); });
|
|
7188
7169
|
await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
|
|
7189
7170
|
} catch (error) {
|
|
7190
7171
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -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-
|
|
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-DTrmDfm5.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';
|
|
@@ -2074,6 +2074,45 @@ Echo message: ${echoMessage}` : "");
|
|
|
2074
2074
|
prompt: messages,
|
|
2075
2075
|
options: sdkOptions
|
|
2076
2076
|
});
|
|
2077
|
+
let waitingForNextMessage = false;
|
|
2078
|
+
let messagePusherStopped = false;
|
|
2079
|
+
const messagePusherTask = (async () => {
|
|
2080
|
+
try {
|
|
2081
|
+
while (!messagePusherStopped) {
|
|
2082
|
+
if (!waitingForNextMessage) {
|
|
2083
|
+
await new Promise((resolve2) => {
|
|
2084
|
+
const checkInterval = setInterval(() => {
|
|
2085
|
+
if (waitingForNextMessage || messagePusherStopped) {
|
|
2086
|
+
clearInterval(checkInterval);
|
|
2087
|
+
resolve2();
|
|
2088
|
+
}
|
|
2089
|
+
}, 10);
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
if (messagePusherStopped) {
|
|
2093
|
+
break;
|
|
2094
|
+
}
|
|
2095
|
+
logger.debug("[claudeRemote] Message pusher waiting for next message");
|
|
2096
|
+
const next = await opts.nextMessage();
|
|
2097
|
+
if (!next) {
|
|
2098
|
+
logger.debug("[claudeRemote] No more messages, ending message stream");
|
|
2099
|
+
messages.end();
|
|
2100
|
+
break;
|
|
2101
|
+
}
|
|
2102
|
+
logger.debug("[claudeRemote] Message pusher received new message, pushing to SDK");
|
|
2103
|
+
mode = next.mode;
|
|
2104
|
+
const nextContent = await buildMessageContent(next.message, next.mode.imageRefs);
|
|
2105
|
+
messages.push({
|
|
2106
|
+
type: "user",
|
|
2107
|
+
uuid: randomUUID(),
|
|
2108
|
+
message: { role: "user", content: nextContent }
|
|
2109
|
+
});
|
|
2110
|
+
waitingForNextMessage = false;
|
|
2111
|
+
}
|
|
2112
|
+
} catch (e) {
|
|
2113
|
+
logger.debug("[claudeRemote] Message pusher error:", e);
|
|
2114
|
+
}
|
|
2115
|
+
})();
|
|
2077
2116
|
updateThinking(true);
|
|
2078
2117
|
try {
|
|
2079
2118
|
logger.debug(`[claudeRemote] Starting to iterate over response`);
|
|
@@ -2093,7 +2132,7 @@ Echo message: ${echoMessage}` : "");
|
|
|
2093
2132
|
}
|
|
2094
2133
|
if (message.type === "result") {
|
|
2095
2134
|
updateThinking(false);
|
|
2096
|
-
logger.debug("[claudeRemote] Result received
|
|
2135
|
+
logger.debug("[claudeRemote] Result received");
|
|
2097
2136
|
if (isCompactCommand) {
|
|
2098
2137
|
logger.debug("[claudeRemote] Compaction completed");
|
|
2099
2138
|
if (opts.onCompletionEvent) {
|
|
@@ -2102,19 +2141,7 @@ Echo message: ${echoMessage}` : "");
|
|
|
2102
2141
|
isCompactCommand = false;
|
|
2103
2142
|
}
|
|
2104
2143
|
opts.onReady();
|
|
2105
|
-
|
|
2106
|
-
if (!next) {
|
|
2107
|
-
messages.end();
|
|
2108
|
-
return;
|
|
2109
|
-
}
|
|
2110
|
-
mode = next.mode;
|
|
2111
|
-
const nextContent = await buildMessageContent(next.message, next.mode.imageRefs);
|
|
2112
|
-
messages.push({
|
|
2113
|
-
type: "user",
|
|
2114
|
-
uuid: randomUUID(),
|
|
2115
|
-
// UUID is required for Claude CLI streaming mode
|
|
2116
|
-
message: { role: "user", content: nextContent }
|
|
2117
|
-
});
|
|
2144
|
+
waitingForNextMessage = true;
|
|
2118
2145
|
}
|
|
2119
2146
|
if (message.type === "user") {
|
|
2120
2147
|
const msg = message;
|
|
@@ -2122,6 +2149,7 @@ Echo message: ${echoMessage}` : "");
|
|
|
2122
2149
|
for (let c of msg.message.content) {
|
|
2123
2150
|
if (c.type === "tool_result" && c.tool_use_id && opts.isAborted(c.tool_use_id)) {
|
|
2124
2151
|
logger.debug("[claudeRemote] Tool aborted, exiting claudeRemote");
|
|
2152
|
+
messagePusherStopped = true;
|
|
2125
2153
|
return;
|
|
2126
2154
|
}
|
|
2127
2155
|
}
|
|
@@ -2136,12 +2164,14 @@ Echo message: ${echoMessage}` : "");
|
|
|
2136
2164
|
}
|
|
2137
2165
|
} finally {
|
|
2138
2166
|
updateThinking(false);
|
|
2167
|
+
messagePusherStopped = true;
|
|
2168
|
+
await Promise.race([
|
|
2169
|
+
messagePusherTask,
|
|
2170
|
+
new Promise((resolve2) => setTimeout(resolve2, 100))
|
|
2171
|
+
]);
|
|
2139
2172
|
}
|
|
2140
2173
|
}
|
|
2141
2174
|
|
|
2142
|
-
const PLAN_FAKE_REJECT = `User approved plan, but you need to be restarted. STOP IMMEDIATELY TO SWITCH FROM PLAN MODE. DO NOT REPLY TO THIS MESSAGE.`;
|
|
2143
|
-
const PLAN_FAKE_RESTART = `PlEaZe Continue with plan.`;
|
|
2144
|
-
|
|
2145
2175
|
function deepEqual(a, b) {
|
|
2146
2176
|
if (a === b) return true;
|
|
2147
2177
|
if (a == null || b == null) return false;
|
|
@@ -2252,15 +2282,10 @@ class PermissionHandler {
|
|
|
2252
2282
|
if (pending.toolName === "exit_plan_mode" || pending.toolName === "ExitPlanMode") {
|
|
2253
2283
|
logger.debug("Plan mode result received", response);
|
|
2254
2284
|
if (response.approved) {
|
|
2255
|
-
logger.debug("Plan approved -
|
|
2256
|
-
|
|
2257
|
-
this.session.queue.unshift(PLAN_FAKE_RESTART, { permissionMode: response.mode });
|
|
2258
|
-
} else {
|
|
2259
|
-
this.session.queue.unshift(PLAN_FAKE_RESTART, { permissionMode: "default" });
|
|
2260
|
-
}
|
|
2261
|
-
pending.resolve({ behavior: "deny", message: PLAN_FAKE_REJECT });
|
|
2285
|
+
logger.debug("Plan approved - continuing normally");
|
|
2286
|
+
pending.resolve({ behavior: "allow", updatedInput: pending.input || {} });
|
|
2262
2287
|
} else {
|
|
2263
|
-
pending.resolve({ behavior: "deny", message: response.reason || "Plan rejected" });
|
|
2288
|
+
pending.resolve({ behavior: "deny", message: response.reason || "Plan rejected by user. Ask the user what changes they would like to make to the plan." });
|
|
2264
2289
|
}
|
|
2265
2290
|
} else if (pending.toolName === "AskUserQuestion") {
|
|
2266
2291
|
if (response.approved) {
|
|
@@ -2297,7 +2322,8 @@ class PermissionHandler {
|
|
|
2297
2322
|
return { behavior: "allow", updatedInput: input };
|
|
2298
2323
|
}
|
|
2299
2324
|
const descriptor = getToolDescriptor(toolName);
|
|
2300
|
-
|
|
2325
|
+
const requiresUserInteraction = toolName === "AskUserQuestion" || toolName === "ExitPlanMode" || toolName === "exit_plan_mode";
|
|
2326
|
+
if (!requiresUserInteraction) {
|
|
2301
2327
|
if (this.permissionMode === "bypassPermissions") {
|
|
2302
2328
|
return { behavior: "allow", updatedInput: input };
|
|
2303
2329
|
}
|
|
@@ -2440,10 +2466,6 @@ class PermissionHandler {
|
|
|
2440
2466
|
if (this.responses.get(toolCallId)?.approved === false) {
|
|
2441
2467
|
return true;
|
|
2442
2468
|
}
|
|
2443
|
-
const toolCall = this.toolCalls.find((tc) => tc.id === toolCallId);
|
|
2444
|
-
if (toolCall && (toolCall.name === "exit_plan_mode" || toolCall.name === "ExitPlanMode")) {
|
|
2445
|
-
return true;
|
|
2446
|
-
}
|
|
2447
2469
|
return false;
|
|
2448
2470
|
}
|
|
2449
2471
|
/**
|
|
@@ -3070,22 +3092,10 @@ async function claudeRemoteLauncher(session) {
|
|
|
3070
3092
|
cwd: session.path,
|
|
3071
3093
|
version: process.env.npm_package_version
|
|
3072
3094
|
}, permissionHandler.getResponses());
|
|
3073
|
-
let planModeToolCalls = /* @__PURE__ */ new Set();
|
|
3074
3095
|
let ongoingToolCalls = /* @__PURE__ */ new Map();
|
|
3075
3096
|
function onMessage(message) {
|
|
3076
3097
|
formatClaudeMessageForInk(message, messageBuffer);
|
|
3077
3098
|
permissionHandler.onMessage(message);
|
|
3078
|
-
if (message.type === "assistant") {
|
|
3079
|
-
let umessage = message;
|
|
3080
|
-
if (umessage.message.content && Array.isArray(umessage.message.content)) {
|
|
3081
|
-
for (let c of umessage.message.content) {
|
|
3082
|
-
if (c.type === "tool_use" && (c.name === "exit_plan_mode" || c.name === "ExitPlanMode")) {
|
|
3083
|
-
logger.debug("[remote]: detected plan mode tool call " + c.id);
|
|
3084
|
-
planModeToolCalls.add(c.id);
|
|
3085
|
-
}
|
|
3086
|
-
}
|
|
3087
|
-
}
|
|
3088
|
-
}
|
|
3089
3099
|
if (message.type === "assistant") {
|
|
3090
3100
|
let umessage = message;
|
|
3091
3101
|
if (umessage.message.content && Array.isArray(umessage.message.content)) {
|
|
@@ -3108,36 +3118,7 @@ async function claudeRemoteLauncher(session) {
|
|
|
3108
3118
|
}
|
|
3109
3119
|
}
|
|
3110
3120
|
}
|
|
3111
|
-
|
|
3112
|
-
if (message.type === "user") {
|
|
3113
|
-
let umessage = message;
|
|
3114
|
-
if (umessage.message.content && Array.isArray(umessage.message.content)) {
|
|
3115
|
-
msg = {
|
|
3116
|
-
...umessage,
|
|
3117
|
-
message: {
|
|
3118
|
-
...umessage.message,
|
|
3119
|
-
content: umessage.message.content.map((c) => {
|
|
3120
|
-
if (c.type === "tool_result" && c.tool_use_id && planModeToolCalls.has(c.tool_use_id)) {
|
|
3121
|
-
if (c.content === PLAN_FAKE_REJECT) {
|
|
3122
|
-
logger.debug("[remote]: hack plan mode exit");
|
|
3123
|
-
logger.debugLargeJson("[remote]: hack plan mode exit", c);
|
|
3124
|
-
return {
|
|
3125
|
-
...c,
|
|
3126
|
-
is_error: false,
|
|
3127
|
-
content: "Plan approved",
|
|
3128
|
-
mode: c.mode
|
|
3129
|
-
};
|
|
3130
|
-
} else {
|
|
3131
|
-
return c;
|
|
3132
|
-
}
|
|
3133
|
-
}
|
|
3134
|
-
return c;
|
|
3135
|
-
})
|
|
3136
|
-
}
|
|
3137
|
-
};
|
|
3138
|
-
}
|
|
3139
|
-
}
|
|
3140
|
-
const logMessage = sdkToLogConverter.convert(msg);
|
|
3121
|
+
const logMessage = sdkToLogConverter.convert(message);
|
|
3141
3122
|
if (logMessage) {
|
|
3142
3123
|
if (logMessage.type === "user" && logMessage.message?.content) {
|
|
3143
3124
|
const content = Array.isArray(logMessage.message.content) ? logMessage.message.content : [];
|
|
@@ -7014,7 +6995,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
7014
6995
|
return;
|
|
7015
6996
|
} else if (subcommand === "codex") {
|
|
7016
6997
|
try {
|
|
7017
|
-
const { runCodex } = await import('./runCodex-
|
|
6998
|
+
const { runCodex } = await import('./runCodex-C6yOfirQ.mjs');
|
|
7018
6999
|
let startedBy = void 0;
|
|
7019
7000
|
for (let i = 1; i < args.length; i++) {
|
|
7020
7001
|
if (args[i] === "--started-by") {
|
|
@@ -7059,7 +7040,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
7059
7040
|
} else if (subcommand === "list") {
|
|
7060
7041
|
try {
|
|
7061
7042
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
7062
|
-
const { listSessions } = await import('./list-
|
|
7043
|
+
const { listSessions } = await import('./list-CrgHUL0f.mjs');
|
|
7063
7044
|
let sessionId;
|
|
7064
7045
|
let titleFilter;
|
|
7065
7046
|
let recentMsgs;
|
|
@@ -7161,7 +7142,7 @@ Examples:
|
|
|
7161
7142
|
process.exit(1);
|
|
7162
7143
|
}
|
|
7163
7144
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
7164
|
-
const { promptSession } = await import('./prompt-
|
|
7145
|
+
const { promptSession } = await import('./prompt-DQg5bz0P.mjs');
|
|
7165
7146
|
await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
|
|
7166
7147
|
} catch (error) {
|
|
7167
7148
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
package/dist/lib.cjs
CHANGED
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-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-DTrmDfm5.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'fs';
|
|
@@ -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-
|
|
1
|
+
import { c as configuration, l as logger, d as decodeBase64, b as decrypt, f as formatTimeAgo, e as libsodiumDecryptFromPublicKey } from './types-DTrmDfm5.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-
|
|
1
|
+
import { c as configuration, b as decrypt, d as decodeBase64, l as logger, g as encodeBase64, h as encrypt } from './types-DTrmDfm5.mjs';
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { io } from 'socket.io-client';
|
|
4
4
|
import '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-
|
|
3
|
+
import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, i as packageJson } from './types-DTrmDfm5.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-
|
|
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-Uj38Af20.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-
|
|
5
|
+
var types = require('./types-Cd6JAaoe.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-
|
|
12
|
+
var index = require('./index-DgAw_5N1.cjs');
|
|
13
13
|
var os = require('node:os');
|
|
14
14
|
var node_path = require('node:path');
|
|
15
15
|
var fs = require('node:fs');
|
|
@@ -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.
|
|
44
|
+
var version = "0.13.2";
|
|
45
45
|
var description = "Mobile and Web client for Claude Code and Codex";
|
|
46
46
|
var author = "Kirill Dubovitskiy";
|
|
47
47
|
var license = "MIT";
|
|
@@ -202,8 +202,8 @@ class Configuration {
|
|
|
202
202
|
isExperimentalEnabled;
|
|
203
203
|
disableCaffeinate;
|
|
204
204
|
constructor() {
|
|
205
|
-
this.serverUrl = process.env.HAPPY_SERVER_URL || "https://happy-server.
|
|
206
|
-
this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://happy.
|
|
205
|
+
this.serverUrl = process.env.HAPPY_SERVER_URL || "https://happy-server.innopals.com";
|
|
206
|
+
this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://happy.innopals.com";
|
|
207
207
|
const args = process.argv.slice(2);
|
|
208
208
|
this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
|
|
209
209
|
if (process.env.HAPPY_HOME_DIR) {
|
|
@@ -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-
|
|
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-Cd6JAaoe.cjs', document.baseURI).href))));
|
|
1154
1154
|
function projectPath() {
|
|
1155
1155
|
const path$1 = path.resolve(__dirname$1, "..");
|
|
1156
1156
|
return path$1;
|
|
@@ -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.
|
|
23
|
+
var version = "0.13.2";
|
|
24
24
|
var description = "Mobile and Web client for Claude Code and Codex";
|
|
25
25
|
var author = "Kirill Dubovitskiy";
|
|
26
26
|
var license = "MIT";
|
|
@@ -181,8 +181,8 @@ class Configuration {
|
|
|
181
181
|
isExperimentalEnabled;
|
|
182
182
|
disableCaffeinate;
|
|
183
183
|
constructor() {
|
|
184
|
-
this.serverUrl = process.env.HAPPY_SERVER_URL || "https://happy-server.
|
|
185
|
-
this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://happy.
|
|
184
|
+
this.serverUrl = process.env.HAPPY_SERVER_URL || "https://happy-server.innopals.com";
|
|
185
|
+
this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://happy.innopals.com";
|
|
186
186
|
const args = process.argv.slice(2);
|
|
187
187
|
this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
|
|
188
188
|
if (process.env.HAPPY_HOME_DIR) {
|