happy-imou-cloud 2.0.7 → 2.0.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/bin/happy-cloud.mjs +1 -1
- package/dist/{api-Dwkm7s_E.cjs → api-CUTdFiFP.cjs} +3 -4
- package/dist/{api-dwwHBzLc.mjs → api-CnvyGas2.mjs} +3 -4
- package/dist/{command-Cfq3Uc0S.mjs → command-BGA3qCKR.mjs} +3 -3
- package/dist/{command-DiAVIsxX.cjs → command-DLAJZsKX.cjs} +3 -3
- package/dist/{index-HyqLXzw-.mjs → index-BpZL4RcT.mjs} +208 -32
- package/dist/{index-CfqxEoyl.cjs → index-D4OdFq68.cjs} +210 -34
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{BaseReasoningProcessor-ClrT-x-H.mjs → names-C9iJODqA.mjs} +98 -3
- package/dist/{BaseReasoningProcessor-DphULXS-.cjs → names-YEhZwVT0.cjs} +100 -2
- package/dist/{persistence-Dg-rxY2a.mjs → persistence-BPV3AmJL.mjs} +100 -4
- package/dist/{persistence-hbhwAYIV.cjs → persistence-CxvL0cwp.cjs} +110 -1
- package/dist/{registerKillSessionHandler-BAvk4GYO.mjs → registerKillSessionHandler-C2O8b5wH.mjs} +2 -2
- package/dist/{registerKillSessionHandler-D1ouN10n.cjs → registerKillSessionHandler-rqd7duc9.cjs} +2 -2
- package/dist/{runClaude-OxYbt3ZQ.mjs → runClaude-8inO7C5p.mjs} +4 -4
- package/dist/{runClaude-CZmJ7qEP.cjs → runClaude-KwIVwFp1.cjs} +5 -5
- package/dist/{runCodex-ByVTEbSY.mjs → runCodex-BQ-fN5E6.mjs} +5 -6
- package/dist/{runCodex-CtncAgso.cjs → runCodex-Ba8COxZe.cjs} +24 -25
- package/dist/{runGemini-BRO6A2jm.mjs → runGemini-BE0FizuV.mjs} +5 -6
- package/dist/{runGemini-ChwjLmhI.cjs → runGemini-DtdLLX9o.cjs} +20 -21
- package/package.json +3 -4
- package/scripts/build.mjs +66 -0
- package/scripts/release-smoke.mjs +166 -30
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var node_crypto = require('node:crypto');
|
|
4
|
-
var api = require('./api-
|
|
5
|
-
var persistence = require('./persistence-
|
|
6
|
-
var index = require('./index-
|
|
7
|
-
var
|
|
8
|
-
var registerKillSessionHandler = require('./registerKillSessionHandler-
|
|
4
|
+
var api = require('./api-CUTdFiFP.cjs');
|
|
5
|
+
var persistence = require('./persistence-CxvL0cwp.cjs');
|
|
6
|
+
var index = require('./index-D4OdFq68.cjs');
|
|
7
|
+
var names = require('./names-YEhZwVT0.cjs');
|
|
8
|
+
var registerKillSessionHandler = require('./registerKillSessionHandler-rqd7duc9.cjs');
|
|
9
9
|
var React = require('react');
|
|
10
10
|
var ink = require('ink');
|
|
11
|
-
var happyProtocol = require('happy-protocol');
|
|
12
11
|
require('axios');
|
|
13
12
|
require('chalk');
|
|
14
13
|
require('fs');
|
|
@@ -313,7 +312,7 @@ const CodexDisplay = ({ messageBuffer, logPath, onExit, title }) => {
|
|
|
313
312
|
));
|
|
314
313
|
};
|
|
315
314
|
|
|
316
|
-
class CodexPermissionHandler extends
|
|
315
|
+
class CodexPermissionHandler extends names.BasePermissionHandler {
|
|
317
316
|
constructor(session) {
|
|
318
317
|
super(session);
|
|
319
318
|
}
|
|
@@ -352,7 +351,7 @@ class CodexSelectionHandler {
|
|
|
352
351
|
};
|
|
353
352
|
pending.timeoutHandle = setTimeout(() => {
|
|
354
353
|
this.handleSelectionTimeout(request.id, pending);
|
|
355
|
-
},
|
|
354
|
+
}, names.getPendingInteractionTimeoutMs());
|
|
356
355
|
this.pendingRequests.set(request.id, pending);
|
|
357
356
|
this.session.updateAgentState((currentState) => ({
|
|
358
357
|
...currentState,
|
|
@@ -388,7 +387,7 @@ class CodexSelectionHandler {
|
|
|
388
387
|
hasPendingRequests() {
|
|
389
388
|
return this.pendingRequests.size > 0;
|
|
390
389
|
}
|
|
391
|
-
supersedePendingRequests(reason =
|
|
390
|
+
supersedePendingRequests(reason = names.INTERACTION_SUPERSEDED_ERROR) {
|
|
392
391
|
const pendingSnapshot = Array.from(this.pendingRequests.entries());
|
|
393
392
|
if (pendingSnapshot.length === 0) {
|
|
394
393
|
return 0;
|
|
@@ -500,7 +499,7 @@ class CodexSelectionHandler {
|
|
|
500
499
|
}
|
|
501
500
|
this.pendingRequests.delete(requestId);
|
|
502
501
|
this.clearPendingRequestTimeout(active);
|
|
503
|
-
active.reject(new Error(
|
|
502
|
+
active.reject(new Error(names.INTERACTION_TIMED_OUT_ERROR));
|
|
504
503
|
this.session.updateAgentState((currentState) => {
|
|
505
504
|
const request = currentState.requests?.[requestId] || {
|
|
506
505
|
tool: "AskUserQuestion",
|
|
@@ -523,7 +522,7 @@ class CodexSelectionHandler {
|
|
|
523
522
|
...request,
|
|
524
523
|
completedAt: Date.now(),
|
|
525
524
|
status: "canceled",
|
|
526
|
-
reason:
|
|
525
|
+
reason: names.INTERACTION_TIMED_OUT_ERROR,
|
|
527
526
|
requestKind: "selection"
|
|
528
527
|
}
|
|
529
528
|
}
|
|
@@ -537,7 +536,7 @@ class CodexSelectionHandler {
|
|
|
537
536
|
}
|
|
538
537
|
}
|
|
539
538
|
|
|
540
|
-
class ReasoningProcessor extends
|
|
539
|
+
class ReasoningProcessor extends names.BaseReasoningProcessor {
|
|
541
540
|
getToolName() {
|
|
542
541
|
return "CodexReasoning";
|
|
543
542
|
}
|
|
@@ -943,7 +942,7 @@ async function codexRemoteLauncher(session) {
|
|
|
943
942
|
}
|
|
944
943
|
case "tool-call": {
|
|
945
944
|
const toolArgs = msg.args ? index.truncateDisplayMessage(msg.args, 100) : "";
|
|
946
|
-
const canonicalToolName =
|
|
945
|
+
const canonicalToolName = names.resolveCanonicalToolNameV2(msg.toolName);
|
|
947
946
|
messageBuffer.addMessage(
|
|
948
947
|
`Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}` : ""}`,
|
|
949
948
|
"tool"
|
|
@@ -952,7 +951,7 @@ async function codexRemoteLauncher(session) {
|
|
|
952
951
|
type: "tool-call",
|
|
953
952
|
name: canonicalToolName,
|
|
954
953
|
callId: msg.callId,
|
|
955
|
-
input:
|
|
954
|
+
input: names.attachToolHappierMetaV2(msg.args, {
|
|
956
955
|
v: 2,
|
|
957
956
|
protocol: "acp",
|
|
958
957
|
provider: "codex",
|
|
@@ -964,7 +963,7 @@ async function codexRemoteLauncher(session) {
|
|
|
964
963
|
return;
|
|
965
964
|
}
|
|
966
965
|
case "tool-result": {
|
|
967
|
-
const isError =
|
|
966
|
+
const isError = names.inferToolResultError(msg.result);
|
|
968
967
|
const resultText = index.truncateDisplayMessage(msg.result, 200) || (isError ? "Unknown error" : "");
|
|
969
968
|
messageBuffer.addMessage(
|
|
970
969
|
`${isError ? "Error:" : "Result:"} ${resultText}`.trim(),
|
|
@@ -973,12 +972,12 @@ async function codexRemoteLauncher(session) {
|
|
|
973
972
|
session.runtimeSession.sendCodexMessage({
|
|
974
973
|
type: "tool-call-result",
|
|
975
974
|
callId: msg.callId,
|
|
976
|
-
output:
|
|
975
|
+
output: names.attachToolHappierMetaV2(msg.result, {
|
|
977
976
|
v: 2,
|
|
978
977
|
protocol: "acp",
|
|
979
978
|
provider: "codex",
|
|
980
979
|
rawToolName: msg.toolName,
|
|
981
|
-
canonicalToolName:
|
|
980
|
+
canonicalToolName: names.resolveCanonicalToolNameV2(msg.toolName)
|
|
982
981
|
}),
|
|
983
982
|
id: node_crypto.randomUUID(),
|
|
984
983
|
isError
|
|
@@ -1021,12 +1020,12 @@ async function codexRemoteLauncher(session) {
|
|
|
1021
1020
|
const { call_id, type, ...inputs } = msg;
|
|
1022
1021
|
messageBuffer.addMessage(`Exec approval requested: ${call_id}`, "tool");
|
|
1023
1022
|
const rawToolName = "CodexBash";
|
|
1024
|
-
const canonicalToolName =
|
|
1023
|
+
const canonicalToolName = names.resolveCanonicalToolNameV2(rawToolName);
|
|
1025
1024
|
session.runtimeSession.sendCodexMessage({
|
|
1026
1025
|
type: "tool-call",
|
|
1027
1026
|
name: canonicalToolName,
|
|
1028
1027
|
callId: call_id,
|
|
1029
|
-
input:
|
|
1028
|
+
input: names.attachToolHappierMetaV2(inputs, {
|
|
1030
1029
|
v: 2,
|
|
1031
1030
|
protocol: "acp",
|
|
1032
1031
|
provider: "codex",
|
|
@@ -1042,12 +1041,12 @@ async function codexRemoteLauncher(session) {
|
|
|
1042
1041
|
const filesMsg = changeCount === 1 ? "1 file" : `${changeCount} files`;
|
|
1043
1042
|
messageBuffer.addMessage(`Modifying ${filesMsg}...`, "tool");
|
|
1044
1043
|
const rawToolName = "CodexPatch";
|
|
1045
|
-
const canonicalToolName =
|
|
1044
|
+
const canonicalToolName = names.resolveCanonicalToolNameV2(rawToolName);
|
|
1046
1045
|
session.runtimeSession.sendCodexMessage({
|
|
1047
1046
|
type: "tool-call",
|
|
1048
1047
|
name: canonicalToolName,
|
|
1049
1048
|
callId: msg.call_id,
|
|
1050
|
-
input:
|
|
1049
|
+
input: names.attachToolHappierMetaV2({
|
|
1051
1050
|
auto_approved: msg.auto_approved,
|
|
1052
1051
|
changes: msg.changes
|
|
1053
1052
|
}, {
|
|
@@ -1070,7 +1069,7 @@ async function codexRemoteLauncher(session) {
|
|
|
1070
1069
|
session.runtimeSession.sendCodexMessage({
|
|
1071
1070
|
type: "tool-call-result",
|
|
1072
1071
|
callId: msg.call_id,
|
|
1073
|
-
output:
|
|
1072
|
+
output: names.attachToolHappierMetaV2({
|
|
1074
1073
|
stdout: msg.stdout,
|
|
1075
1074
|
stderr: msg.stderr,
|
|
1076
1075
|
success: msg.success
|
|
@@ -1079,7 +1078,7 @@ async function codexRemoteLauncher(session) {
|
|
|
1079
1078
|
protocol: "acp",
|
|
1080
1079
|
provider: "codex",
|
|
1081
1080
|
rawToolName: "CodexPatch",
|
|
1082
|
-
canonicalToolName:
|
|
1081
|
+
canonicalToolName: names.resolveCanonicalToolNameV2("CodexPatch")
|
|
1083
1082
|
}),
|
|
1084
1083
|
id: node_crypto.randomUUID(),
|
|
1085
1084
|
isError: !msg.success
|
|
@@ -1442,7 +1441,7 @@ async function runCodex(opts) {
|
|
|
1442
1441
|
machineId,
|
|
1443
1442
|
metadata: index.initialMachineMetadata
|
|
1444
1443
|
});
|
|
1445
|
-
const { state, metadata } =
|
|
1444
|
+
const { state, metadata } = names.createSessionMetadata({
|
|
1446
1445
|
flavor: "codex",
|
|
1447
1446
|
machineId,
|
|
1448
1447
|
startedBy: opts.startedBy
|
|
@@ -1458,7 +1457,7 @@ async function runCodex(opts) {
|
|
|
1458
1457
|
}
|
|
1459
1458
|
let sessionClient;
|
|
1460
1459
|
let codexSession = null;
|
|
1461
|
-
const { session: initialSession, reconnectionHandle } =
|
|
1460
|
+
const { session: initialSession, reconnectionHandle } = names.setupOfflineReconnection({
|
|
1462
1461
|
api: api$1,
|
|
1463
1462
|
sessionTag,
|
|
1464
1463
|
metadata,
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
2
2
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import { l as logger, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-
|
|
5
|
-
import { readSettings } from './persistence-
|
|
6
|
-
import { B as BasePermissionHandler, a as BaseReasoningProcessor, c as createSessionMetadata, s as setupOfflineReconnection } from './
|
|
7
|
-
import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, s as saveGeminiModelToConfig, a as createGeminiBackend, b as stopCaffeinate } from './index-
|
|
8
|
-
import { M as MessageQueue2, h as hashObject, a as MessageBuffer, r as registerKillSessionHandler } from './registerKillSessionHandler-
|
|
9
|
-
import { attachToolHappierMetaV2, resolveCanonicalToolNameV2, inferToolResultError } from 'happy-protocol';
|
|
4
|
+
import { l as logger, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-CnvyGas2.mjs';
|
|
5
|
+
import { readSettings } from './persistence-BPV3AmJL.mjs';
|
|
6
|
+
import { B as BasePermissionHandler, a as BaseReasoningProcessor, c as createSessionMetadata, s as setupOfflineReconnection, b as attachToolHappierMetaV2, r as resolveCanonicalToolNameV2, i as inferToolResultError } from './names-C9iJODqA.mjs';
|
|
7
|
+
import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, s as saveGeminiModelToConfig, a as createGeminiBackend, b as stopCaffeinate } from './index-BpZL4RcT.mjs';
|
|
8
|
+
import { M as MessageQueue2, h as hashObject, a as MessageBuffer, r as registerKillSessionHandler } from './registerKillSessionHandler-C2O8b5wH.mjs';
|
|
10
9
|
import 'axios';
|
|
11
10
|
import 'chalk';
|
|
12
11
|
import 'fs';
|
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
var ink = require('ink');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var api = require('./api-
|
|
7
|
-
var persistence = require('./persistence-
|
|
8
|
-
var
|
|
9
|
-
var index = require('./index-
|
|
10
|
-
var registerKillSessionHandler = require('./registerKillSessionHandler-
|
|
11
|
-
var happyProtocol = require('happy-protocol');
|
|
6
|
+
var api = require('./api-CUTdFiFP.cjs');
|
|
7
|
+
var persistence = require('./persistence-CxvL0cwp.cjs');
|
|
8
|
+
var names = require('./names-YEhZwVT0.cjs');
|
|
9
|
+
var index = require('./index-D4OdFq68.cjs');
|
|
10
|
+
var registerKillSessionHandler = require('./registerKillSessionHandler-rqd7duc9.cjs');
|
|
12
11
|
require('axios');
|
|
13
12
|
require('chalk');
|
|
14
13
|
require('fs');
|
|
@@ -185,7 +184,7 @@ const GeminiDisplay = ({ messageBuffer, logPath, currentModel, onExit }) => {
|
|
|
185
184
|
));
|
|
186
185
|
};
|
|
187
186
|
|
|
188
|
-
class GeminiPermissionHandler extends
|
|
187
|
+
class GeminiPermissionHandler extends names.BasePermissionHandler {
|
|
189
188
|
currentPermissionMode = "default";
|
|
190
189
|
constructor(session) {
|
|
191
190
|
super(session);
|
|
@@ -270,7 +269,7 @@ class GeminiPermissionHandler extends BaseReasoningProcessor.BasePermissionHandl
|
|
|
270
269
|
}
|
|
271
270
|
}
|
|
272
271
|
|
|
273
|
-
class GeminiReasoningProcessor extends
|
|
272
|
+
class GeminiReasoningProcessor extends names.BaseReasoningProcessor {
|
|
274
273
|
getToolName() {
|
|
275
274
|
return "GeminiReasoning";
|
|
276
275
|
}
|
|
@@ -601,7 +600,7 @@ async function runGemini(opts) {
|
|
|
601
600
|
} catch (error) {
|
|
602
601
|
api.logger.debug("[Gemini] Failed to fetch cloud token:", error);
|
|
603
602
|
}
|
|
604
|
-
const { state, metadata } =
|
|
603
|
+
const { state, metadata } = names.createSessionMetadata({
|
|
605
604
|
flavor: "gemini",
|
|
606
605
|
machineId,
|
|
607
606
|
startedBy: opts.startedBy
|
|
@@ -629,7 +628,7 @@ async function runGemini(opts) {
|
|
|
629
628
|
pendingSessionSwap = null;
|
|
630
629
|
}
|
|
631
630
|
};
|
|
632
|
-
const { session: initialSession, reconnectionHandle } =
|
|
631
|
+
const { session: initialSession, reconnectionHandle } = names.setupOfflineReconnection({
|
|
633
632
|
api: api$1,
|
|
634
633
|
sessionTag,
|
|
635
634
|
metadata,
|
|
@@ -951,13 +950,13 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
951
950
|
if (isInvestigationTool && msg.args && typeof msg.args === "object" && "objective" in msg.args) {
|
|
952
951
|
api.logger.debug(`[gemini] \u{1F50D} Investigation objective: ${String(msg.args.objective).substring(0, 150)}...`);
|
|
953
952
|
}
|
|
954
|
-
const canonicalToolName =
|
|
953
|
+
const canonicalToolName = names.resolveCanonicalToolNameV2(msg.toolName);
|
|
955
954
|
messageBuffer.addMessage(`Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}${toolArgs.length >= 100 ? "..." : ""}` : ""}`, "tool");
|
|
956
955
|
session.sendAgentMessage("gemini", {
|
|
957
956
|
type: "tool-call",
|
|
958
957
|
name: canonicalToolName,
|
|
959
958
|
callId: msg.callId,
|
|
960
|
-
input:
|
|
959
|
+
input: names.attachToolHappierMetaV2(msg.args, {
|
|
961
960
|
v: 2,
|
|
962
961
|
protocol: "acp",
|
|
963
962
|
provider: "gemini",
|
|
@@ -968,7 +967,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
968
967
|
});
|
|
969
968
|
break;
|
|
970
969
|
case "tool-result":
|
|
971
|
-
const isError =
|
|
970
|
+
const isError = names.inferToolResultError(msg.result);
|
|
972
971
|
const resultText = typeof msg.result === "string" ? msg.result.substring(0, 200) : JSON.stringify(msg.result).substring(0, 200);
|
|
973
972
|
const truncatedResult = resultText + (typeof msg.result === "string" && msg.result.length > 200 ? "..." : "");
|
|
974
973
|
const resultSize = typeof msg.result === "string" ? msg.result.length : JSON.stringify(msg.result).length;
|
|
@@ -989,12 +988,12 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
989
988
|
session.sendAgentMessage("gemini", {
|
|
990
989
|
type: "tool-result",
|
|
991
990
|
callId: msg.callId,
|
|
992
|
-
output:
|
|
991
|
+
output: names.attachToolHappierMetaV2(msg.result, {
|
|
993
992
|
v: 2,
|
|
994
993
|
protocol: "acp",
|
|
995
994
|
provider: "gemini",
|
|
996
995
|
rawToolName: msg.toolName,
|
|
997
|
-
canonicalToolName:
|
|
996
|
+
canonicalToolName: names.resolveCanonicalToolNameV2(msg.toolName)
|
|
998
997
|
}),
|
|
999
998
|
id: node_crypto.randomUUID(),
|
|
1000
999
|
isError
|
|
@@ -1044,12 +1043,12 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1044
1043
|
const { call_id, type, ...inputs } = execApprovalMsg;
|
|
1045
1044
|
api.logger.debug(`[gemini] Exec approval request received: ${callId}`);
|
|
1046
1045
|
messageBuffer.addMessage(`Exec approval requested: ${callId}`, "tool");
|
|
1047
|
-
const execCanonicalToolName =
|
|
1046
|
+
const execCanonicalToolName = names.resolveCanonicalToolNameV2("GeminiBash");
|
|
1048
1047
|
session.sendAgentMessage("gemini", {
|
|
1049
1048
|
type: "tool-call",
|
|
1050
1049
|
name: execCanonicalToolName,
|
|
1051
1050
|
callId,
|
|
1052
|
-
input:
|
|
1051
|
+
input: names.attachToolHappierMetaV2(inputs, {
|
|
1053
1052
|
v: 2,
|
|
1054
1053
|
protocol: "acp",
|
|
1055
1054
|
provider: "gemini",
|
|
@@ -1067,12 +1066,12 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1067
1066
|
const filesMsg = changeCount === 1 ? "1 file" : `${changeCount} files`;
|
|
1068
1067
|
messageBuffer.addMessage(`Modifying ${filesMsg}...`, "tool");
|
|
1069
1068
|
api.logger.debug(`[gemini] Patch apply begin: ${patchCallId}, files: ${changeCount}`);
|
|
1070
|
-
const patchCanonicalToolName =
|
|
1069
|
+
const patchCanonicalToolName = names.resolveCanonicalToolNameV2("GeminiPatch");
|
|
1071
1070
|
session.sendAgentMessage("gemini", {
|
|
1072
1071
|
type: "tool-call",
|
|
1073
1072
|
name: patchCanonicalToolName,
|
|
1074
1073
|
callId: patchCallId,
|
|
1075
|
-
input:
|
|
1074
|
+
input: names.attachToolHappierMetaV2({
|
|
1076
1075
|
auto_approved,
|
|
1077
1076
|
changes
|
|
1078
1077
|
}, {
|
|
@@ -1100,7 +1099,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1100
1099
|
session.sendAgentMessage("gemini", {
|
|
1101
1100
|
type: "tool-result",
|
|
1102
1101
|
callId: patchEndCallId,
|
|
1103
|
-
output:
|
|
1102
|
+
output: names.attachToolHappierMetaV2({
|
|
1104
1103
|
stdout,
|
|
1105
1104
|
stderr,
|
|
1106
1105
|
success
|
|
@@ -1109,7 +1108,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1109
1108
|
protocol: "acp",
|
|
1110
1109
|
provider: "gemini",
|
|
1111
1110
|
rawToolName: "GeminiPatch",
|
|
1112
|
-
canonicalToolName:
|
|
1111
|
+
canonicalToolName: names.resolveCanonicalToolNameV2("GeminiPatch")
|
|
1113
1112
|
}),
|
|
1114
1113
|
id: node_crypto.randomUUID(),
|
|
1115
1114
|
isError: !success
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "happy-imou-cloud",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.9",
|
|
4
4
|
"description": "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI",
|
|
5
5
|
"author": "long.zhu",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"// ==== TypeScript & Build ====": "",
|
|
44
44
|
"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",
|
|
45
45
|
"typecheck": "tsc --noEmit",
|
|
46
|
-
"build": "
|
|
46
|
+
"build": "node ./scripts/build.mjs",
|
|
47
47
|
"// ==== Testing ====": "",
|
|
48
48
|
"test": "yarn build && vitest run",
|
|
49
49
|
"test:integration": "yarn build && vitest run --config vitest.integration.config.ts",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"dev:local-server": "yarn build && tsx --env-file .env.dev-local-server src/index.ts",
|
|
60
60
|
"dev:integration-test-env": "yarn build && tsx --env-file .env.integration-test src/index.ts",
|
|
61
61
|
"// ==== Release ====": "",
|
|
62
|
-
"prepublishOnly": "yarn release:smoke",
|
|
62
|
+
"prepublishOnly": "yarn release:smoke",
|
|
63
63
|
"release": "yarn install && release-it",
|
|
64
64
|
"release:smoke": "node ./scripts/release-smoke.mjs",
|
|
65
65
|
"// ==== Dev/Stable Variant Management ====": "",
|
|
@@ -99,7 +99,6 @@
|
|
|
99
99
|
"expo-server-sdk": "^3.15.0",
|
|
100
100
|
"fastify": "^5.6.2",
|
|
101
101
|
"fastify-type-provider-zod": "4.0.2",
|
|
102
|
-
"happy-protocol": "0.1.0",
|
|
103
102
|
"http-proxy": "^1.18.1",
|
|
104
103
|
"http-proxy-middleware": "^3.0.5",
|
|
105
104
|
"ink": "^6.5.1",
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { existsSync, readFileSync, rmSync } from 'node:fs';
|
|
5
|
+
import { dirname, resolve } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const packageRoot = resolve(here, '..');
|
|
10
|
+
const workspaceRoot = resolve(packageRoot, '..', '..');
|
|
11
|
+
const packageJson = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8'));
|
|
12
|
+
|
|
13
|
+
function resolveTool(binName, packageSpecs) {
|
|
14
|
+
const suffix = process.platform === 'win32' ? '.cmd' : '';
|
|
15
|
+
const packageLocalBin = resolve(packageRoot, 'node_modules', '.bin', `${binName}${suffix}`);
|
|
16
|
+
const workspaceLocalBin = resolve(workspaceRoot, 'node_modules', '.bin', `${binName}${suffix}`);
|
|
17
|
+
|
|
18
|
+
if (existsSync(packageLocalBin)) {
|
|
19
|
+
return {
|
|
20
|
+
command: packageLocalBin,
|
|
21
|
+
prefixArgs: [],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (existsSync(workspaceLocalBin)) {
|
|
26
|
+
return {
|
|
27
|
+
command: workspaceLocalBin,
|
|
28
|
+
prefixArgs: [],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
command: 'npx',
|
|
34
|
+
prefixArgs: ['-y', ...packageSpecs.flatMap((packageSpec) => ['-p', packageSpec]), binName],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function runStep(name, command, args) {
|
|
39
|
+
console.log(`\n[build] ${name}`);
|
|
40
|
+
console.log(`> ${command} ${args.join(' ')}`);
|
|
41
|
+
|
|
42
|
+
const result = spawnSync(command, args, {
|
|
43
|
+
cwd: packageRoot,
|
|
44
|
+
stdio: 'inherit',
|
|
45
|
+
shell: process.platform === 'win32',
|
|
46
|
+
env: process.env,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (result.status !== 0) {
|
|
50
|
+
throw new Error(`[build] Step failed: ${name}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function runTool(name, tool, args) {
|
|
55
|
+
runStep(name, tool.command, [...tool.prefixArgs, ...args]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const tsc = resolveTool('tsc', [`typescript@${packageJson.devDependencies.typescript}`]);
|
|
59
|
+
const pkgroll = resolveTool('pkgroll', [
|
|
60
|
+
`pkgroll@${packageJson.devDependencies.pkgroll}`,
|
|
61
|
+
`typescript@${packageJson.devDependencies.typescript}`,
|
|
62
|
+
]);
|
|
63
|
+
|
|
64
|
+
rmSync(resolve(packageRoot, 'dist'), { recursive: true, force: true });
|
|
65
|
+
runTool('typecheck', tsc, ['--noEmit']);
|
|
66
|
+
runTool('bundle', pkgroll, []);
|
|
@@ -1,66 +1,202 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
4
6
|
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { dirname, resolve } from 'node:path';
|
|
7
|
+
import { dirname, join, resolve } from 'node:path';
|
|
6
8
|
|
|
7
9
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
8
10
|
const packageRoot = resolve(here, '..');
|
|
11
|
+
const workspaceRoot = resolve(packageRoot, '..', '..');
|
|
12
|
+
const packageJson = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8'));
|
|
13
|
+
|
|
14
|
+
function resolveTool(binName, packageName) {
|
|
15
|
+
const suffix = process.platform === 'win32' ? '.cmd' : '';
|
|
16
|
+
const packageLocalBin = resolve(packageRoot, 'node_modules', '.bin', `${binName}${suffix}`);
|
|
17
|
+
const workspaceLocalBin = resolve(workspaceRoot, 'node_modules', '.bin', `${binName}${suffix}`);
|
|
18
|
+
|
|
19
|
+
if (existsSync(packageLocalBin)) {
|
|
20
|
+
return {
|
|
21
|
+
command: packageLocalBin,
|
|
22
|
+
prefixArgs: [],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (existsSync(workspaceLocalBin)) {
|
|
27
|
+
return {
|
|
28
|
+
command: workspaceLocalBin,
|
|
29
|
+
prefixArgs: [],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const version =
|
|
34
|
+
packageJson.devDependencies?.[packageName]
|
|
35
|
+
?? packageJson.dependencies?.[packageName];
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
command: 'npx',
|
|
39
|
+
prefixArgs: ['-y', '-p', `${packageName}@${version}`, binName],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function shouldUseShell(command) {
|
|
44
|
+
if (process.platform !== 'win32') {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return !/\.exe$/i.test(command);
|
|
49
|
+
}
|
|
9
50
|
|
|
10
51
|
function runStep(name, command, args, options = {}) {
|
|
11
52
|
console.log(`\n[release-smoke] ${name}`);
|
|
12
53
|
console.log(`> ${command} ${args.join(' ')}`);
|
|
13
|
-
|
|
54
|
+
|
|
14
55
|
const result = spawnSync(command, args, {
|
|
15
56
|
cwd: packageRoot,
|
|
16
57
|
stdio: 'inherit',
|
|
17
|
-
shell:
|
|
18
|
-
env:
|
|
58
|
+
shell: shouldUseShell(command),
|
|
59
|
+
env: {
|
|
60
|
+
...process.env,
|
|
61
|
+
NODE_ENV: 'development',
|
|
62
|
+
YARN_PRODUCTION: 'false',
|
|
63
|
+
npm_config_production: 'false',
|
|
64
|
+
},
|
|
65
|
+
...options,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (result.status !== 0) {
|
|
69
|
+
throw new Error(`[release-smoke] Step failed: ${name}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function runStepCapture(name, command, args, options = {}) {
|
|
74
|
+
console.log(`\n[release-smoke] ${name}`);
|
|
75
|
+
console.log(`> ${command} ${args.join(' ')}`);
|
|
76
|
+
|
|
77
|
+
const result = spawnSync(command, args, {
|
|
78
|
+
cwd: packageRoot,
|
|
79
|
+
stdio: 'pipe',
|
|
80
|
+
encoding: 'utf8',
|
|
81
|
+
shell: shouldUseShell(command),
|
|
82
|
+
env: {
|
|
83
|
+
...process.env,
|
|
84
|
+
NODE_ENV: 'development',
|
|
85
|
+
YARN_PRODUCTION: 'false',
|
|
86
|
+
npm_config_production: 'false',
|
|
87
|
+
},
|
|
19
88
|
...options,
|
|
20
89
|
});
|
|
21
90
|
|
|
22
91
|
if (result.status !== 0) {
|
|
92
|
+
if (result.stdout) {
|
|
93
|
+
process.stdout.write(result.stdout);
|
|
94
|
+
}
|
|
95
|
+
if (result.stderr) {
|
|
96
|
+
process.stderr.write(result.stderr);
|
|
97
|
+
}
|
|
23
98
|
throw new Error(`[release-smoke] Step failed: ${name}`);
|
|
24
99
|
}
|
|
100
|
+
|
|
101
|
+
return result.stdout;
|
|
25
102
|
}
|
|
26
103
|
|
|
27
|
-
function
|
|
28
|
-
|
|
104
|
+
function runToolStep(name, tool, args, options = {}) {
|
|
105
|
+
runStep(name, tool.command, [...tool.prefixArgs, ...args], options);
|
|
29
106
|
}
|
|
30
107
|
|
|
108
|
+
function verifyPackedInstall() {
|
|
109
|
+
const tempRoot = mkdtempSync(join(tmpdir(), 'happy-cli-release-smoke-'));
|
|
110
|
+
let tarballPath = null;
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const packOutput = runStepCapture('pack tarball', 'npm', ['pack', '--json', '--ignore-scripts']);
|
|
114
|
+
const packResult = JSON.parse(packOutput);
|
|
115
|
+
const tarballFile = Array.isArray(packResult) ? packResult[0]?.filename : null;
|
|
116
|
+
|
|
117
|
+
if (typeof tarballFile !== 'string' || tarballFile.length === 0) {
|
|
118
|
+
throw new Error('[release-smoke] npm pack did not return a tarball filename');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
tarballPath = resolve(packageRoot, tarballFile);
|
|
122
|
+
|
|
123
|
+
writeFileSync(
|
|
124
|
+
join(tempRoot, 'package.json'),
|
|
125
|
+
JSON.stringify({ private: true, name: 'happy-cli-release-smoke' }, null, 2)
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
runStep('install packed tarball', 'npm', [
|
|
129
|
+
'install',
|
|
130
|
+
'--ignore-scripts',
|
|
131
|
+
'--no-audit',
|
|
132
|
+
'--fund=false',
|
|
133
|
+
tarballPath,
|
|
134
|
+
], {
|
|
135
|
+
cwd: tempRoot,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
runStep('run packed cli help', 'node', [
|
|
139
|
+
join(tempRoot, 'node_modules', 'happy-imou-cloud', 'bin', 'happy-cloud.mjs'),
|
|
140
|
+
'--help',
|
|
141
|
+
], {
|
|
142
|
+
cwd: tempRoot,
|
|
143
|
+
});
|
|
144
|
+
} finally {
|
|
145
|
+
if (tarballPath) {
|
|
146
|
+
try {
|
|
147
|
+
unlinkSync(tarballPath);
|
|
148
|
+
} catch {}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
rmSync(tempRoot, { recursive: true, force: true });
|
|
153
|
+
} catch {}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function shouldRunProviderSmoke(provider) {
|
|
158
|
+
return process.env[`HAPPY_SMOKE_${provider.toUpperCase()}`] === '1';
|
|
159
|
+
}
|
|
160
|
+
|
|
31
161
|
function main() {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
162
|
+
const tsc = resolveTool('tsc', 'typescript');
|
|
163
|
+
const vitest = resolveTool('vitest', 'vitest');
|
|
164
|
+
|
|
165
|
+
runToolStep('typecheck', tsc, ['--noEmit']);
|
|
166
|
+
runToolStep('unit runtime suite', vitest, [
|
|
35
167
|
'run',
|
|
168
|
+
'src/agent/acp/AcpBackend.test.ts',
|
|
36
169
|
'src/agent/acp/AcpBackend.startup.test.ts',
|
|
170
|
+
'src/agent/acp/AcpBackend.waitForResponseComplete.test.ts',
|
|
171
|
+
'src/agent/acp/AcpBackend.initDelay.test.ts',
|
|
37
172
|
'src/agent/acp/acpSpawn.test.ts',
|
|
38
173
|
'src/agent/acp/createAcpFilteredStdoutReadable.multiline.test.ts',
|
|
39
174
|
'src/agent/acp/killProcessTree.test.ts',
|
|
40
|
-
'src/runtime/executeProvider.test.ts',
|
|
41
|
-
'src/runtime/command.test.ts',
|
|
42
|
-
'src/runtime/launch.test.ts',
|
|
43
|
-
'src/runtime/RuntimeShell.test.ts',
|
|
44
|
-
'src/runtime/createDefaultRuntimeShell.test.ts',
|
|
45
|
-
'src/security/signedTransport.test.ts',
|
|
46
|
-
'src/agent/initializeAgents.test.ts',
|
|
47
|
-
'src/agent/factories/factories.test.ts',
|
|
48
|
-
'src/packageContract.test.ts',
|
|
175
|
+
'src/runtime/executeProvider.test.ts',
|
|
176
|
+
'src/runtime/command.test.ts',
|
|
177
|
+
'src/runtime/launch.test.ts',
|
|
178
|
+
'src/runtime/RuntimeShell.test.ts',
|
|
179
|
+
'src/runtime/createDefaultRuntimeShell.test.ts',
|
|
180
|
+
'src/security/signedTransport.test.ts',
|
|
181
|
+
'src/agent/initializeAgents.test.ts',
|
|
182
|
+
'src/agent/factories/factories.test.ts',
|
|
183
|
+
'src/packageContract.test.ts',
|
|
49
184
|
]);
|
|
50
185
|
runStep('build', 'yarn', ['build']);
|
|
51
|
-
runStep('runtime providers', '
|
|
52
|
-
runStep('help', '
|
|
186
|
+
runStep('runtime providers', 'node', ['./bin/happy-cloud.mjs', 'runtime', 'providers']);
|
|
187
|
+
runStep('help', 'node', ['./bin/happy-cloud.mjs', '--help']);
|
|
188
|
+
verifyPackedInstall();
|
|
53
189
|
|
|
54
190
|
if (shouldRunProviderSmoke('cursor')) {
|
|
55
|
-
runStep('cursor smoke', '
|
|
191
|
+
runStep('cursor smoke', 'node', ['./bin/happy-cloud.mjs', 'cursor', 'release smoke']);
|
|
56
192
|
}
|
|
57
193
|
}
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
main();
|
|
61
|
-
console.log('\n[release-smoke] All required steps passed');
|
|
62
|
-
} catch (error) {
|
|
63
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
64
|
-
console.error(`\n${message}`);
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
main();
|
|
197
|
+
console.log('\n[release-smoke] All required steps passed');
|
|
198
|
+
} catch (error) {
|
|
199
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
200
|
+
console.error(`\n${message}`);
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|