@zhigang1992/happy-cli 0.12.6 → 0.12.10
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 +20 -2
- package/dist/{index-BkDVLUcE.cjs → index-B2T-8Qkp.cjs} +50 -23
- package/dist/{index-h3SrsKqR.mjs → index-xZm9eMZ-.mjs} +54 -27
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +5 -0
- package/dist/lib.d.mts +5 -0
- package/dist/lib.mjs +1 -1
- package/dist/{list-LCFlAICJ.cjs → list-CE0RKOOh.cjs} +1 -1
- package/dist/{list-BJBPeYMn.mjs → list-DwEmJUfq.mjs} +1 -1
- package/dist/{prompt-B35fwI-i.mjs → prompt-B4TvNDA2.mjs} +1 -1
- package/dist/{prompt-B0ezty5F.cjs → prompt-IezYY014.cjs} +1 -1
- package/dist/{runCodex-uPJ1h0J4.cjs → runCodex-CFnERFiI.cjs} +6 -4
- package/dist/{runCodex-BarDBoPV.mjs → runCodex-CjK_Hx1-.mjs} +6 -4
- package/dist/{types-Cn6qSxMP.mjs → types-DeW4Ii33.mjs} +10 -3
- package/dist/{types-Bd_EJ8VV.cjs → types-jTJmEbfZ.cjs} +11 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
# Happy CLI (Fork)
|
|
2
|
+
|
|
3
|
+
> **This is a personal fork of [happy-cli](https://github.com/slopus/happy-cli) from the amazing [Happy](https://happy.engineering) project.**
|
|
4
|
+
>
|
|
5
|
+
> All credit goes to the original authors. I've made some tweaks for my own self-hosted setup, but my changes are too scattered and experimental to submit upstream. If you're looking for the official version, please visit [github.com/slopus/happy-cli](https://github.com/slopus/happy-cli).
|
|
6
|
+
|
|
7
|
+
## Fork Changes
|
|
8
|
+
|
|
9
|
+
- Renamed package to `@zhigang1992/happy-cli` for personal npm publishing
|
|
10
|
+
- Changed default server URLs to `happy-server.reily.app` and `happy.reily.app`
|
|
11
|
+
- Switched from yarn to bun
|
|
12
|
+
- Lazy download of tools to reduce package size (~110MB to ~186KB)
|
|
13
|
+
- Added image attachment support in messages
|
|
14
|
+
- Improved push notifications with folder name
|
|
15
|
+
- Various bug fixes and improvements
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
1
19
|
# Happy
|
|
2
20
|
|
|
3
21
|
Code on the go controlling claude code from your mobile device.
|
|
@@ -41,8 +59,8 @@ This will:
|
|
|
41
59
|
|
|
42
60
|
## Environment Variables
|
|
43
61
|
|
|
44
|
-
- `HAPPY_SERVER_URL` - Custom server URL (default: https://
|
|
45
|
-
- `HAPPY_WEBAPP_URL` - Custom web app URL (default: https://
|
|
62
|
+
- `HAPPY_SERVER_URL` - Custom server URL (default: https://happy-server.reily.app)
|
|
63
|
+
- `HAPPY_WEBAPP_URL` - Custom web app URL (default: https://happy.reily.app)
|
|
46
64
|
- `HAPPY_HOME_DIR` - Custom home directory for Happy data (default: ~/.happy)
|
|
47
65
|
- `HAPPY_DISABLE_CAFFEINATE` - Disable macOS sleep prevention (set to `true`, `1`, or `yes`)
|
|
48
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-jTJmEbfZ.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');
|
|
@@ -22,10 +22,10 @@ require('node:events');
|
|
|
22
22
|
require('socket.io-client');
|
|
23
23
|
var tweetnacl = require('tweetnacl');
|
|
24
24
|
require('expo-server-sdk');
|
|
25
|
+
var os$1 = require('os');
|
|
25
26
|
var crypto = require('crypto');
|
|
26
27
|
var psList = require('ps-list');
|
|
27
28
|
var spawn = require('cross-spawn');
|
|
28
|
-
var os$1 = require('os');
|
|
29
29
|
var tmp = require('tmp');
|
|
30
30
|
var qrcode = require('qrcode-terminal');
|
|
31
31
|
var open = require('open');
|
|
@@ -56,6 +56,7 @@ function _interopNamespaceDefault(e) {
|
|
|
56
56
|
return Object.freeze(n);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
var os__namespace = /*#__PURE__*/_interopNamespaceDefault(os$1);
|
|
59
60
|
var tmp__namespace = /*#__PURE__*/_interopNamespaceDefault(tmp);
|
|
60
61
|
var hex__namespace = /*#__PURE__*/_interopNamespaceDefault(hex);
|
|
61
62
|
|
|
@@ -801,12 +802,18 @@ async function claudeLocalLauncher(session) {
|
|
|
801
802
|
break;
|
|
802
803
|
}
|
|
803
804
|
} catch (e) {
|
|
805
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
804
806
|
types.logger.debug("[local]: launch error", e);
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
} else {
|
|
807
|
+
const reason = exitReason;
|
|
808
|
+
if (reason === "switch") {
|
|
809
|
+
session.client.sendSessionEvent({ type: "message", message: `Error during mode switch: ${errorMessage}` });
|
|
809
810
|
break;
|
|
811
|
+
} else if (reason === "exit") {
|
|
812
|
+
session.client.sendSessionEvent({ type: "message", message: `Error during exit: ${errorMessage}` });
|
|
813
|
+
break;
|
|
814
|
+
} else {
|
|
815
|
+
session.client.sendSessionEvent({ type: "message", message: `Process error: ${errorMessage}` });
|
|
816
|
+
continue;
|
|
810
817
|
}
|
|
811
818
|
}
|
|
812
819
|
types.logger.debug("[local]: launch done");
|
|
@@ -1082,7 +1089,7 @@ class AbortError extends Error {
|
|
|
1082
1089
|
}
|
|
1083
1090
|
}
|
|
1084
1091
|
|
|
1085
|
-
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-
|
|
1092
|
+
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-B2T-8Qkp.cjs', document.baseURI).href)));
|
|
1086
1093
|
const __dirname$1 = node_path.join(__filename$1, "..");
|
|
1087
1094
|
function getDefaultClaudeCodePath() {
|
|
1088
1095
|
return node_path.join(__dirname$1, "..", "..", "..", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
@@ -1313,7 +1320,8 @@ function query(config) {
|
|
|
1313
1320
|
model,
|
|
1314
1321
|
fallbackModel,
|
|
1315
1322
|
strictMcpConfig,
|
|
1316
|
-
canCallTool
|
|
1323
|
+
canCallTool,
|
|
1324
|
+
onStderr
|
|
1317
1325
|
} = {}
|
|
1318
1326
|
} = config;
|
|
1319
1327
|
if (!process.env.CLAUDE_CODE_ENTRYPOINT) {
|
|
@@ -1369,11 +1377,15 @@ function query(config) {
|
|
|
1369
1377
|
streamToStdin(prompt, child.stdin, config.options?.abort);
|
|
1370
1378
|
childStdin = child.stdin;
|
|
1371
1379
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1380
|
+
child.stderr.on("data", (data) => {
|
|
1381
|
+
const stderrText = data.toString();
|
|
1382
|
+
if (process.env.DEBUG) {
|
|
1383
|
+
console.error("Claude Code stderr:", stderrText);
|
|
1384
|
+
}
|
|
1385
|
+
if (onStderr) {
|
|
1386
|
+
onStderr(stderrText);
|
|
1387
|
+
}
|
|
1388
|
+
});
|
|
1377
1389
|
const cleanup = () => {
|
|
1378
1390
|
if (!child.killed) {
|
|
1379
1391
|
child.kill("SIGTERM");
|
|
@@ -1744,7 +1756,8 @@ Echo message: ${echoMessage}` : "");
|
|
|
1744
1756
|
abort: opts.signal,
|
|
1745
1757
|
pathToClaudeCodeExecutable: (() => {
|
|
1746
1758
|
return node_path.resolve(node_path.join(types.projectPath(), "scripts", "claude_remote_launcher.cjs"));
|
|
1747
|
-
})()
|
|
1759
|
+
})(),
|
|
1760
|
+
onStderr: opts.onStderr
|
|
1748
1761
|
};
|
|
1749
1762
|
let thinking = false;
|
|
1750
1763
|
const updateThinking = (newThinking) => {
|
|
@@ -2984,14 +2997,23 @@ async function claudeRemoteLauncher(session) {
|
|
|
2984
2997
|
onReady: () => {
|
|
2985
2998
|
if (!pending && session.queue.size() === 0) {
|
|
2986
2999
|
session.client.sendSessionEvent({ type: "ready" });
|
|
2987
|
-
const
|
|
3000
|
+
const hostname = os__namespace.hostname();
|
|
3001
|
+
const notificationTitle = `(${hostname}) ${session.path}`;
|
|
3002
|
+
const sessionName = session.client.getSummary() || path.basename(session.path);
|
|
2988
3003
|
session.api.push().sendToAllDevices(
|
|
2989
|
-
|
|
2990
|
-
|
|
3004
|
+
notificationTitle,
|
|
3005
|
+
sessionName,
|
|
2991
3006
|
{ sessionId: session.client.sessionId }
|
|
2992
3007
|
);
|
|
2993
3008
|
}
|
|
2994
3009
|
},
|
|
3010
|
+
onStderr: (data) => {
|
|
3011
|
+
const trimmed = data.trim();
|
|
3012
|
+
if (trimmed) {
|
|
3013
|
+
types.logger.debug(`[remote]: stderr: ${trimmed}`);
|
|
3014
|
+
session.client.sendSessionEvent({ type: "message", message: trimmed });
|
|
3015
|
+
}
|
|
3016
|
+
},
|
|
2995
3017
|
signal: abortController.signal
|
|
2996
3018
|
});
|
|
2997
3019
|
session.consumeOneTimeFlags();
|
|
@@ -2999,9 +3021,14 @@ async function claudeRemoteLauncher(session) {
|
|
|
2999
3021
|
session.client.sendSessionEvent({ type: "message", message: "Aborted by user" });
|
|
3000
3022
|
}
|
|
3001
3023
|
} catch (e) {
|
|
3024
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
3002
3025
|
types.logger.debug("[remote]: launch error", e);
|
|
3003
|
-
if (
|
|
3004
|
-
session.client.sendSessionEvent({ type: "message", message:
|
|
3026
|
+
if (exitReason === "switch") {
|
|
3027
|
+
session.client.sendSessionEvent({ type: "message", message: `Error during mode switch: ${errorMessage}` });
|
|
3028
|
+
} else if (exitReason === "exit") {
|
|
3029
|
+
session.client.sendSessionEvent({ type: "message", message: `Error during exit: ${errorMessage}` });
|
|
3030
|
+
} else {
|
|
3031
|
+
session.client.sendSessionEvent({ type: "message", message: `Process error: ${errorMessage}` });
|
|
3005
3032
|
continue;
|
|
3006
3033
|
}
|
|
3007
3034
|
} finally {
|
|
@@ -6315,7 +6342,7 @@ ${chalk.bold("Examples:")}
|
|
|
6315
6342
|
${chalk.bold("Notes:")}
|
|
6316
6343
|
\u2022 You must be authenticated with Happy first (run 'happy auth login')
|
|
6317
6344
|
\u2022 API keys are encrypted and stored securely in Happy cloud
|
|
6318
|
-
\u2022 You can manage your stored keys at
|
|
6345
|
+
\u2022 You can manage your stored keys at happy.reily.app
|
|
6319
6346
|
`);
|
|
6320
6347
|
}
|
|
6321
6348
|
async function handleConnectVendor(vendor, displayName) {
|
|
@@ -6393,7 +6420,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
6393
6420
|
return;
|
|
6394
6421
|
} else if (subcommand === "codex") {
|
|
6395
6422
|
try {
|
|
6396
|
-
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-
|
|
6423
|
+
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-CFnERFiI.cjs'); });
|
|
6397
6424
|
let startedBy = void 0;
|
|
6398
6425
|
for (let i = 1; i < args.length; i++) {
|
|
6399
6426
|
if (args[i] === "--started-by") {
|
|
@@ -6438,7 +6465,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
6438
6465
|
} else if (subcommand === "list") {
|
|
6439
6466
|
try {
|
|
6440
6467
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
6441
|
-
const { listSessions } = await Promise.resolve().then(function () { return require('./list-
|
|
6468
|
+
const { listSessions } = await Promise.resolve().then(function () { return require('./list-CE0RKOOh.cjs'); });
|
|
6442
6469
|
let sessionId;
|
|
6443
6470
|
let titleFilter;
|
|
6444
6471
|
let recentMsgs;
|
|
@@ -6540,7 +6567,7 @@ Examples:
|
|
|
6540
6567
|
process.exit(1);
|
|
6541
6568
|
}
|
|
6542
6569
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
6543
|
-
const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-
|
|
6570
|
+
const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-IezYY014.cjs'); });
|
|
6544
6571
|
await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
|
|
6545
6572
|
} catch (error) {
|
|
6546
6573
|
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-DeW4Ii33.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';
|
|
@@ -20,10 +20,11 @@ import 'node:events';
|
|
|
20
20
|
import 'socket.io-client';
|
|
21
21
|
import tweetnacl from 'tweetnacl';
|
|
22
22
|
import 'expo-server-sdk';
|
|
23
|
+
import * as os from 'os';
|
|
24
|
+
import os__default from 'os';
|
|
23
25
|
import { createHash, randomBytes as randomBytes$1 } from 'crypto';
|
|
24
26
|
import psList from 'ps-list';
|
|
25
27
|
import spawn$2 from 'cross-spawn';
|
|
26
|
-
import os from 'os';
|
|
27
28
|
import * as tmp from 'tmp';
|
|
28
29
|
import qrcode from 'qrcode-terminal';
|
|
29
30
|
import open from 'open';
|
|
@@ -778,12 +779,18 @@ async function claudeLocalLauncher(session) {
|
|
|
778
779
|
break;
|
|
779
780
|
}
|
|
780
781
|
} catch (e) {
|
|
782
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
781
783
|
logger.debug("[local]: launch error", e);
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
784
|
+
const reason = exitReason;
|
|
785
|
+
if (reason === "switch") {
|
|
786
|
+
session.client.sendSessionEvent({ type: "message", message: `Error during mode switch: ${errorMessage}` });
|
|
787
|
+
break;
|
|
788
|
+
} else if (reason === "exit") {
|
|
789
|
+
session.client.sendSessionEvent({ type: "message", message: `Error during exit: ${errorMessage}` });
|
|
786
790
|
break;
|
|
791
|
+
} else {
|
|
792
|
+
session.client.sendSessionEvent({ type: "message", message: `Process error: ${errorMessage}` });
|
|
793
|
+
continue;
|
|
787
794
|
}
|
|
788
795
|
}
|
|
789
796
|
logger.debug("[local]: launch done");
|
|
@@ -1290,7 +1297,8 @@ function query(config) {
|
|
|
1290
1297
|
model,
|
|
1291
1298
|
fallbackModel,
|
|
1292
1299
|
strictMcpConfig,
|
|
1293
|
-
canCallTool
|
|
1300
|
+
canCallTool,
|
|
1301
|
+
onStderr
|
|
1294
1302
|
} = {}
|
|
1295
1303
|
} = config;
|
|
1296
1304
|
if (!process.env.CLAUDE_CODE_ENTRYPOINT) {
|
|
@@ -1346,11 +1354,15 @@ function query(config) {
|
|
|
1346
1354
|
streamToStdin(prompt, child.stdin, config.options?.abort);
|
|
1347
1355
|
childStdin = child.stdin;
|
|
1348
1356
|
}
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1357
|
+
child.stderr.on("data", (data) => {
|
|
1358
|
+
const stderrText = data.toString();
|
|
1359
|
+
if (process.env.DEBUG) {
|
|
1360
|
+
console.error("Claude Code stderr:", stderrText);
|
|
1361
|
+
}
|
|
1362
|
+
if (onStderr) {
|
|
1363
|
+
onStderr(stderrText);
|
|
1364
|
+
}
|
|
1365
|
+
});
|
|
1354
1366
|
const cleanup = () => {
|
|
1355
1367
|
if (!child.killed) {
|
|
1356
1368
|
child.kill("SIGTERM");
|
|
@@ -1721,7 +1733,8 @@ Echo message: ${echoMessage}` : "");
|
|
|
1721
1733
|
abort: opts.signal,
|
|
1722
1734
|
pathToClaudeCodeExecutable: (() => {
|
|
1723
1735
|
return resolve(join(projectPath(), "scripts", "claude_remote_launcher.cjs"));
|
|
1724
|
-
})()
|
|
1736
|
+
})(),
|
|
1737
|
+
onStderr: opts.onStderr
|
|
1725
1738
|
};
|
|
1726
1739
|
let thinking = false;
|
|
1727
1740
|
const updateThinking = (newThinking) => {
|
|
@@ -2961,14 +2974,23 @@ async function claudeRemoteLauncher(session) {
|
|
|
2961
2974
|
onReady: () => {
|
|
2962
2975
|
if (!pending && session.queue.size() === 0) {
|
|
2963
2976
|
session.client.sendSessionEvent({ type: "ready" });
|
|
2964
|
-
const
|
|
2977
|
+
const hostname = os.hostname();
|
|
2978
|
+
const notificationTitle = `(${hostname}) ${session.path}`;
|
|
2979
|
+
const sessionName = session.client.getSummary() || basename(session.path);
|
|
2965
2980
|
session.api.push().sendToAllDevices(
|
|
2966
|
-
|
|
2967
|
-
|
|
2981
|
+
notificationTitle,
|
|
2982
|
+
sessionName,
|
|
2968
2983
|
{ sessionId: session.client.sessionId }
|
|
2969
2984
|
);
|
|
2970
2985
|
}
|
|
2971
2986
|
},
|
|
2987
|
+
onStderr: (data) => {
|
|
2988
|
+
const trimmed = data.trim();
|
|
2989
|
+
if (trimmed) {
|
|
2990
|
+
logger.debug(`[remote]: stderr: ${trimmed}`);
|
|
2991
|
+
session.client.sendSessionEvent({ type: "message", message: trimmed });
|
|
2992
|
+
}
|
|
2993
|
+
},
|
|
2972
2994
|
signal: abortController.signal
|
|
2973
2995
|
});
|
|
2974
2996
|
session.consumeOneTimeFlags();
|
|
@@ -2976,9 +2998,14 @@ async function claudeRemoteLauncher(session) {
|
|
|
2976
2998
|
session.client.sendSessionEvent({ type: "message", message: "Aborted by user" });
|
|
2977
2999
|
}
|
|
2978
3000
|
} catch (e) {
|
|
3001
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
2979
3002
|
logger.debug("[remote]: launch error", e);
|
|
2980
|
-
if (
|
|
2981
|
-
session.client.sendSessionEvent({ type: "message", message:
|
|
3003
|
+
if (exitReason === "switch") {
|
|
3004
|
+
session.client.sendSessionEvent({ type: "message", message: `Error during mode switch: ${errorMessage}` });
|
|
3005
|
+
} else if (exitReason === "exit") {
|
|
3006
|
+
session.client.sendSessionEvent({ type: "message", message: `Error during exit: ${errorMessage}` });
|
|
3007
|
+
} else {
|
|
3008
|
+
session.client.sendSessionEvent({ type: "message", message: `Process error: ${errorMessage}` });
|
|
2982
3009
|
continue;
|
|
2983
3010
|
}
|
|
2984
3011
|
} finally {
|
|
@@ -4468,10 +4495,10 @@ function startDaemonControlServer({
|
|
|
4468
4495
|
}
|
|
4469
4496
|
|
|
4470
4497
|
const initialMachineMetadata = {
|
|
4471
|
-
host:
|
|
4472
|
-
platform:
|
|
4498
|
+
host: os__default.hostname(),
|
|
4499
|
+
platform: os__default.platform(),
|
|
4473
4500
|
happyCliVersion: packageJson.version,
|
|
4474
|
-
homeDir:
|
|
4501
|
+
homeDir: os__default.homedir(),
|
|
4475
4502
|
happyHomeDir: configuration.happyHomeDir,
|
|
4476
4503
|
happyLibDir: projectPath()
|
|
4477
4504
|
};
|
|
@@ -5306,10 +5333,10 @@ async function install$1() {
|
|
|
5306
5333
|
<true/>
|
|
5307
5334
|
|
|
5308
5335
|
<key>StandardErrorPath</key>
|
|
5309
|
-
<string>${
|
|
5336
|
+
<string>${os__default.homedir()}/.happy/daemon.err</string>
|
|
5310
5337
|
|
|
5311
5338
|
<key>StandardOutPath</key>
|
|
5312
|
-
<string>${
|
|
5339
|
+
<string>${os__default.homedir()}/.happy/daemon.log</string>
|
|
5313
5340
|
|
|
5314
5341
|
<key>WorkingDirectory</key>
|
|
5315
5342
|
<string>/tmp</string>
|
|
@@ -6292,7 +6319,7 @@ ${chalk.bold("Examples:")}
|
|
|
6292
6319
|
${chalk.bold("Notes:")}
|
|
6293
6320
|
\u2022 You must be authenticated with Happy first (run 'happy auth login')
|
|
6294
6321
|
\u2022 API keys are encrypted and stored securely in Happy cloud
|
|
6295
|
-
\u2022 You can manage your stored keys at
|
|
6322
|
+
\u2022 You can manage your stored keys at happy.reily.app
|
|
6296
6323
|
`);
|
|
6297
6324
|
}
|
|
6298
6325
|
async function handleConnectVendor(vendor, displayName) {
|
|
@@ -6370,7 +6397,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
6370
6397
|
return;
|
|
6371
6398
|
} else if (subcommand === "codex") {
|
|
6372
6399
|
try {
|
|
6373
|
-
const { runCodex } = await import('./runCodex-
|
|
6400
|
+
const { runCodex } = await import('./runCodex-CjK_Hx1-.mjs');
|
|
6374
6401
|
let startedBy = void 0;
|
|
6375
6402
|
for (let i = 1; i < args.length; i++) {
|
|
6376
6403
|
if (args[i] === "--started-by") {
|
|
@@ -6415,7 +6442,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
6415
6442
|
} else if (subcommand === "list") {
|
|
6416
6443
|
try {
|
|
6417
6444
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
6418
|
-
const { listSessions } = await import('./list-
|
|
6445
|
+
const { listSessions } = await import('./list-DwEmJUfq.mjs');
|
|
6419
6446
|
let sessionId;
|
|
6420
6447
|
let titleFilter;
|
|
6421
6448
|
let recentMsgs;
|
|
@@ -6517,7 +6544,7 @@ Examples:
|
|
|
6517
6544
|
process.exit(1);
|
|
6518
6545
|
}
|
|
6519
6546
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
6520
|
-
const { promptSession } = await import('./prompt-
|
|
6547
|
+
const { promptSession } = await import('./prompt-B4TvNDA2.mjs');
|
|
6521
6548
|
await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
|
|
6522
6549
|
} catch (error) {
|
|
6523
6550
|
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-
|
|
5
|
-
require('./types-
|
|
4
|
+
require('./index-B2T-8Qkp.cjs');
|
|
5
|
+
require('./types-jTJmEbfZ.cjs');
|
|
6
6
|
require('zod');
|
|
7
7
|
require('node:child_process');
|
|
8
8
|
require('node:os');
|
|
@@ -24,10 +24,10 @@ require('node:events');
|
|
|
24
24
|
require('socket.io-client');
|
|
25
25
|
require('tweetnacl');
|
|
26
26
|
require('expo-server-sdk');
|
|
27
|
+
require('os');
|
|
27
28
|
require('crypto');
|
|
28
29
|
require('ps-list');
|
|
29
30
|
require('cross-spawn');
|
|
30
|
-
require('os');
|
|
31
31
|
require('tmp');
|
|
32
32
|
require('qrcode-terminal');
|
|
33
33
|
require('open');
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import 'chalk';
|
|
2
|
-
import './index-
|
|
3
|
-
import './types-
|
|
2
|
+
import './index-xZm9eMZ-.mjs';
|
|
3
|
+
import './types-DeW4Ii33.mjs';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'node:child_process';
|
|
6
6
|
import 'node:os';
|
|
@@ -22,10 +22,10 @@ import 'node:events';
|
|
|
22
22
|
import 'socket.io-client';
|
|
23
23
|
import 'tweetnacl';
|
|
24
24
|
import 'expo-server-sdk';
|
|
25
|
+
import 'os';
|
|
25
26
|
import 'crypto';
|
|
26
27
|
import 'ps-list';
|
|
27
28
|
import 'cross-spawn';
|
|
28
|
-
import 'os';
|
|
29
29
|
import 'tmp';
|
|
30
30
|
import 'qrcode-terminal';
|
|
31
31
|
import 'open';
|
package/dist/lib.cjs
CHANGED
package/dist/lib.d.cts
CHANGED
|
@@ -430,6 +430,11 @@ declare class ApiSessionClient extends EventEmitter {
|
|
|
430
430
|
* Send usage data to the server
|
|
431
431
|
*/
|
|
432
432
|
sendUsageData(usage: Usage): void;
|
|
433
|
+
/**
|
|
434
|
+
* Get the current session summary/title
|
|
435
|
+
* @returns The summary text or undefined if not set
|
|
436
|
+
*/
|
|
437
|
+
getSummary(): string | undefined;
|
|
433
438
|
/**
|
|
434
439
|
* Update session metadata
|
|
435
440
|
* @param handler - Handler function that returns the updated metadata
|
package/dist/lib.d.mts
CHANGED
|
@@ -430,6 +430,11 @@ declare class ApiSessionClient extends EventEmitter {
|
|
|
430
430
|
* Send usage data to the server
|
|
431
431
|
*/
|
|
432
432
|
sendUsageData(usage: Usage): void;
|
|
433
|
+
/**
|
|
434
|
+
* Get the current session summary/title
|
|
435
|
+
* @returns The summary text or undefined if not set
|
|
436
|
+
*/
|
|
437
|
+
getSummary(): string | undefined;
|
|
433
438
|
/**
|
|
434
439
|
* Update session metadata
|
|
435
440
|
* @param handler - Handler function that returns the updated metadata
|
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-DeW4Ii33.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-DeW4Ii33.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-DeW4Ii33.mjs';
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { io } from 'socket.io-client';
|
|
4
4
|
import 'chalk';
|
|
@@ -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-jTJmEbfZ.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-B2T-8Qkp.cjs');
|
|
13
13
|
var os = require('node:os');
|
|
14
14
|
var node_path = require('node:path');
|
|
15
15
|
var fs = require('node:fs');
|
|
@@ -30,9 +30,9 @@ require('expo-server-sdk');
|
|
|
30
30
|
require('node:child_process');
|
|
31
31
|
require('node:readline');
|
|
32
32
|
require('node:url');
|
|
33
|
+
require('os');
|
|
33
34
|
require('ps-list');
|
|
34
35
|
require('cross-spawn');
|
|
35
|
-
require('os');
|
|
36
36
|
require('tmp');
|
|
37
37
|
require('qrcode-terminal');
|
|
38
38
|
require('open');
|
|
@@ -876,8 +876,10 @@ async function runCodex(opts) {
|
|
|
876
876
|
const sendReady = () => {
|
|
877
877
|
session.sendSessionEvent({ type: "ready" });
|
|
878
878
|
try {
|
|
879
|
+
const hostname = os.hostname();
|
|
880
|
+
const notificationTitle = `(${hostname}) ${process.cwd()}`;
|
|
879
881
|
api.push().sendToAllDevices(
|
|
880
|
-
|
|
882
|
+
notificationTitle,
|
|
881
883
|
"Codex is waiting for your command",
|
|
882
884
|
{ sessionId: session.sessionId }
|
|
883
885
|
);
|
|
@@ -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-DeW4Ii33.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-xZm9eMZ-.mjs';
|
|
11
11
|
import os from 'node:os';
|
|
12
12
|
import { resolve, join } from 'node:path';
|
|
13
13
|
import fs from 'node:fs';
|
|
@@ -28,9 +28,9 @@ import 'expo-server-sdk';
|
|
|
28
28
|
import 'node:child_process';
|
|
29
29
|
import 'node:readline';
|
|
30
30
|
import 'node:url';
|
|
31
|
+
import 'os';
|
|
31
32
|
import 'ps-list';
|
|
32
33
|
import 'cross-spawn';
|
|
33
|
-
import 'os';
|
|
34
34
|
import 'tmp';
|
|
35
35
|
import 'qrcode-terminal';
|
|
36
36
|
import 'open';
|
|
@@ -874,8 +874,10 @@ async function runCodex(opts) {
|
|
|
874
874
|
const sendReady = () => {
|
|
875
875
|
session.sendSessionEvent({ type: "ready" });
|
|
876
876
|
try {
|
|
877
|
+
const hostname = os.hostname();
|
|
878
|
+
const notificationTitle = `(${hostname}) ${process.cwd()}`;
|
|
877
879
|
api.push().sendToAllDevices(
|
|
878
|
-
|
|
880
|
+
notificationTitle,
|
|
879
881
|
"Codex is waiting for your command",
|
|
880
882
|
{ sessionId: session.sessionId }
|
|
881
883
|
);
|
|
@@ -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.12.
|
|
23
|
+
var version = "0.12.10";
|
|
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://
|
|
185
|
-
this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://
|
|
184
|
+
this.serverUrl = process.env.HAPPY_SERVER_URL || "https://happy-server.reily.app";
|
|
185
|
+
this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://happy.reily.app";
|
|
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) {
|
|
@@ -1697,6 +1697,13 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1697
1697
|
logger.debugLargeJson("[SOCKET] Sending usage data:", usageReport);
|
|
1698
1698
|
this.socket.emit("usage-report", usageReport);
|
|
1699
1699
|
}
|
|
1700
|
+
/**
|
|
1701
|
+
* Get the current session summary/title
|
|
1702
|
+
* @returns The summary text or undefined if not set
|
|
1703
|
+
*/
|
|
1704
|
+
getSummary() {
|
|
1705
|
+
return this.metadata?.summary?.text;
|
|
1706
|
+
}
|
|
1700
1707
|
/**
|
|
1701
1708
|
* Update session metadata
|
|
1702
1709
|
* @param handler - Handler function that returns the updated metadata
|
|
@@ -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.12.
|
|
44
|
+
var version = "0.12.10";
|
|
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://
|
|
206
|
-
this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://
|
|
205
|
+
this.serverUrl = process.env.HAPPY_SERVER_URL || "https://happy-server.reily.app";
|
|
206
|
+
this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://happy.reily.app";
|
|
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-jTJmEbfZ.cjs', document.baseURI).href))));
|
|
1154
1154
|
function projectPath() {
|
|
1155
1155
|
const path$1 = path.resolve(__dirname$1, "..");
|
|
1156
1156
|
return path$1;
|
|
@@ -1718,6 +1718,13 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1718
1718
|
logger.debugLargeJson("[SOCKET] Sending usage data:", usageReport);
|
|
1719
1719
|
this.socket.emit("usage-report", usageReport);
|
|
1720
1720
|
}
|
|
1721
|
+
/**
|
|
1722
|
+
* Get the current session summary/title
|
|
1723
|
+
* @returns The summary text or undefined if not set
|
|
1724
|
+
*/
|
|
1725
|
+
getSummary() {
|
|
1726
|
+
return this.metadata?.summary?.text;
|
|
1727
|
+
}
|
|
1721
1728
|
/**
|
|
1722
1729
|
* Update session metadata
|
|
1723
1730
|
* @param handler - Handler function that returns the updated metadata
|