happy-imou-cloud 2.0.0 → 2.0.1
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/{BaseReasoningProcessor-BRCQXCZY.cjs → BaseReasoningProcessor-01KqA3Kz.cjs} +96 -9
- package/dist/{BaseReasoningProcessor-BKLRCKTU.mjs → BaseReasoningProcessor-DQE2l7Xu.mjs} +95 -10
- package/dist/{api-BGXYX0yH.mjs → api-B5Ui8Fw0.mjs} +68 -6
- package/dist/{api-D7OK-mML.cjs → api-B8v4tczT.cjs} +70 -5
- package/dist/{command-CnLtKtP-.mjs → command-BfIuJmeo.mjs} +3 -3
- package/dist/{command-G85giEAF.cjs → command-D8yNlaDo.cjs} +3 -3
- package/dist/{index-C7Y0R-MI.mjs → index-BByhFIIq.mjs} +682 -220
- package/dist/{index-B_wlQBy2.cjs → index-BOqJ9hwi.cjs} +684 -220
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +1 -0
- package/dist/lib.d.mts +1 -0
- package/dist/lib.mjs +1 -1
- package/dist/{persistence-DHgf1CTG.cjs → persistence-C33AMdtv.cjs} +1 -1
- package/dist/{persistence-BA_unuca.mjs → persistence-CzpZpiL3.mjs} +1 -1
- package/dist/{registerKillSessionHandler-CLREXN11.cjs → registerKillSessionHandler-BkzQulD9.cjs} +6 -4
- package/dist/{registerKillSessionHandler-C2-yHm1V.mjs → registerKillSessionHandler-BtSK7IOa.mjs} +6 -4
- package/dist/{runClaude-CwAitpX-.cjs → runClaude-CNVufgZb.cjs} +14 -6
- package/dist/{runClaude-uNC5Eym4.mjs → runClaude-C_WLfM6c.mjs} +13 -5
- package/dist/{runCodex-B-05E-YZ.mjs → runCodex-8eWjTPJr.mjs} +636 -819
- package/dist/{runCodex-Cm0VTqw_.cjs → runCodex-Dzy8anlX.cjs} +639 -819
- package/dist/{runGemini-CLWjwDYS.cjs → runGemini-CgsVKP7m.cjs} +20 -16
- package/dist/{runGemini-_biXvQAH.mjs → runGemini-nbr0mm-S.mjs} +20 -16
- package/package.json +14 -14
- package/scripts/env-wrapper.cjs +11 -11
- package/scripts/setup-dev.cjs +4 -4
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
var os = require('node:os');
|
|
4
4
|
var path = require('node:path');
|
|
5
|
-
var api = require('./api-
|
|
6
|
-
var index = require('./index-
|
|
5
|
+
var api = require('./api-B8v4tczT.cjs');
|
|
6
|
+
var index = require('./index-BOqJ9hwi.cjs');
|
|
7
|
+
var node_events = require('node:events');
|
|
7
8
|
var node_crypto = require('node:crypto');
|
|
8
9
|
|
|
9
10
|
function createSessionMetadata(opts) {
|
|
@@ -31,7 +32,10 @@ function createSessionMetadata(opts) {
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
function createOfflineSessionStub(sessionTag) {
|
|
34
|
-
|
|
35
|
+
const emitter = new node_events.EventEmitter();
|
|
36
|
+
let metadata = null;
|
|
37
|
+
let agentState = null;
|
|
38
|
+
const stub = {
|
|
35
39
|
sessionId: `offline-${sessionTag}`,
|
|
36
40
|
sendCodexMessage: () => {
|
|
37
41
|
},
|
|
@@ -53,20 +57,29 @@ function createOfflineSessionStub(sessionTag) {
|
|
|
53
57
|
},
|
|
54
58
|
close: async () => {
|
|
55
59
|
},
|
|
56
|
-
updateMetadata: () => {
|
|
60
|
+
updateMetadata: (handler) => {
|
|
61
|
+
metadata = handler(metadata || {});
|
|
62
|
+
emitter.emit("metadata-updated", metadata);
|
|
57
63
|
},
|
|
58
|
-
updateAgentState: () => {
|
|
64
|
+
updateAgentState: (handler) => {
|
|
65
|
+
agentState = handler(agentState || {});
|
|
66
|
+
emitter.emit("agent-state-updated", agentState);
|
|
59
67
|
},
|
|
60
|
-
getMetadataSnapshot: () =>
|
|
61
|
-
getAgentStateSnapshot: () =>
|
|
62
|
-
waitForMetadataUpdate: async () =>
|
|
68
|
+
getMetadataSnapshot: () => metadata,
|
|
69
|
+
getAgentStateSnapshot: () => agentState,
|
|
70
|
+
waitForMetadataUpdate: async () => metadata,
|
|
63
71
|
onUserMessage: () => {
|
|
64
72
|
},
|
|
65
73
|
rpcHandlerManager: {
|
|
66
74
|
registerHandler: () => {
|
|
67
75
|
}
|
|
68
|
-
}
|
|
76
|
+
},
|
|
77
|
+
on: emitter.on.bind(emitter),
|
|
78
|
+
once: emitter.once.bind(emitter),
|
|
79
|
+
off: emitter.off.bind(emitter),
|
|
80
|
+
emit: emitter.emit.bind(emitter)
|
|
69
81
|
};
|
|
82
|
+
return stub;
|
|
70
83
|
}
|
|
71
84
|
|
|
72
85
|
function setupOfflineReconnection(opts) {
|
|
@@ -96,6 +109,15 @@ function setupOfflineReconnection(opts) {
|
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
const INTERACTION_SUPERSEDED_ERROR = "Interaction superseded by new user message";
|
|
112
|
+
const INTERACTION_TIMED_OUT_ERROR = "Interaction timed out waiting for user response";
|
|
113
|
+
const DEFAULT_INTERACTION_TIMEOUT_MS = 2 * 60 * 1e3;
|
|
114
|
+
function getPendingInteractionTimeoutMs() {
|
|
115
|
+
const raw = Number(process.env.HAPPY_INTERACTION_TIMEOUT_MS);
|
|
116
|
+
if (Number.isFinite(raw) && raw > 0) {
|
|
117
|
+
return raw;
|
|
118
|
+
}
|
|
119
|
+
return DEFAULT_INTERACTION_TIMEOUT_MS;
|
|
120
|
+
}
|
|
99
121
|
class BasePermissionHandler {
|
|
100
122
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
101
123
|
session;
|
|
@@ -126,6 +148,7 @@ class BasePermissionHandler {
|
|
|
126
148
|
return;
|
|
127
149
|
}
|
|
128
150
|
this.pendingRequests.delete(response.id);
|
|
151
|
+
this.clearPendingRequestTimeout(pending);
|
|
129
152
|
const result = response.approved ? { decision: response.decision === "approved_for_session" ? "approved_for_session" : "approved" } : { decision: response.decision === "denied" ? "denied" : "abort" };
|
|
130
153
|
pending.resolve(result);
|
|
131
154
|
this.session.updateAgentState((currentState) => {
|
|
@@ -167,6 +190,22 @@ class BasePermissionHandler {
|
|
|
167
190
|
}
|
|
168
191
|
}));
|
|
169
192
|
}
|
|
193
|
+
registerPendingRequest(toolCallId, toolName, input, logSuffix = "") {
|
|
194
|
+
return new Promise((resolve, reject) => {
|
|
195
|
+
const pending = {
|
|
196
|
+
resolve,
|
|
197
|
+
reject,
|
|
198
|
+
toolName,
|
|
199
|
+
input
|
|
200
|
+
};
|
|
201
|
+
pending.timeoutHandle = setTimeout(() => {
|
|
202
|
+
this.handlePendingRequestTimeout(toolCallId, pending);
|
|
203
|
+
}, getPendingInteractionTimeoutMs());
|
|
204
|
+
this.pendingRequests.set(toolCallId, pending);
|
|
205
|
+
this.addPendingRequestToState(toolCallId, toolName, input);
|
|
206
|
+
api.logger.debug(`${this.getLogPrefix()} Permission request sent for tool: ${toolName} (${toolCallId})${logSuffix}`);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
170
209
|
hasPendingRequests() {
|
|
171
210
|
return this.pendingRequests.size > 0;
|
|
172
211
|
}
|
|
@@ -178,6 +217,7 @@ class BasePermissionHandler {
|
|
|
178
217
|
this.pendingRequests.clear();
|
|
179
218
|
const completedAt = Date.now();
|
|
180
219
|
for (const [, pending] of pendingSnapshot) {
|
|
220
|
+
this.clearPendingRequestTimeout(pending);
|
|
181
221
|
pending.resolve({ decision: "abort" });
|
|
182
222
|
}
|
|
183
223
|
this.session.updateAgentState((currentState) => {
|
|
@@ -221,6 +261,7 @@ class BasePermissionHandler {
|
|
|
221
261
|
this.pendingRequests.clear();
|
|
222
262
|
for (const [id, pending] of pendingSnapshot) {
|
|
223
263
|
try {
|
|
264
|
+
this.clearPendingRequestTimeout(pending);
|
|
224
265
|
pending.reject(new Error("Session reset"));
|
|
225
266
|
} catch (err) {
|
|
226
267
|
api.logger.debug(`${this.getLogPrefix()} Error rejecting pending request ${id}:`, err);
|
|
@@ -248,6 +289,50 @@ class BasePermissionHandler {
|
|
|
248
289
|
this.isResetting = false;
|
|
249
290
|
}
|
|
250
291
|
}
|
|
292
|
+
clearPendingRequestTimeout(pending) {
|
|
293
|
+
if (pending?.timeoutHandle) {
|
|
294
|
+
clearTimeout(pending.timeoutHandle);
|
|
295
|
+
pending.timeoutHandle = void 0;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
handlePendingRequestTimeout(toolCallId, pending) {
|
|
299
|
+
const active = this.pendingRequests.get(toolCallId);
|
|
300
|
+
if (!active || active !== pending) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
this.pendingRequests.delete(toolCallId);
|
|
304
|
+
this.clearPendingRequestTimeout(active);
|
|
305
|
+
active.resolve({ decision: "abort" });
|
|
306
|
+
this.session.updateAgentState((currentState) => {
|
|
307
|
+
const request = currentState.requests?.[toolCallId] || {
|
|
308
|
+
tool: active.toolName,
|
|
309
|
+
arguments: active.input,
|
|
310
|
+
createdAt: Date.now(),
|
|
311
|
+
requestKind: "permission"
|
|
312
|
+
};
|
|
313
|
+
const { [toolCallId]: _, ...remainingRequests } = currentState.requests || {};
|
|
314
|
+
return {
|
|
315
|
+
...currentState,
|
|
316
|
+
requests: remainingRequests,
|
|
317
|
+
completedRequests: {
|
|
318
|
+
...currentState.completedRequests,
|
|
319
|
+
[toolCallId]: {
|
|
320
|
+
...request,
|
|
321
|
+
completedAt: Date.now(),
|
|
322
|
+
status: "canceled",
|
|
323
|
+
reason: INTERACTION_TIMED_OUT_ERROR,
|
|
324
|
+
decision: "abort",
|
|
325
|
+
requestKind: request.requestKind || "permission"
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
});
|
|
330
|
+
this.session.sendSessionEvent({
|
|
331
|
+
type: "message",
|
|
332
|
+
message: "Pending interaction timed out waiting for a response. Send a new message to continue."
|
|
333
|
+
});
|
|
334
|
+
api.logger.debug(`${this.getLogPrefix()} Permission request timed out for ${active.toolName} (${toolCallId})`);
|
|
335
|
+
}
|
|
251
336
|
}
|
|
252
337
|
|
|
253
338
|
class BaseReasoningProcessor {
|
|
@@ -447,5 +532,7 @@ class BaseReasoningProcessor {
|
|
|
447
532
|
exports.BasePermissionHandler = BasePermissionHandler;
|
|
448
533
|
exports.BaseReasoningProcessor = BaseReasoningProcessor;
|
|
449
534
|
exports.INTERACTION_SUPERSEDED_ERROR = INTERACTION_SUPERSEDED_ERROR;
|
|
535
|
+
exports.INTERACTION_TIMED_OUT_ERROR = INTERACTION_TIMED_OUT_ERROR;
|
|
450
536
|
exports.createSessionMetadata = createSessionMetadata;
|
|
537
|
+
exports.getPendingInteractionTimeoutMs = getPendingInteractionTimeoutMs;
|
|
451
538
|
exports.setupOfflineReconnection = setupOfflineReconnection;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
-
import { c as configuration, p as packageJson, s as startOfflineReconnection, l as logger } from './api-
|
|
4
|
-
import { p as projectPath } from './index-
|
|
3
|
+
import { c as configuration, p as packageJson, s as startOfflineReconnection, l as logger } from './api-B5Ui8Fw0.mjs';
|
|
4
|
+
import { p as projectPath } from './index-BByhFIIq.mjs';
|
|
5
|
+
import { EventEmitter } from 'node:events';
|
|
5
6
|
import { randomUUID } from 'node:crypto';
|
|
6
7
|
|
|
7
8
|
function createSessionMetadata(opts) {
|
|
@@ -29,7 +30,10 @@ function createSessionMetadata(opts) {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
function createOfflineSessionStub(sessionTag) {
|
|
32
|
-
|
|
33
|
+
const emitter = new EventEmitter();
|
|
34
|
+
let metadata = null;
|
|
35
|
+
let agentState = null;
|
|
36
|
+
const stub = {
|
|
33
37
|
sessionId: `offline-${sessionTag}`,
|
|
34
38
|
sendCodexMessage: () => {
|
|
35
39
|
},
|
|
@@ -51,20 +55,29 @@ function createOfflineSessionStub(sessionTag) {
|
|
|
51
55
|
},
|
|
52
56
|
close: async () => {
|
|
53
57
|
},
|
|
54
|
-
updateMetadata: () => {
|
|
58
|
+
updateMetadata: (handler) => {
|
|
59
|
+
metadata = handler(metadata || {});
|
|
60
|
+
emitter.emit("metadata-updated", metadata);
|
|
55
61
|
},
|
|
56
|
-
updateAgentState: () => {
|
|
62
|
+
updateAgentState: (handler) => {
|
|
63
|
+
agentState = handler(agentState || {});
|
|
64
|
+
emitter.emit("agent-state-updated", agentState);
|
|
57
65
|
},
|
|
58
|
-
getMetadataSnapshot: () =>
|
|
59
|
-
getAgentStateSnapshot: () =>
|
|
60
|
-
waitForMetadataUpdate: async () =>
|
|
66
|
+
getMetadataSnapshot: () => metadata,
|
|
67
|
+
getAgentStateSnapshot: () => agentState,
|
|
68
|
+
waitForMetadataUpdate: async () => metadata,
|
|
61
69
|
onUserMessage: () => {
|
|
62
70
|
},
|
|
63
71
|
rpcHandlerManager: {
|
|
64
72
|
registerHandler: () => {
|
|
65
73
|
}
|
|
66
|
-
}
|
|
74
|
+
},
|
|
75
|
+
on: emitter.on.bind(emitter),
|
|
76
|
+
once: emitter.once.bind(emitter),
|
|
77
|
+
off: emitter.off.bind(emitter),
|
|
78
|
+
emit: emitter.emit.bind(emitter)
|
|
67
79
|
};
|
|
80
|
+
return stub;
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
function setupOfflineReconnection(opts) {
|
|
@@ -94,6 +107,15 @@ function setupOfflineReconnection(opts) {
|
|
|
94
107
|
}
|
|
95
108
|
|
|
96
109
|
const INTERACTION_SUPERSEDED_ERROR = "Interaction superseded by new user message";
|
|
110
|
+
const INTERACTION_TIMED_OUT_ERROR = "Interaction timed out waiting for user response";
|
|
111
|
+
const DEFAULT_INTERACTION_TIMEOUT_MS = 2 * 60 * 1e3;
|
|
112
|
+
function getPendingInteractionTimeoutMs() {
|
|
113
|
+
const raw = Number(process.env.HAPPY_INTERACTION_TIMEOUT_MS);
|
|
114
|
+
if (Number.isFinite(raw) && raw > 0) {
|
|
115
|
+
return raw;
|
|
116
|
+
}
|
|
117
|
+
return DEFAULT_INTERACTION_TIMEOUT_MS;
|
|
118
|
+
}
|
|
97
119
|
class BasePermissionHandler {
|
|
98
120
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
99
121
|
session;
|
|
@@ -124,6 +146,7 @@ class BasePermissionHandler {
|
|
|
124
146
|
return;
|
|
125
147
|
}
|
|
126
148
|
this.pendingRequests.delete(response.id);
|
|
149
|
+
this.clearPendingRequestTimeout(pending);
|
|
127
150
|
const result = response.approved ? { decision: response.decision === "approved_for_session" ? "approved_for_session" : "approved" } : { decision: response.decision === "denied" ? "denied" : "abort" };
|
|
128
151
|
pending.resolve(result);
|
|
129
152
|
this.session.updateAgentState((currentState) => {
|
|
@@ -165,6 +188,22 @@ class BasePermissionHandler {
|
|
|
165
188
|
}
|
|
166
189
|
}));
|
|
167
190
|
}
|
|
191
|
+
registerPendingRequest(toolCallId, toolName, input, logSuffix = "") {
|
|
192
|
+
return new Promise((resolve, reject) => {
|
|
193
|
+
const pending = {
|
|
194
|
+
resolve,
|
|
195
|
+
reject,
|
|
196
|
+
toolName,
|
|
197
|
+
input
|
|
198
|
+
};
|
|
199
|
+
pending.timeoutHandle = setTimeout(() => {
|
|
200
|
+
this.handlePendingRequestTimeout(toolCallId, pending);
|
|
201
|
+
}, getPendingInteractionTimeoutMs());
|
|
202
|
+
this.pendingRequests.set(toolCallId, pending);
|
|
203
|
+
this.addPendingRequestToState(toolCallId, toolName, input);
|
|
204
|
+
logger.debug(`${this.getLogPrefix()} Permission request sent for tool: ${toolName} (${toolCallId})${logSuffix}`);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
168
207
|
hasPendingRequests() {
|
|
169
208
|
return this.pendingRequests.size > 0;
|
|
170
209
|
}
|
|
@@ -176,6 +215,7 @@ class BasePermissionHandler {
|
|
|
176
215
|
this.pendingRequests.clear();
|
|
177
216
|
const completedAt = Date.now();
|
|
178
217
|
for (const [, pending] of pendingSnapshot) {
|
|
218
|
+
this.clearPendingRequestTimeout(pending);
|
|
179
219
|
pending.resolve({ decision: "abort" });
|
|
180
220
|
}
|
|
181
221
|
this.session.updateAgentState((currentState) => {
|
|
@@ -219,6 +259,7 @@ class BasePermissionHandler {
|
|
|
219
259
|
this.pendingRequests.clear();
|
|
220
260
|
for (const [id, pending] of pendingSnapshot) {
|
|
221
261
|
try {
|
|
262
|
+
this.clearPendingRequestTimeout(pending);
|
|
222
263
|
pending.reject(new Error("Session reset"));
|
|
223
264
|
} catch (err) {
|
|
224
265
|
logger.debug(`${this.getLogPrefix()} Error rejecting pending request ${id}:`, err);
|
|
@@ -246,6 +287,50 @@ class BasePermissionHandler {
|
|
|
246
287
|
this.isResetting = false;
|
|
247
288
|
}
|
|
248
289
|
}
|
|
290
|
+
clearPendingRequestTimeout(pending) {
|
|
291
|
+
if (pending?.timeoutHandle) {
|
|
292
|
+
clearTimeout(pending.timeoutHandle);
|
|
293
|
+
pending.timeoutHandle = void 0;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
handlePendingRequestTimeout(toolCallId, pending) {
|
|
297
|
+
const active = this.pendingRequests.get(toolCallId);
|
|
298
|
+
if (!active || active !== pending) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
this.pendingRequests.delete(toolCallId);
|
|
302
|
+
this.clearPendingRequestTimeout(active);
|
|
303
|
+
active.resolve({ decision: "abort" });
|
|
304
|
+
this.session.updateAgentState((currentState) => {
|
|
305
|
+
const request = currentState.requests?.[toolCallId] || {
|
|
306
|
+
tool: active.toolName,
|
|
307
|
+
arguments: active.input,
|
|
308
|
+
createdAt: Date.now(),
|
|
309
|
+
requestKind: "permission"
|
|
310
|
+
};
|
|
311
|
+
const { [toolCallId]: _, ...remainingRequests } = currentState.requests || {};
|
|
312
|
+
return {
|
|
313
|
+
...currentState,
|
|
314
|
+
requests: remainingRequests,
|
|
315
|
+
completedRequests: {
|
|
316
|
+
...currentState.completedRequests,
|
|
317
|
+
[toolCallId]: {
|
|
318
|
+
...request,
|
|
319
|
+
completedAt: Date.now(),
|
|
320
|
+
status: "canceled",
|
|
321
|
+
reason: INTERACTION_TIMED_OUT_ERROR,
|
|
322
|
+
decision: "abort",
|
|
323
|
+
requestKind: request.requestKind || "permission"
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
});
|
|
328
|
+
this.session.sendSessionEvent({
|
|
329
|
+
type: "message",
|
|
330
|
+
message: "Pending interaction timed out waiting for a response. Send a new message to continue."
|
|
331
|
+
});
|
|
332
|
+
logger.debug(`${this.getLogPrefix()} Permission request timed out for ${active.toolName} (${toolCallId})`);
|
|
333
|
+
}
|
|
249
334
|
}
|
|
250
335
|
|
|
251
336
|
class BaseReasoningProcessor {
|
|
@@ -442,4 +527,4 @@ class BaseReasoningProcessor {
|
|
|
442
527
|
}
|
|
443
528
|
}
|
|
444
529
|
|
|
445
|
-
export { BasePermissionHandler as B, INTERACTION_SUPERSEDED_ERROR as I, BaseReasoningProcessor as a, createSessionMetadata as c, setupOfflineReconnection as s };
|
|
530
|
+
export { BasePermissionHandler as B, INTERACTION_SUPERSEDED_ERROR as I, BaseReasoningProcessor as a, INTERACTION_TIMED_OUT_ERROR as b, createSessionMetadata as c, getPendingInteractionTimeoutMs as g, setupOfflineReconnection as s };
|
|
@@ -17,7 +17,7 @@ import { resolve, join as join$1 } from 'path';
|
|
|
17
17
|
import { Expo } from 'expo-server-sdk';
|
|
18
18
|
|
|
19
19
|
var name = "happy-imou-cloud";
|
|
20
|
-
var version = "2.0.
|
|
20
|
+
var version = "2.0.1";
|
|
21
21
|
var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
|
|
22
22
|
var author = "long.zhu";
|
|
23
23
|
var license = "MIT";
|
|
@@ -100,7 +100,7 @@ var scripts = {
|
|
|
100
100
|
"unlink:dev": "node scripts/link-dev.cjs unlink"
|
|
101
101
|
};
|
|
102
102
|
var dependencies = {
|
|
103
|
-
"@agentclientprotocol/sdk": "^0.
|
|
103
|
+
"@agentclientprotocol/sdk": "^0.14.1",
|
|
104
104
|
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
105
105
|
"@stablelib/base64": "^2.0.1",
|
|
106
106
|
"@stablelib/hex": "^2.0.1",
|
|
@@ -431,7 +431,7 @@ async function listDaemonLogFiles(limit = 50) {
|
|
|
431
431
|
return { file, path: fullPath, modified: stats.mtime };
|
|
432
432
|
}).sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
433
433
|
try {
|
|
434
|
-
const { readDaemonState } = await import('./persistence-
|
|
434
|
+
const { readDaemonState } = await import('./persistence-CzpZpiL3.mjs');
|
|
435
435
|
const state = await readDaemonState();
|
|
436
436
|
if (!state) {
|
|
437
437
|
return logs;
|
|
@@ -2097,6 +2097,42 @@ class PushNotificationClient {
|
|
|
2097
2097
|
}
|
|
2098
2098
|
}
|
|
2099
2099
|
|
|
2100
|
+
const AUTHENTICATION_REQUIRED_MESSAGE = 'Happy authentication failed. Run "hicloud auth login --force" to re-authenticate.';
|
|
2101
|
+
const SIGNING_BOOTSTRAP_REQUIRED_MESSAGE = 'Happy request signing initialization failed. Run "hicloud auth login --force" to retry. If it still fails, inspect the server response and local credentials state.';
|
|
2102
|
+
let authenticationWarningShown = false;
|
|
2103
|
+
class AuthenticationRequiredError extends Error {
|
|
2104
|
+
constructor(message = AUTHENTICATION_REQUIRED_MESSAGE) {
|
|
2105
|
+
super(message);
|
|
2106
|
+
this.name = "AuthenticationRequiredError";
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
function isAuthenticationRequiredError(error) {
|
|
2110
|
+
return error instanceof AuthenticationRequiredError;
|
|
2111
|
+
}
|
|
2112
|
+
class SigningBootstrapRequiredError extends AuthenticationRequiredError {
|
|
2113
|
+
constructor(message = SIGNING_BOOTSTRAP_REQUIRED_MESSAGE) {
|
|
2114
|
+
super(message);
|
|
2115
|
+
this.name = "SigningBootstrapRequiredError";
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
function isSigningBootstrapRequiredError(error) {
|
|
2119
|
+
return error instanceof SigningBootstrapRequiredError;
|
|
2120
|
+
}
|
|
2121
|
+
function printAuthenticationRequiredWarning(error) {
|
|
2122
|
+
if (authenticationWarningShown) {
|
|
2123
|
+
return;
|
|
2124
|
+
}
|
|
2125
|
+
authenticationWarningShown = true;
|
|
2126
|
+
if (isSigningBootstrapRequiredError(error)) {
|
|
2127
|
+
console.log(chalk.yellow("\u26A0\uFE0F Happy request signing initialization failed"));
|
|
2128
|
+
console.log(chalk.gray(' Run "hicloud auth login --force" to retry signing initialization.'));
|
|
2129
|
+
console.log(chalk.gray(" If it still fails, inspect the server response and local credentials state."));
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2132
|
+
console.log(chalk.yellow("\u26A0\uFE0F Happy authentication failed"));
|
|
2133
|
+
console.log(chalk.gray(' Run "hicloud auth login --force" to re-authenticate.'));
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2100
2136
|
function startOfflineReconnection(config) {
|
|
2101
2137
|
let reconnected = false;
|
|
2102
2138
|
let session = null;
|
|
@@ -2123,9 +2159,19 @@ function startOfflineReconnection(config) {
|
|
|
2123
2159
|
config.onNotify("\u2705 Reconnected! Session syncing in background.");
|
|
2124
2160
|
logger.debug("[OfflineReconnection] Successfully reconnected");
|
|
2125
2161
|
} catch (e) {
|
|
2162
|
+
if (isSigningBootstrapRequiredError(e)) {
|
|
2163
|
+
logger.debug("[OfflineReconnection] Signing bootstrap incomplete, stopping retries");
|
|
2164
|
+
config.onNotify("\u274C Request signing initialization failed. Re-run `hicloud auth login --force`; if it still fails, inspect the server response and local credentials state.");
|
|
2165
|
+
return;
|
|
2166
|
+
}
|
|
2126
2167
|
if (axios.isAxiosError(e) && e.response?.status === 401) {
|
|
2127
2168
|
logger.debug("[OfflineReconnection] Authentication error, stopping retries");
|
|
2128
|
-
config.onNotify("\u274C Authentication failed. Please re-authenticate with `
|
|
2169
|
+
config.onNotify("\u274C Authentication failed. Please re-authenticate with `hicloud auth`.");
|
|
2170
|
+
return;
|
|
2171
|
+
}
|
|
2172
|
+
if (isAuthenticationRequiredError(e)) {
|
|
2173
|
+
logger.debug("[OfflineReconnection] Authentication error, stopping retries");
|
|
2174
|
+
config.onNotify("\u274C Authentication failed. Please re-authenticate with `hicloud auth`.");
|
|
2129
2175
|
return;
|
|
2130
2176
|
}
|
|
2131
2177
|
failureCount++;
|
|
@@ -2170,7 +2216,7 @@ const ERROR_DESCRIPTIONS = {
|
|
|
2170
2216
|
EHOSTUNREACH: "server host unreachable",
|
|
2171
2217
|
ENETUNREACH: "network unreachable",
|
|
2172
2218
|
// HTTP errors
|
|
2173
|
-
"401": "authentication failed - run `
|
|
2219
|
+
"401": "authentication failed - run `hicloud auth`",
|
|
2174
2220
|
"403": "access forbidden",
|
|
2175
2221
|
"404": "endpoint not found, check server deployment",
|
|
2176
2222
|
"500": "server internal error",
|
|
@@ -2232,6 +2278,12 @@ class ApiClient {
|
|
|
2232
2278
|
this.credential = credential;
|
|
2233
2279
|
this.pushClient = new PushNotificationClient(credential, configuration.serverUrl);
|
|
2234
2280
|
}
|
|
2281
|
+
createAuthenticationError() {
|
|
2282
|
+
if (!this.credential.signing) {
|
|
2283
|
+
return new SigningBootstrapRequiredError(SIGNING_BOOTSTRAP_REQUIRED_MESSAGE);
|
|
2284
|
+
}
|
|
2285
|
+
return new AuthenticationRequiredError(AUTHENTICATION_REQUIRED_MESSAGE);
|
|
2286
|
+
}
|
|
2235
2287
|
async request(opts) {
|
|
2236
2288
|
return axios.request({
|
|
2237
2289
|
method: opts.method,
|
|
@@ -2316,6 +2368,11 @@ class ApiClient {
|
|
|
2316
2368
|
});
|
|
2317
2369
|
return null;
|
|
2318
2370
|
}
|
|
2371
|
+
if (axios.isAxiosError(error) && error.response?.status === 401) {
|
|
2372
|
+
const authError = this.createAuthenticationError();
|
|
2373
|
+
printAuthenticationRequiredWarning(authError);
|
|
2374
|
+
throw authError;
|
|
2375
|
+
}
|
|
2319
2376
|
if (axios.isAxiosError(error) && error.response?.status) {
|
|
2320
2377
|
const status = error.response.status;
|
|
2321
2378
|
if (status >= 500) {
|
|
@@ -2395,6 +2452,11 @@ class ApiClient {
|
|
|
2395
2452
|
}
|
|
2396
2453
|
if (axios.isAxiosError(error) && error.response?.status) {
|
|
2397
2454
|
const status = error.response.status;
|
|
2455
|
+
if (status === 401) {
|
|
2456
|
+
const authError = this.createAuthenticationError();
|
|
2457
|
+
printAuthenticationRequiredWarning(authError);
|
|
2458
|
+
throw authError;
|
|
2459
|
+
}
|
|
2398
2460
|
if (status === 403 || status === 409) {
|
|
2399
2461
|
console.log(chalk.yellow(
|
|
2400
2462
|
`\u26A0\uFE0F Machine registration rejected by the server with status ${status}`
|
|
@@ -2537,4 +2599,4 @@ var api = /*#__PURE__*/Object.freeze({
|
|
|
2537
2599
|
ApiClient: ApiClient
|
|
2538
2600
|
});
|
|
2539
2601
|
|
|
2540
|
-
export { ApiClient as A, HAPPY_CLOUD_DAEMON_PORT as H, ApiSessionClient as a, connectionState as b, configuration as c, backoff as d, encodeBase64 as e, delay as f, AsyncLock as g, buildAuthenticatedHeaders as h,
|
|
2602
|
+
export { ApiClient as A, HAPPY_CLOUD_DAEMON_PORT as H, SigningBootstrapRequiredError as S, ApiSessionClient as a, connectionState as b, configuration as c, backoff as d, encodeBase64 as e, delay as f, AsyncLock as g, buildAuthenticatedHeaders as h, isAuthenticationRequiredError as i, SIGNING_BOOTSTRAP_REQUIRED_MESSAGE as j, encodeBase64Url as k, logger as l, buildClientHeaders as m, decodeBase64 as n, getLatestDaemonLog as o, packageJson as p, api as q, startOfflineReconnection as s };
|
|
@@ -19,7 +19,7 @@ var path$1 = require('path');
|
|
|
19
19
|
var expoServerSdk = require('expo-server-sdk');
|
|
20
20
|
|
|
21
21
|
var name = "happy-imou-cloud";
|
|
22
|
-
var version = "2.0.
|
|
22
|
+
var version = "2.0.1";
|
|
23
23
|
var description = "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI";
|
|
24
24
|
var author = "long.zhu";
|
|
25
25
|
var license = "MIT";
|
|
@@ -102,7 +102,7 @@ var scripts = {
|
|
|
102
102
|
"unlink:dev": "node scripts/link-dev.cjs unlink"
|
|
103
103
|
};
|
|
104
104
|
var dependencies = {
|
|
105
|
-
"@agentclientprotocol/sdk": "^0.
|
|
105
|
+
"@agentclientprotocol/sdk": "^0.14.1",
|
|
106
106
|
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
107
107
|
"@stablelib/base64": "^2.0.1",
|
|
108
108
|
"@stablelib/hex": "^2.0.1",
|
|
@@ -433,7 +433,7 @@ async function listDaemonLogFiles(limit = 50) {
|
|
|
433
433
|
return { file, path: fullPath, modified: stats.mtime };
|
|
434
434
|
}).sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
435
435
|
try {
|
|
436
|
-
const { readDaemonState } = await Promise.resolve().then(function () { return require('./persistence-
|
|
436
|
+
const { readDaemonState } = await Promise.resolve().then(function () { return require('./persistence-C33AMdtv.cjs'); });
|
|
437
437
|
const state = await readDaemonState();
|
|
438
438
|
if (!state) {
|
|
439
439
|
return logs;
|
|
@@ -2099,6 +2099,42 @@ class PushNotificationClient {
|
|
|
2099
2099
|
}
|
|
2100
2100
|
}
|
|
2101
2101
|
|
|
2102
|
+
const AUTHENTICATION_REQUIRED_MESSAGE = 'Happy authentication failed. Run "hicloud auth login --force" to re-authenticate.';
|
|
2103
|
+
const SIGNING_BOOTSTRAP_REQUIRED_MESSAGE = 'Happy request signing initialization failed. Run "hicloud auth login --force" to retry. If it still fails, inspect the server response and local credentials state.';
|
|
2104
|
+
let authenticationWarningShown = false;
|
|
2105
|
+
class AuthenticationRequiredError extends Error {
|
|
2106
|
+
constructor(message = AUTHENTICATION_REQUIRED_MESSAGE) {
|
|
2107
|
+
super(message);
|
|
2108
|
+
this.name = "AuthenticationRequiredError";
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
function isAuthenticationRequiredError(error) {
|
|
2112
|
+
return error instanceof AuthenticationRequiredError;
|
|
2113
|
+
}
|
|
2114
|
+
class SigningBootstrapRequiredError extends AuthenticationRequiredError {
|
|
2115
|
+
constructor(message = SIGNING_BOOTSTRAP_REQUIRED_MESSAGE) {
|
|
2116
|
+
super(message);
|
|
2117
|
+
this.name = "SigningBootstrapRequiredError";
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
function isSigningBootstrapRequiredError(error) {
|
|
2121
|
+
return error instanceof SigningBootstrapRequiredError;
|
|
2122
|
+
}
|
|
2123
|
+
function printAuthenticationRequiredWarning(error) {
|
|
2124
|
+
if (authenticationWarningShown) {
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
2127
|
+
authenticationWarningShown = true;
|
|
2128
|
+
if (isSigningBootstrapRequiredError(error)) {
|
|
2129
|
+
console.log(chalk.yellow("\u26A0\uFE0F Happy request signing initialization failed"));
|
|
2130
|
+
console.log(chalk.gray(' Run "hicloud auth login --force" to retry signing initialization.'));
|
|
2131
|
+
console.log(chalk.gray(" If it still fails, inspect the server response and local credentials state."));
|
|
2132
|
+
return;
|
|
2133
|
+
}
|
|
2134
|
+
console.log(chalk.yellow("\u26A0\uFE0F Happy authentication failed"));
|
|
2135
|
+
console.log(chalk.gray(' Run "hicloud auth login --force" to re-authenticate.'));
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2102
2138
|
function startOfflineReconnection(config) {
|
|
2103
2139
|
let reconnected = false;
|
|
2104
2140
|
let session = null;
|
|
@@ -2125,9 +2161,19 @@ function startOfflineReconnection(config) {
|
|
|
2125
2161
|
config.onNotify("\u2705 Reconnected! Session syncing in background.");
|
|
2126
2162
|
logger.debug("[OfflineReconnection] Successfully reconnected");
|
|
2127
2163
|
} catch (e) {
|
|
2164
|
+
if (isSigningBootstrapRequiredError(e)) {
|
|
2165
|
+
logger.debug("[OfflineReconnection] Signing bootstrap incomplete, stopping retries");
|
|
2166
|
+
config.onNotify("\u274C Request signing initialization failed. Re-run `hicloud auth login --force`; if it still fails, inspect the server response and local credentials state.");
|
|
2167
|
+
return;
|
|
2168
|
+
}
|
|
2128
2169
|
if (axios.isAxiosError(e) && e.response?.status === 401) {
|
|
2129
2170
|
logger.debug("[OfflineReconnection] Authentication error, stopping retries");
|
|
2130
|
-
config.onNotify("\u274C Authentication failed. Please re-authenticate with `
|
|
2171
|
+
config.onNotify("\u274C Authentication failed. Please re-authenticate with `hicloud auth`.");
|
|
2172
|
+
return;
|
|
2173
|
+
}
|
|
2174
|
+
if (isAuthenticationRequiredError(e)) {
|
|
2175
|
+
logger.debug("[OfflineReconnection] Authentication error, stopping retries");
|
|
2176
|
+
config.onNotify("\u274C Authentication failed. Please re-authenticate with `hicloud auth`.");
|
|
2131
2177
|
return;
|
|
2132
2178
|
}
|
|
2133
2179
|
failureCount++;
|
|
@@ -2172,7 +2218,7 @@ const ERROR_DESCRIPTIONS = {
|
|
|
2172
2218
|
EHOSTUNREACH: "server host unreachable",
|
|
2173
2219
|
ENETUNREACH: "network unreachable",
|
|
2174
2220
|
// HTTP errors
|
|
2175
|
-
"401": "authentication failed - run `
|
|
2221
|
+
"401": "authentication failed - run `hicloud auth`",
|
|
2176
2222
|
"403": "access forbidden",
|
|
2177
2223
|
"404": "endpoint not found, check server deployment",
|
|
2178
2224
|
"500": "server internal error",
|
|
@@ -2234,6 +2280,12 @@ class ApiClient {
|
|
|
2234
2280
|
this.credential = credential;
|
|
2235
2281
|
this.pushClient = new PushNotificationClient(credential, configuration.serverUrl);
|
|
2236
2282
|
}
|
|
2283
|
+
createAuthenticationError() {
|
|
2284
|
+
if (!this.credential.signing) {
|
|
2285
|
+
return new SigningBootstrapRequiredError(SIGNING_BOOTSTRAP_REQUIRED_MESSAGE);
|
|
2286
|
+
}
|
|
2287
|
+
return new AuthenticationRequiredError(AUTHENTICATION_REQUIRED_MESSAGE);
|
|
2288
|
+
}
|
|
2237
2289
|
async request(opts) {
|
|
2238
2290
|
return axios.request({
|
|
2239
2291
|
method: opts.method,
|
|
@@ -2318,6 +2370,11 @@ class ApiClient {
|
|
|
2318
2370
|
});
|
|
2319
2371
|
return null;
|
|
2320
2372
|
}
|
|
2373
|
+
if (axios.isAxiosError(error) && error.response?.status === 401) {
|
|
2374
|
+
const authError = this.createAuthenticationError();
|
|
2375
|
+
printAuthenticationRequiredWarning(authError);
|
|
2376
|
+
throw authError;
|
|
2377
|
+
}
|
|
2321
2378
|
if (axios.isAxiosError(error) && error.response?.status) {
|
|
2322
2379
|
const status = error.response.status;
|
|
2323
2380
|
if (status >= 500) {
|
|
@@ -2397,6 +2454,11 @@ class ApiClient {
|
|
|
2397
2454
|
}
|
|
2398
2455
|
if (axios.isAxiosError(error) && error.response?.status) {
|
|
2399
2456
|
const status = error.response.status;
|
|
2457
|
+
if (status === 401) {
|
|
2458
|
+
const authError = this.createAuthenticationError();
|
|
2459
|
+
printAuthenticationRequiredWarning(authError);
|
|
2460
|
+
throw authError;
|
|
2461
|
+
}
|
|
2400
2462
|
if (status === 403 || status === 409) {
|
|
2401
2463
|
console.log(chalk.yellow(
|
|
2402
2464
|
`\u26A0\uFE0F Machine registration rejected by the server with status ${status}`
|
|
@@ -2543,6 +2605,8 @@ exports.ApiClient = ApiClient;
|
|
|
2543
2605
|
exports.ApiSessionClient = ApiSessionClient;
|
|
2544
2606
|
exports.AsyncLock = AsyncLock;
|
|
2545
2607
|
exports.HAPPY_CLOUD_DAEMON_PORT = HAPPY_CLOUD_DAEMON_PORT;
|
|
2608
|
+
exports.SIGNING_BOOTSTRAP_REQUIRED_MESSAGE = SIGNING_BOOTSTRAP_REQUIRED_MESSAGE;
|
|
2609
|
+
exports.SigningBootstrapRequiredError = SigningBootstrapRequiredError;
|
|
2546
2610
|
exports.api = api;
|
|
2547
2611
|
exports.backoff = backoff;
|
|
2548
2612
|
exports.buildAuthenticatedHeaders = buildAuthenticatedHeaders;
|
|
@@ -2554,6 +2618,7 @@ exports.delay = delay;
|
|
|
2554
2618
|
exports.encodeBase64 = encodeBase64;
|
|
2555
2619
|
exports.encodeBase64Url = encodeBase64Url;
|
|
2556
2620
|
exports.getLatestDaemonLog = getLatestDaemonLog;
|
|
2621
|
+
exports.isAuthenticationRequiredError = isAuthenticationRequiredError;
|
|
2557
2622
|
exports.logger = logger;
|
|
2558
2623
|
exports.packageJson = packageJson;
|
|
2559
2624
|
exports.startOfflineReconnection = startOfflineReconnection;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as createDefaultRuntimeShell } from './index-
|
|
1
|
+
import { c as createDefaultRuntimeShell } from './index-BByhFIIq.mjs';
|
|
2
2
|
import 'chalk';
|
|
3
|
-
import './api-
|
|
3
|
+
import './api-B5Ui8Fw0.mjs';
|
|
4
4
|
import 'axios';
|
|
5
5
|
import 'fs';
|
|
6
6
|
import 'node:fs';
|
|
@@ -17,7 +17,7 @@ import 'fs/promises';
|
|
|
17
17
|
import 'crypto';
|
|
18
18
|
import 'path';
|
|
19
19
|
import 'expo-server-sdk';
|
|
20
|
-
import './persistence-
|
|
20
|
+
import './persistence-CzpZpiL3.mjs';
|
|
21
21
|
import 'node:fs/promises';
|
|
22
22
|
import 'os';
|
|
23
23
|
import 'tmp';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-BOqJ9hwi.cjs');
|
|
4
4
|
require('chalk');
|
|
5
|
-
require('./api-
|
|
5
|
+
require('./api-B8v4tczT.cjs');
|
|
6
6
|
require('axios');
|
|
7
7
|
require('fs');
|
|
8
8
|
require('node:fs');
|
|
@@ -19,7 +19,7 @@ require('fs/promises');
|
|
|
19
19
|
require('crypto');
|
|
20
20
|
require('path');
|
|
21
21
|
require('expo-server-sdk');
|
|
22
|
-
require('./persistence-
|
|
22
|
+
require('./persistence-C33AMdtv.cjs');
|
|
23
23
|
require('node:fs/promises');
|
|
24
24
|
require('os');
|
|
25
25
|
require('tmp');
|