@zhigang1992/happy-cli 0.12.4 → 0.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codex/happyMcpStdioBridge.cjs +2 -5
- package/dist/codex/happyMcpStdioBridge.mjs +2 -5
- package/dist/{index-CHEjP0zg.cjs → index-BkDVLUcE.cjs} +6 -6
- package/dist/{index-BERBU6rR.mjs → index-h3SrsKqR.mjs} +8 -8
- 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-BvtUKVTq.mjs → list-BJBPeYMn.mjs} +1 -1
- package/dist/{list-DOsBjFRJ.cjs → list-LCFlAICJ.cjs} +1 -1
- package/dist/{prompt-Dh_trad0.cjs → prompt-B0ezty5F.cjs} +1 -1
- package/dist/{prompt-BbMNN7fl.mjs → prompt-B35fwI-i.mjs} +1 -1
- package/dist/{runCodex-CYkmZphO.mjs → runCodex-BarDBoPV.mjs} +31 -4
- package/dist/{runCodex-DUqqO-m8.cjs → runCodex-uPJ1h0J4.cjs} +31 -4
- package/dist/{types-Q-euvEmG.cjs → types-Bd_EJ8VV.cjs} +29 -13
- package/dist/{types-Cw6y7GyQ.mjs → types-Cn6qSxMP.mjs} +34 -18
- package/package.json +8 -7
|
@@ -29,10 +29,7 @@ async function main() {
|
|
|
29
29
|
let httpClient = null;
|
|
30
30
|
async function ensureHttpClient() {
|
|
31
31
|
if (httpClient) return httpClient;
|
|
32
|
-
const client = new index_js.Client(
|
|
33
|
-
{ name: "happy-stdio-bridge", version: "1.0.0" },
|
|
34
|
-
{ capabilities: { tools: {} } }
|
|
35
|
-
);
|
|
32
|
+
const client = new index_js.Client({ name: "happy-stdio-bridge", version: "1.0.0" });
|
|
36
33
|
const transport = new streamableHttp_js.StreamableHTTPClientTransport(new URL(baseUrl));
|
|
37
34
|
await client.connect(transport);
|
|
38
35
|
httpClient = client;
|
|
@@ -41,7 +38,7 @@ async function main() {
|
|
|
41
38
|
const server = new mcp_js.McpServer({
|
|
42
39
|
name: "Happy MCP Bridge",
|
|
43
40
|
version: "1.0.0",
|
|
44
|
-
|
|
41
|
+
title: "STDIO bridge forwarding to Happy HTTP MCP"
|
|
45
42
|
});
|
|
46
43
|
server.registerTool(
|
|
47
44
|
"change_title",
|
|
@@ -27,10 +27,7 @@ async function main() {
|
|
|
27
27
|
let httpClient = null;
|
|
28
28
|
async function ensureHttpClient() {
|
|
29
29
|
if (httpClient) return httpClient;
|
|
30
|
-
const client = new Client(
|
|
31
|
-
{ name: "happy-stdio-bridge", version: "1.0.0" },
|
|
32
|
-
{ capabilities: { tools: {} } }
|
|
33
|
-
);
|
|
30
|
+
const client = new Client({ name: "happy-stdio-bridge", version: "1.0.0" });
|
|
34
31
|
const transport = new StreamableHTTPClientTransport(new URL(baseUrl));
|
|
35
32
|
await client.connect(transport);
|
|
36
33
|
httpClient = client;
|
|
@@ -39,7 +36,7 @@ async function main() {
|
|
|
39
36
|
const server = new McpServer({
|
|
40
37
|
name: "Happy MCP Bridge",
|
|
41
38
|
version: "1.0.0",
|
|
42
|
-
|
|
39
|
+
title: "STDIO bridge forwarding to Happy HTTP MCP"
|
|
43
40
|
});
|
|
44
41
|
server.registerTool(
|
|
45
42
|
"change_title",
|
|
@@ -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-Bd_EJ8VV.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');
|
|
@@ -1082,7 +1082,7 @@ class AbortError extends Error {
|
|
|
1082
1082
|
}
|
|
1083
1083
|
}
|
|
1084
1084
|
|
|
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-
|
|
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
1086
|
const __dirname$1 = node_path.join(__filename$1, "..");
|
|
1087
1087
|
function getDefaultClaudeCodePath() {
|
|
1088
1088
|
return node_path.join(__dirname$1, "..", "..", "..", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
@@ -4902,7 +4902,7 @@ async function startHappyServer(client) {
|
|
|
4902
4902
|
const mcp = new mcp_js.McpServer({
|
|
4903
4903
|
name: "Happy MCP",
|
|
4904
4904
|
version: "1.0.0",
|
|
4905
|
-
|
|
4905
|
+
title: "Happy CLI MCP Server"
|
|
4906
4906
|
});
|
|
4907
4907
|
mcp.registerTool("change_title", {
|
|
4908
4908
|
description: "Change the title of the current chat session",
|
|
@@ -6393,7 +6393,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
6393
6393
|
return;
|
|
6394
6394
|
} else if (subcommand === "codex") {
|
|
6395
6395
|
try {
|
|
6396
|
-
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-
|
|
6396
|
+
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-uPJ1h0J4.cjs'); });
|
|
6397
6397
|
let startedBy = void 0;
|
|
6398
6398
|
for (let i = 1; i < args.length; i++) {
|
|
6399
6399
|
if (args[i] === "--started-by") {
|
|
@@ -6438,7 +6438,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
6438
6438
|
} else if (subcommand === "list") {
|
|
6439
6439
|
try {
|
|
6440
6440
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
6441
|
-
const { listSessions } = await Promise.resolve().then(function () { return require('./list-
|
|
6441
|
+
const { listSessions } = await Promise.resolve().then(function () { return require('./list-LCFlAICJ.cjs'); });
|
|
6442
6442
|
let sessionId;
|
|
6443
6443
|
let titleFilter;
|
|
6444
6444
|
let recentMsgs;
|
|
@@ -6540,7 +6540,7 @@ Examples:
|
|
|
6540
6540
|
process.exit(1);
|
|
6541
6541
|
}
|
|
6542
6542
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
6543
|
-
const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-
|
|
6543
|
+
const { promptSession } = await Promise.resolve().then(function () { return require('./prompt-B0ezty5F.cjs'); });
|
|
6544
6544
|
await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
|
|
6545
6545
|
} catch (error) {
|
|
6546
6546
|
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-Cn6qSxMP.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';
|
|
@@ -1059,10 +1059,10 @@ class AbortError extends Error {
|
|
|
1059
1059
|
}
|
|
1060
1060
|
}
|
|
1061
1061
|
|
|
1062
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
1063
|
-
const __dirname = join(__filename, "..");
|
|
1062
|
+
const __filename$1 = fileURLToPath(import.meta.url);
|
|
1063
|
+
const __dirname$1 = join(__filename$1, "..");
|
|
1064
1064
|
function getDefaultClaudeCodePath() {
|
|
1065
|
-
return join(__dirname, "..", "..", "..", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
1065
|
+
return join(__dirname$1, "..", "..", "..", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
1066
1066
|
}
|
|
1067
1067
|
function logDebug(message) {
|
|
1068
1068
|
if (process.env.DEBUG) {
|
|
@@ -4879,7 +4879,7 @@ async function startHappyServer(client) {
|
|
|
4879
4879
|
const mcp = new McpServer({
|
|
4880
4880
|
name: "Happy MCP",
|
|
4881
4881
|
version: "1.0.0",
|
|
4882
|
-
|
|
4882
|
+
title: "Happy CLI MCP Server"
|
|
4883
4883
|
});
|
|
4884
4884
|
mcp.registerTool("change_title", {
|
|
4885
4885
|
description: "Change the title of the current chat session",
|
|
@@ -6370,7 +6370,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
6370
6370
|
return;
|
|
6371
6371
|
} else if (subcommand === "codex") {
|
|
6372
6372
|
try {
|
|
6373
|
-
const { runCodex } = await import('./runCodex-
|
|
6373
|
+
const { runCodex } = await import('./runCodex-BarDBoPV.mjs');
|
|
6374
6374
|
let startedBy = void 0;
|
|
6375
6375
|
for (let i = 1; i < args.length; i++) {
|
|
6376
6376
|
if (args[i] === "--started-by") {
|
|
@@ -6415,7 +6415,7 @@ async function handleConnectVendor(vendor, displayName) {
|
|
|
6415
6415
|
} else if (subcommand === "list") {
|
|
6416
6416
|
try {
|
|
6417
6417
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
6418
|
-
const { listSessions } = await import('./list-
|
|
6418
|
+
const { listSessions } = await import('./list-BJBPeYMn.mjs');
|
|
6419
6419
|
let sessionId;
|
|
6420
6420
|
let titleFilter;
|
|
6421
6421
|
let recentMsgs;
|
|
@@ -6517,7 +6517,7 @@ Examples:
|
|
|
6517
6517
|
process.exit(1);
|
|
6518
6518
|
}
|
|
6519
6519
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
6520
|
-
const { promptSession } = await import('./prompt-
|
|
6520
|
+
const { promptSession } = await import('./prompt-B35fwI-i.mjs');
|
|
6521
6521
|
await promptSession(credentials, sessionId, promptText, timeoutMinutes ?? void 0);
|
|
6522
6522
|
} catch (error) {
|
|
6523
6523
|
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-Cn6qSxMP.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-Cn6qSxMP.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-Cn6qSxMP.mjs';
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { io } from 'socket.io-client';
|
|
4
4
|
import 'chalk';
|
|
@@ -1,16 +1,17 @@
|
|
|
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-Cn6qSxMP.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-h3SrsKqR.mjs';
|
|
11
11
|
import os from 'node:os';
|
|
12
12
|
import { resolve, join } from 'node:path';
|
|
13
13
|
import fs from 'node:fs';
|
|
14
|
+
import { parse } from '@iarna/toml';
|
|
14
15
|
import 'axios';
|
|
15
16
|
import 'chalk';
|
|
16
17
|
import 'fs';
|
|
@@ -74,7 +75,7 @@ class CodexMcpClient {
|
|
|
74
75
|
constructor() {
|
|
75
76
|
this.client = new Client(
|
|
76
77
|
{ name: "happy-codex-client", version: "1.0.0" },
|
|
77
|
-
{ capabilities: {
|
|
78
|
+
{ capabilities: { elicitation: {} } }
|
|
78
79
|
);
|
|
79
80
|
this.client.setNotificationHandler(z.object({
|
|
80
81
|
method: z.literal("codex/event"),
|
|
@@ -1139,13 +1140,39 @@ async function runCodex(opts) {
|
|
|
1139
1140
|
}
|
|
1140
1141
|
}
|
|
1141
1142
|
});
|
|
1143
|
+
let existingMcpServers = {};
|
|
1144
|
+
try {
|
|
1145
|
+
const codexConfigPath = join(os.homedir(), ".codex", "config.toml");
|
|
1146
|
+
if (fs.existsSync(codexConfigPath)) {
|
|
1147
|
+
const configContents = fs.readFileSync(codexConfigPath, "utf8");
|
|
1148
|
+
const parsedConfig = parse(configContents);
|
|
1149
|
+
const parsedServers = parsedConfig?.mcp_servers;
|
|
1150
|
+
if (parsedServers && typeof parsedServers === "object") {
|
|
1151
|
+
for (const [name, rawConfig] of Object.entries(parsedServers)) {
|
|
1152
|
+
if (!rawConfig || typeof rawConfig !== "object") {
|
|
1153
|
+
continue;
|
|
1154
|
+
}
|
|
1155
|
+
const command = rawConfig.command;
|
|
1156
|
+
if (typeof command !== "string") {
|
|
1157
|
+
logger.debug(`[codex] Skipping MCP server "${name}" because command is missing`);
|
|
1158
|
+
continue;
|
|
1159
|
+
}
|
|
1160
|
+
existingMcpServers[name] = rawConfig;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
} catch (error) {
|
|
1165
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1166
|
+
logger.debug(`[codex] Error reading Codex config: ${message}`);
|
|
1167
|
+
}
|
|
1142
1168
|
const happyServer = await startHappyServer(session);
|
|
1143
1169
|
const bridgeCommand = join(projectPath(), "bin", "happy-mcp.mjs");
|
|
1144
1170
|
const mcpServers = {
|
|
1145
1171
|
happy: {
|
|
1146
1172
|
command: bridgeCommand,
|
|
1147
1173
|
args: ["--url", happyServer.url]
|
|
1148
|
-
}
|
|
1174
|
+
},
|
|
1175
|
+
...existingMcpServers
|
|
1149
1176
|
};
|
|
1150
1177
|
let first = true;
|
|
1151
1178
|
try {
|
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
var ink = require('ink');
|
|
4
4
|
var React = require('react');
|
|
5
|
-
var types = require('./types-
|
|
5
|
+
var types = require('./types-Bd_EJ8VV.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-BkDVLUcE.cjs');
|
|
13
13
|
var os = require('node:os');
|
|
14
14
|
var node_path = require('node:path');
|
|
15
15
|
var fs = require('node:fs');
|
|
16
|
+
var toml = require('@iarna/toml');
|
|
16
17
|
require('axios');
|
|
17
18
|
require('chalk');
|
|
18
19
|
require('fs');
|
|
@@ -76,7 +77,7 @@ class CodexMcpClient {
|
|
|
76
77
|
constructor() {
|
|
77
78
|
this.client = new index_js.Client(
|
|
78
79
|
{ name: "happy-codex-client", version: "1.0.0" },
|
|
79
|
-
{ capabilities: {
|
|
80
|
+
{ capabilities: { elicitation: {} } }
|
|
80
81
|
);
|
|
81
82
|
this.client.setNotificationHandler(z.z.object({
|
|
82
83
|
method: z.z.literal("codex/event"),
|
|
@@ -1141,13 +1142,39 @@ async function runCodex(opts) {
|
|
|
1141
1142
|
}
|
|
1142
1143
|
}
|
|
1143
1144
|
});
|
|
1145
|
+
let existingMcpServers = {};
|
|
1146
|
+
try {
|
|
1147
|
+
const codexConfigPath = node_path.join(os.homedir(), ".codex", "config.toml");
|
|
1148
|
+
if (fs.existsSync(codexConfigPath)) {
|
|
1149
|
+
const configContents = fs.readFileSync(codexConfigPath, "utf8");
|
|
1150
|
+
const parsedConfig = toml.parse(configContents);
|
|
1151
|
+
const parsedServers = parsedConfig?.mcp_servers;
|
|
1152
|
+
if (parsedServers && typeof parsedServers === "object") {
|
|
1153
|
+
for (const [name, rawConfig] of Object.entries(parsedServers)) {
|
|
1154
|
+
if (!rawConfig || typeof rawConfig !== "object") {
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
const command = rawConfig.command;
|
|
1158
|
+
if (typeof command !== "string") {
|
|
1159
|
+
types.logger.debug(`[codex] Skipping MCP server "${name}" because command is missing`);
|
|
1160
|
+
continue;
|
|
1161
|
+
}
|
|
1162
|
+
existingMcpServers[name] = rawConfig;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
} catch (error) {
|
|
1167
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1168
|
+
types.logger.debug(`[codex] Error reading Codex config: ${message}`);
|
|
1169
|
+
}
|
|
1144
1170
|
const happyServer = await index.startHappyServer(session);
|
|
1145
1171
|
const bridgeCommand = node_path.join(types.projectPath(), "bin", "happy-mcp.mjs");
|
|
1146
1172
|
const mcpServers = {
|
|
1147
1173
|
happy: {
|
|
1148
1174
|
command: bridgeCommand,
|
|
1149
1175
|
args: ["--url", happyServer.url]
|
|
1150
|
-
}
|
|
1176
|
+
},
|
|
1177
|
+
...existingMcpServers
|
|
1151
1178
|
};
|
|
1152
1179
|
let first = true;
|
|
1153
1180
|
try {
|
|
@@ -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.6";
|
|
45
45
|
var description = "Mobile and Web client for Claude Code and Codex";
|
|
46
46
|
var author = "Kirill Dubovitskiy";
|
|
47
47
|
var license = "MIT";
|
|
@@ -98,18 +98,19 @@ var scripts = {
|
|
|
98
98
|
"why do we need to build before running tests / dev?": "We need the binary to be built so we run daemon commands which directly run the binary - we don't want them to go out of sync or have custom spawn logic depending how we started happy",
|
|
99
99
|
typecheck: "tsc --noEmit",
|
|
100
100
|
build: "shx rm -rf dist && npx tsc --noEmit && pkgroll",
|
|
101
|
-
test: "
|
|
102
|
-
start: "
|
|
101
|
+
test: "bun run build && tsx --env-file .env.integration-test node_modules/.bin/vitest run",
|
|
102
|
+
start: "bun run build && ./bin/happy.mjs",
|
|
103
103
|
dev: "tsx src/index.ts",
|
|
104
|
-
"dev:local-server": "
|
|
105
|
-
"dev:integration-test-env": "
|
|
106
|
-
prepublishOnly: "
|
|
104
|
+
"dev:local-server": "bun run build && tsx --env-file .env.dev-local-server src/index.ts",
|
|
105
|
+
"dev:integration-test-env": "bun run build && tsx --env-file .env.integration-test src/index.ts",
|
|
106
|
+
prepublishOnly: "bun run build && bun test",
|
|
107
107
|
release: "release-it"
|
|
108
108
|
};
|
|
109
109
|
var dependencies = {
|
|
110
110
|
"@anthropic-ai/claude-code": "2.0.55",
|
|
111
111
|
"@anthropic-ai/sdk": "0.65.0",
|
|
112
112
|
"@elevenlabs/elevenlabs-js": "^2.25.1",
|
|
113
|
+
"@iarna/toml": "^3.0.0",
|
|
113
114
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
114
115
|
"@stablelib/base64": "^2.0.1",
|
|
115
116
|
"@stablelib/hex": "^2.0.1",
|
|
@@ -161,7 +162,7 @@ var resolutions = {
|
|
|
161
162
|
var publishConfig = {
|
|
162
163
|
registry: "https://registry.npmjs.org"
|
|
163
164
|
};
|
|
164
|
-
var packageManager = "
|
|
165
|
+
var packageManager = "bun@1.3.3";
|
|
165
166
|
var packageJson = {
|
|
166
167
|
name: name,
|
|
167
168
|
version: version,
|
|
@@ -357,6 +358,18 @@ function decryptBlobWithDataKey(bundle, dataKey) {
|
|
|
357
358
|
return null;
|
|
358
359
|
}
|
|
359
360
|
}
|
|
361
|
+
function decryptBlobWithSecretBox(bundle, secret) {
|
|
362
|
+
if (bundle.length < 1 + tweetnacl.secretbox.nonceLength) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
if (bundle[0] !== 0) {
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
const nonce = bundle.slice(1, 1 + tweetnacl.secretbox.nonceLength);
|
|
369
|
+
const ciphertext = bundle.slice(1 + tweetnacl.secretbox.nonceLength);
|
|
370
|
+
const decrypted = tweetnacl.secretbox.open(ciphertext, nonce, secret);
|
|
371
|
+
return decrypted || null;
|
|
372
|
+
}
|
|
360
373
|
function encrypt(key, variant, data) {
|
|
361
374
|
if (variant === "legacy") {
|
|
362
375
|
return encryptLegacy(data, key);
|
|
@@ -371,6 +384,13 @@ function decrypt(key, variant, data) {
|
|
|
371
384
|
return decryptWithDataKey(data, key);
|
|
372
385
|
}
|
|
373
386
|
}
|
|
387
|
+
function decryptBlob(key, variant, bundle) {
|
|
388
|
+
if (variant === "legacy") {
|
|
389
|
+
return decryptBlobWithSecretBox(bundle, key);
|
|
390
|
+
} else {
|
|
391
|
+
return decryptBlobWithDataKey(bundle, key);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
374
394
|
function authChallenge(secret) {
|
|
375
395
|
const keypair = tweetnacl.sign.keyPair.fromSeed(secret);
|
|
376
396
|
const challenge = getRandomBytes(32);
|
|
@@ -1130,7 +1150,7 @@ class RpcHandlerManager {
|
|
|
1130
1150
|
}
|
|
1131
1151
|
}
|
|
1132
1152
|
|
|
1133
|
-
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-Bd_EJ8VV.cjs', document.baseURI).href))));
|
|
1134
1154
|
function projectPath() {
|
|
1135
1155
|
const path$1 = path.resolve(__dirname$1, "..");
|
|
1136
1156
|
return path$1;
|
|
@@ -1783,11 +1803,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1783
1803
|
const encryptedData = new Uint8Array(response.data);
|
|
1784
1804
|
const mimeType = response.headers["x-blob-mimetype"];
|
|
1785
1805
|
const originalSize = parseInt(response.headers["x-blob-size"], 10);
|
|
1786
|
-
|
|
1787
|
-
logger.debug("[API] Cannot decrypt blob: session uses legacy encryption");
|
|
1788
|
-
return null;
|
|
1789
|
-
}
|
|
1790
|
-
const decryptedData = decryptBlobWithDataKey(encryptedData, this.encryptionKey);
|
|
1806
|
+
const decryptedData = decryptBlob(this.encryptionKey, this.encryptionVariant, encryptedData);
|
|
1791
1807
|
if (!decryptedData) {
|
|
1792
1808
|
logger.debug("[API] Failed to decrypt blob");
|
|
1793
1809
|
return null;
|
|
@@ -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.6";
|
|
24
24
|
var description = "Mobile and Web client for Claude Code and Codex";
|
|
25
25
|
var author = "Kirill Dubovitskiy";
|
|
26
26
|
var license = "MIT";
|
|
@@ -33,9 +33,9 @@ var bin = {
|
|
|
33
33
|
"happy-mcp": "./bin/happy-mcp.mjs"
|
|
34
34
|
};
|
|
35
35
|
var main = "./dist/index.cjs";
|
|
36
|
-
var module = "./dist/index.mjs";
|
|
36
|
+
var module$1 = "./dist/index.mjs";
|
|
37
37
|
var types = "./dist/index.d.cts";
|
|
38
|
-
var exports = {
|
|
38
|
+
var exports$1 = {
|
|
39
39
|
".": {
|
|
40
40
|
require: {
|
|
41
41
|
types: "./dist/index.d.cts",
|
|
@@ -77,18 +77,19 @@ var scripts = {
|
|
|
77
77
|
"why do we need to build before running tests / dev?": "We need the binary to be built so we run daemon commands which directly run the binary - we don't want them to go out of sync or have custom spawn logic depending how we started happy",
|
|
78
78
|
typecheck: "tsc --noEmit",
|
|
79
79
|
build: "shx rm -rf dist && npx tsc --noEmit && pkgroll",
|
|
80
|
-
test: "
|
|
81
|
-
start: "
|
|
80
|
+
test: "bun run build && tsx --env-file .env.integration-test node_modules/.bin/vitest run",
|
|
81
|
+
start: "bun run build && ./bin/happy.mjs",
|
|
82
82
|
dev: "tsx src/index.ts",
|
|
83
|
-
"dev:local-server": "
|
|
84
|
-
"dev:integration-test-env": "
|
|
85
|
-
prepublishOnly: "
|
|
83
|
+
"dev:local-server": "bun run build && tsx --env-file .env.dev-local-server src/index.ts",
|
|
84
|
+
"dev:integration-test-env": "bun run build && tsx --env-file .env.integration-test src/index.ts",
|
|
85
|
+
prepublishOnly: "bun run build && bun test",
|
|
86
86
|
release: "release-it"
|
|
87
87
|
};
|
|
88
88
|
var dependencies = {
|
|
89
89
|
"@anthropic-ai/claude-code": "2.0.55",
|
|
90
90
|
"@anthropic-ai/sdk": "0.65.0",
|
|
91
91
|
"@elevenlabs/elevenlabs-js": "^2.25.1",
|
|
92
|
+
"@iarna/toml": "^3.0.0",
|
|
92
93
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
93
94
|
"@stablelib/base64": "^2.0.1",
|
|
94
95
|
"@stablelib/hex": "^2.0.1",
|
|
@@ -140,7 +141,7 @@ var resolutions = {
|
|
|
140
141
|
var publishConfig = {
|
|
141
142
|
registry: "https://registry.npmjs.org"
|
|
142
143
|
};
|
|
143
|
-
var packageManager = "
|
|
144
|
+
var packageManager = "bun@1.3.3";
|
|
144
145
|
var packageJson = {
|
|
145
146
|
name: name,
|
|
146
147
|
version: version,
|
|
@@ -153,9 +154,9 @@ var packageJson = {
|
|
|
153
154
|
repository: repository,
|
|
154
155
|
bin: bin,
|
|
155
156
|
main: main,
|
|
156
|
-
module: module,
|
|
157
|
+
module: module$1,
|
|
157
158
|
types: types,
|
|
158
|
-
exports: exports,
|
|
159
|
+
exports: exports$1,
|
|
159
160
|
files: files,
|
|
160
161
|
scripts: scripts,
|
|
161
162
|
dependencies: dependencies,
|
|
@@ -336,6 +337,18 @@ function decryptBlobWithDataKey(bundle, dataKey) {
|
|
|
336
337
|
return null;
|
|
337
338
|
}
|
|
338
339
|
}
|
|
340
|
+
function decryptBlobWithSecretBox(bundle, secret) {
|
|
341
|
+
if (bundle.length < 1 + tweetnacl.secretbox.nonceLength) {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
if (bundle[0] !== 0) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
const nonce = bundle.slice(1, 1 + tweetnacl.secretbox.nonceLength);
|
|
348
|
+
const ciphertext = bundle.slice(1 + tweetnacl.secretbox.nonceLength);
|
|
349
|
+
const decrypted = tweetnacl.secretbox.open(ciphertext, nonce, secret);
|
|
350
|
+
return decrypted || null;
|
|
351
|
+
}
|
|
339
352
|
function encrypt(key, variant, data) {
|
|
340
353
|
if (variant === "legacy") {
|
|
341
354
|
return encryptLegacy(data, key);
|
|
@@ -350,6 +363,13 @@ function decrypt(key, variant, data) {
|
|
|
350
363
|
return decryptWithDataKey(data, key);
|
|
351
364
|
}
|
|
352
365
|
}
|
|
366
|
+
function decryptBlob(key, variant, bundle) {
|
|
367
|
+
if (variant === "legacy") {
|
|
368
|
+
return decryptBlobWithSecretBox(bundle, key);
|
|
369
|
+
} else {
|
|
370
|
+
return decryptBlobWithDataKey(bundle, key);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
353
373
|
function authChallenge(secret) {
|
|
354
374
|
const keypair = tweetnacl.sign.keyPair.fromSeed(secret);
|
|
355
375
|
const challenge = getRandomBytes(32);
|
|
@@ -1109,9 +1129,9 @@ class RpcHandlerManager {
|
|
|
1109
1129
|
}
|
|
1110
1130
|
}
|
|
1111
1131
|
|
|
1112
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
1132
|
+
const __dirname$1 = dirname(fileURLToPath(import.meta.url));
|
|
1113
1133
|
function projectPath() {
|
|
1114
|
-
const path = resolve(__dirname, "..");
|
|
1134
|
+
const path = resolve(__dirname$1, "..");
|
|
1115
1135
|
return path;
|
|
1116
1136
|
}
|
|
1117
1137
|
|
|
@@ -1762,11 +1782,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1762
1782
|
const encryptedData = new Uint8Array(response.data);
|
|
1763
1783
|
const mimeType = response.headers["x-blob-mimetype"];
|
|
1764
1784
|
const originalSize = parseInt(response.headers["x-blob-size"], 10);
|
|
1765
|
-
|
|
1766
|
-
logger.debug("[API] Cannot decrypt blob: session uses legacy encryption");
|
|
1767
|
-
return null;
|
|
1768
|
-
}
|
|
1769
|
-
const decryptedData = decryptBlobWithDataKey(encryptedData, this.encryptionKey);
|
|
1785
|
+
const decryptedData = decryptBlob(this.encryptionKey, this.encryptionVariant, encryptedData);
|
|
1770
1786
|
if (!decryptedData) {
|
|
1771
1787
|
logger.debug("[API] Failed to decrypt blob");
|
|
1772
1788
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhigang1992/happy-cli",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.6",
|
|
4
4
|
"description": "Mobile and Web client for Claude Code and Codex",
|
|
5
5
|
"author": "Kirill Dubovitskiy",
|
|
6
6
|
"license": "MIT",
|
|
@@ -57,18 +57,19 @@
|
|
|
57
57
|
"why do we need to build before running tests / dev?": "We need the binary to be built so we run daemon commands which directly run the binary - we don't want them to go out of sync or have custom spawn logic depending how we started happy",
|
|
58
58
|
"typecheck": "tsc --noEmit",
|
|
59
59
|
"build": "shx rm -rf dist && npx tsc --noEmit && pkgroll",
|
|
60
|
-
"test": "
|
|
61
|
-
"start": "
|
|
60
|
+
"test": "bun run build && tsx --env-file .env.integration-test node_modules/.bin/vitest run",
|
|
61
|
+
"start": "bun run build && ./bin/happy.mjs",
|
|
62
62
|
"dev": "tsx src/index.ts",
|
|
63
|
-
"dev:local-server": "
|
|
64
|
-
"dev:integration-test-env": "
|
|
65
|
-
"prepublishOnly": "
|
|
63
|
+
"dev:local-server": "bun run build && tsx --env-file .env.dev-local-server src/index.ts",
|
|
64
|
+
"dev:integration-test-env": "bun run build && tsx --env-file .env.integration-test src/index.ts",
|
|
65
|
+
"prepublishOnly": "bun run build && bun test",
|
|
66
66
|
"release": "release-it"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@anthropic-ai/claude-code": "2.0.55",
|
|
70
70
|
"@anthropic-ai/sdk": "0.65.0",
|
|
71
71
|
"@elevenlabs/elevenlabs-js": "^2.25.1",
|
|
72
|
+
"@iarna/toml": "^3.0.0",
|
|
72
73
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
73
74
|
"@stablelib/base64": "^2.0.1",
|
|
74
75
|
"@stablelib/hex": "^2.0.1",
|
|
@@ -120,5 +121,5 @@
|
|
|
120
121
|
"publishConfig": {
|
|
121
122
|
"registry": "https://registry.npmjs.org"
|
|
122
123
|
},
|
|
123
|
-
"packageManager": "
|
|
124
|
+
"packageManager": "bun@1.3.3"
|
|
124
125
|
}
|