@zhigang1992/happy-cli 0.12.6 → 0.12.9

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 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://api.cluster-fluster.com)
45
- - `HAPPY_WEBAPP_URL` - Custom web app URL (default: https://app.happy.engineering)
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-Bd_EJ8VV.cjs');
6
+ var types = require('./types-DU-KcuRq.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
 
@@ -1082,7 +1083,7 @@ class AbortError extends Error {
1082
1083
  }
1083
1084
  }
1084
1085
 
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-BkDVLUcE.cjs', document.baseURI).href)));
1086
+ 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-DvMFDzz3.cjs', document.baseURI).href)));
1086
1087
  const __dirname$1 = node_path.join(__filename$1, "..");
1087
1088
  function getDefaultClaudeCodePath() {
1088
1089
  return node_path.join(__dirname$1, "..", "..", "..", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
@@ -2984,10 +2985,12 @@ async function claudeRemoteLauncher(session) {
2984
2985
  onReady: () => {
2985
2986
  if (!pending && session.queue.size() === 0) {
2986
2987
  session.client.sendSessionEvent({ type: "ready" });
2987
- const folderName = path.basename(session.path);
2988
+ const hostname = os__namespace.hostname();
2989
+ const notificationTitle = `(${hostname}) ${session.path}`;
2990
+ const sessionName = session.client.getSummary() || path.basename(session.path);
2988
2991
  session.api.push().sendToAllDevices(
2989
- `Ready`,
2990
- folderName,
2992
+ notificationTitle,
2993
+ sessionName,
2991
2994
  { sessionId: session.client.sessionId }
2992
2995
  );
2993
2996
  }
@@ -6315,7 +6318,7 @@ ${chalk.bold("Examples:")}
6315
6318
  ${chalk.bold("Notes:")}
6316
6319
  \u2022 You must be authenticated with Happy first (run 'happy auth login')
6317
6320
  \u2022 API keys are encrypted and stored securely in Happy cloud
6318
- \u2022 You can manage your stored keys at app.happy.engineering
6321
+ \u2022 You can manage your stored keys at happy.reily.app
6319
6322
  `);
6320
6323
  }
6321
6324
  async function handleConnectVendor(vendor, displayName) {
@@ -6393,7 +6396,7 @@ async function handleConnectVendor(vendor, displayName) {
6393
6396
  return;
6394
6397
  } else if (subcommand === "codex") {
6395
6398
  try {
6396
- const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-uPJ1h0J4.cjs'); });
6399
+ const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-B33w9tjC.cjs'); });
6397
6400
  let startedBy = void 0;
6398
6401
  for (let i = 1; i < args.length; i++) {
6399
6402
  if (args[i] === "--started-by") {
@@ -6438,7 +6441,7 @@ async function handleConnectVendor(vendor, displayName) {
6438
6441
  } else if (subcommand === "list") {
6439
6442
  try {
6440
6443
  const { credentials } = await authAndSetupMachineIfNeeded();
6441
- const { listSessions } = await Promise.resolve().then(function () { return require('./list-LCFlAICJ.cjs'); });
6444
+ const { listSessions } = await Promise.resolve().then(function () { return require('./list-sCcVgML_.cjs'); });
6442
6445
  let sessionId;
6443
6446
  let titleFilter;
6444
6447
  let recentMsgs;
@@ -6540,7 +6543,7 @@ Examples:
6540
6543
  process.exit(1);
6541
6544
  }
6542
6545
  const { credentials } = await authAndSetupMachineIfNeeded();
6543
- const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-B0ezty5F.cjs'); });
6546
+ const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-DQyb25aY.cjs'); });
6544
6547
  await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
6545
6548
  } catch (error) {
6546
6549
  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-Cn6qSxMP.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-BQ_WM2tI.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';
@@ -2961,10 +2962,12 @@ async function claudeRemoteLauncher(session) {
2961
2962
  onReady: () => {
2962
2963
  if (!pending && session.queue.size() === 0) {
2963
2964
  session.client.sendSessionEvent({ type: "ready" });
2964
- const folderName = basename(session.path);
2965
+ const hostname = os.hostname();
2966
+ const notificationTitle = `(${hostname}) ${session.path}`;
2967
+ const sessionName = session.client.getSummary() || basename(session.path);
2965
2968
  session.api.push().sendToAllDevices(
2966
- `Ready`,
2967
- folderName,
2969
+ notificationTitle,
2970
+ sessionName,
2968
2971
  { sessionId: session.client.sessionId }
2969
2972
  );
2970
2973
  }
@@ -4468,10 +4471,10 @@ function startDaemonControlServer({
4468
4471
  }
4469
4472
 
4470
4473
  const initialMachineMetadata = {
4471
- host: os.hostname(),
4472
- platform: os.platform(),
4474
+ host: os__default.hostname(),
4475
+ platform: os__default.platform(),
4473
4476
  happyCliVersion: packageJson.version,
4474
- homeDir: os.homedir(),
4477
+ homeDir: os__default.homedir(),
4475
4478
  happyHomeDir: configuration.happyHomeDir,
4476
4479
  happyLibDir: projectPath()
4477
4480
  };
@@ -5306,10 +5309,10 @@ async function install$1() {
5306
5309
  <true/>
5307
5310
 
5308
5311
  <key>StandardErrorPath</key>
5309
- <string>${os.homedir()}/.happy/daemon.err</string>
5312
+ <string>${os__default.homedir()}/.happy/daemon.err</string>
5310
5313
 
5311
5314
  <key>StandardOutPath</key>
5312
- <string>${os.homedir()}/.happy/daemon.log</string>
5315
+ <string>${os__default.homedir()}/.happy/daemon.log</string>
5313
5316
 
5314
5317
  <key>WorkingDirectory</key>
5315
5318
  <string>/tmp</string>
@@ -6292,7 +6295,7 @@ ${chalk.bold("Examples:")}
6292
6295
  ${chalk.bold("Notes:")}
6293
6296
  \u2022 You must be authenticated with Happy first (run 'happy auth login')
6294
6297
  \u2022 API keys are encrypted and stored securely in Happy cloud
6295
- \u2022 You can manage your stored keys at app.happy.engineering
6298
+ \u2022 You can manage your stored keys at happy.reily.app
6296
6299
  `);
6297
6300
  }
6298
6301
  async function handleConnectVendor(vendor, displayName) {
@@ -6370,7 +6373,7 @@ async function handleConnectVendor(vendor, displayName) {
6370
6373
  return;
6371
6374
  } else if (subcommand === "codex") {
6372
6375
  try {
6373
- const { runCodex } = await import('./runCodex-BarDBoPV.mjs');
6376
+ const { runCodex } = await import('./runCodex-BeLLGX3X.mjs');
6374
6377
  let startedBy = void 0;
6375
6378
  for (let i = 1; i < args.length; i++) {
6376
6379
  if (args[i] === "--started-by") {
@@ -6415,7 +6418,7 @@ async function handleConnectVendor(vendor, displayName) {
6415
6418
  } else if (subcommand === "list") {
6416
6419
  try {
6417
6420
  const { credentials } = await authAndSetupMachineIfNeeded();
6418
- const { listSessions } = await import('./list-BJBPeYMn.mjs');
6421
+ const { listSessions } = await import('./list-DqbAuRvF.mjs');
6419
6422
  let sessionId;
6420
6423
  let titleFilter;
6421
6424
  let recentMsgs;
@@ -6517,7 +6520,7 @@ Examples:
6517
6520
  process.exit(1);
6518
6521
  }
6519
6522
  const { credentials } = await authAndSetupMachineIfNeeded();
6520
- const { promptSession } = await import('./prompt-B35fwI-i.mjs');
6523
+ const { promptSession } = await import('./prompt-DwjhpAf5.mjs');
6521
6524
  await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
6522
6525
  } catch (error) {
6523
6526
  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-BkDVLUcE.cjs');
5
- require('./types-Bd_EJ8VV.cjs');
4
+ require('./index-DvMFDzz3.cjs');
5
+ require('./types-DU-KcuRq.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-h3SrsKqR.mjs';
3
- import './types-Cn6qSxMP.mjs';
2
+ import './index-iFxcl7Hn.mjs';
3
+ import './types-BQ_WM2tI.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
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types-Bd_EJ8VV.cjs');
3
+ var types = require('./types-DU-KcuRq.cjs');
4
4
  require('axios');
5
5
  require('chalk');
6
6
  require('fs');
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-Cn6qSxMP.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-BQ_WM2tI.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-Cn6qSxMP.mjs';
1
+ import { c as configuration, l as logger, d as decodeBase64, b as decrypt, f as formatTimeAgo, e as libsodiumDecryptFromPublicKey } from './types-BQ_WM2tI.mjs';
2
2
  import axios from 'axios';
3
3
  import { existsSync, readdirSync, statSync, readFileSync } from 'fs';
4
4
  import { join } from 'path';
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types-Bd_EJ8VV.cjs');
3
+ var types = require('./types-DU-KcuRq.cjs');
4
4
  var axios = require('axios');
5
5
  var fs = require('fs');
6
6
  var path = require('path');
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var types = require('./types-Bd_EJ8VV.cjs');
3
+ var types = require('./types-DU-KcuRq.cjs');
4
4
  var axios = require('axios');
5
5
  var socket_ioClient = require('socket.io-client');
6
6
  require('chalk');
@@ -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-Cn6qSxMP.mjs';
1
+ import { c as configuration, b as decrypt, d as decodeBase64, l as logger, g as encodeBase64, h as encrypt } from './types-BQ_WM2tI.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-Bd_EJ8VV.cjs');
5
+ var types = require('./types-DU-KcuRq.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-BkDVLUcE.cjs');
12
+ var index = require('./index-DvMFDzz3.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
- "It's ready!",
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-Cn6qSxMP.mjs';
3
+ import { l as logger, A as ApiClient, r as readSettings, p as projectPath, c as configuration, i as packageJson } from './types-BQ_WM2tI.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-h3SrsKqR.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-iFxcl7Hn.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
- "It's ready!",
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.6";
23
+ var version = "0.12.9";
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://api.cluster-fluster.com";
185
- this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://app.happy.engineering";
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.6";
44
+ var version = "0.12.9";
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://api.cluster-fluster.com";
206
- this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://app.happy.engineering";
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-Bd_EJ8VV.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-DU-KcuRq.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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhigang1992/happy-cli",
3
- "version": "0.12.6",
3
+ "version": "0.12.9",
4
4
  "description": "Mobile and Web client for Claude Code and Codex",
5
5
  "author": "Kirill Dubovitskiy",
6
6
  "license": "MIT",